//stream:对数据源进行一系列流水线式的操作,产生新数据,所以数据源不会改变
//创建stream4种方式
//1.通过Collection系列集合提供的stream()或parallelStream()
//stream()是单线程的,而parallelStream()是多线程并行处理
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> stream1 = list.stream();
stream1.forEach(System.out::println);//1 2 3 4 5
Stream<Integer> stream2 = list.parallelStream();
stream2.forEach(System.out::println);//3 5 4 2 1(多线程并行,所以无序)
//2.通过Arrays中的静态方法stream()获取
String[] stringArray = new String[]{"a","b","c","d"};
Stream<String> stream3= Arrays.stream(stringArray);
stream3.forEach(System.out::println);//a b c d
//3.通过Stream类中的静态方法of()
Stream<String> stream4 = Stream.of("aa","bb","cc");
stream4.forEach(System.out::println);//aa bb cc
//4.创建无限流,前面创建的流都是有固定范围的
//4.1迭代(此处用limit(10)来固定了打印前10个)
//iterate第二个参数UnaryOperator为函数式接口
//以1为初始值,每次+2
Stream<Integer> stream5 = Stream.iterate(1,x->x+2);
stream5.limit(5).forEach(System.out::println);//1 3 5 7 9
//4.2生成
//generate方法参数Supplier也是函数式接口
Stream.generate(()->Math.random()).limit(5).forEach(System.out::println);
//stream中间操作:
//"惰性求值",即中间操作不会执行任何的处理,只有触发了终止操作,才会一次性全部处理
List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5, 3);
//1.筛选与切片
//filter--接收Lambda,从流中排除某些元素
Stream<Integer> integerStream = integerList.stream().filter((e) -> {
System.out.println("a");
return e >= 3;
});
//下面的forEach是终止操作,执行时才会执行上面的语句
integerStream.forEach(System.out::println);
//limit--截断流,使其元素不超过给定数量
integerList.stream().limit(3).forEach(System.out::println);//1 2 3
//skip(n)--跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回空流
integerList.stream().skip(2).forEach(System.out::println);//3 4 5 3
//distinct--筛选,通过流所生成的hashCode()和equals()去除重复元素
integerList.stream().distinct().forEach(System.out::println);//1 2 3 4 5
//中间操作:映射
//map-接收Lambda,将元素转换成其他形式或提取信息,接收一个函数作为参数,该函数会应用到每个元素上,并将其映射成一个新的元素
//flatMap-接收一个函数作为参数,将流中的每个值都转换成另一个流,后将所有的流转换成一个流
List<String> mapList = Arrays.asList("a", "b", "c", "d", "e");
mapList.stream().map((s) -> s.toUpperCase()).forEach(System.out::println);//A B C D E
mapList.stream().map(String::toUpperCase).forEach(System.out::println);//A B C D E
Stream<Stream<Character>> aa = mapList.stream().map(EurekaMain7001::find);
aa.forEach((sm) -> sm.forEach(System.out::println));
//即find方法返回的也必须是一个流
Stream<Character> ss = mapList.stream().flatMap(EurekaMain7001::find);
//排序
//sorted()-自然排序
List<String> sortList = Arrays.asList("b", "a", "d", "g", "c");
//sortList.stream().sorted().forEach(System.out::println);//a b c d g
//sorted(Comparator com)-定制排序
sortList.stream().sorted((e1, e2) -> {
if (e1.compareTo(e2) > 0) {
return e2.compareTo(e1);
} else {
return -e2.compareTo(e1);
}
}).forEach(System.out::println);
@org.junit.Test
public void test() {
//age升序
List<User> uu4 = userList.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());
//age降序
List<User> uu5 = userList.stream().sorted(Comparator.comparing(User::getAge).reversed()).collect(Collectors.toList());
//先age升序,再name升序
List<User> uu = userList.stream().sorted(Comparator.comparing(User::getAge).thenComparing(User::getName)).collect(Collectors.toList());
//先age降序,再name降序
List<User> uu1 = userList.stream().sorted(Comparator.comparing(User::getAge, Comparator.reverseOrder()).thenComparing(User::getName, Comparator.reverseOrder())).collect(Collectors.toList());
//先age降序,再name升序
List<User> uu2 = userList.stream().sorted(Comparator.comparing(User::getAge).reversed().thenComparing(User::getName)).collect(Collectors.toList());
//先age升序,再name降序
List<User> uu3 = userList.stream().sorted(Comparator.comparing(User::getAge).thenComparing(User::getName, Comparator.reverseOrder())).collect(Collectors.toList());
//age升序
userList.stream().sorted((e1, e2) -> {
if (e1.getAge() > e2.getAge()) {
return e1.getName().compareTo(e2.getName());
} else {
return -e1.getName().compareTo(e2.getName());
}
}).forEach(e -> {
System.out.println(e.getName() + e.getAge());
});
}
/**
* 终止操作
* 查找与匹配
* allMatch-检查是否匹配所有元素
* anyMatch-检查是否至少匹配一个元素
* noneMatch-检查是否没有匹配所有元素
* findFirst-返回第一个元素
* findAny-返回当前流中的任意元素
* count-返回流中元素的总个数
* max-返回流中的最大值
* min-返回流中的最小值
*/
@org.junit.Test
public void test1() {
boolean b1 = userList.stream().allMatch((e) -> e.getName().equals("f"));//false,不是所有的name都为f
boolean b2 = userList.stream().anyMatch((e) -> e.getName().equals("a"));//true,存在user的name为a
System.out.println("b2:" + b2);
boolean b3 = userList.stream().noneMatch(e -> e.getName().equals("g"));//true,没有任何user的name为g
System.out.println("b3" + b3);
Optional<User> userFirst = userList.stream().sorted(Comparator.comparing(e -> e.getAge())).findFirst();//按照age正序,获取第一个user(Optional类型)
System.out.println("age正序的第一值为:" + userFirst.get().getAge() + "名称为:" + userFirst.get().getName());
Optional<User> userAny = userList.stream().sorted(Comparator.comparing(e -> e.getAge())).findAny();//按照age正序,获取任意一个user(Optional类型)
System.out.println("age正序的任意一个值为:" + userAny.get().getAge() + "名称为:" + userAny.get().getName());
long a = userList.stream().count();//6 userList一共6条数据
System.out.println("count的值为:" + a);
Optional<User> userMax = userList.stream().max((e1, e2) -> Double.compare(e1.getAge(), e2.getAge()));//获取age最大的user(Optional类型)
System.out.println("最大值为:" + userMax.get().getAge() + "名称为:" + userMax.get().getName());
Optional<Integer> dd = userList.stream().map(user -> user.getAge()).min(Integer::compare);//比较age小的,返回age值(Optional类型)
}
/**
* 归约
* reduce(T identity,BinaryOperator) / reduce(BinaryOperator)-将流中的元素反复结合起来,得到一个值
*/
@org.junit.Test
public void test2() {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
//以0为起始值,将0作为x,1作为y,得到和1,再将和1作为x,2作为y,得到和3,再将3作为x,3作为y,得到和6,再将6作为x,4作为y.....
Integer sum = list.stream().reduce(0, (x, y) -> x + y);
System.out.println("总和为:" + sum);//总和为:55
//map-reduce模式
Optional<Integer> ageSum = userList.stream().map(User::getAge).reduce(Integer::sum);//获取年龄总和(Optional类型)
}
/**
* 收集
* collect-将流转换成为其他形式,接收一个Collector接口的实现,用于给stream中元素做汇总的方法
*/
@org.junit.Test
public void test3() {
//将userList里面的user实体里面的name属性收集到一个list
List<String> stringList = userList.stream().map(User::getName).collect(Collectors.toList());
stringList.forEach(System.out::println);
System.out.println("----------------------------------------");
//将userList里面的user实体里面的name属性收集到一个list
Set<String> stringSet = userList.stream().map(User::getName).collect(Collectors.toSet());
stringSet.forEach(System.out::println);
System.out.println("----------------------------------------");
//将userList里面的user实体里面的name属性收集到一个HashSet中
HashSet<String> set = userList.stream().map(User::getName).collect(Collectors.toCollection(HashSet::new));
set.forEach(System.out::println);
System.out.println("----------------------------------------");
long num = userList.stream().collect(Collectors.counting());
System.out.println("总数为:" + num);//userList中size:6
//获取age平均值
double average = userList.stream().collect(Collectors.averagingInt(User::getAge));
//age总和
double sum = userList.stream().collect(Collectors.summingInt(User::getAge));
//age最大值对应的User对象
Optional<User> u = userList.stream().collect(Collectors.maxBy((e1, e2) -> Double.compare(e1.getAge(), e2.getAge())));
//将userList分组,返回map中key 为分组属性name,value为分组后的List<User>,map不能做forEach操作
Map<String, List<User>> map = userList.stream().collect(Collectors.groupingBy(User::getName));
//多级分组:先按照name分组,对应twoMap里面的key,再按照age分为三组(青年,中年,老年),对应twoMap里面的value中的map的key
Map<String, Map<String, List<User>>> twoMap = userList.stream().collect(Collectors.groupingBy(User::getName, Collectors.groupingBy((e) -> {
if (e.getAge() <= 35) {
return "青年";
} else if (e.getAge() <= 50) {
return "中年";
} else {
return "老年";
}
})));
//分区:age大于20的booleanListMap对应的key为true,反之为false
Map<Boolean, List<User>> booleanListMap = userList.stream().collect(Collectors.partitioningBy(e -> e.getAge() > 20));
//连接name字符串,中间用”,“分隔
String string = userList.stream().map(User::getName).collect(Collectors.joining(","));
//求和,求最大值等操作的另一种获取方式(获取多个结果时,此时不需要写多个stream)
IntSummaryStatistics intSummaryStatistics = userList.stream().collect(Collectors.summarizingInt(User::getAge));
intSummaryStatistics.getAverage();
intSummaryStatistics.getCount();
intSummaryStatistics.getMax();
intSummaryStatistics.getMin();
}