JAVA8新特性-流(Stream)
程序员文章站
2022-04-28 21:26:34
...
java8新特性-流(stream)的基础操作
目录结构
Person:pojo对象
package com.dhh.data;
//Person类
public class Person implements Comparable<Person>{
//姓名
private String name;
//性别
private String gender;
//年龄
private int age;
//成绩
private int score;
public String getName() {
return name;
}
public Person setName(String name) {
this.name = name;
return this;
}
public int getAge() {
return age;
}
public Person setAge(int age) {
this.age = age;
return this;
}
public int getScore() {
return score;
}
public Person setScore(int score) {
this.score = score;
return this;
}
public String getGender() {
return gender;
}
public Person setGender(String gender) {
this.gender = gender;
return this;
}
public Person(String name, int age, int score, String gender) {
this.name = name;
this.age = age;
this.score = score;
this.gender = gender;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
", score='" + score + '\'' +
'}';
}
public Person() {
}
@Override
public int compareTo(Person o) {
return this.getScore() - o.getScore();
}
}
Data:数据源
package com.dhh.data;
import java.util.ArrayList;
import java.util.List;
//数据源
public class Data {
public static List<Person> getData() {
List<Person> personList = new ArrayList<>();
personList.add(new Person("小明", 12, 90, "男"));
personList.add(new Person("小华", 13, 80, "女"));
personList.add(new Person("小丁", 15, 85, "男"));
personList.add(new Person("小李", 17, 40, "女"));
personList.add(new Person("小毛", 18, 70, "男"));
personList.add(new Person("小宁", 12, 60, "女"));
//验证流操作会不会出现NPE异常
Person null1 = new Person().setAge(12).setGender("女");
Person null2 = new Person().setAge(12).setName("空2").setGender("女");
personList.add(null1);
personList.add(null2);
return personList;
}
}
Main:测试Demo
package com.dhh;
import com.dhh.data.Data;
import com.dhh.data.Person;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
//java8新特性:流的操作
public class Main {
//三个步骤
//1.获取数据源:集合 数组
//2.对数据进行处理的过程:过滤 排序 映射... (中间操作)
//3.对流中数据的整合:转成集合,数量...(最终操作)
public static void main(String[] args) {
//1.获取流: Stream<?> s = Data.getData().stream();
/**************************************************************************最终操作**************************************************/
//2.最终操作1: collect,与 Collectors 配合使用 Collectors.toList() Collectors.toSet()
//转成List
List<Person> personList = Data.getData().stream().collect(Collectors.toList());
System.out.println(personList);
//转成set
Set<Person> personSet = Data.getData().stream().collect(Collectors.toSet());
System.out.println(personSet);
//转成map (key为name,value为年龄),两种写法
//TODO 转map时注意:key不可以重复 否则报错java.lang.IllegalStateException: Duplicate key
Map<String, Integer> map = Data.getData().stream().collect(Collectors.toMap(i -> i.getName(), i -> i.getAge()));
Map<String, Integer> map1 = Data.getData().stream().collect(Collectors.toMap(Person::getName, Person::getAge));
System.out.println(map);
System.out.println(map1);
//3.最终操作2:reduce (Comparator接口,n1,n2为集合或数组中每个元素)
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Optional<Integer> optional = stream.reduce((n1, n2) -> n1 + n2);
System.out.println(optional.get());
//求所有学生的成绩总和
Person temp = new Person();//实例化一个临时对象存放两个人成绩的和,避免重复创建对象浪费资源
Optional<Person> reduce = Data.getData().stream().reduce((n1, n2) -> temp.setScore(n1.getScore() + n2.getScore()));
System.out.println(reduce.get().getScore());
//4.最终操作3:max和min(Comparator接口)
//需求1:找到最高成绩的人的信息(若有两个相同最高成绩的,随机取一个)
Optional<Person> max = Data.getData().stream().max((n1, n2) -> n1.getScore() - n2.getScore());//max()里面自定义大小比较的依据
System.out.println(max.get());
//需求2:找到最低成绩的人的信息(若有两个相同最高成绩的,随机取一个)
Optional<Person> min = Data.getData().stream().min((n1, n2) -> n1.getScore() - n2.getScore());
System.out.println(min.get());
//5.最终操作4:anyMatch,allMatch,noneMatch
//需求1:判断集合中是否存在成绩不合格的学生
boolean anyMatch = Data.getData().stream().anyMatch(person -> person.getScore() < 60);//是否存在匹配的
System.out.println(anyMatch);
//需求2:判断集合中是否所有的同学成绩都合格
boolean allMatch = Data.getData().stream().allMatch(person -> person.getScore() >= 60);//是否全部匹配
System.out.println(allMatch);
boolean noneMatch = Data.getData().stream().noneMatch(person -> person.getScore() < 60);//是否全部不匹配
System.out.println(noneMatch);
//6.最终操作5:count
//需求:求元数据中有多少个元素
long count = Data.getData().stream().count();
System.out.println(count);
//7.最终操作6 forEach
Data.getData().stream().forEach(i -> System.out.println(i));
//8.最终操作注意事项
Stream<Person> stream1 = Data.getData().stream();
Person maxPerson = stream1.max((n1, n2) -> n1.getScore() - n2.getScore()).get();
// Person minPerson = stream1.min((n1, n2) -> n1.getScore() - n2.getScore()).get();
//TODO 运行上面三行代码会报异常:Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
// at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:229)
// at java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:479)
// at java.util.stream.ReferencePipeline.min(ReferencePipeline.java:520)
// at com.dhh.Main.main(Main.java:71)
//TODO 最终操作执行过后 流会被关闭,此时在对其做其他处理就会报异常。
/*********************************************************************中间操作***********************************************/
//中间操作1:filter
//filter:是一个过滤器,可以自定义过滤一个条件,保留满足条件的元素。剔除不满足条件的元素
//需求1:保留集合中所有成绩大于等于80的成员信息
System.out.println("*********************************************************************中间操作***********************************************");
Data.getData().stream().filter(person -> person.getScore() >= 80).forEach(i -> System.out.println(i));
//中间操作2:distinct
//distinct:去重 去除集合中重复的元素
//去重规则:先判断hashcode(),如果hashcode()相同,再判断equals(),也相同 则认为元素重复。
Data.getData().stream().distinct().forEach(i -> System.out.println(i));
Stream<String> stream2 = Stream.of("1", "1", "2", "3", "4");
stream2.distinct().forEach(i -> System.out.println(i));//输出 1 2 3 4
//中间操作3:sorted
//sorted:排序,对流中的元素进行排序,有参的排序优先级>无参类中实现的排序优先级
//sorted():无参,要求流中的元素对应的类需要实现 comparable 接口【不常用】
Data.getData().stream().sorted().forEach(i -> System.out.println(i));
//sorted()有参【常用】
Data.getData().stream().sorted((i1, i2) -> i1.getScore() - i2.getScore()).forEach(i -> System.out.println(i));
//中间操作4:limit skip
//limit:限制,只取流中前指定位的元素
Data.getData().stream().limit(3).forEach(i -> System.out.println(i));//截取前三条数据
//skip:跳过,跳过流中前指定位的元素,取后面的元素
Data.getData().stream().skip(3).forEach(i -> System.out.println(i));//跳过前三条数据
//需求1,获取集合元素中第2个到第10个元素
Data.getData().stream().skip(1).limit(9).forEach(i -> System.out.println(i));
//中间操作5:map
//map: 元素映射,用指定的元素替换流中的元素
//需求2:将流中的person对象替换成姓名
Data.getData().stream().map(i -> i.getName()).forEach(i -> System.out.println(i));
/****************************************************************测试练习***************************************************/
/**
* 需求:一个集合中存储了若干个Person对象,要求查询出一下结果
*
* 1.所有及格的学生的信息
* 2.所有及格的学生的姓名
* 3.班级的前三名(按照成绩)
* 4.班级的3——10名(按照成绩)
* 5.所有不及格的学生的平均成绩
* 6.及格的学生,按照成绩的降序输出学生信息
* 7.班级同学的总分
*/
System.out.println("1.所有及格的学生的信息");
System.out.println(Data.getData().stream().filter(i -> i.getScore() >= 60).collect(Collectors.toList()));
System.out.println("2.所有及格的学生的姓名");
System.out.println(Data.getData().stream().filter(i -> i.getScore() >= 60).map(m -> m.getName()).collect(Collectors.toList()));
System.out.println("3.班级的前三名(按照成绩)");
System.out.println(Data.getData().stream().sorted((n1, n2) -> n2.getScore() - n1.getScore()).limit(3).collect(Collectors.toList()));
System.out.println("4.班级的3——10名(按照成绩)");
System.out.println(Data.getData().stream().sorted((n1, n2) -> n2.getScore() - n1.getScore()).skip(2).limit(8).collect(Collectors.toList()));
System.out.println("5.所有不及格的学生的平均成绩");
long count1 = Data.getData().stream().filter(i -> i.getScore() < 60).count();
Person temp1 = new Person();
Optional<Person> reduce1 = Data.getData().stream().filter(i -> i.getScore() < 60).reduce((n1, n2) -> temp1.setScore(n1.getScore() + n2.getScore()));
float avg = reduce1.get().getScore() / (float) count1;
System.out.println(avg);
System.out.println("6.及格的学生,按照成绩的降序输出学生信息");
System.out.println(Data.getData().stream().filter(i -> i.getScore() >= 60).sorted((n1, n2) -> n2.getScore() - n1.getScore()).collect(Collectors.toList()));
System.out.println("7.班级同学的总分");
Optional<Person> reduce2 = Data.getData().stream().reduce((n1, n2) -> temp1.setScore(n1.getScore() + n2.getScore()));
System.out.println(reduce2.get().getScore());
//输出结果
//1.所有及格的学生的信息
//[Person{name='小明', gender='男', age=12, score='90'}, Person{name='小华', gender='女', age=13, score='80'}, Person{name='小丁', gender='男', age=15, score='85'}, Person{name='小毛', gender='男', age=18, score='70'}, Person{name='小宁', gender='女', age=12, score='60'}]
//2.所有及格的学生的姓名
//[小明, 小华, 小丁, 小毛, 小宁]
//3.班级的前三名(按照成绩)
//[Person{name='小明', gender='男', age=12, score='90'}, Person{name='小丁', gender='男', age=15, score='85'}, Person{name='小华', gender='女', age=13, score='80'}]
//4.班级的3——10名(按照成绩)
//[Person{name='小华', gender='女', age=13, score='80'}, Person{name='小毛', gender='男', age=18, score='70'}, Person{name='小宁', gender='女', age=12, score='60'}, Person{name='小李', gender='女', age=17, score='40'}, Person{name='null', gender='女', age=12, score='0'}, Person{name='空2', gender='女', age=12, score='0'}]
//5.所有不及格的学生的平均成绩
//13.333333
//6.及格的学生,按照成绩的降序输出学生信息
//[Person{name='小明', gender='男', age=12, score='90'}, Person{name='小丁', gender='男', age=15, score='85'}, Person{name='小华', gender='女', age=13, score='80'}, Person{name='小毛', gender='男', age=18, score='70'}, Person{name='小宁', gender='女', age=12, score='60'}]
//7.班级同学的总分
//425
}
}
上一篇: WebLogic域的创建与发布