Java 如何比较两个巨大的列表<;字符串>;在爪哇?
我的应用程序生成2个大列表(最多3.5个字符串记录)。我需要最好最快的方法来比较。目前我是这样做的:Java 如何比较两个巨大的列表<;字符串>;在爪哇?,java,arraylist,Java,Arraylist,我的应用程序生成2个大列表(最多3.5个字符串记录)。我需要最好最快的方法来比较。目前我是这样做的: List list1 = ListUtils.subtract(sourceDbResults, hiveResults); List list2 = ListUtils.subtract(hiveResults, sourceDbResults); 但正如我从jconsole看到的那样,这种方法在内存上非常昂贵,有时甚至在其上处理堆栈。有什么好的解决方案或想法吗 列表中的元素位置/顺序总是相
List list1 = ListUtils.subtract(sourceDbResults, hiveResults);
List list2 = ListUtils.subtract(hiveResults, sourceDbResults);
但正如我从jconsole看到的那样,这种方法在内存上非常昂贵,有时甚至在其上处理堆栈。有什么好的解决方案或想法吗
列表中的元素位置/顺序总是相同的,因此我不需要处理它。比较之后,我需要知道列表是否相同,如果不相同,则从这些列表中获得差异。减法非常适用于小列表。鉴于您已经说过两个列表已经排序,它们可以在O(N)时间内进行比较,这比当前使用ListUtils的解决方案快得多。下面的方法使用了一种类似于合并两个排序列表的算法,这两个排序列表可以在大多数教科书中找到
import java.util.*;
public class CompareSortedLists {
public static void main(String[] args) {
List<Integer> sourceDbResults = Arrays.asList(1, 2, 3, 4, 5, 8);
List<Integer> hiveResults = Arrays.asList(2, 3, 6, 7);
List<Integer> inSourceDb_notInHive = new ArrayList<>();
List<Integer> inHive_notInSourceDb = new ArrayList<>();
compareSortedLists(
sourceDbResults, hiveResults,
inSourceDb_notInHive, inHive_notInSourceDb);
assert inSourceDb_notInHive.equals(Arrays.asList(1, 4, 5, 8));
assert inHive_notInSourceDb.equals(Arrays.asList(6, 7));
}
/**
* Compares two sorted lists (or other iterable collections in ascending order).
* Adds to onlyInList1 any and all elements in list1 that are not in list2; and
* conversely to onlyInList2. The caller must ensure the two input lists are
* already sorted and should initialize onlyInList1 and onlyInList2 to empty,
* writable collections.
*/
public static <T extends Comparable<? super T>> void compareSortedLists(
Iterable<T> list1, Iterable<T> list2,
Collection<T> onlyInList1, Collection<T> onlyInList2) {
Iterator<T> it1 = list1.iterator();
Iterator<T> it2 = list2.iterator();
T e1 = it1.hasNext() ? it1.next() : null;
T e2 = it2.hasNext() ? it2.next() : null;
while (e1 != null || e2 != null) {
if (e2 == null) { // No more elements in list2, some remaining in list1
onlyInList1.add(e1);
e1 = it1.hasNext() ? it1.next() : null;
}
else if (e1 == null) { // No more elements in list1, some remaining in list2
onlyInList2.add(e2);
e2 = it2.hasNext() ? it2.next() : null;
}
else {
int comp = e1.compareTo(e2);
if (comp < 0) {
onlyInList1.add(e1);
e1 = it1.hasNext() ? it1.next() : null;
}
else if (comp > 0) {
onlyInList2.add(e2);
e2 = it2.hasNext() ? it2.next() : null;
}
else /* comp == 0 */ {
e1 = it1.hasNext() ? it1.next() : null;
e2 = it2.hasNext() ? it2.next() : null;
}
}
}
}
}
import java.util.*;
公共类比较列表{
公共静态void main(字符串[]args){
List sourceDbResults=Arrays.asList(1,2,3,4,5,8);
List hiveResults=Arrays.asList(2,3,6,7);
List inSourceDb_notInHive=new ArrayList();
List inHive_notInSourceDb=new ArrayList();
比较列表(
sourceDbResults、hiveResults、,
内包b_非内包,内包b_非内包b);
断言insourcedbu_notInHive.equals(Arrays.asList(1,4,5,8));
断言inHive_notInSourceDb.equals(Arrays.asList(6,7));
}
/**
*比较两个已排序的列表(或按升序排列的其他iterable集合)。
*仅向列表1中添加列表1中不在列表2中的任何和所有元素;以及
*与OnlyList2相反。调用方必须确保两个输入列表
*已排序,应将OnlyList1和OnlyList2初始化为空,
*可写集合。
*/
public static已重新打开。看起来不像的副本。在另一个问题中,列表长度仅为100000,并且由于未知原因导致内存不足。这个问题似乎更多地涉及算法。您只需要知道这两个列表是否相等吗?元素的顺序重要吗?是否需要其他类似的信息如果列表1是另一个列表的子集。你能更好地描述一下你比较这两个列表的意思吗?列表排序了吗?@KlitosKyriacou是的,列表排序了。我不需要解决这个问题
public static <T extends Comparable<? super T>> void compareSortedLists(
Iterable<T> list1, Iterable<T> list2,
Collection<T> onlyInList1, Collection<T> onlyInList2) {
PeekingIterator<T> it1 = new PeekingIterator<>(list1.iterator());
PeekingIterator<T> it2 = new PeekingIterator<>(list2.iterator());
while (it1.hasNext() && it2.hasNext()) {
int comp = it1.peek().compareTo(it2.peek());
if (comp < 0)
onlyInList1.add(it1.next());
else if (comp > 0)
onlyInList2.add(it2.next());
else /* comp == 0 */ {
it1.next();
it2.next();
}
}
it1.forEachRemaining(onlyInList1::add);
it2.forEachRemaining(onlyInList2::add);
}