【发布时间】:2017-09-01 07:36:28
【问题描述】:
有谁知道类似于 ArrayList 的东西,它更适合尽快处理大量数据?
我有一个带有非常大的 ArrayList 的程序,当它试图探索或修改 ArrayList 时,它会变得阻塞。
大概当你这样做时:
//i is an int;
arrayList.remove(i);
幕后的代码运行如下:
public T remove(int i){
//Let's say ArrayList stores it's data in a T [] array called "contents".
T output = contents[i];
T [] overwrite = new T [contents.length - 1];
//Yes, I know generic arrays aren't created this simply. Bear with me here...
for(int x=0;x<i;x++){
overwrite[x] = contents[x];
}
for(int x=i+1;x<contents.length;x++){
overwrite[x-1] = contents[x];
}
contents = overwrite;
return output;
}
当 ArrayList 的大小为几百万个单位左右时,所有这些重新排列数组中项目位置的循环将花费大量时间。
我试图通过创建我自己的自定义 ArrayList 子类来缓解这个问题,该子类将它的数据存储分割成更小的 ArrayList。任何需要 ArrayList 扫描特定项目的数据的进程都会为其中的每个较小的 ArrayList 生成一个新的搜索线程(以利用我的多个 CPU 内核)。
但是这个系统不起作用,因为当调用搜索的线程在任何 ArrayList 中同步了一个项目时,它可以阻止那些单独的搜索线程完成它们的搜索,这反过来又锁定了调用在搜索过程中,本质上使整个程序死锁。
我真的需要某种数据存储类,以在 PC 的能力范围内尽可能快地包含和操作大量对象。
有什么想法吗?
【问题讨论】:
-
尝试使用 LinkedList
-
数组怎么样?当然,它需要一些辅助函数。
-
我会使用 ConcurrentLinkedHashMap
-
我倾向于以 DUP 身份关闭 stackoverflow.com/questions/559839/… ...但现在:请检查该页面是否为您提供了开始所需的信息。
-
与您的假设相反,
ArrayList.remove实现通常只是从i+1..end到i..end-1执行 System.arrayCopy。他们不分配任何额外的空间。 (请记住,ArrayList 的支持数组通常大于 ArrayList 的大小。) System.arrayCopy 通常是本机代码并且速度非常快。您确定是remove方法占用了 CPU 时间吗?
标签: java multithreading arraylist large-data-volumes