当把一个数据结构包装成 Stream 后,就要开始对里面的元素进行各类操作了。常见的操作可以归类如下。
Intermediate: (中间)
map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered
Terminal:(终端)
forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator
Short-circuiting:(短路)
anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limi
版权声明:本文为博主原创文章,转载请附上博文链接!
1、filter方法
在前面的例子中我们已经演示了如何使用filter,其定义为:Stream filter(Predicate<? super T> predicate), filter接受一个谓词Predicate,我们可以通过这个谓词定义筛选条件,在介绍lambda表达式时我们介绍过Predicate是一个函数式接口,其包含一个test(T t)方法,该方法返回boolean。现在我们希望从集合students中筛选出所有age是21的学生,那么我们可以通过filter来实现,并将筛选操作作为参数传递给filter:
//filter()方法
List<Student> student1=students.stream().filter(s->s.getAge()==21).collect(Collectors.toList());
for (Student s:student1){
System.out.println(s.toString());
}
2、distinct方法
distinct操作类似于我们在写SQL语句时,添加的DISTINCT关键字,用于去重处理,distinct基于Object.equals(Object)实现,回到最开始的例子,假设我们希望筛选出所有不重复的偶数,那么可以添加distinct操作。
List<Integer> nums=new ArrayList<>();
nums.add(1);
nums.add(2);
nums.add(3);
nums.add(2);
nums.add(4);
nums.add(5);
List<Integer> evens = nums.stream()
.filter(num -> num % 2 == 0).distinct()
.collect(Collectors.toList());
for (Integer i:evens){
System.out.println(i);
}
这个例子是去掉重复的偶数,distinct()方法主要是调用equals()和hashCode()方法,如果是建的类的话,调用这个方法,如果内容相同,但是hashcode不同,也是不同,要实现内容相同,即为相同,要重写方法。
package com.example.demo11;
public class Student {
/** 学号 */
private long id;
private String name;
private int age;
/** 年级 */
private int grade;
/** 专业 */
private String major;
/** 学校 */
private String school;
public Student(long id, String name, int age, int grade, String major, String school) {
this.id = id;
this.name = name;
this.age = age;
this.grade = grade;
this.major = major;
this.school = school;
}
@Override
public int hashCode() {
int hashno = 7;
hashno = 13 * hashno + (name == null ? 0 : name.hashCode());
return hashno;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
final Student student = (Student) obj;
if (this == student) {
return true;
} else {
return (this.name.equals(student.name) && this.age ==student.age);
}
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", grade=" + grade +
", major='" + major + '\'' +
", school='" + school + '\'' +
'}';
}
}
//distinct
List<Student> student2=students.stream().distinct().collect(Collectors.toList());
for (Student s:student2){
System.out.println(s.toString());
}
3、limit方法
limit操作也类似于SQL语句中的LIMIT关键字,不过相对功能较弱,limit返回包含前n个元素的流,当集合大小小于n时,则返回实际长度,比如下面的例子返回前两个专业为土木工程专业的学生:
List<Student> civilStudents = students.stream()
.filter(student -> "土木工程".equals(student.getMajor())).limit(2)
.collect(Collectors.toList());
说到limit,不得不提及一下另外一个流操作:sorted。该操作用于对流中元素进行排序,sorted要求待比较的元素必须实现Comparable接口,如果没有实现也不要紧,我们可以将比较器作为参数传递给sorted(Comparator<? super T> comparator),比如我们希望筛选出专业为土木工程的学生,并按年龄从小到大排序,筛选出年龄最小的两个学生,那么可以实现为:
List<Student> sortedCivilStudents = students.stream()
.filter(student -> "土木工程".equals(student.getMajor())).sorted((s1, s2) -> s1.getAge() - s2.getAge())
.limit(2)
.collect(Collectors.toList());
4、skip方法
skip操作与limit操作相反,如同其字面意思一样,是跳过前n个元素,比如我们希望找出排序在2之后的土木工程专业的学生,那么可以实现为:
List<Student> civilStudents = students.stream()
.filter(student -> "土木工程".equals(student.getMajor()))
.skip(2)
.collect(Collectors.toList());
通过skip,就会跳过前面两个元素,返回由后面所有元素构造的流,如果n大于满足条件的集合的长度,则会返回一个空的集合。
5、map方法
students.stream().map(emp->emp.getAge()).distinct().forEach(age->{
System.out.println(age);
});