【发布时间】:2015-03-12 16:07:06
【问题描述】:
我有两节课
答:
public class A {
private int intValue;
private String stringValue;
public A(int intValue, String stringValue) {
this.intValue = intValue;
this.stringValue = stringValue;
}
int getIntValue() {
return intValue;
}
String getStringValue() {
return stringValue;
}
}
和乙:
public class B {
private int intValue;
private String stringValue;
B(int intValue, String stringValue) {
this.intValue = intValue;
this.stringValue = stringValue;
}
int getIntValue() {
return intValue;
}
String getStringValue() {
return stringValue;
}
}
还有一些相当大的 A 对象数组。
我想有效地将A[] 转换为ArrayList<B>。我知道有几种方法可以做到这一点:
final A[] array = {new A(1, "1"), new A(2, "2")/*...*/};
// 1 - old-school
final List<B> list0 = new ArrayList<>(array.length);
for (A a : array) {
list0.add(new B(a.getIntValue(), a.getStringValue()));
}
// 2 - pretty mush same as 1
final List<B> list1 = new ArrayList<>(array.length);
Arrays.stream(array).forEach(a -> list1.add(new B(a.getIntValue(), a.getStringValue())));
// 3 - lambda-style
final List<B> list2 = Arrays.stream(array).map(a -> new B(a.getIntValue(), a.getStringValue())).collect(Collectors.toList());
// 4 - lambda-style with custom Collector
final List<B> list3 = Arrays.stream(array)
.map(a -> new B(a.getIntValue(), a.getStringValue()))
.collect(Collector.of((Supplier<List<B>>)() -> new ArrayList(array.length), List::add, (left, right) -> {
left.addAll(right);
return left;
}));
AFAIK 1 是最有效的。但是使用 java 8 的特性可以使它更短。 2 与 1 几乎相同,但 foreach 循环被流 foreach 替换。不确定它的有效性。 3 是最短的方法,但默认的Collectors.toList() 收集器使用默认的ArrayList::new 构造函数,这意味着如果我们有相当大的初始数组,ArrayList 中的数组将至少调整一次大小。所以效率不高。而 4,据我了解(尽管从未使用过这种方式)与 3 几乎相同,但在ArrayList 中为数组分配了单个内存。但它看起来很丑。
所以,我的问题是。我对这 4 种方法及其有效性是否正确?有没有其他简单有效的方法来做到这一点?
【问题讨论】:
-
@a_horse_with_no_name,
Arrays.asList()只将A[]转换为List<A>,这不是我想要的 -
@a_horse_with_no_name 对于可以附加到或从中删除的列表,
new ArrayList<>(Arrays.asList())。