【发布时间】:2018-06-20 18:51:50
【问题描述】:
假设我有以下代码:
public Set<String> csvToSet(String src) {
String[] splitted = src.split(",");
Set<String> result = new HashSet<>(splitted.length);
for (String s : splitted) {
result.add(s);
}
return result;
}
所以我需要将一个数组转换为 Set。
Intellij Idea 建议将我的 for-each 循环替换为 Collection.addAll one-liner 所以我得到:
...
Set<String> result = new HashSet<>(splitted.length);
result.addAll(Arrays.asList(splitted));
return result;
完整的检查信息是:
在调用批量方法(例如 collection.addAll(listOfX) 时,可以替换循环中调用某些方法(例如 collection.add(x))时的此检查警告。 如果选中复选框“使用 Arrays.asList() 包装数组”,则即使原始代码迭代数组而批量方法需要 Collection,检查也会发出警告。在这种情况下,快速修复操作将使用 Arrays.asList() 调用自动包装一个数组。
从检查描述来看,它听起来像预期的那样工作。
如果我们参考关于将数组转换为 Set (How to convert an Array to a Set in Java) 的问题的最佳答案,建议使用相同的一行:
Set<T> mySet = new HashSet<T>(Arrays.asList(someArray));
尽管从数组创建一个 ArrayList 是 O(1),但我不喜欢创建一个额外的 List 对象的想法。
通常我相信 Intellij 检查并假设它不会提供任何效率较低的东西。
但今天我很好奇为什么两者:顶级 SO 答案和 Intellij Idea(使用默认设置)建议使用相同的单线创建无用的中间 List 对象,而自 JDK 6 以来还有一个 Collections.addAll(destCollection, yourArray)。
我看到的唯一原因是(检查和答案)都太旧了。如果是这样,这就是改进intellij想法并为提出Collections.addAll()的答案提供更多投票的原因:)
【问题讨论】:
-
你在问什么?哪个最好?第三个。
-
@AndyTurner 哪个最好,哪里最好 = 最高性能?
-
使用
asList(array)只是在数组周围包装一些方便的行为;这样做允许您使用HashSet构造函数,以便您可以创建集合并一步填充它。我不明白为什么会有任何性能下降。 -
@Derp 最好,因为它是最简洁的,并且创建该列表的性能影响 - 如果有的话 - 不值得担心。试图不创建列表是(可能没有根据的)微优化。这里经常重复的建议是:编写最易读的代码;如果您发现性能不足,请对其进行分析,并且只有当您发现 this 是瓶颈时,您才应该担心重写它。
-
@khelwood with for,没有对 Iterator 方法的调用,因此使用的委托较少,因此可能某些编译器循环优化在原始代码中效果更好(即软件流水线 en.wikipedia.org/wiki/Software_pipelining )。我认为 IntelliJ 做得不好
标签: java intellij-idea collections