使用 Java 流查找不同的数组

Jam*_*udd 3 java java-stream

考虑这个代码

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());
Run Code Online (Sandbox Code Playgroud)

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

And*_*ner 5

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

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

这是有效的,因为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());
Run Code Online (Sandbox Code Playgroud)