- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
考虑以下代码:
List<String> myList = Arrays.asList(1, 2, 3);
String[] myArray1 = myList.toArray(new String[myList.size()]);
String[] myArray2 = myList.stream().toArray(String[]::new);
assert Arrays.equals(myArray1, myArray2);
在我看来,使用流要简单得多。
因此,我测试了每一个的速度。
List<String> myList = Arrays.asList("1", "2", "3");
double start;
start = System.currentTimeMillis();
for (int i = 0; i < 10_000_000; i++) {
String[] myArray1 = myList.toArray(new String[myList.size()]);
assert myArray1.length == 3;
}
System.out.println(System.currentTimeMillis() - start);
start = System.currentTimeMillis();
for (int i = 0; i < 10_000_000; i++) {
String[] myArray2 = myList.stream().toArray(String[]::new);
assert myArray2.length == 3;
}
System.out.println(System.currentTimeMillis() - start);
结果是使用流大约慢四倍。在我的机器上,816 毫秒(流)与 187 毫秒(无流)。我还尝试切换计时语句(myArray2 在 myArray1 之前),这对结果影响不大。为什么这么慢?创建 Stream
的计算量如此之大吗?
我听从了@Holger 的建议并研究了一些(当然还不够)JVM 测试,阅读 this post , this article , this article ,并使用 JMH .
结果(通过 JMH):
private static final List<String> myList = IntStream.range(1, 1000).mapToObj(String::valueOf).collect(Collectors.toList());
@Benchmark
public void testMethod() {
String[] myArray = myArrayList.stream().toArray(String[]::new);
}
StreamToArrayArrayListBenchmark.testMethod avgt 5 2846.346 ± 32.500 ns/op
private static final List<String> myList = IntStream.range(1, 1000).mapToObj(String::valueOf).collect(Collectors.toList());
@Benchmark
public void testMethod() {
String[] myArray = myArrayList.toArray(new String[0]);
}
ToArrayEmptyArrayListBenchmark.testMethod avgt 5 1417.474 ± 20.725 ns/op
private static final List<String> myList = IntStream.range(1, 1000).mapToObj(String::valueOf).collect(Collectors.toList());
@Benchmark
public void testMethod() {
String[] myArray = myArrayList.toArray(new String[myList.size()]);
}
ToArraySizedArrayListBenchmark.testMethod avgt 5 1853.622 ± 178.351 ns/op
private static final List<String> myList = new LinkedList<>(IntStream.range(1, 1000).mapToObj(String::valueOf).collect(Collectors.toList()));
@Benchmark
public void testMethod() {
String[] myArray = myArrayList.stream().toArray(String[]::new);
}
StreamToArrayLinkedListBenchmark.testMethod avgt 5 4152.003 ± 59.281 ns/op
private static final List<String> myList = new LinkedList<>(IntStream.range(1, 1000).mapToObj(String::valueOf).collect(Collectors.toList()));
@Benchmark
public void testMethod() {
String[] myArray = myArrayList.toArray(new String[0]);
}
ToArrayEmptyLinkedListBenchmark.testMethod avgt 5 4089.550 ± 29.880 ns/op
private static final List<String> myList = new LinkedList<>(IntStream.range(1, 1000).mapToObj(String::valueOf).collect(Collectors.toList()));
@Benchmark
public void testMethod() {
String[] myArray = myArrayList.toArray(new String[myList.size()]);
}
ToArraySizedArrayListBenchmark.testMethod avgt 5 4115.557 ± 93.964 ns/op
总结:
| ArrayList | LinkedList
stream | 2846 | 4152
toArray sized | 1853 | 4115
toArray empty | 1417 | 4089
使用 JMH(可能天真),我仍然看到 ArrayList::toArray
大约是 Stream::toArray
的两倍。然而,这似乎是因为 ArrayList
只进行数组复制的能力,正如@Andreas 指出的那样,因为当源是 LinkedList
时,结果是大致相等。
了解myList.toArray(new String[0])
绝对是件好事。
最佳答案
Arrays.asList()
创建一个固定大小的 List
,它直接由 varargs 数组参数支持。 Javadoc 甚至这样说:
Returns a fixed-size list backed by the specified array.
其对toArray()
的实现是一个简单的 System.arraycopy()
. 非常快。
另一方面,当您执行 myList.stream().toArray(String[]::new)
时,大小未知,因此 Stream.toArray()
方法必须使用流、收集所有值、然后创建数组并将值复制到数组中。这要慢很多,并且需要很多更多内存。
简而言之,这是一种资源浪费。
如果您想要更简单,请不要给出数组大小。它仍然比使用 Streams 更快且内存占用更少:
String[] myArray1 = myList.toArray(new String[0]);
关于java - Collection.toArray() 与 Collection.stream().toArray(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42012471/
我一直在学习如何使用 java 进行编程,但对于 LinkedList 的 toArray(T[] a) 的区别我还没有得到任何明确的解释和 toArray() 方法。第二个简单地将 LinkedLi
查看 java 集合框架的 java api,我在 HashSet 中找不到 toArray() 方法,抽象类 Set 中有 toArray() 方法。 class Ideone { publ
对不起,如果我问的是愚蠢的问题,但任何人都可以解释以下两个调用 (ToArray) 之间的区别。在智能感知中,它不会将它们显示为重载方法,当然这两个调用的输出是相同的。 List i = new Li
考虑以下代码: List myList = Arrays.asList(1, 2, 3); String[] myArray1 = myList.toArray(new String[myList.s
我有一个ArrayList叫listtable 。由于某种原因Clause[] whatever = listtable.toArray()给出不兼容的类型错误,但 Clause[] whatever
我从不使用重载版本的 toArray Object[] toArray(Object[] a) 将集合转换为数组。 下面是我的javacode- public class Track { publi
我需要将 ID 列表转换为 ID 数组。我可以通过多种方式做到这一点,但不确定应该使用哪一种。 说, 1. ids.stream().toArray(Id[]::new) 2. ids.toArray
我试图通过在类中实现 List 接口(interface)来稍微调整 List。 我可以毫无问题地重写和实现所有方法,除了这个: T[] toArray(T[] a); Android Studio
我对 Node.js 和 MongoDB 非常陌生,正在尝试拼凑我自己的博客应用程序。我在尝试通过我的“博客”模型查询具有特定用户名的模型时遇到问题。当我尝试运行时: var userBlogs =
根据 toArray() 的 java 文档返回包含此集合中所有元素的数组。 和 toArray(Object obj[])。返回包含此集合中所有元素的数组;返回数组的运行时类型是指定数组的类型。 第
当尝试从 IEnumerable 对象集合中获取对象数组时(与我想要的数组不同的转换方式),我知道我可以先将源集合转换为正确的类型,然后从中获取数组,但是方法 ToArray() 给我的印象是它可以一
这些查询之间有区别吗?我很想知道 mongo 如何解释传递给 map 方法的 javascript 代码与查询解析后的映射。 db.collection('myCollection').find()
假设我有一个 ArrayList ArrayList myList; 我想调用toArray,是否有性能原因需要使用 MyClass[] arr = myList.toArray(new MyClas
我有一个 List在 Java 中,并希望将其转换为数组。 起初,我使用以数组作为输入的 toArray 语法,但后来我切换到无参数版本,即我从: String[] myArray = myList.
我最近在使用某种网络方法时遇到了很多问题: void CheckGfiHelpdesks(string ticket, GfiCheck[] newHelpdeskChecks, GfiCheck[]
我在我的项目中使用 angular-filter 按页面对输出对象进行排序,问题是当我使用这样的语法时: {{key}} {{dziecko.rodzina}} {{dzi
Laravel 5.8 我懒惰地将用户加载到与 crmaccount 对象具有一对一关系的相关客户 这些模型正在工作,因此当我检索预先加载的实体时,它会显示所有嵌套关系。 一行之后,我对该对象使用了“
我有一个简单的问题。 这是我的代码,问题是当我运行一些表情符号时,它会将它们显示为?,因为它将表情符号切成两半。 angular.module('Joe.filters').filter("initi
我想我已经陷入困境。由于性能原因,我正在尝试利用Java parallelStream。 函数Specimen.pick()采样并返回Specimen的实例。 我想在替换池时使用parallelStr
我写了这段代码,这是一个评级系统。我想要发生的是,当你将鼠标悬停在一颗星星上时,它应该触发之前的星星。 每当我将鼠标悬停在星星上时,图片就会发生变化,但它之前的星星不会改变。
我是一名优秀的程序员,十分优秀!