stream流用法:用于简化对集合数组之类的操作,作用类似于lambda表达式。
stream流标准格式:输入流+操作流+终结流
首先来对比一下:
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张三","李四","王五","赵六","张麒","王八","柳九");
System.out.println(list);
ArrayList<Object> list1 = new ArrayList<>();
for (String s : list) {
if(s.startsWith("张")&&s.length()==2){
list1.add(s);
}
}
System.out.println(list1);
//用stream流来解决
List<String> list2 = list.stream().filter(s -> s.startsWith("张")).
filter(a -> a.length()==2).collect(Collectors.toList());
System.out.println(list2);
}
好了,我们接下来拆分一下:
如何使用stream流:要在集合或数组后.stream()作为开头,这样之后就可以用stream流的各种常见的中间方法有:
1.filter():用于过滤数据,在括号中写符合的条件,符合则留下,否则去掉。
2.shorted():用于给数据排序,注意,只能给基本数据类型默认排序,如果是定义数据类型,则需要在括号中书写排序规则。
3.limit():取前多少个数据,在括号中写上对应的数字,则就会取到前多少个数据。
4.skip():跳过前多少个数据,在括号中填入数字,代表跳过多少个数据。
5.map():对stream流中的数据进行加工之后再返回新的流。括号中填写加工方式。
6.distinct():对数据进行去重复,如果希望内容一样就代表重复,则要重写equals方法和hashcode方法。
7.concat():对两个stream流进行合并。
接下来,用几个具体案例来看看这些方法的用法:
public static void main(String[] args) {
ArrayList<Double> scores = new ArrayList<>();
Collections.addAll(scores,89.2,49.6,55.8,99.9,55.2,52.7,60.0,59.9);
//需求1:找出大于60分的数据,并升序后再输出
//filter用于过滤数据,sorted默认升序排序,这两个方法使用后都会再返回stream,同时可以在后面继续.stream方法,
// 这类方法被称为stream流的中间流
scores.stream().filter(s -> s>=60).sorted().forEach(s -> System.out.println(s));
ArrayList<Student> students = new ArrayList<>();
Student s1= new Student("张三", 18, 90);
Student s2= new Student("李四", 19, 85);
Student s6 = new Student("李四", 19, 85);
Student s3 = new Student("王五", 20, 95);
Student s4 = new Student("赵六", 21, 92);
Student s5 = new Student("孙七", 22, 98);
Collections.addAll(students,s1, s6,s3,s4,s5);
//需求2:找出年龄大于等于23,且年龄小于等于0岁的学生,并按照年龄降序输出
//注意:这里sorted的方法默认只能给基础数据类型进行排序,这里需要在sorted方法中定义比较规则
students.stream().filter(s ->s.getAge()>=18&&s.getAge()<=20).
sorted(((o1, o2) -> o2.getAge()-o1.getAge()))
.forEach(s-> System.out.println(s));
System.out.println("----------------------------------------------------------");
//需求3:取出分数最高的3名学生,并输出。
students.stream().sorted(((o1, o2) -> Double.compare(o2.getScore(), o1.getScore()))).
limit(3).forEach( System.out::println);
//limit的作用:取前多少个数据
System.out.println("------------------------------------------------------------");
//需求4:取出分数倒数的2名学生,并输出
students.stream().sorted(((o1, o2) -> Double.compare(o2.getScore(), o1.getScore()))).
skip(students.size()-2).forEach(s-> System.out.println(s));
//skip的作用:跳过多少个数据
//需求5:找出分数超过90的学生叫什么名字,要求去重复再输出
students.stream().filter(s->s.getScore()>90).map(s-> s.getName()).
distinct().forEach(s-> System.out.println(s));
//map作用:对元素进行加工,并返回对应的新流
//distinct作用:去重复,但是如果希望对象的内容一样就认为重复,需要重写equals和hashcode方法
//合并两个stream流:concat
Stream<String> st1 = Stream.of("张三","李四");
Stream<String> st2 = Stream.of("张三2","李四2","王五");
Stream<String> st3 = Stream.concat(st1,st2);
st3.forEach(System.out::println);
}
掌握了常用的中间方法,我们来看一下stream流中最后的终结方法:
1.forEach():对整个集合的数据进行遍历。
2.count():统计符合条件的数据的个数。
3.get():返回对象。
4.collect():将返回的数据放到一个集合中去,括号里面用Collectors表示要返回什么类型的集合
好,接下来再用具体案例来看一下:
public static void main(String[] args) {
ArrayList<Student> students = new ArrayList<>();
Student s1= new Student("张三", 18, 90);
Student s2= new Student("李四", 19, 85);
Student s6 = new Student("李四", 19, 85);
Student s3 = new Student("王五", 20, 95);
Student s4 = new Student("赵六", 21, 92);
Student s5 = new Student("孙七", 22, 98);
Collections.addAll(students,s1,s2,s3,s4,s5,s6);
//需求1:计算出年龄超过20的学生有几人 count
long size = students.stream().filter(s->s.getAge()>20).count();
System.out.println(size);
//需求2:请找出分数最高的学生对象,并输出
//max:根据比较规则,找出最大的那个并输出 get:返回对象
Student student = students.stream().max(((o1, o2) -> Double.compare(o1.getScore(),o2.getScore()))).get();
System.out.println(student);
//需求3:请找出分数最低的学生对象,并输出 min:根据比较规则,找出最低的那个输出
Student student2 = students.stream().min(((o1, o2) -> Double.compare(o1.getScore(),o2.getScore()))).get();
System.out.println(student2);
//收集stream流:把stream流操作后的结果转回到集合或者数组中去返回
//需求4:请找出分数超过90的学生对象,并返回到一个新集合中去返回
//collect:将返回的数据放到一个集合中去,里面用Collectors表示要返回什么类型的集合
List<Student> students1 = students.stream().filter(a -> a.getScore() > 90).collect(Collectors.toList());
System.out.println(students1);
Set<Student> students2 = students.stream().filter(a -> a.getScore() > 90).collect(Collectors.toSet());
System.out.println(students2);
//注意:这里不能单独将前面一致的stream流拿出来作为一个新的stream流再使用,否则会报错
//因为流只能收集一次,类似于迭代器,下面再用时已经遍历完了故报错
//需求5:请找出分数超过90的学生对象,并把学生对象的名字和分数存入一个Map集合中返回
Map<String,Double> students3 = students.stream().filter(a -> a.getScore() > 90)
.collect(Collectors.toMap(a->a.getName(), a->a.getScore()));
//注意:用toMap方法时,要在里面申明键和值。
System.out.println(students3);
Object[] arr = students.stream().filter(a -> a.getScore() > 90).toArray();
System.out.println(Arrays.toString(arr));
}
好了,以上大概就是stream流的全部内容了。
总的来说,stream流是一种对集合或数组进行操作的简化写法,他将原本需要很多行代码的操作简化成一条代码完成,使代码更加简洁。
本笔记为自用复习笔记,也欢迎各位大佬来指正和纠错。同样对计算机感兴趣的同学也可以进群交流:595586832