如何将数组列表与现代Java的相等性进行比较?

2022-08-31 14:10:23

我有两个数组列表。

如何在不使用外部库的情况下轻松地将这些与Java 8及其功能的相等性进行比较?我正在寻找一个“更好”(更高级,更短,更有效)的解决方案,而不是像这样的暴力代码(未经测试的代码,可能包含拼写错误等,而不是问题的重点):

boolean compare(List<String[]> list1, List<String[]> list2) 
{
    // tests for nulls etc omitted
    if(list1.size() != list2.size()) {
       return false;
    }
    for(i=0; i<list1.size(); ++i) {
        if(!Arrays.equals(list1.get(i), list2.get(i))) {
            return false;
        }
    }
    return true;
}

或者,如果没有更好的方法,那也是一个有效的答案。

奖励:如果Java 9提供了Java 8可以提供的更好的方式,请随时提及它。

编辑:在查看了注释并了解了这个问题如何变得适度热门之后,我认为更好”应该包括在检查数组内容之前首先检查所有数组的长度,因为如果内部数组很长,这有可能更快地发现不等式。


答案 1

该循环至少可以流式传输,从而导致:for

return (list1.size()==list2.size() &&
        IntStream.range(0, list1.size())
                 .allMatch(i -> Arrays.equals(list1.get(i), list2.get(i)));

答案 2

1) 基于 Java 8 流的解决方案:

List<List<String>> first = list1.stream().map(Arrays::asList).collect(toList());
List<List<String>> second = list2.stream().map(Arrays::asList).collect(toList());
return first.equals(second);

2)更简单的解决方案(适用于Java 5 +):

return Arrays.deepEquals(list1.toArray(), list2.toArray());

3)关于您的新要求(首先检查包含的String数组长度),您可以编写一个泛型帮助器方法,对转换后的列表进行相等性检查:

<T, U> boolean equal(List<T> list1, List<T> list2, Function<T, U> mapper) {
    List<U> first = list1.stream().map(mapper).collect(toList());
    List<U> second = list2.stream().map(mapper).collect(toList());
    return first.equals(second);
}

那么解决方案可能是:

return equal(list1, list2, s -> s.length)
    && equal(list1, list2, Arrays::asList);