Arrays.asList与Arrays.stream一起使用forEach()

如果您有一个Array并且想要使用Java8 forEach()方法,那么哪种方法更好或更有效:

Arrays.asList(new String[]{"hallo","hi"}).forEach(System.out::println); 

要么

 Arrays.stream(new String[]{"hallo","hi"}).forEach(System.out::println); 

差异是显着的还是有更好的解决方案来解决这个问题?

都不是。 如果你已经有一个arrays,

 String[] array; 

我会用:

 Arrays.stream(array).forEach(System.out::println); 

因为您将数组的转换保留为JDK的流 – 让它负责效率等。

但是,既然你没有数组,我会使用Stream.of()的varargs来创建一个值的流:

 Stream.of("hallo","hi").forEach(System.out::println); 

这再次让JDK负责在其认为合适时有效地传输值。

它似乎几乎完全没有区别。 我为此创建了一个测试类。 在五次运行的过程中,我的输出是这样的:

 Run 1: Arrays.asList() method................: 3231 ms Arrays.stream() method................: 3111 ms Stream.of() method....................: 3031 ms Arrays.asList() (premade array) method: 3086 ms Arrays.stream() (premade array) method: 3231 ms Stream.of() (premade array) method....: 3191 ms Run 2: Arrays.asList() method................: 3270 ms Arrays.stream() method................: 3072 ms Stream.of() method....................: 3086 ms Arrays.asList() (premade array) method: 3002 ms Arrays.stream() (premade array) method: 3251 ms Stream.of() (premade array) method....: 3271 ms Run 3: Arrays.asList() method................: 3307 ms Arrays.stream() method................: 3092 ms Stream.of() method....................: 2911 ms Arrays.asList() (premade array) method: 3035 ms Arrays.stream() (premade array) method: 3241 ms Stream.of() (premade array) method....: 3241 ms Run 4: Arrays.asList() method................: 3630 ms Arrays.stream() method................: 2981 ms Stream.of() method....................: 2821 ms Arrays.asList() (premade array) method: 3058 ms Arrays.stream() (premade array) method: 3221 ms Stream.of() (premade array) method....: 3214 ms Run 5: Arrays.asList() method................: 3338 ms Arrays.stream() method................: 3174 ms Stream.of() method....................: 3262 ms Arrays.asList() (premade array) method: 3064 ms Arrays.stream() (premade array) method: 3269 ms Stream.of() (premade array) method....: 3275 ms 

从输出看起来, Stream.of()方法看起来非常简单(但始终如一)是最有效的,并且

 Stream.of("hallo","hi").forEach(System.out::println); 

是非常易读的代码。 Stream.of的优点在于它不必将数组转换为列表,或创建数组然后创建流,但可以直接从元素创建流。 对我来说有点令人惊讶的是,由于我进行测试的方式,每次使用Stream.of()实例化一个新的数组流比通过一个预先制作的数组更快,可能是因为“捕获“lambdas – 引用外部变量的那些 – 效率稍差。

这是我的测试类的代码:

 import java.util.Arrays; import java.util.function.Consumer; import java.util.stream.Stream; public class StreamArrayTest { public static void main(String[] args){ System.out.println("Arrays.asList() method................: " + arraysAsListMethod() + " ms"); System.out.println("Arrays.stream() method................: " + arraysStreamMethod() + " ms"); System.out.println("Stream.of() method....................: " + streamOfMethod() + " ms"); System.out.println("Arrays.asList() (premade array) method: " + presetArraysAsListMethod() + " ms"); System.out.println("Arrays.stream() (premade array) method: " + presetArraysStreamMethod() + " ms"); System.out.println("Stream.of() (premade array) method....: " + presetStreamsOfMethod() + " ms"); } private static Long timeOneMillion(Runnable runner){ MilliTimer mt = MilliTimer.start(); for (int i = 0; i < 1000000; i++){ runner.run(); } return mt.end(); } private static Long timeOneMillion(String[] strings, Consumer consumer){ MilliTimer mt = MilliTimer.start(); for (int i = 0; i < 1000000; i++){ consumer.accept(strings); } return mt.end(); } public static Long arraysAsListMethod(){ return timeOneMillion(()->Arrays.asList(new String[]{"hallo","hi","test","test2","test3","test4","test5","test6","test7","test8"}).forEach(StreamArrayTest::doSomething)); } public static Long arraysStreamMethod(){ return timeOneMillion(()->Arrays.stream(new String[]{"hallo","hi","test","test2","test3","test4","test5","test6","test7","test8"}).forEach(StreamArrayTest::doSomething)); } public static Long streamOfMethod(){ return timeOneMillion(()->Stream.of("hallo","hi","test","test2","test3","test4","test5","test6","test7","test8").forEach(StreamArrayTest::doSomething)); } public static Long presetArraysAsListMethod(){ String[] strings = new String[]{"hallo","hi","test","test2","test3","test4","test5","test6","test7","test8"}; return timeOneMillion(strings, (s)->Arrays.asList(s).forEach(StreamArrayTest::doSomething)); } public static Long presetArraysStreamMethod(){ String[] strings = new String[]{"hallo","hi","test","test2","test3","test4","test5","test6","test7","test8"}; return timeOneMillion(strings, (s)->Arrays.stream(s).forEach(StreamArrayTest::doSomething)); } public static Long presetStreamsOfMethod(){ String[] strings = new String[]{"hallo","hi","test","test2","test3","test4","test5","test6","test7","test8"}; return timeOneMillion(strings, (s)->Stream.of(s).forEach(StreamArrayTest::doSomething)); } public static void doSomething(String s){ String result = s; for (int i = 0; i < 10; i++){ result = result.concat(s); } } } 

我使用的MilliTimer类:

 public class MilliTimer { private long startTime = 0L; private MilliTimer(long startTime){ this.startTime = startTime; } public static MilliTimer start(){ return new MilliTimer(System.currentTimeMillis()); } public long end() throws IllegalArgumentException { return System.currentTimeMillis() - startTime; } } 
 Arrays.asList() method................: 22 ms Arrays.stream() method................: 26 ms Stream.of() method....................: 26 ms Arrays.asList() (premade array) method: 8 ms Arrays.stream() (premade array) method: 30 ms Stream.of() (premade array) method....: 17 ms 

当您将doSomething更改为实际上不执行任何操作时,如下所示:

 public static void doSomething(String s){ } 

然后你测量这些操作的实际速度而不是操作String = String + String; 这就是doSomething正在做的事情,当然它的速度始终如一。 但是,实际速度并不相同,并且带有预制arrays的asList要快得多。

这里的实际结果已经被其他人注意到你应该注意流,因为它通常比普通的旧java(非lambda)方法慢4倍。