【发布时间】:2017-08-28 10:23:15
【问题描述】:
我正在迭代 两个集合,并检查两个集合是否包含 相同的元素。我不能使用 Java 8。
一年后编辑:
我在问题中创建了方法来检查两个集合是否包含相同的元素,而没有考虑我将两个 Collection 实现传递给该方法这一事实。
但 Collection 并不能确定元素的排序方式。我正在迭代这些集合。因此,Collection 的某些实现可以按随机顺序保存元素,同时包含相同的元素。
两个集合都包含可比较的元素和内容
被定义为相等,如果所有元素都返回一个 x.compareTo(y) 和 0。
两个值被定义为不同,如果其中一个为空,另一个不为空。
我想找到一种优雅的方式来比较无效性并防止
对最终的 compareTo() 进行空检查。
我目前的实现:
public static <T extends Comparable<T>> boolean isSame(@Nullable Collection<T> a, @Nullable Collection<T> b) {
if (a == null || b == null) {
return (a == null && b == null);
}
if (a.size() != b.size()) {
return false;
}
Iterator<T> aIt = a.iterator();
Iterator<T> bIt = b.iterator();
while (aIt.hasNext()) {
T aValue = aIt.next();
T bValue = bIt.next();
if (aValue == null || bValue == null) {
if (aValue == null ^ bValue == null) {
return false;
}
//both null, don't compare, continue looping...
} else if (aValue.compareTo(bValue) != 0) {
return false;
}
}
return true;
}
如果两个值都为空,我想继续 while 循环,因为那是 定义为相等。
但我在这部分苦苦挣扎:
if (aValue == null || bValue == null) {
if (aValue == null ^ bValue == null) {
return false;
}
}
问题:
是否有一种更优雅、更易读的方法来比较 null,如果两者都不为 null,则进行进一步比较,如果只有一个为 null,则返回 false,如果两个值都为 null,则继续循环?强>
【问题讨论】:
-
if (aValue == null && bValue == null) continue;这不行吗? -
当然可以,但是在调用 compareTo 之前,我必须至少检查 aValue 是否为 null,否则它可能会因 NPE 而崩溃
-
天真的解决方案:为每个集合创建一个新列表,对每个列表进行排序,然后比较排序后的列表。更明智的方法:为每个集合创建一个计数映射,键是元素,值是集合中每个元素的计数(HashMap 允许以 null 作为键),然后比较两个映射是否相同条目,或者仅当它们各自的条目集相等时。
标签: java collections null iterator java-7