5、转换Stream流
正文
1、概念
转换Stream
其实就是把一个Stream
通过某些行为转换成一个新的Stream
。
多个转换可以连接起来形成一个流水线,除非流水线上触发终止操作,否则转换操作不会执行任何的处理,而是在终止操作时候一次性全部处理,称为“惰性求值”。
2、筛选与切片
2.1、filter
filter
对于Stream
中包含的元素使用给定的过滤函数进行过滤操作,新生成的Stream
只包含符合条件的元素
下面的代码就是过滤出年纪大于25岁的学生
List<Student> studentList = new ArrayList<>();
studentList.add(new Student(1, "赵迪", 23));
studentList.add(new Student(2, "tom", 25));
studentList.add(new Student(2, "jack", 27));
studentList.add(new Student(2, "rose", 22));
List<Student> newList = studentList.stream().filter(x->x.getAge()>25).collect(Collectors.toList());
System.out.println(newList);//[Student(id=2, name=jack, age=27)]
2.2、limit
limit
对一个Stream
进行截断操作,获取其前N
个元素,如果原Stream
中包含的元素个数小于N
,那就获取其所有的元素
下面的代码就是过滤出前2个学生
List<Student> studentList = new ArrayList<>();
studentList.add(new Student(1, "赵迪", 23));
studentList.add(new Student(2, "tom", 25));
studentList.add(new Student(2, "jack", 27));
studentList.add(new Student(2, "rose", 22));
List<Student> newList = studentList.stream().limit(2).collect(Collectors.toList());
System.out.println(newList);//[Student(id=1, name=赵迪, age=23), Student(id=2, name=tom, age=25)]
2.3、skip
skip
跳过指定的个数,返回一个丢弃原Stream
的前N
个元素后剩下元素组成的新Stream
,如果原Stream
中包含的元素个数小于N
,那么返回空Stream
下面的代码就是跳过前面2个学生
List<Student> studentList = new ArrayList<>();
studentList.add(new Student(1, "赵迪", 23));
studentList.add(new Student(2, "tom", 25));
studentList.add(new Student(2, "jack", 27));
studentList.add(new Student(2, "rose", 22));
List<Student> newList = studentList.stream().skip(2).collect(Collectors.toList());
System.out.println(newList);//[Student(id=2, name=jack, age=27), Student(id=2, name=rose, age=22)]
2.4、distinct
distinct
表示对stream
中的元素进行去重操作,得到新的stream
不存在重复的元素,去重的逻辑依赖元素的equals
方法
下面的代码是去重学生,根据ID
List<Student> studentList = new ArrayList<>();
studentList.add(new Student(1, "赵迪", 23));
studentList.add(new Student(2, "tom", 25));
studentList.add(new Student(2, "tom", 27));
studentList.add(new Student(2, "rose", 22));
List<Student> newList = studentList.stream().distinct().collect(Collectors.toList());
3、映射
在SQL
中,借助SELECT
关键字后面添加需要的字段名称,可以仅输出我们需要的字段数据,而流式处理的映射操作也是实现这一目的,在java8
的流式处理中,主要包含两类映射操作:map
和flatMap
。
3.1、map
将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
下面的代码就是通过map将student的年纪映射出来
List<Student> studentList = new ArrayList<>();
studentList.add(new Student(1, "赵迪", 23));
studentList.add(new Student(2, "tom", 25));
studentList.add(new Student(2, "tom", 27));
studentList.add(new Student(2, "rose", 22));
studentList.stream().map(x -> x.getAge()).collect(Collectors.toList());
List<Integer> newList = studentList.stream().map(x -> x.getAge()).collect(Collectors.toList());
System.out.println(newList);//[23, 25, 27, 22]
3.2、flatMap
与map类似,不同的是其每个元素转换得到的是Stream
对象,会把子Stream
中的元素压缩到父集合中,也就是说,将流中的每一个值都换成另一个流,然后把所有流连成一个流。
3.3、map和flatMap区别
举例子说明
有二箱鸡蛋,每箱5个,现在要把鸡蛋加工成煎蛋,然后分给学生。
map做的事情:把二箱鸡蛋分别加工成煎蛋,还是放成原来的两箱,分给2组学生;
flatMap做的事情:把二箱鸡蛋分别加工成煎蛋,然后放到一起【10个煎蛋】,分给10个学生;
4、排序
排序主要分为两种,第一种就是自然排序,第二种就是定制排序
4.1、自然排序(java.lang.Comparable)
Comparable
接口强行对实现它的每个类的对象进行整体排序,这种排序被称为类的自然排序
实现 Comparable
的类必须实现 compareTo(Object obj)
方法,两个对象即 通过 compareTo(Object obj)
方法的返回值来比较大小。如果当前对象this大 于形参对象obj
,则返回正整数,如果当前对象this
小于形参对象obj
,则返回 负整数,如果当前对象this
等于形参对象obj
,则返回零。
实现Comparable
接口的对象列表(和数组)可以通过 Collections.sort
或 Arrays.sort
进行自动排序。实现此接口的对象可以用作有序映射中的键或有 序集合中的元素,无需指定比较器。
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student implements Comparable {
private Integer id;
private String name;
private Integer age;
@Override
public int compareTo(Object o) {
Student other = (Student) o;
if (this.getAge() > other.getAge()) {
return 1;
} else if (this.getAge() < other.getAge()) {
return -1;
}
return 0;
}
}
上述代码中,Student类实现了Comparable
接口,并且实现了comparaTo
方法
public class StreamDemo01 {
public static void main(String[] args) {
List<Student> studentList = new ArrayList<>();
studentList.add(new Student(1, "赵迪", 23));
studentList.add(new Student(3, "tom", 25));
studentList.add(new Student(2, "tom", 27));
studentList.add(new Student(2, "rose", 22));
List<Student> list = studentList.stream().sorted().collect(Collectors.toList());
System.out.println(list);
}
}
上述代码按照age
进行由低到高排序,结果如下
[Student(id=2, name=rose, age=22), Student(id=1, name=赵迪, age=23), Student(id=3, name=tom, age=25), Student(id=2, name=tom, age=27)]
4.2、定制排序(java.util.Comparator)
当元素的类型没有实现java.lang.Comparable
接口而又不方便修改代码,或者实现了java.lang.Comparable
接口的排序规则不适合当前的操作,那么可以考虑使用Comparator
的对象来排序,强行对多个对象进行整体排序的比较。
重写compare(Object o1,Object o2)
方法,比较o1和o2的大小:如果方法返 回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示 o1小于o2
可以将Comparator
传递给sort
方法(如 Collections.sort
或 Arrays.sort
), 从而允许在排序顺序上实现精确控制
public class StreamDemo01 {
public static void main(String[] args) {
List<Student> studentList = new ArrayList<>();
studentList.add(new Student(1, "赵迪", 23));
studentList.add(new Student(3, "tom", 25));
studentList.add(new Student(2, "tom", 27));
studentList.add(new Student(2, "rose", 22));
Comparator<Student> comparator = new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getId() - o2.getId();
}
};
List<Student> list = studentList.stream().sorted(comparator).collect(Collectors.toList());
System.out.println(list);
}
上述代码中,自定义比较器comparator
,传递给sorted
,按照id
从小到大排序,结果如下
[Student(id=1, name=赵迪, age=23), Student(id=2, name=tom, age=27), Student(id=2, name=rose, age=22), Student(id=3, name=tom, age=25)]
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!