为了将Integer数组转换为整数列表,我尝试了以下方法:
初始化列表(整数类型),遍历数组并插入列表
使用Java 8 Streams:
int[] ints = {1, 2, 3};
List<Integer> list = new ArrayList<Integer>();
Collections.addAll(list, Arrays.stream(ints).boxed().toArray(Integer[]::new));
在性能方面哪个更好?
答案 0 :(得分:44)
第二个创建一个新的整数数组(第一次传递),然后将这个新数组的所有元素添加到列表中(第二次传递)。因此它的效率低于第一个,它只进行一次通过,并且不会创建一个不必要的整数数组。
使用流的更好方法是
List<Integer> list = Arrays.stream(ints).boxed().collect(Collectors.toList());
与第一个应该具有大致相同的性能。
请注意,对于如此小的阵列,不会有任何显着差异。您应该尝试编写正确,可读,可维护的代码,而不是关注性能。
答案 1 :(得分:42)
只需尝试类似
的内容Arrays.asList(array)
答案 2 :(得分:11)
如果您不想更改列表:
List<Integer> list = Arrays.asList(array)
但是如果你想修改它,那么你可以使用它:
List<Integer> list = new ArrayList<Integer>(Arrays.asList(ints));
或者只使用 java8 ,如下所示:
List<Integer> list = Arrays.stream(ints).collect(Collectors.toList());
Java9 引入了这种方法:
List<Integer> list = List.of(ints);
但是,这将返回一个无法添加的不可变列表。
您需要执行以下操作才能使其变为可变:
List<Integer> list = new ArrayList<Integer>(List.of(ints));
答案 3 :(得分:1)
如果您正在处理String []而不是int [],我们可以使用
ArrayList<String> list = new ArrayList<>();
list.addAll(Arrays.asList(StringArray));
答案 4 :(得分:1)
如果您不介意第三方依赖,您可以使用本机支持原始集合的库,如Eclipse Collections,并完全避免装箱。如果需要,您还可以使用原始集合来创建盒装常规集合。
int[] ints = {1, 2, 3};
MutableIntList intList = IntLists.mutable.with(ints);
List<Integer> list = intList.collect(Integer::valueOf);
如果你想要最后的盒装集合,这就是collect
上IntArrayList
的代码在幕后做的事情:
public <V> MutableList<V> collect(IntToObjectFunction<? extends V> function)
{
return this.collect(function, FastList.newList(this.size));
}
public <V, R extends Collection<V>> R collect(IntToObjectFunction<? extends V> function,
R target)
{
for (int i = 0; i < this.size; i++)
{
target.add(function.valueOf(this.items[i]));
}
return target;
}
由于这个问题是关于性能的,所以我使用你的解决方案编写了一些JMH基准测试,这是最受欢迎的答案以及Eclipse Collections的原始和盒装版本。
import org.eclipse.collections.api.list.primitive.IntList;
import org.eclipse.collections.impl.factory.primitive.IntLists;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@State(Scope.Thread)
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@Fork(2)
public class IntegerArrayListFromIntArray
{
private int[] source = IntStream.range(0, 1000).toArray();
public static void main(String[] args) throws RunnerException
{
Options options = new OptionsBuilder().include(
".*" + IntegerArrayListFromIntArray.class.getSimpleName() + ".*")
.forks(2)
.mode(Mode.Throughput)
.timeUnit(TimeUnit.SECONDS)
.build();
new Runner(options).run();
}
@Benchmark
public List<Integer> jdkClassic()
{
List<Integer> list = new ArrayList<>(source.length);
for (int each : source)
{
list.add(each);
}
return list;
}
@Benchmark
public List<Integer> jdkStreams1()
{
List<Integer> list = new ArrayList<>(source.length);
Collections.addAll(list,
Arrays.stream(source).boxed().toArray(Integer[]::new));
return list;
}
@Benchmark
public List<Integer> jdkStreams2()
{
return Arrays.stream(source).boxed().collect(Collectors.toList());
}
@Benchmark
public IntList ecPrimitive()
{
return IntLists.immutable.with(source);
}
@Benchmark
public List<Integer> ecBoxed()
{
return IntLists.mutable.with(source).collect(Integer::valueOf);
}
}
这些是我的Mac Book Pro上的这些测试的结果。单位是每秒的操作数,因此数字越大越好。我使用ImmutableIntList
作为ecPrimitive
基准,因为Eclipse Collections中的MutableIntList
默认情况下不会复制数组。它只是适应你给它的数组。这报告了ecPrimitive
的更大数字,误差幅度非常大,因为它实质上是衡量单个对象创建的成本。
# Run complete. Total time: 00:06:52
Benchmark Mode Cnt Score Error Units
IntegerArrayListFromIntArray.ecBoxed thrpt 40 191671.859 ± 2107.723 ops/s
IntegerArrayListFromIntArray.ecPrimitive thrpt 40 2311575.358 ± 9194.262 ops/s
IntegerArrayListFromIntArray.jdkClassic thrpt 40 138231.703 ± 1817.613 ops/s
IntegerArrayListFromIntArray.jdkStreams1 thrpt 40 87421.892 ± 1425.735 ops/s
IntegerArrayListFromIntArray.jdkStreams2 thrpt 40 103034.520 ± 1669.947 ops/s
如果有人发现基准测试的任何问题,我会很乐意进行更正并再次运行它们。
注意:我是Eclipse Collections的提交者。
答案 5 :(得分:0)
Arrays.stream(ints).forEach(list::add);
这基本上用2(使用Java 8)执行1(在数组上迭代)。 (其中1和2代表您的原始问题)
答案 6 :(得分:0)
其中stateb是列表'' 存储桶是二维数组
statesb = IntStream.of(bucket [j-1])。boxed()。collect(Collectors.toList());
与 导入java.util.stream.IntStream;
请参阅https://examples.javacodegeeks.com/core-java/java8-convert-array-list-example/
答案 7 :(得分:0)
第一种方法更好,第二种方法花费更多时间创建新数组并转换为列表
答案 8 :(得分:-3)
老路但仍在工作!
int[] values = {1,2,3,4};
List<Integer> list = new ArrayList<>(values.length);
for(int valor : values) {
list.add(valor);
}