不区分大小写的显式排序番石榴

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 个选项(按生存能力递减,即我建议尽可能使用第一个选项):

  1. TreeMultimap 提供一个自定义的 Comparator,它可以根据需要处理大小写(请参阅 shmosel 的实现答案)。
  2. ExplicitOrdering 提供一个 wrapper/factory,它在创建时和 rank() 方法中将所有值带到相同的大小写。如果您对为隐式排序传递的值没有影响,则可以使用它。但是,您也可以结合使用选项 1 进行比较(在将字符串输入 ExplicitOrdering 之前将字符串变为小写),并为构造函数提供一组预转换的输入字符串。
  3. 以不区分大小写的方式围绕实现 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());
}