使用Java stream查找不同的数组

4

考虑以下代码

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”列表只包含两个元素“colours1”和“colours2”(因为1和3是等效的)。但是由于流“distinct()”方法执行相等比较,它仍然包含所有3种颜色数组。我想要一个自定义的distinct功能,可以提供一个比较器。在这种情况下,“Objects#deepEquals”就足够了。有简单的方法来实现这个吗?
1个回答

5

将数组包装在列表中,使用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());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接