一.Stream
1.所在包
import java.util.stream.*;
2.中间方法与终端方法
//中间方法返回的stream类型 可以连续调用
//终端方法--》返回类型肯定不是Steam 【long void Optional int ....
//中间方法必须以终端方法收尾才能执行
//否则中间方法不执行
//终端方法后面肯定没有方法吗? XXXX的
//filter((T x)->{return boolean }); 断言型接口
3.特点
内部迭代 惰性求值 函数编程
4.Filter 断言型编程
符合条件的进入stream流 中间方法
5.Limit(long maxSize) 保留maxSize个元素 中间方法
Stream<T> filter(Predicate<? super T> predicate)
返回由与此给定谓词匹配的此流的元素组成的流。
ArrayList<Student> list = new ArrayList<>();Student s1 = new Student("Lee",21,77);Student s2 = new Student("Andy",25,76);Student s3 = new Student("Joker",20,58);Student s4 = new Student("Andy",25,76);Collections.addAll(list,s1,s2,s3,s4);// 打印两位大于60分的学生//过滤 filter出 元素//截断 保留元素//打印/*list.stream().filter((stu)->{return stu.getScore()>60;}).limit(2).forEach((stu)->{System.out.println(stu);});*///简化list.stream()// 泛型Student 返回Stream.filter(stu->stu.getScore()>60)// 泛型Student 返回Stream.limit(4)// 泛型Student 返回Stream//如果使用方法引用的话需要方法覆盖Student的toString//void accept (T x)//void println 一个.forEach(System.out::println);
6.Stream<T> distinct() 中间方法
如果是用在引用数据类型中要重写 hashCode equals方法
去重用的 底层是 hashCode == equals
ArrayList<Student> list = new ArrayList<>();Student s1 = new Student("Lee",21,77);Student s2 = new Student("Andy",25,76);Student s3 = new Student("Joker",20,58);Student s4 = new Student("Andy",25,76);Collections.addAll(list,s1,s2,s3,s4);//去重list.stream().distinct()//底层不是equals 底层是hashCode == euqals.forEach(System.out::println);
7.<R> Stream<R> map(Function<? super T,? extends R> mapper) apply应用
四大接口之一的Function
抽象方法 R apply(T)对元素中每一个进行类型转换 将T类型->R类【基本数据类型是包装类】
//打印不及格的成绩
list.stream()//getScore.map((stu)->{return stu.getScore();})//将Student类型---》Integer类型
.filter((score)->{return score<60;})//过滤出不及格的成绩Student对象们 stream返回类型.forEach((x)->{System.out.println(x);});
//简化
list.stream()//调用stram流
// Integer apply (Student)
//Integer getScore() 符合 类::实例方法
// Student::getScore() 类::实例方法//下面可改成方法引用.map(stu->stu.getScore()) //.map(Student::getScore)//将Student对象转为Integer对象.filter(score->score<60)//过滤Integer对象中不及格的元素.forEach(System.out::println);//打印出不及格的元素分数
面试题:【两个重点的东西】
Stream中filter和map的区别?
Filter((x)->{return boolean;}); 个数
流元素的个数可能改变 但是元素的类型肯定不变
Map((x)->{return R}); 映射类型
流中的元素个数肯定不变 但是元素的类型可能改变
8.Stream中的Stream<> sorted 中间方法 可以对集合的元素进行排序
ArrayList<Integer>list_1=new ArrayList<>();Collections.addAll(list_1,100,25,65,18,78);//Stream中的Stream<> sorted 中间方法 可以对集合的元素进行排序list_1.stream().sorted()//按照类的自定义自然顺序进行排序for则会.ClassCastException.forEach(System.out::println);
9. Stream 中Stream<T> sorted(Comparator<? super T> comparator)
list_1.stream().sorted((x,y)->{return y-x;})//有参的soretd.forEach(System.out::println);
练习 sorted()和 sorted(ComapreTor)
ArrayList<Student> list = new ArrayList<>();Student s1 = new Student("Lee",21,77);Student s2 = new Student("Andy",25,76);Student s3 = new Student("Joker",20,58);Student s4 = new Student("Andy",25,76);Collections.addAll(list,s1,s2,s3,s4);//降序打印分数list.stream().map((stu)->{return stu.getScore();}).sorted((x,y)->{return y-x;})//比较器--->lambda表达.forEach(System.out::println);//升序打印分数list.stream().map((stu)->{return stu.getScore();})//将student-》Integer类型.sorted()//默认类型的compareTo .forEach(System.out::println);
//按照名字升序 需要在Student类进行compareTo的重写
//按照姓名升序打印list.stream()//两个参数 int compare X Y//一个参数 int compareTo x//.sorted((n,old)-> n.getName().compareTo(old.getName()))//.sorted((n,old)->{return n.getName().compareTo(old.getName());})//简化 后 类::实例方法.sorted(Student::compareTo).forEach((stu)->{System.out.println(stu.getName());});
Student类:Comparable<Student>@Overridepublic int compareTo(Student s1){return this.name.compareTo(s1.name);}
FlatMap 不是很重要 不需要掌握下面这两个
generate(()->{return xxx;}) 与 limit一起
Iterate(初始值,(x)->{x+1})与 limit一起
Stream.generate().limit(个数).forEach() 产生无数个相同的内容,结合limit 来使用
Stream.iterate(0 初始值,(x)->x+1).limit().forEach() 打印0 1 2 3 .... 产生无数个不同的内容
返回类型boolean 的 三个
.allMatch(x->return boolean )是否全部匹配
.anyMatch()是否至少有一个匹配
.noneMatch()是否都不匹配
ArrayList<Student> list = new ArrayList<>();Student s1 = new Student("Aee",21,77);Student s2 = new Student("Andy",25,76);Student s3 = new Student("Aoker",20,58);Student s4 = new Student("Andy",25,76);Collections.addAll(list,s1,s2,s3,s4);//是不是所有同学以A开头boolean flag=list.stream().allMatch((stu)->{return stu.getName().charAt(0)=='A';});//是否有未成年boolean flag_1=list.stream().anyMatch((stu)->{return stu.getAge()<18;});System.out.println("是不是所有同学以A开头"+flag);System.out.println("是否有未成年"+flag_1);
返回类型是Optional<XXX>
findFirst
Optional<T> findFirst()
返回描述此流的第一个元素的Optional如果流为空,则返回一个空的Optional 。 如果流没有遇到顺序,则可能会返回任何元素
//得到全班最大的年龄Integer age=list.stream().sorted((n,old)->{return old.getAge()-n.getAge();}).map((stu)->{return stu.getAge();})//(被转化的类型)->{ 转化以后的类型}.findFirst()//放 ofNullable.orElse(0);//取System.out.println(age);//打印第一个A开头的String mingzi=list.stream().map((stu)->{return stu.gametName();})//Student--->String 类型了.filter((name)->{return ne.startsWith("A");})//String-->过滤名字为A开头的.findFirst()//找到第一个A开头的 如果能找到则就是那个 找不到就为Optional.empty.orElse("null");//为空则 null 不为空则没事System.out.println(mingzi);
.max(比较器) 返回最后一个元素 Optional【升序默认】
.min(比较器) 返回第一一个元素 Optional【升序默认】
//得到全班最大的年龄 maxInteger age=list.stream().map((stu)->{return stu.getAge();}).max((n,o)->{return n-o;}).orElse(0);System.out.println("最大的年龄"+age);//得到名字最长的学生Student maxStu=list.stream().max((n,o)->{return n.getName().length()-o.getName().length();}).orElseGet(Student::new);
//.orElse(new Student());System.out.println("最长的学生"+maxStu);
.reduce()//合并 求总分 Optional类型
//求全班总分Integer ss=list.stream().map((stu)->{return stu.getScore();}).reduce((sum,y)->{System.out.println("sum="+sum+" y="+y);return sum+y;}).orElse(0);System.out.println("总分:"+ss);
.count() long类型的 统计流中的个数 统计上一步的
long count()
返回此流中的元素数
long count()
返回此流中的元素数//求全班总分Integer ss=list.stream().map((stu)->{return stu.getScore();}).reduce((sum,y)->{System.out.println("sum="+sum+" y="+y);return sum+y;}).orElse(0);System.out.println("总分:"+ss);//统计低于平均分int avg=ss/list.size();long number=list.stream().map(Student::getScore).filter((score)->{return score<avg;}).count();System.out.println("低于平均分个数:"+number);
Collect(Collector)收集器
collect(Collectors.toList())
//将所有及格的学生收集到list中//collect(Collectors.toList())List<Student> list01=list.stream().filter((stu)->{return stu.getScore()>=60;}).collect(Collectors.toList());System.out.println(list01);
collect(Collectors.toSet()) 去重
//将所有不及格的成绩收集到Set【quchong]//collect(Collectors.toSet())Set<Integer> set=list.stream().filter((stu)->{return stu.getScore()>=60;}).map((stu)->{return stu.getScore();}).collect(Collectors.toSet());System.out.println(set);
ToMap 两个参数 值一样会异常 和 三个参数
.collect(Collectors.toMap(()->{}.()->{},()->{}))Map<String,Integer> map=list.stream().collect(Collectors.toMap((stu)->{return stu.getName();},(stu)->{return stu.getScore();},(oldV,newV)->{return newV;}));System.out.println(map);
collect 分组的 20-【jakc.okrd】 25-【Aron.andy】
//Map<T ,List<R>> map=list.stream().collect(()->{});
Map<Integer,List<Student>> map01=list.stream().collect(Collectors.groupingBy(Student::getAge));System.out.println(map01);
)
collect.joining()
//必须前一个是String类型
String ss=list.stream().map(Student::getName).collect(Collectors.joining(“@”));
Lee@Andy@Joker
这样拼起来