如果您有一个数组,并且希望使用Java8 forEach()方法,哪种方法更好或更有效:
Arrays.asList(new String[]{"hallo","hi"}).forEach(System.out::println);或
Arrays.stream(new String[]{"hallo","hi"}).forEach(System.out::println);差异是否显着,或者有没有更好的解决方案?
发布于 2014-12-10 07:55:08
都不是。如果你已经有了一个数组,
String[] array;我将使用:
Arrays.stream(array).forEach(System.out::println);因为您将数组到流的转换留给了JDK -让它负责效率等。
但是,由于您没有数组,我将使用Stream.of()的varargs来创建一个值流:
Stream.of("hallo","hi").forEach(System.out::println);这又一次让JDK负责在它认为合适的时候有效地流式传输这些值。
发布于 2014-12-12 06:17:35
这似乎完全没有什么不同。我为此创建了一个测试类。在五次运行过程中,我的输出是:
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那些引用外部变量的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<String[]> 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;
}
}发布于 2018-06-09 13:25:05
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){
}然后,您将测量这些操作的实际速度,而不是操作字符串=字符串+字符串;这就是doSomething正在做的事情,当然,它的速度大致相同。然而,实际的速度并不相同,使用预制数组的asList要快得多。
这里的实际结果已经被其他人注意到了,你应该当心流,因为它通常比普通的老式java (非lambda)方法慢4倍。
https://stackoverflow.com/questions/27391028
复制相似问题