【问题标题】:Is there a Comparator<List<T>> or Comparator<Collection<T>>?是否有 Comparator<List<T>> 或 Comparator<Collection<T>>?
【发布时间】:2014-08-28 12:15:00
【问题描述】:

我正在寻找一个实现以下之一的类

java.util.Comparator<int[]>
java.util.Comparator<List<T>>
java.util.Comparator<Collection<T>>

为什么Java标准库/Apache Common/Google Guava中没有这个类?

【问题讨论】:

  • 因为没有一个标准的方法来比较集合(按长度,按第一个元素的丑陋程度?),就像比较数字一样。
  • 我猜你在问是否有一个方便的类提供集合的lexicographical ordering。为此,您需要 Comparator&lt; List&lt;T extends Comparable&lt;T&gt; &gt; 或者您必须提供 Comparator&lt;T&gt;
  • 这就像问哪个汉堡最好,有没有办法比较汉堡(不同的美食杂志会有不同的汉堡比较)
  • @webuster 有一种比较字符串的标准方法,比较集合应该具有相同的行为
  • @Morad 您可以对字符串进行类比,这确实有道理,但我的意思是有些集合没有顺序/继承(想想Sets)字符串的方式。我相信你需要的是@Raedwald 的建议。

标签: java collections guava apache-commons-collection


【解决方案1】:

Guava 的 Ordering 类提供 Iterables 的字典顺序,它使用基 Ordering 来比较每对元素。

Ordering<T> elementOrdering = ...
Ordering<Iterable<T>> lexicographical = elementOrdering.lexicographical();

【讨论】:

    【解决方案2】:

    Apache Commons Collections 有一个 ComparatorChain,这可能是您正在寻找的。​​p>

    但是实现一个字典比较器也不是那么难:

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.List;
    
    public class LexicographicalComparatorsTest
    {
        public static void main(String[] args)
        {
            List<List<String>> lists = new ArrayList<List<String>>();
            lists.add(Arrays.asList("A", "B", "4"));
            lists.add(Arrays.asList("A", "B", "1"));
            lists.add(Arrays.asList("A", "B", "3"));
            lists.add(Arrays.asList("A", "B", "2"));
            lists.add(Arrays.asList("A", "A", "9"));
            lists.add(Arrays.asList("A", "C", "0"));
    
            Comparator<String> c = comparableComparator();
            Comparator<List<String>> cc = createCompatator(c);
    
            Collections.sort(lists, cc);
            for (List<String> list : lists)
            {
                System.out.println(list);
            }
        }
    
        private static <T extends Comparable<T>> Comparator<T> comparableComparator()
        {
            return new Comparator<T>()
            {
                @Override
                public int compare(T t0, T t1)
                {
                    return t0.compareTo(t1);
                }
            };
        }
    
        public static <T> Comparator<List<T>> createCompatator(
            final Comparator<T> comparator)
        {
            return new Comparator<List<T>>()
            {
                @Override
                public int compare(List<T> list0, List<T> list1)
                {
                    int n = Math.min(list0.size(), list1.size());
                    for (int i=0; i<n; i++)
                    {
                        T t0 = list0.get(i);
                        T t1 = list1.get(i);
                        int result = comparator.compare(t0, t1);
                        if (result != 0)
                        {
                            return result;
                        }
                    }
                    return 0;
                }
            };
        }
    }
    

    可以通过反转列表遍历方向来实现一个colexicographical比较器。

    此示例中的比较器也可以通过手动遍历从集合中获得的两个Iterator&lt;T&gt; 实例推广到Comparator&lt;Collection&lt;T&gt;&gt;

    【讨论】:

    • 您还需要根据列表的长度(“a”Ordering.lexicographical(),下面推荐,有这个的代码,所以如果你使用它,你会很好。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-28
    相关资源
    最近更新 更多