不区分大小写的显式排序番石榴
case insensitive explicit ordering guava
下面的代码 returns 输出 'ladies' 正确,因为区分大小写。
import com.google.common.collect.SortedSetMultimap;
import com.google.common.collect.TreeMultimap;
import com.google.common.collect.Ordering;
private static final Ordering<String> PRODUCT_ORDER = Ordering
.explicit("men","ladies")
.reverse();
private void testGuavaOrdering() {
SortedSetMultimap<Integer, String> onlineAreaPriorityCountMap = TreeMultimap
.create(Collections.reverseOrder(), PRODUCT_ORDER);
onlineAreaPriorityCountMap.put(1, "men");
onlineAreaPriorityCountMap.put(1, "men");
onlineAreaPriorityCountMap.put(1, "ladies");
onlineAreaPriorityCountMap.put(1, "ladies");
System.out.println(onlineAreaPriorityCountMap.values().iterator().next());
}
但是,下面的代码不起作用,如果我从 men 更改为 Men,则会抛出异常。
private static final Ordering<String> PRODUCT_ORDER = Ordering
.explicit("Men","Ladies")
.reverse()
private void testGuavaOrdering() {
SortedSetMultimap<Integer, String> onlineAreaPriorityCountMap = TreeMultimap
.create(Collections.reverseOrder(), PRODUCT_ORDER);
onlineAreaPriorityCountMap.put(1, "men");
onlineAreaPriorityCountMap.put(1, "men");
onlineAreaPriorityCountMap.put(1, "ladies");
onlineAreaPriorityCountMap.put(1, "ladies");
System.out.println(onlineAreaPriorityCountMap.values().iterator().next());
}
异常:
Exception in thread "main" com.google.common.collect.Ordering$IncomparableValueException: Cannot compare value: men
at com.google.common.collect.ExplicitOrdering.rank(ExplicitOrdering.java:46)
at com.google.common.collect.ExplicitOrdering.compare(ExplicitOrdering.java:40)
at com.google.common.collect.ReverseOrdering.compare(ReverseOrdering.java:38)
at java.util.TreeMap.compare(TreeMap.java:1295)
at java.util.TreeMap.put(TreeMap.java:538)
at java.util.TreeSet.add(TreeSet.java:255)
at com.google.common.collect.AbstractMapBasedMultimap.put(AbstractMapBasedMultimap.java:195)
at com.google.common.collect.AbstractSetMultimap.put(AbstractSetMultimap.java:121)
at com.google.common.collect.TreeMultimap.put(TreeMultimap.java:78)
at TestMap.testGuavaOrdering(TestMap.java:38)
at TestMap.main(TestMap.java:32)
如何在番石榴中进行不区分大小写的比较?
据我所知,您至少有 3 个选项(按生存能力递减,即我建议尽可能使用第一个选项):
- 为
TreeMultimap
提供一个自定义的 Comparator
,它可以根据需要处理大小写(请参阅 shmosel 的实现答案)。
- 为
ExplicitOrdering
提供一个 wrapper/factory,它在创建时和 rank()
方法中将所有值带到相同的大小写。如果您对为隐式排序传递的值没有影响,则可以使用它。但是,您也可以结合使用选项 1 进行比较(在将字符串输入 ExplicitOrdering
之前将字符串变为小写),并为构造函数提供一组预转换的输入字符串。
- 以不区分大小写的方式围绕实现
equals()
(和 hashcode()
)的字符串提供包装器。将它们用于您的订购以及地图键。
您不能使 Ordering
本身不区分大小写,但如果您可以将其值全部设为小写,则可以将其包装在 Comparator
中,在排名前将输入转换为小写:
private static final Ordering<String> PRODUCT_ORDER = Ordering
.explicit("men","ladies")
.reverse();
private static void testGuavaOrdering() {
SortedSetMultimap<Integer, String> onlineAreaPriorityCountMap = TreeMultimap
.create(Collections.reverseOrder(),
Comparator.comparing(String::toLowerCase, PRODUCT_ORDER));
onlineAreaPriorityCountMap.put(1, "Men");
onlineAreaPriorityCountMap.put(1, "men");
onlineAreaPriorityCountMap.put(1, "Ladies");
onlineAreaPriorityCountMap.put(1, "ladies");
System.out.println(onlineAreaPriorityCountMap.values().iterator().next());
}
下面的代码 returns 输出 'ladies' 正确,因为区分大小写。
import com.google.common.collect.SortedSetMultimap;
import com.google.common.collect.TreeMultimap;
import com.google.common.collect.Ordering;
private static final Ordering<String> PRODUCT_ORDER = Ordering
.explicit("men","ladies")
.reverse();
private void testGuavaOrdering() {
SortedSetMultimap<Integer, String> onlineAreaPriorityCountMap = TreeMultimap
.create(Collections.reverseOrder(), PRODUCT_ORDER);
onlineAreaPriorityCountMap.put(1, "men");
onlineAreaPriorityCountMap.put(1, "men");
onlineAreaPriorityCountMap.put(1, "ladies");
onlineAreaPriorityCountMap.put(1, "ladies");
System.out.println(onlineAreaPriorityCountMap.values().iterator().next());
}
但是,下面的代码不起作用,如果我从 men 更改为 Men,则会抛出异常。
private static final Ordering<String> PRODUCT_ORDER = Ordering
.explicit("Men","Ladies")
.reverse()
private void testGuavaOrdering() {
SortedSetMultimap<Integer, String> onlineAreaPriorityCountMap = TreeMultimap
.create(Collections.reverseOrder(), PRODUCT_ORDER);
onlineAreaPriorityCountMap.put(1, "men");
onlineAreaPriorityCountMap.put(1, "men");
onlineAreaPriorityCountMap.put(1, "ladies");
onlineAreaPriorityCountMap.put(1, "ladies");
System.out.println(onlineAreaPriorityCountMap.values().iterator().next());
}
异常:
Exception in thread "main" com.google.common.collect.Ordering$IncomparableValueException: Cannot compare value: men
at com.google.common.collect.ExplicitOrdering.rank(ExplicitOrdering.java:46)
at com.google.common.collect.ExplicitOrdering.compare(ExplicitOrdering.java:40)
at com.google.common.collect.ReverseOrdering.compare(ReverseOrdering.java:38)
at java.util.TreeMap.compare(TreeMap.java:1295)
at java.util.TreeMap.put(TreeMap.java:538)
at java.util.TreeSet.add(TreeSet.java:255)
at com.google.common.collect.AbstractMapBasedMultimap.put(AbstractMapBasedMultimap.java:195)
at com.google.common.collect.AbstractSetMultimap.put(AbstractSetMultimap.java:121)
at com.google.common.collect.TreeMultimap.put(TreeMultimap.java:78)
at TestMap.testGuavaOrdering(TestMap.java:38)
at TestMap.main(TestMap.java:32)
如何在番石榴中进行不区分大小写的比较?
据我所知,您至少有 3 个选项(按生存能力递减,即我建议尽可能使用第一个选项):
- 为
TreeMultimap
提供一个自定义的Comparator
,它可以根据需要处理大小写(请参阅 shmosel 的实现答案)。 - 为
ExplicitOrdering
提供一个 wrapper/factory,它在创建时和rank()
方法中将所有值带到相同的大小写。如果您对为隐式排序传递的值没有影响,则可以使用它。但是,您也可以结合使用选项 1 进行比较(在将字符串输入ExplicitOrdering
之前将字符串变为小写),并为构造函数提供一组预转换的输入字符串。 - 以不区分大小写的方式围绕实现
equals()
(和hashcode()
)的字符串提供包装器。将它们用于您的订购以及地图键。
您不能使 Ordering
本身不区分大小写,但如果您可以将其值全部设为小写,则可以将其包装在 Comparator
中,在排名前将输入转换为小写:
private static final Ordering<String> PRODUCT_ORDER = Ordering
.explicit("men","ladies")
.reverse();
private static void testGuavaOrdering() {
SortedSetMultimap<Integer, String> onlineAreaPriorityCountMap = TreeMultimap
.create(Collections.reverseOrder(),
Comparator.comparing(String::toLowerCase, PRODUCT_ORDER));
onlineAreaPriorityCountMap.put(1, "Men");
onlineAreaPriorityCountMap.put(1, "men");
onlineAreaPriorityCountMap.put(1, "Ladies");
onlineAreaPriorityCountMap.put(1, "ladies");
System.out.println(onlineAreaPriorityCountMap.values().iterator().next());
}