使用时ToList(),是否需要考虑性能影响?
我正在编写一个查询来从目录中检索文件,这是查询:
string[] imageArray = Directory.GetFiles(directory);
但是,由于我喜欢与之合作List<>,我决定投入......
List<string> imageList = Directory.GetFiles(directory).ToList();
那么,在决定进行这样的转换时是否应该考虑某种性能影响 - 或者仅在处理大量文件时考虑?这是一个微不足道的转换?
我是一位经验丰富的Java开发人员,我一直在看这样的事情
List<Integer> l = new ArrayList<Integer>(0);
Run Code Online (Sandbox Code Playgroud)
我真的无法理解.ArrayList当你知道它将超出容量时,创建一个初始容量为0的重点是什么?
这样做有什么好处吗?
请注意,这与为什么启动具有初始容量的ArrayList 不重复?
查看java.util.ArrayList类的源代码,从至少java 1.8开始,我看到以下代码:
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
Run Code Online (Sandbox Code Playgroud)
哪里
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
Run Code Online (Sandbox Code Playgroud)
虽然javadoc正式声明:
构造一个初始容量为10的空列表.
我概述:......初始容量为10.这十个在哪里?
我是否完全疯了,错过了什么,或者这里只有一个javadoc错误?
UPD:它看起来像以前的Java 1.8:
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
/**
* Constructs an empty list with an initial capacity …Run Code Online (Sandbox Code Playgroud) 我有点困惑.在填充循环的第一次迭代中,我在使用initial capacityfor ArrayListvs而不使用初始容量时看到填充时间的一些回归.
根据常识和这个问题:为什么要启动具有初始容量的ArrayList?
它必须完全相反.
它不是很好的基准测试,我想知道:为什么在第一次迭代时它总是在使用初始容量时消耗更多的时间和CPU ArrayList?
这是测试:
public class TestListGen {
public static final int TEST = 100_000_000;
public static void main(String[] args) {
test(false);
}
private static void test(boolean withInitCapacity) {
System.out.println("Init with capacity? " + withInitCapacity);
for (int i = 0; i < 5; i++)
av += fillAndTest(TEST, withInitCapacity ? new ArrayList<Integer>(TEST) : new ArrayList<Integer>());
System.out.println("Average: " + (av / 5));
}
private static long fillAndTest(int capacity, …Run Code Online (Sandbox Code Playgroud) 我注意到实现动态数组非常常见(特别是在面试问题和家庭作业中); 通常,我看到的问题是:
实现一个阵列,当满了时容量翻倍
或者非常相似的东西.他们几乎总是(根据我的经验)明确地使用双词,而不是更一般
实现一个阵列,在满员时增加容量
我的问题是,为什么加倍?我理解为什么使用常量值是个坏主意(感谢这个问题),但似乎使用更大的倍数而不是双倍更有意义; 为什么不将容量增加三倍,或者将容量增加四倍,或者将其平方?
要清楚,我不是要问如何将数组的容量加倍,我问为什么加倍是常规.
我的问题可能听起来很愚蠢,但请先阅读整个问题.
我想知道很长一段时间,为什么ArrayList和其他类实现List,Set等,没有提供一个简单的构造函数来接受参数的变量计数?
List<Integer> list = new ArrayList<>(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)
这看起来简单明了.Java 9提供了新的List.of()静态工厂方法,它只复制Apache Utils和Guava引入的相同内容.我们被迫使用冗长的解决方法.
List<Integer> list = Arrays.asList(1, 2, 3);
List<Integer> list = Stream.of(1, 2, 3).collect(Collectors.toList());
List<Integer> list = new ArrayList<Integer>() {{ add(1); add(2); add(3); }};
Run Code Online (Sandbox Code Playgroud)
...除非我们乐意升级到Java 9或向上面的一个util库添加依赖项,或者创建一个扩展ArrayList和编写我们自己的构造函数的类.
最后,我问的问题:是什么原因使设计师省略了这个构造函数?
你可以说我已经存在一个构造函数ArrayList(int initialCapacity),它"构造一个具有指定初始容量的空列表"(同一页面的源代码) - 我知道这与我的想法相冲突,但说实话:我们多少次不得不提前声明ArrayList的大小?我们不需要具有用于ex的预定义值的ArrayList.单元测试数据?仅99.9%的情况下,默认情况下初始化new ArrayList<>()哪些调用是不够的this(10)?
每个List::add(..)调用一个方法来确保存储大量数据的数组的数组的大小,并且具有预定义大小的ArrayList的构造函数是受欢迎的 - 所以,为什么我们不使用数组?之后我们需要编辑大型数组吗?-将其添加到使用Arrays.asList(阵列)ArrayList中它要求System.arraycopy只是一次,或者我们可以的ensureCapacity.
这是我在浏览java.util中的一些类之后理解ArrayList的当前设计的方式.请纠正我的理解错误或知识不足的地方.
是否有任何技术问题解释为什么构造函数 new ArrayList<>(1, 2, 3) 没有实现?
我有一些类的ArrayList字段只是有时使用。我通常像这样初始化这些字段:
private List<Widget> widgets = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)
我了解使用重载构造函数来设置初始容量,所以我想知道是否应该这样声明这些字段:
private List<Widget> widgets = new ArrayList<>(0);
Run Code Online (Sandbox Code Playgroud)
困境在于,如果我用 0 初始化列表,那么列表将始终必须重新初始化自己才能添加一项。但是,如果我使用默认构造函数,它的默认容量为 10,那么我可能会有一堆项目(并且可能有很多)正在浪费未使用容量的内存。
我知道你们中的一些人会拒绝询问“多久一次”和“你期待多少项目”,但我真的在寻找“最佳实践”方法。所有事情都相等,是否应该使用有时使用的列表(0)或()在列表上进行初始化?
始终初始化列表是我们部门的政策,因此我可能不会简单地将列表保留为null,此外,这只会回避问题。
如果我知道那个点的大小,那么传递Collection给Collection构造函数的大小是否更好?扩展Collection和分配/重新分配的节约效果是否显着?
如果我知道最小尺寸Collection而不是上限,该怎么办?至少在最小尺寸的情况下仍然值得创造吗?
java ×7
arraylist ×5
arrays ×3
capacity ×2
collections ×2
constructor ×2
performance ×2
benchmarking ×1
c# ×1
jmh ×1
jvm ×1
jvm-hotspot ×1
list ×1