我今天了解到,您可以使用静态方法创建一个新的 ArrayList 对象,如下所示:
List<String> listDummy = Arrays.asList("Coding", "is", "fun");
ArrayList<String> stringList = new ArrayList<>(listDummy);
或者更简洁:
ArrayList<String> stringList = new ArrayList<>(Arrays.asList("Coding", "is", "fun"));
我的问题是:与“传统”方式相比,这种性能方式的成本有多高? (下)
ArrayList<String> stringList = new ArrayList<>();
stringList.add("Coding");
stringList.add("is");
stringList.add("fun");
我意识到创建 ArrayList 的上层方法包括创建额外的 List 对象,但是,我更喜欢更短、更紧凑的语法,在某种程度上我愿意牺牲一些性能,但必须在某处划清界限。
PS。将“new ArrayList<>()
”中的类型信息(<>)留空是 Java SE 7 功能,不是错误。
预先感谢您的回答!
如果有疑问,我总是说;尽可能简单明了地编写代码,它通常也能正常执行。
add()
方式调用三个方法。
asList()
方式创建一个数组,然后对其执行
clone()
(进行浅复制),然后由于这个错误而手动复制所有元素。之后,如果您想向
stringList
添加另一个元素,则必须增大数组并重新复制元素,因为所提供的元素的大小是准确的。 (所有这些都取决于实现并假设 Oracle JDK)对于三个元素,后者会更慢,但对于任何实际用途来说,它都可以忽略不计。对于许多元素,这两种方法的性能可能相同,而前一种方法可能
甚至会变得更慢。 写下你认为读起来最好的内容,性能损失很小,你不应该关心它,直到它证明自己是瓶颈。
总而言之,如果您追求 consice 语法,您可能会喜欢 Google Guava 的
:
List<String> stringList = Lists.newArrayList("Coding", "is", "fun");
我已经有一段时间没有使用经典的
ArrayList
构造函数了。
public static <T> List<T> asList(T... a) {
return new ArrayList<T>(a);
}
警告:该列表是只读的,因此如果您需要写入它,则需要使用 new ArrayList(..) 来包装它。
尽管如此,我认为使用 Arrays.asList 应该比使用重复调用“add”创建列表更好,因为 ArrayList 的内部数组是用正确的大小初始化的。所以最好的办法是
List<String> myList= Arrays.asList("Coding", "is", "fun");
// or if you need to write the list
List<String> myList = new ArrayList(Arrays.asList("Coding", "is", "fun"));
这也是最具可读性的恕我直言,对我来说可读性总是胜过非常小的性能提升,除非你真的需要额外的性能。如果您确实需要进行性能调整,请使用分析器。瓶颈通常出现在你意想不到的地方。分析器可以为您提供有关程序的哪些部分速度缓慢的准确信息,您可以根据需要对其进行优化。
List<String> listDummy = Arrays.asList("Coding", "is", "fun");
否则
new ArrayList<>(listDummy)
比手动逐一添加元素效率更高,参见ArrayList(Collection) src:
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
已优化:
1)它创建了精确大小的数组
2)它使用元素的本机复制
ArrayList<String> stringList = new ArrayList<>(){{
add("Coding");
add("is");
add("fun");
}};
这是一个匿名类,它是 ArrayList 的子类
,带有实例块。
如果您逐一添加项目,则会在目标数组内发生多次重新分配。
如果您一次添加整个集合,则只需进行一次分配,因为大小是事先已知的。
public static <T> ArrayList<T> asArrayList(T... args) {
ArrayList<T> list = new ArrayList<T>(args.length);
Collections.addAll(list, args);
return list;
}
这比
Arrays.asList
路线快一点。 (并不是说这对于硬编码列表来说真的很重要。)