有没有人知道类似于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子类来解决这个问题,该子类将它的数据存储划分为更小的ArrayLists。任何需要ArrayList扫描特定项目数据的进程都会为每个较小的ArrayLists生成一个新的搜索线程(以利用我的多个CPU核心)。
但是这个系统不起作用,因为当调用搜索的线程在任何ArrayLists中同步一个项时,它可以阻止那些单独的搜索线程完成搜索,从而锁定原始线程在这个过程中称为搜索,基本上使整个程序陷入僵局。
我真的需要某种数据存储类,以便能够像PC一样快速地包含和操作大量对象。
有什么想法吗?
答案 0 :(得分:1)
我真的需要某种数据存储类,以便能够像PC一样快速地包含和操作大量对象。
答案很大程度上取决于您所谈论的数据类型以及您需要的具体操作。你使用的工作&#34;探索&#34;没有定义它。
如果您正在讨论查找记录,那么对于线程操作,没有什么比HashMap
- ConcurrentHashMap
更好。如果你在谈论保持秩序,特别是在处理线程时,那么我建议ConcurrentSkipListMap
具有O(logN)查找,插入,删除等。
您可能还想考虑使用多个集合。您需要注意,集合不会失去同步,这对于线程来说尤其具有挑战性,但根据您正在进行的各种操作,这可能会更快。
当ArrayList的大小为几百万左右时,重新排列数组中项目位置的所有周期将花费大量时间。
如上所述,ConcurrentSkipListMap
是O(logN),用于重新排列项目。即删除并添加新职位。
幕后的[
ArrayList.remove(i)
]代码运行如下:......
嗯,不是真的。你可以看一下code in the JDK吧? ArrayList
使用System.arraycopy(...)
进行此类操作。它们可能对你的情况没有效率,但它不是O(N)
。
答案 1 :(得分:0)
链接列表的良好用法的一个示例是列表元素非常大,即。足够大,只有一两个可以同时适应CPU缓存。此时,用于迭代的连续块容器(如矢量或数组)的优势或多或少地无效,并且如果实时发生许多插入和移除,则可能具有性能优势。
参考:Under what circumstances are linked lists useful?
参考:https://coderanch.com/t/508171/java/Collection-datastructure-large-data
答案 2 :(得分:0)
不同的集合类型对于各种操作具有不同的时间复杂度。典型的复杂性是:O(1),O(N)和O(log(N))。要选择集合,首先需要确定经常使用的操作,并避免对该操作具有O(N)复杂性的集合。在这里,您经常使用操作ArrayList.remove(i)
,即O(N)。更糟糕的是,您使用remove(i)
而非remove(element)
。如果remove(element)
是唯一经常使用的操作,则LinkedList
可以提供帮助,其remove(element)
为O(1),但LinkedList.remove(i)
也为O(N)。< / p>
我怀疑可以实现List
具有remove(i)
复杂度的O(1)。最好的时间是O(log(N)),这肯定比O(N)好。 Java标准库没有这样的实现。您可以尝试通过“二进制索引树”关键字进行谷歌搜索。
但我要做的第一件事就是检查算法并尝试摆脱List.remove(i)
操作。