集合流式编程简介
集合流式操作(Stream)是java8中的一个新特性,是对集合操作的增强,它像一个迭代器,可以单向的不重复的遍历集合中的每个元素。并可以对数据进行很多类型的过滤。
操作步骤:
- 将数据读到集合流 – 数据源的获取
- 对流中的数据处理、操作 – 中间操作
- 中间操作的返回值都是一个流本身,可以用这个返回值返回的流对象,再进行其他的操作
- 对操作后的流数据进行整合 – 最终操作
最终操作:
//将persons的静态属性(经过初始化的)赋值给list
ArrayList<Person> list = Persons.list;
//获取流
Stream<Person> s = list.stream();
//最终操作
//将流转为list(或者set、map)集合 Collectors是一个工具类
s.collect(Collectors.toList);
//获取流中的元素数量
long count = s.count();
//获取流中最大的数据,类似于Collections.max
//返回的是optional类型元素
Person p = s.max((e1, e2) -> e1.age - e2.age).get();
//成绩最低
Person p2 = s.min((e1, e2) ->{
if(e1.score > e2.score){
return 1;
}
return -1;
}).get();
System.out.println(p2);
//快速迭代流中的每个元素
s.forEach(System.out::println);
//matches -> anyMatch 、allMatch 、NoneMatch
//判断流中是否包含指定条件的元素
s.anyMatch(ele -> ele.score >= 60);
//find
//获取流中的第一个元素
Person p = s.findFirst().get();
//在一个线程下结果和findFirst相同,在多线程中,可能不同
Person p2 = s.findAny().get();
//reduce
ArrayList<Iteger> ls = new ArrayList<>();
for(int i = 0; i< 10; i++){
ls.add(i);
}
//n1+n2结果作为n1继续和下个元素相加,最终结果为0-9相加的和
int result = ls.stream().reduce((n1, n2) -> n1 + n2).get();
中间操作:
Stream<Person> s = Persons.list.stream();
//1.filter:过滤器,对流中的数据进行过滤
//将流中所有元素带入到接口方法,如果返回true保留这个元素
//保留所有成绩及格的Person对象
s.filter(ele -> e.score >= 60).forEach(System.out::println);
//2.distinct:去除流中重复的元素
//去重逻辑:同hashset去重相同,先比较hashCode值,相同再比较equals
s.distinct().forEach(System.out::println);
//3.sorted排序
//通过comparator接口进行排序
s.sorted((p1, p2) -> p1.age - p2.age).forEach(System.out::println);
//无参排序方法,需要类去实现comparable接口,重写compareTo方法
s.sorted().forEach(System.out::println);
//4.skip:跳过 limit:截取
//跳过4个元素
s.skip(4);
//从流中截取前面指定数量的元素,后面的元素舍弃
s.limit(5).forEach(System.out::prinln);
//5.map:映射 将流中的元素替换成指定的其他元素
s.map(ele -> ele.name).forEach(System.out::println);//返回所有对象的名字
s.map(ele ->ele.score).forEach(System.out::println);//所有的成绩
//所有名字和成绩(一一对应)
s.map(ele ->{
HashMap<String, Float> map = new HashMap<>();
map.put(ele.name, ele,score);
return map;
}).forEach(System.out::println);
//平局值
s.mapToDouble(e -> e.score).average().getAsDouble;
//总和
s.mapToDouble(e -> e.score).sum().getAsDouble;
//6.flatMap:扁平化 将每一个元素都做成单独的流,最后再将流汇总到一起
//
String[] array = {"hello", "world"};
Arrays.stream(array).map(ele -> ele.split(""))flatMap(Arrays::stream).forEach(System.out::println);
Collectors工具类
Collectors是一个工具类,用来获取一个Collector接口的实现类对象
int[] array = {1,2,3,4,5,6,7,8,9,10};
Stream<Integer> s = Arrays.stream(array);
s.collect(Collectors.toMap(e -> e, e -> e*10));//
//maxBy、minBy
System.out.println(s.collect(Collectors.maxBy(e1, e2) -> e1 - e2)).get();
//joining:将流中的所有元素拼成一个字符串
System.out.println(s.map(e -> e.toString()).collect(Collectors.joining(", ")));
//summingInt
System.out.println(s.collect(Collectors.summingInt(e -> e)).valueInt());
//averagingInt
System.out.println(s.collect(Collectors.AveragingInt(e -> e)).valueInt());
//summarizingInt
IntSummaryStatics summary = s.collect(Collectors.summarizingInt(e -> e)).valueInt();
summary.getSum();
summary.getCount();
summary.getAverage();
案例:
需求:一个集合中存储了若干个Student对象,要求查询出一下结果:
1.所有及格的学生信息
2.所有及格的学生姓名
3.所有学生的平均成绩
4.班级的前三名(按照成绩)
5.班级的3-10名(按照成绩)
6.所有不及格学生的平均成绩
7.将及格学生,按照成绩降序输出所有信息
8.班级学生的总分
public class Program {
public static void main(String[] args) {
List<Student> list = Students.list;
Stream<Student> s = list.stream();
//1.所有及格的学生信息
//s.filter(ele -> ele.score >= 60).forEach(System.out::println);
//2.所有及格的学生姓名
//s.filter(ele ->ele.score >= 60).map(ele -> ele.name).forEach(System.out::println);
//3.所有学生的平均成绩
//System.out.println(s.collect(Collectors.averagingInt(ele -> ele.score)).intValue());
//4.班级的前三名(按照成绩)
//s.sorted((e1, e2) -> e2.score - e1.score).limit(3).forEach(System.out::println);
//5.班级的3-10名(按照成绩)
//s.sorted((e1, e2) -> e2.score - e1.score).skip(2).limit(8).forEach(System.out::println);
//6.所有不及格学生的平均成绩
//System.out.println(s.filter(ele -> ele.score <= 60).collect(Collectors.averagingInt(ele -> ele.score)).intValue());
//7.将及格学生,按照成绩降序输出所有信息
//s.filter(ele -> ele.score >= 60).sorted((e1, e2) -> e2.score - e1.score).forEach(System.out::println);
//8.班级学生的总分
//System.out.println(s.collect(Collectors.summingInt(e -> e.score)).intValue());
}
}
class Students{
public static final List<Student> list = new ArrayList<>();
static {
list.add(new Student("xiaoming", 100));
list.add(new Student("xiaoli", 38));
list.add(new Student("xiaohong", 86));
list.add(new Student("xiaobai", 16));
list.add(new Student("xiaohei", 97));
list.add(new Student("xiaolv", 88));
list.add(new Student("xiaolan", 79));
list.add(new Student("xiaoqing", 89));
list.add(new Student("xiaozi", 62));
list.add(new Student("xiaocheng", 77));
list.add(new Student("xiaoleng", 94));
list.add(new Student("xiaochi", 80));
list.add(new Student("xiaoliu", 70));
list.add(new Student("xiaoqi", 45));
}
}
class Student{
String name;
int score;
public Student(String name, int score) {
super();
this.name = name;
this.score = score;
}
public Student() {
super();
}
@Override
public String toString() {
return "Person [name=" + name + ", score=" + score + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
}