Rom*_*man 118 java arrays collections transformation
假设我们有一个Collection<Foo>.什么是最好的(在当前环境中最短的LoC)方式将其转换为Foo[]?任何知名的图书馆都是允许的.
UPD:(更多的情况在本节中,发表评论,如果你认为这是值得创建另一个线程它):关于什么转变Collection<Foo>到Bar[]那里Bar与1个型参数有构造函数Foo,即public Bar(Foo foo){ ... }?
dou*_*lep 243
x集合在哪里:
Foo[] foos = x.toArray(new Foo[x.size()]);
Run Code Online (Sandbox Code Playgroud)
Jul*_*les 34
使用Java 8更新问题的替代解决方案:
Bar[] result = foos.stream()
.map(x -> new Bar(x))
.toArray(size -> new Bar[size]);
Run Code Online (Sandbox Code Playgroud)
And*_*s_D 10
如果您多次使用它或在循环中使用它,您可以定义一个常量
public static final Foo[] FOO = new Foo[]{};
Run Code Online (Sandbox Code Playgroud)
并进行转换
Foo[] foos = fooCollection.toArray(FOO);
Run Code Online (Sandbox Code Playgroud)
该toArray方法将采用空数组来确定目标数组的正确类型,并为您创建一个新数组.
这是我的更新建议:
Collection<Foo> foos = new ArrayList<Foo>();
Collection<Bar> temp = new ArrayList<Bar>();
for (Foo foo:foos)
temp.add(new Bar(foo));
Bar[] bars = temp.toArray(new Bar[]{});
Run Code Online (Sandbox Code Playgroud)
与JDK / 11,转换的替代方式Collection<Foo>,以一个Foo[]可利用的Collection.toArray(IntFunction<T[]> generator)为:
Foo[] foos = fooCollection.toArray(new Foo[0]); // before JDK 11
Foo[] updatedFoos = fooCollection.toArray(Foo[]::new); // after JDK 11
Run Code Online (Sandbox Code Playgroud)
正如@Stuart 在邮件列表(重点是我的)中所解释的那样,它的性能应该与现有的性能基本相同Collection.toArray(new T[0])——
结果是使用
Arrays.copyOf() 的实现是最快的,可能是因为它是一个内在的.它可以避免对新分配的数组进行零填充,因为它知道整个数组内容将被覆盖。无论公共 API 是什么样子,这都是正确的。
JDK 中 API 的实现内容如下:
default <T> T[] toArray(IntFunction<T[]> generator) {
return toArray(generator.apply(0));
}
Run Code Online (Sandbox Code Playgroud)
默认实现调用
generator.apply(0)获取零长度数组,然后简单地调用toArray(T[]). 这通过Arrays.copyOf()快速路径,因此它的速度基本上与toArray(new T[0]).
注意:- 只是当用于带有值的代码时,API 的使用应与向后不兼容一起进行指导,null例如,toArray(null)因为这些调用现在由于存在toArray(T[] a)而变得不明确并且将无法编译。
如果您在项目中使用 Guava,则可以使用Iterables::toArray.
Foo[] foos = Iterables.toArray(x, Foo.class);
Run Code Online (Sandbox Code Playgroud)