【问题标题】:Find distinct arrays with Java stream使用 Java 流查找不同的数组
【发布时间】:2021-05-12 11:13:03
【问题描述】:

考虑这段代码

String[] colours1 = new String[]{"red", "green", "blue"};
String[] colours2 = new String[]{"red", "yellow", "blue"};
String[] colours3 = new String[]{"red", "green", "blue"};

List<String[]> distinct = Stream.of(colours1, colours2, colours3)
        .distinct() // Do something here to compare arrays better
        .collect(Collectors.toList());

我希望 distinct 列表仅包含 2 个元素 colours1colours2(因为 1 和 3 是等价的)。但是,由于流 distinct() 方法执行等于比较,它仍然包含所有 3 种颜色数组。我想要一个自定义的独特功能,您可以在其中提供比较器。在这种情况下,Objects#deepEquals 就足够了。有没有简单的方法来实现这一点?

【问题讨论】:

    标签: java java-stream


    【解决方案1】:

    将数组包装在列表中,使用distinct(),再次打开它们:

    Stream.of(colours1, colours2, colours3)
        .map(Arrays::asList)
        .distinct()
        .map(list -> list.toArray(new String[0]))
        .collect(toList())
    

    这是可行的,因为List.equals 认为如果两个列表具有相同的内容(元素数量相同,并且两个列表中相应位置的元素相等),则它们是相等的。

    但是,这不会返回相同的数组实例。如果您在最终列表中需要(某些)相同的数组实例,您可以执行以下操作:

    class MyArrayList<T> extends AbstractList<T> {
      final T[] arr;
    
      MyArrayList(T[] arr) { this.arr = arr; }
      @Override public int size() { return arr.length; }
      @Override public T get(int i) { return arr[i]; }
    }
    
    List<String> distinct =
        Stream.of(colours1, colours2, colours3)
            .map(MyArrayList::new)
            .distinct()
            .map(el -> el.arr)
            .collect(toList());
    

    【讨论】:

      猜你喜欢
      • 2019-05-10
      • 1970-01-01
      • 1970-01-01
      • 2016-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多