突变流中的元素 [英] Mutate elements in a Stream

查看:126
本文介绍了突变流中的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否存在改变流中元素的'最佳实践'?我特意指的是流管道中的元素,而不是它之外的元素。

Is there a 'best practice' for mutating elements within a Stream? I'm specifically referring to elements within the stream pipeline, not outside of it.

例如,考虑我想要获取用户列表的情况,设置一个null属性的默认值并将其打印到控制台。

For example, consider the case where I want to get a list of Users, set a default value for a null property and print it to the console.

假设用户类:

class User {
    String name;

    static User next(int i) {
        User u = new User();
        if (i % 3 != 0) {
            u.name = "user " + i;
        }
        return u;
    }
}

在java 7中,它有点像线条of:

In java 7 it'd be something along the lines of:

for (int i = 0; i < 7; i++) {
    User user = User.next(i);
    if(user.name == null) {
        user.name = "defaultName";
    }
    System.out.println(user.name);
}

在java 8中,似乎我会使用.map()和返回对mutated对象的引用:

In java 8 it would seem like I'd use .map() and return a reference to the mutated object:

IntStream.range(0, 7)
    .mapToObj(User::next)
    .map(user -> {
        if (user.name == null) {
            user.name = "defaultName";
        }
        return user;
    })
    //other non-terminal operations
    //before a terminal such as .forEach or .collect
    .forEach(it -> System.out.println(it.name));

有没有更好的方法来实现这一目标?也许使用.filter()来处理null变异然后连接未过滤的流和过滤的流?有些巧妙使用Optional?目标是能够在终端.forEach()之前使用其他非终端操作。

Is there a better way to achieve this? Perhaps using .filter() to handle the null mutation and then concat the unfiltered stream and the filtered stream? Some clever use of Optional? The goal being the ability to use other non-terminal operations before the terminal .forEach().

在流的'精神'中我试图这样做而没有中间集合和简单的纯操作,不依赖于管道外的副作用。

In the 'spirit' of streams I'm trying to do this without intermediary collections and simple 'pure' operations that don't depend on side effects outside the pipeline.

编辑:官方Stream java doc说明'少量流操作,例如forEach()和peek(),只能通过副作用运行;这些应该谨慎使用。鉴于这将是一个不干扰的操作,具体是什么使它危险?我看到的例子到达管道之外,这显然是粗略的。

The official Stream java doc states 'A small number of stream operations, such as forEach() and peek(), can operate only via side-effects; these should be used with care.' Given that this would be a non-interfering operation, what specifically makes it dangerous? The examples I've seen reach outside the pipeline, which is clearly sketchy.

推荐答案

不要改变对象,映射到直接名称:

Don't mutate the object, map to the name directly:

IntStream.range(0, 7)
    .mapToObj(User::next)
    .map(user -> user.name)
    .map(name -> name == null ? "defaultName" : name)
    .forEach(System.out::println);

这篇关于突变流中的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆