一.准备工作
1.创建person类对象,里面有姓名,年龄和性别:
package office;
public class Person {
private String name;
private Integer age;
private final Gender gender;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", gender=" + gender +
'}';
}
public String getName() {
return name;
}
public Gender getGender() {
return gender;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Person(String name, Integer age,Gender gender){
this.name=name;
this.age=age;
this.gender=gender;
}
}
2.性别这里使用了枚举进行定义,方便观察
package office;
public enum Gender {
MALE,FEMALE;
}
3.进行初始化赋值
private static List<Person> getPeople(){
return Arrays.asList(
new Person("a1",20,Gender.MALE),
new Person("a2",15,Gender.FEMALE),
new Person("a3",57,Gender.FEMALE),
new Person("a4",74,Gender.FEMALE),
new Person("a5",47,Gender.MALE),
new Person("a6",8,Gender.MALE),
new Person("a7",37,Gender.MALE)
);
/*
List.of返回不可变的list,参数不能为null
*/
}
这里有个小知识点:Arrays.asList和List.of都可以返回一个List集合
区别:List.of返回不可变的list,参数不能为null
Arrays.aslist返回可变的list,参数可以为null,如原list里面的值改变,Arrays.aslist返回的list里面的值也会跟着改变。
注:List.of为java11发行,如果jdk版本低于11会报错,我使用的是jdk8,所以无法使用List.of。
二.流的使用-以一个集合为例
1.普通遍历和stream流遍历的区别
【1】.普通便利-遍历person集合中性别为女的对象
List<Person> people=getPeople();
//no
List<Person> fe=new ArrayList<>();
for (Person person:people){
if (person.getGender().equals(Gender.FEMALE)){
fe.add(person);
}
}
fe.forEach(System.out::println);
【2】.stream流遍历-遍历person集合中性别为女的对象
List<Person> people=getPeople();
List<Person> fe=people.stream()
.filter(person -> person.getGender().equals(Gender.FEMALE))
.collect(Collectors.toList());
(2-1)知识点:.filter:过滤器,相当于普通遍历里的if语句,其作用为筛选,并形成新的流。
.collect():终端操作,因为流是尽可能惰性执行的,因此当有终端操作时才会执行。 collect()的作用是能够把stream管道中的结果集装进一个List集合的终极操作。因此 Collectors.toList()则是将流里面的元素转换成List集合
【3】.stream流的排序
List<Person> sorted=people.stream()
.sorted(Comparator.comparing(Person::getAge).reversed())//.reversed()
.collect(Collectors.toList());
//people.forEach(System.out::println);
sorted.forEach(System.out::println);
(3-1)知识点:.sorted(Comsumer<? super T> action):
产生一个流,它与当前流中的元素相同,在获取其中每个元素时,会将其传递给action。
sorted()默认倒序输出.revarsed()则是升序输出。
【4】.stream接口终端操作 anyMatch,allMatch,noneMatch
//All match
boolean allMath=people.stream()
.allMatch(person -> person.getAge()>5);
//System.out.println(allMath);
//Any match
boolean anyMath=people.stream()
.anyMatch(person -> person.getAge()>20);
//System.out.println(anyMath);
//None match
boolean noneMath=people.stream()
.noneMatch(person -> person.getName().equals("a10"));
(4-1)知识点:anyMatch,allMatch,noneMatch
anyMatch:判断的条件里,任意一个元素成功,返回true。
allMatch:判断条件里的元素,所有的都是,返回true。
noneMatch:与allMatch相反,判断条件里的元素,所有的都不是,返回true。
【5】stream流的Max和Min
//Max
// Optional<Person> max= people.stream()
// .max(Comparator.comparing(Person::getAge));
// System.out.println(max);
// people.stream()
// .max(Comparator.comparing(Person::getAge))
// .ifPresent(System.out::println);
//Min
// people.stream()
// .min(Comparator.comparing(Person::getAge))
// .ifPresent(System.out::println);
(5-1)知识点:Max()和Min()均会返回一个Optional实例,该实例可以接收null。
异常:如果最大元素为null,则此方法引发NullPointerException。
方法一:返回Optional实例后直接输出该Optional实例对象。
方法二:使用流自带的.ifPresent()方法快速输出,该方法将判定.max()中是否有数值,如果有,将执行.ifPresent()里面的方法。
【6】stream流的分组功能
//Group
Map<Gender,List<Person>>map=people.stream()
.collect(Collectors.groupingBy(Person::getGender));
// map.forEach((gender, people1) ->{
// System.out.println(gender);
// people1.forEach(System.out::println);
// System.out.println();
// });
(6-1)知识点:Collectors.groupingBy()。
Collectors是一个十分强大的工具类,里面有各种方法,这里的例子只是进行了性别分类,通过Collectors类还可以是实现各种复杂的分类。
Collectors.groupingBy配合Stream流使用,可以对集合中一个或多个属性进行分组,分组后还可以做聚合运算。
【7】stream流的复杂查询
Optional optional=people.stream()
// .filter(person -> person.getGender().equals(Gender.MALE))
// .min(Comparator.comparing(Person::getAge))
// .map(Person::getName);
// optional.ifPresent(System.out::println);
使用流可以进行多种多样的查询,此例中我们查询了性别为女中年龄最大的对象,其次我们还可以查找性别男中年龄最小的对象等,stream流具体十分强大的功能,熟练的掌握它将大大节省我们编写代码的时间。