java8 stream中的map误区

场景:

通过stream将 List<A>转化为List<B> 。 其中B类中存在某个方法 

public B fromA(A a);

具体代码如下

package cn.zwy;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class StreamTest {

    public static void main(String[] args) {
        List<String> names = new ArrayList<>();
        names.add("zhou");
        names.add("wen");
        List<User> users = names.stream().map(new User()::setName).collect(Collectors.toList());
        System.out.println(users);
    }

    static class User {
        private String name;

        public String getName() {
            return name;
        }

        public User setName(String name) {
            this.name = name;
            return this;
        }

        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }
}

此处代码有误:

List<User> users = names.stream().map(new User()::setName).collect(Collectors.toList());

输出结果如下:

[User{name='wen'}, User{name='wen'}]

 

原因解析:

官网描述:

Method References
You use lambda expressions to create anonymous methods. Sometimes, however, a lambda expression does nothing but call an existing method. In those cases, it’s often clearer to refer to the existing method by name. Method references enable you to do this; they are compact, easy-to-read lambda expressions for methods that already have a name.

上步的代码等效于

        User user = new User();
        List<User> users = names.stream().map(user::setName).collect(Collectors.toList());

map内并不是每个数据进来就执行new User().setName方法。该方式只是注册一个对象,并一直调用该方法

正确处理方式应该为:

List<User> users = names.stream().map(name->new User().setName(name)).collect(Collectors.toList());

或者

static class User {
        private String name;

        public User() {
        }

        public User(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public User setName(String name) {
            this.name = name;
            return this;
        }

        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }
List<User> users = names.stream().map(User::new).collect(Collectors.toList());

 

map这个有点诡异,对于lambda的说明有点模棱两可

以上

 

posted @ 2021-06-24 11:37  周周周文阳  阅读(255)  评论(0编辑  收藏  举报