首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用forEach()的Arrays.asList与Arrays.stream

使用forEach()的Arrays.asList与Arrays.stream
EN

Stack Overflow用户
提问于 2014-12-10 07:50:15
回答 3查看 13.9K关注 0票数 16

如果您有一个数组,并且希望使用Java8 forEach()方法,哪种方法更好或更有效:

代码语言:javascript
复制
Arrays.asList(new String[]{"hallo","hi"}).forEach(System.out::println);

代码语言:javascript
复制
Arrays.stream(new String[]{"hallo","hi"}).forEach(System.out::println);

差异是否显着,或者有没有更好的解决方案?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-12-10 07:55:08

都不是。如果你已经有了一个数组,

代码语言:javascript
复制
String[] array;

我将使用:

代码语言:javascript
复制
Arrays.stream(array).forEach(System.out::println);

因为您将数组到流的转换留给了JDK -让它负责效率等。

但是,由于您没有数组,我将使用Stream.of()的varargs来创建一个值流:

代码语言:javascript
复制
Stream.of("hallo","hi").forEach(System.out::println);

这又一次让JDK负责在它认为合适的时候有效地流式传输这些值。

票数 20
EN

Stack Overflow用户

发布于 2014-12-12 06:17:35

这似乎完全没有什么不同。我为此创建了一个测试类。在五次运行过程中,我的输出是:

代码语言:javascript
复制
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()方法看起来是最有效的(但始终如此),并且

代码语言:javascript
复制
Stream.of("hallo","hi").forEach(System.out::println);

是可读性很强的代码。Stream.of的优势在于,它不必将数组转换为列表,也不必创建数组然后创建流,而是可以直接从元素创建流。让我有点惊讶的是,由于我做测试的方式,每次用Stream.of()实例化一个新的数组流比传递一个预制的数组更快,可能是因为“捕获”lambdas那些引用外部变量的lambdas的效率有点低。

下面是我的测试类的代码:

代码语言:javascript
复制
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类:

代码语言:javascript
复制
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;
    }
}
票数 12
EN

Stack Overflow用户

发布于 2018-06-09 13:25:05

代码语言:javascript
复制
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更改为实际不执行任何操作时,如下所示:

代码语言:javascript
复制
public static void doSomething(String s){
}

然后,您将测量这些操作的实际速度,而不是操作字符串=字符串+字符串;这就是doSomething正在做的事情,当然,它的速度大致相同。然而,实际的速度并不相同,使用预制数组的asList要快得多。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27391028

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档