package com.tonis.demo;
import com.tonis.demo.entity.User;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class StreamTest {
public static void main(String[] args) {
// stream實例例化
// 數組
String[] str = {"a", "b","c"};
Stream<String> stream1 = Arrays.stream(str);
Stream<String> stream4 = Stream.of(str);
// list集合
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream2 = list.stream();
// set集合
Set<String> set = new HashSet();
Stream<String> stream3 = set.stream();
//
List<User> userList = new ArrayList<>();
userList.add(new User(1,"陳晨", 20));
userList.add(new User(2,"張曉霞", 15));
userList.add(new User(3,"李書童", 40));
// 常用api
// foreach遍歷
list.forEach(System.out::print); //print abc
list.stream().forEach(System.out::print); // print abc
// filter
list.stream().filter(e->e.equals("b")).forEach(System.out::print); // print b
// sorted 默認升序
Stream.of(1,9,6,2,7).sorted().forEach(System.out::print); //print 12679
Stream.of(1,9,6,2,7).sorted((a,b)-> b-a).forEach(System.out::print); // print 97621
userList.stream().sorted(Comparator.comparing(User::getAge)).forEach(u-> System.out.print(u.getName()+"\t"));
userList.stream().sorted(Comparator.comparing(User::getAge).reversed()).forEach(u-> System.out.print(u.getName()+"\t"));
// skip limit 從1開始
// 取第一元素
userList.stream().limit(1).forEach(e-> System.out.println(e.getName()));
// 取第二個元素
userList.stream().skip(1).limit(1).forEach(e-> System.out.println(e.getName()));
// map
List<String> userNameList = userList.stream().map(User::getName).collect(Collectors.toList());
// map to 聚合操作
// 聚合操作時有空數據需先使用filte過濾,否則會報空指針異常
System.out.println(userList.stream().mapToInt(User::getAge).sum());
IntSummaryStatistics summaryStatistics = userList.stream().mapToInt(User::getAge).summaryStatistics();
System.out.println(summaryStatistics.getCount());
System.out.println(summaryStatistics.getMax());
System.out.println(summaryStatistics.getMin());
System.out.println(summaryStatistics.getAverage());
System.out.println(summaryStatistics.getSum());
// reduce 歸約聚合
Integer sum = userList.stream().map(User::getAge).reduce(0, (a,b)->a+b);
// out print: reduce規約:75
System.out.println("reduce歸約:"+sum);
Integer sum2 = userList.stream().map(User::getAge).reduce((a,b)->a+b).get();
// out print: reduce歸約:75
System.out.println("reduce歸約:"+sum2);
// flat map 合併集合
List<List<String>> listOfLists = Arrays.asList(
Arrays.asList("1", "2"),
Arrays.asList("5", "6"),
Arrays.asList("3", "4")
);
IntStream ss = listOfLists.stream().flatMapToInt(e-> e.stream().mapToInt(Integer::new));
ss.forEach(System.out::print);
// distinct
// 對象按hashCode和equals去重
userList.add(new User(3,"李書童", 40));
userList.stream().distinct().collect(Collectors.toList());
// peek
System.out.println("test peek method:");
/**
* 1、對流中元素有操作時,peek方法纔會被調用
* 2、peek方法主要用於調式,便於debug時查看流中的元素
*/
// 不打印任何信息
Stream.of(1,9,6,2,7).peek(System.out::print);
// out print: 9 6 2 7
Stream.of(1,9,6,2,7).filter(e-
>e!=1).peek(System.out::println).collect(Collectors.toList());
System.out.println("test peek method: end");
// 項目中常用的場景
// list轉array
System.out.println(Arrays.toString(Arrays.asList(1,2,3).toArray()));
// list轉string
// Collectors.joining() 默認空白拼接 結果:陳晨張曉霞李書童李書童
System.out.println(userList.stream().map(User::getName).collect(Collectors.joining()));
// 指定拼接串 結果:陳晨-張曉霞-李書童-李書童
System.out.println(userList.stream().map(User::getName).collect(Collectors.joining("-")));
// 自定義屬性去重
userList.stream().filter(distinctByKey(b -> b.getName())).forEach(e-> System.out.println(e.getName()));
userList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User::getName))), ArrayList::new)).forEach(e-> System.out.println(e.getName()));
userList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(u->u.getName()+u.getAge()))), ArrayList::new)).forEach(e-> System.out.println(e.getName()));
// 分組
Map<Integer, List<User>> groupMap = userList.stream().collect(Collectors.groupingBy(User::getAge));
System.out.println(groupMap);
// 集合操作 交集、並集、差集
// https://blog.csdn.net/weixin_41835612/article/details/83713891
}
static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Map<Object,Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
}