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倍。
- 用于DAO和Web服务的数据库插入方法的Junit测试用例
- WCF FaultException 是否支持与Java Web服务错误的互操作
- 在Microsoft Azure Web App中部署WAR FILE
- 将ZipEntry复制到新ZipFile的惯用方法是什么?
- 在OS启动时自动运行Java应用程序
- Java robot.mouseMove(x,y)没有产生正确的结果
- Eclipse Mac OS X调试错误:“本机方法中的致命错误:JDWP没有传输初始化,jvmtiError = AGENT_ERROR_TRANSPORT_INIT(197)”
- 在调用getter之后执行业务逻辑
- Java:将背景图像添加到框架