stream() 必须搭配collect() ?

原先无法执行{}内的代码

    attrs.stream().map((attr) -> {
      SkuSaleAttrValueEntity skuSaleAttrValue = new SkuSaleAttrValueEntity();
      skuSaleAttrValue.setAttrId(attr.getAttrId());
      skuSaleAttrValueService.save(skuSaleAttrValue);
      return null;
    });

后来 ,增加了.collect(Collectors.toList())后就可以执行{}内的代码了

    attrs.stream().map((attr) -> {
      SkuSaleAttrValueEntity skuSaleAttrValue = new SkuSaleAttrValueEntity();
      skuSaleAttrValue.setAttrId(attr.getAttrId());
      skuSaleAttrValueService.save(skuSaleAttrValue);
      return null;
    })).collect(Collectors.toList());

请问我的猜想对么?
感激不尽

直接用简单的例子告诉你结论是错的

public class Main {

    public static void main(String[] args) {
        List<A> list = new ArrayList<>();
        list.add(new A("a", 1));
        list.add(new A("b", 2));
        list.add(new A("c", 3));
        System.out.println(list);
        list.stream().map(p -> {
            if ("b".equals(p.getName())) {
                p.setAge(4);
            }
            return p;
        });
        System.out.println(list);
        list.stream().forEach(p -> {
            if ("b".equals(p.getName())) {
                p.setAge(5);
            }
        });
        System.out.println(list);
    }

    static class A {
        private String name;

        private Integer age;

        A(String name, Integer age) {
            this.name = name;
            this.age = age;
        }

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

        public String getName() {
            return name;
        }

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

        public Integer getAge() {
            return age;
        }

        public void setAge(Integer age) {
            this.age = age;
        }
    }
}

运行结果:
图片说明

stream()是将list转成流, collect()可以将流转成list。
两个不同的结果是因为map方法与forEach方法的区别。

是的,这是java8 stream的规定写法。需要collect转换成stream

Java stream的操作分为两种函数,终结函数和非终结函数,而且stream还是延迟调用,只有当调用到forEach、collect这种终结函数是才会真正的进行实际的调用