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

Java 不区分大小写的显式排序番石榴,java,guava,Java,Guava,下面的代码正确返回输出'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

下面的代码正确返回输出'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());
    }

如何在番石榴中进行不区分大小写的比较

在我看来,您至少有3种选择(在下降可行性方面,即,如果可能,我建议使用第一种):

  • TreeMultimap
    提供一个自定义的
    比较器
    ,该比较器可根据需要处理案例(有关实现,请参阅shmosel的答案)
  • explicitorOrdering
    提供一个包装器/工厂,它在创建时和
    rank()
    方法中将所有值带到相同的大小写中。如果对传递给隐式排序的值没有影响,则可以使用它。但是,您也可以使用选项1的组合来进行比较(在将字符串馈送到
    explicitorOrdering
    之前将其小写),并将预转换的输入字符串数组馈送给构造函数
  • 在以不区分大小写的方式实现
    equals()
    (和
    hashcode()
    )的字符串周围提供一个包装器。将这些用于您的订购以及地图键

  • 您不能使
    排序
    本身不区分大小写,但如果您可以使其值全部小写,则可以将其包装在
    比较器
    中,该比较器在排序之前将输入转换为小写:

    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());
    }
    
    私有静态最终订购产品\u订单=订购
    .明确(“男性”、“女性”)
    .reverse();
    私有静态void testGuavaOrdering(){
    SortedSetMultimap Online Area PriorityCountMap=TreeMultimap
    .create(Collections.reverseOrder(),
    比较(字符串::toLowerCase,乘积_顺序));
    onlineAreaPriorityCountMap.put(1,“男性”);
    onlineAreaPriorityCountMap.put(1,“男性”);
    onlineAreaPriorityCountMap.put(1,“女士”);
    onlineAreaPriorityCountMap.put(1,“女士”);
    System.out.println(onlineAreaPriorityCountMap.values().iterator().next());
    }
    
    案例变化不应该出现在目标地图中吗?还是明确的顺序超出了您的控制范围?对于所有一直标记为重复的人,请仔细阅读问题。如果您仍然认为另一个答案是相关的,请测试它以确认。我不认为这是一个重复的问题,因为我有自定义的显式顺序。关于第3点,您还需要覆盖
    compareTo()
    @sargue no,因为
    explicitorOrdering
    不会调用元素上的
    compareTo()
    ,而是在映射中进行秩查找。除此之外,这些元素不需要实现
    Comparable
    ,因此不能保证有
    compareTo()
    可以覆盖。我不理解您的第二种解决方案。介意举个例子吗?@shmosel这似乎有点让人困惑,因为选项1和2非常相似。基本上,选项2与您建议的解决方案类似,但如果您无法控制给定的顺序或不想控制,则可以将作为显式顺序传递的值以小写形式置于重写构造函数或工厂方法中。@Thomas我认为这是不可能的。Guava的内部类/方法的可见性非常有限。
    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)
    
    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());
    }