2022年8月1日 作者 zeroheart

stream流里面的操作整理

1.map,遍历或者拿到属性

items.stream().map(OrderItem::getOrderNo)
items.stream().map(orderItem->{
   xxx;
   return orderItem;
})

2.Collectors.toMap
https://blog.csdn.net/liuerchong/article/details/120279530
在实际项目中我们经常会用到 List 转 Map 操作 ->过去是for循环的操作,现在可以学习如下的方法Collectors.toMap

Map<String, String> mapHouse = houses.stream().collect(Collectors.toMap(House::getHousename, House::getAddress));
System.out.println(mapHouse);
//{aa=湖北武汉, bb=浙江杭州, cc=北京海淀}

/**
         * 收集一下属性和对象本身
         */
        Map<Integer, House> houseMap = houses.stream().collect(Collectors.toMap(House::getOwnerid, o -> o));
        Map<Integer, House> houseMap1 = houses.stream().collect(Collectors.toMap(House::getOwnerid,  Function.identity()));
        System.out.println(houseMap);
       /**
         * {1=House{id=1, ownerid=1, housename='aa', address='北京海淀'}, 
         * 2=House{id=2, ownerid=2, housename='bb', address='湖北武汉'}, 
         * 3=House{id=3, ownerid=3, housename='cc', address='浙江杭州'}}
         */

2.1java.lang.IllegalStateException: Duplicate key 问题处理
解决办法:出现重复时,取前面value的值,或者取后面放入的value值,则覆盖先前的value值
houses.stream().collect(Collectors.toMap(House::getOwnerid, House::getHousename,(v1,v2)->v2));
houses.stream().collect(Collectors.toMap(House::getOwnerid, House::getHousename,(v1,v2)->v1));


3. Function.identity()这个标识对象本身

4.Collectors.toList()
items.stream().map(OrderItem::getOrderNo).collect(Collectors.toList());
最基本的收集map的数据

5.Collectors.groupingBy
https://blog.csdn.net/u014231523/article/details/102535902

普通分组、属性拼接分组、二级分组、分组属性求和、分组数、联合其他收集器等

Map<String, Long> prodMap = prodList.stream().collect(Collectors.groupingBy(Product::getCategory, Collectors.counting()));
//{"啤酒":2,"零食":3}


Map<String, Integer> prodMap = prodList.stream().collect(Collectors.groupingBy(Product::getCategory, Collectors.summingInt(Product::getNum)));
//{"啤酒":13,"零食":6}

Map<String, Product> prodMap = prodList.stream().collect(Collectors.groupingBy(Product::getCategory, Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparingInt(Product::getNum)), Optional::get)));
//{"啤酒":{"category":"啤酒","id":5,"name":"百威啤酒","num":10,"price":15},"零食":{"category":"零食","id":3,"name":"月饼","num":3,"price":30}}


Map<String, Set<String>> prodMap = prodList.stream().collect(Collectors.groupingBy(Product::getCategory, Collectors.mapping(Product::getName, Collectors.toSet())));
//{"啤酒":["青岛啤酒","百威啤酒"],"零食":["面包","饼干","月饼"]}


6.Collectors.mapping
Collectors.mapping() 一般用于多重 map and reduce 中。 Java 文档中描述的原型如下

String nameByAge = list.stream().collect(Collectors.mapping(Person::getName, Collectors.joining(",", "[", "]")));
    System.out.println(nameByAge);
    nameByAge = list.stream().map(person -> person.getName()).collect(Collectors.joining(",", "[", "]"));
    System.out.println(nameByAge);

分组最大值
Map<Integer, Double> result = studentList.stream()
            .collect(Collectors.groupingBy(Student::getAge,
                    Collectors.mapping(Student::getScore, Collectors.maxBy(Integer::compareTo))));

分组集合
Map<Integer, Set<String>> result = studentList.stream()
            .collect(Collectors.groupingBy(Student::getAge, 
                    Collectors.mapping(Student::getName, Collectors.toSet())));

7.Collectors.reducing
https://blog.csdn.net/weixin_43939924/article/details/120904075

List<Integer> testData = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
		Optional<Integer> sum = testData.stream().collect(Collectors.reducing((prev, cur) -> {
			System.out.println("prev=>" + prev + "cur=>" + cur);
			return prev + cur;
		}));
		System.out.print(sum.get()); // 45


List<Integer> testData = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
		Integer sum = testData.stream().collect(Collectors.reducing(20, (prev, cur) -> {
			System.out.println("prev=>" + prev + "cur=>" + cur);
			return prev + cur;
		}));
		System.out.print(sum); //65



List<Integer> testData = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
		String joinStr = testData.stream().collect(Collectors.reducing("转换成字符串", in -> {
			return in + "";
		}, (perv, cur) -> {
			return perv + "," + cur;
		}));
		System.out.print(joinStr); // 转换成字符串,1,2,3,4,5,6,7,8,9


8.peek
peek方法和map方法的区别
1.peek方法是消费型接口。
调用peek方法后, 流还在。peek不需要return,直接改了值

2.map方法是函数型接口。
调用map方法后,流已经被消费。map需要return

peek() 的典型用法:协助调试

Stream.of("one", "two", "three", "four")
         .filter(e -> e.length() > 3)
         .peek(e -> System.out.println("Filtered value: " + e))
         .map(String::toUpperCase)
         .peek(e -> System.out.println("Mapped value: " + e))
         .collect(Collectors.toList());