【发布时间】:2018-09-28 15:33:50
【问题描述】:
我有两个非常大的ArrayList,每个都包含数百万个数据。我想从List1 中过滤掉List2 中不存在的数据和/或反之亦然。
我尝试了 Apache CollectionUtils,Java 8 流 API 没有任何成功。
Java 8 并行流正在消耗所有 CPU,CollectionUtils 继续比较数据集而没有任何输出。
POJO 示例
public DataVO {
private String id;
private String value;
...
// getters / setters
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = (prime * result) + ((id == null) ? 0 : id.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
...
...
final DataVO other = (DataVO) obj;
if (id == null) {
if (other.id != null) {
return false;
}
}
else if (!id.equals(other.id)) {
return false;
}
return true;
}
}
hashCode() / equals() 可以有更多字段,现在我保持简单。
我还尝试将List1 拆分为更小的块,然后尝试与List2 进行比较,但没有任何结果。我查看了其他问题,但没有一个问题考虑过大容量。
如果您有任何指示,请告诉我。
【问题讨论】:
-
如果您要交叉比较列表中的数百万个项目,则需要时间和内存。您可能需要进行一些完整性检查日志记录(例如,每 100k 打印一次当前项目的索引或其他内容),以便您至少可以看到(a)它正在取得任何进展,以及(b)它是否/在哪里陷入困境或者仅仅是因为您必须多次迭代多个列表。一般来说,你不想这样做。
-
您是否尝试将第一个数组放入集合,然后遍历第二个集合并检查元素是否在集合中?
-
您需要了解集合的运行时复杂性。在 List 中查找对象是 O(N) ,使得整个过程 O(M*N)。在 HashSet 中找到一个对象是 O(1)。因此,将其中一个列表(最小的一个)变成一个 HashSet,检查另一个列表的元素是否存在于 Set 中。这将使过程 O(M)。
-
这些数组是否已排序?如果是,我们将使用类似于“合并排序”的算法来解决问题。
-
感谢大家的反馈。我需要提取丢失的数据,顺序无关紧要。如果 list1=[1,2,3,4] 和 list2=[4,3,5,6] 那么输出应该是 list=[1,2]。由于大小,Apache CollectionUtils
substract或removeAll都不起作用。我会试试HashSet,希望能奏效。
标签: java list collections