Par*_*vil 1 java arrays string arraylist variable-declaration
我正在使用
ArrayList<String> var1 = new ArrayList<>();
for(condition){
// Add items to var1
}
return var1.toArray(new String[]{})
Run Code Online (Sandbox Code Playgroud)
我的 IDE 建议我将最后一行更改为
return var1.toArray(String[]::new)
Run Code Online (Sandbox Code Playgroud)
这是更好的约定还是编译时或内存使用也有一些好处。
String[]::new是一个函数。它不创建新的字符串数组,它定义了一个创建新字符串数组的函数。这就像蛋糕和制作蛋糕的食谱之间的区别。一种由面粉和糖衣组成。另一种只是文字和纸张。完全不同的东西,但相关的,因为食谱让你做蛋糕(任何数量,甚至!)
String[]::new 是以下的简写*:
public String[] makeNewStringArray(int size) {
return new String[size];
}
Run Code Online (Sandbox Code Playgroud)
仅仅编写根本不会产生任何字符串数组;每次调用该函数时都会生成一个字符串数组。
例子:
IntFunction<String[]> stringArrayMaker = String[]::new;
String[] size10 = stringArrayMaker.apply(10);
Run Code Online (Sandbox Code Playgroud)
你写的有点不标准;new String[0]更标准。所以让我们比较new String[0]vs String[]::new。
这个参数唯一的一点是让 arraylist 知道你想要什么类型。您可能认为 arraylist 已经知道(ArrayList<String>毕竟它是一个!)但由于泛型擦除(一个相当复杂的主题),代码toArray无法知道您想要什么,因此,您必须指定。
new String[0]最终制作了一个长度为 0 的字符串数组,然后立即将其丢弃。这感觉很浪费,但垃圾收集就是这样,“快速垃圾”(创建和丢弃的对象非常快,从不与其他线程共享)几乎完全免费。此方法 ( toArray(T[])) 的工作原理如下: 如果传入的数组与所需的数组一样大或更大,则将其填充并返回。如果它太小,则会创建一个具有相同组件类型且大小合适的新数组,填充该数组,然后返回该数组。
因此,您会认为这var1.toArray(new String[var1.size()])是最有效的。但是 JMH 告诉我根本没有区别。这表明 Java 在处理短期垃圾方面的效率是多么令人难以置信(当我说“短期垃圾是免费的”时,我是认真的。几乎不可能见证它的成本)。
函数式方法(你通过的地方String[]::new)意味着这个函数将负责制作数组,toArray它本身只依赖于它得到的东西。这..也很好用。它最终会在您的类文件中的某个地方创建一个方法。
所以,真的无所谓。我发现 IDE 在这里过于说教了。String[]::new创建一个新方法,并且仅在类空间中的开销可能意味着它最终的效率较低,即使垃圾的创建更容易理解效率低下。
但是,我们在这里真的很挑剔。字面上谈论纳秒 - 你永远不会注意到。
做任何你认为最易读的事情(尽管我会避开new String[]{}- 它本身并没有错,但它不是很常见并且没有任何好处new String[0]- 如果它无关紧要,也可以做社区所做的事情)。
*) 这有点过于简化了,但不是太多。