Java 在集合集合中添加元素的最快方法

Java 在集合集合中添加元素的最快方法,java,treeset,Java,Treeset,我有一项任务要添加到treeset>10000000个按顺序排列的元素中 如果我使用 for (long index = 0; index < 10000000; index++) { result.add(index); } for(长索引=0;索引

我有一项任务要添加到treeset>10000000个按顺序排列的元素中

如果我使用

for (long index = 0; index < 10000000; index++)
    {
        result.add(index);
    }
for(长索引=0;索引<10000000;索引++)
{
结果:添加(索引);
}
需要8083毫秒。是否有任何解决方案来提高此任务的性能


另外,目前最快的方法是:
List range=IntStream.range(010000).boxed().collect(Collectors.toList())结果约370毫秒

如果您已经按正确的顺序添加了项目,树集将在每个添加的复杂项目后自行排序,LinkedHashSet只保留插入顺序

因此,如果您确实需要一个集合,请执行如下LinkedHashSet实现:

Set<Long> result = new LinkedHashSet<Long>();
for (Long index = 0L; index != 10000000L;) { //Avoid autoboxing
    result.add(index++);
}
Set result=new LinkedHashSet();
对于(长索引=0L;索引!=10000000L;){//避免自动装箱
结果.添加(索引++);
}
请看这里:
树集是一棵平衡的红黑树。由于每次添加新项目时都会平衡树,因此需要花费大量时间。尝试以不同的顺序添加项目;实际上,按照这个顺序:

  • 5000 000-介于0和10000 000之间(您的套装尺寸为10000 000)
  • 250万-介于0和5000万之间
  • 7500000-介于5000000和10000000之间
  • >0、2、500、000、的中间数 <Li>2、500、000和5、000、000、等等
这样,您将始终保持树的平衡,并且不会执行其他操作(以平衡树)。
只需确保计算下一个要添加的数字的算法不太复杂。

您真的需要收集吗?为甚么目的,若然? 实际上,使用普通数组可以大大提高性能

   long [] ar = new long[10000000];
    for (int i = 0; i < 10000000; i++) {
        ar[i] = (long )i;
    }

UPD:实际上,可以使用Arrays实用程序在阵列上执行大多数操作

long [] ar = new long[10000000];
for (int i = 0; i < 10000000; i++) {
    ar[i] = (long )i;
}

long[] copyOfRange = Arrays.copyOfRange(ar, 50000, 1000000);

试试HPPC:Java的高性能原语集合

许可证:Apache许可证2.0

<dependency>
  <groupId>com.carrotsearch</groupId>
  <artifactId>hppc</artifactId>
  <version>0.7.1</version>
</dependency>

搜索引擎
hppc
0.7.1
LongHashSet在1190ms内执行:

LongSet result = new LongHashSet();
for (Long index = 0L; index < 10000000L;) {
  result.add(index++);
}
LongSet result=new longhasset();
用于(长索引=0L;索引<10000000L;){
结果.添加(索引++);
}
LongScatterSet在850ms内执行:

LongSet result = new LongScatterSet();
for (Long index = 0L; index < 10000000L;) {
  result.add(index++);
}
LongSet结果=新的LongScatterSet();
用于(长索引=0L;索引<10000000L;){
结果.添加(索引++);
}

您真的需要一组从0到9999999的所有数字吗?也许维护一个补码集是有意义的(0到9999999之间的所有数字都不在原始集中)。补码集为空,因此初始化更快:)…Eran hi。问题是我尝试使用set来保存大范围的ip。甚至可能孔的范围为0.0.0.0-255.255.255.255。然后我想操纵它们,比如添加或删除范围。它必须是树集吗?它可能是位集吗?我可能会使用表示范围的数据结构,而不是单个IP。然后,您可以为每个范围开始设置一个集合,为每个范围结束设置另一个集合,从而使操作更加轻松。或者,您可以尝试一种类似位字段的方法,其中您有一个(相当长的)字节数组,每个位表示该地址的存在/不存在。形成3236 LinkedHashSet的时间比形成7595 Treeset的时间快两倍!他在评论中解释了这一点。它应该支持添加和删除项目。实际上,我在github上为您共享了该项目,这样您就可以看到它是如何在端口范围内工作的,但现在我可以肯定地说它在IP范围内不起作用。数据集太大。对于github链接,请观看第一篇文章。感谢大家,实际上,使用Arrays实用程序可以在阵列上执行大多数操作。查看我的答案更新。我找到了另一种方法:
List range=IntStream.range(0,10000000).boxed().collect(Collectors.toList())范围大小:10000000,需要时间形成-372毫秒是的,我以前试过。但在我的工作站上,这需要5.097秒。这是一个很好的解决方案,但现在我意识到了一个更优雅的解决方案,如果不是将ip保存为长数字,而是使用某种自制的类,可以容纳一个范围或一个ip。在将其保存到集合中之后。。。。
LongSet result = new LongHashSet();
for (Long index = 0L; index < 10000000L;) {
  result.add(index++);
}
LongSet result = new LongScatterSet();
for (Long index = 0L; index < 10000000L;) {
  result.add(index++);
}