当前位置: 首页 > news >正文

Java中Stream流的使用

在 Java 中,Stream 流是 Java 8 引入的一个强大特性,它允许你以声明式的方式处理集合数据。Stream 流提供了一种高效且易于使用的方式来对数据进行过滤、映射、排序、聚合等操作,使代码更加简洁和可读。

1. 获取Stream流

要使用Stream流首先要获取到Stream流

public static void main(String[] args) {//创建Stream流//1. 单列集合创建List<String> list = new ArrayList<>();Stream<?> stream1 = list.stream();Set<String> set = new HashSet<>();Stream<?> stream2 = set.stream();Stack<String> stack = new Stack<>();Stream<?> stream3 = stack.stream();Queue<String> queue = new LinkedList<>();Stream<?> stream4 = stack.stream();//2. 双列集合创建Map<String, String> map = new HashMap<>();Stream<?> stream5 = map.entrySet().stream();//3. 数组创建int[] arr = {1, 2 ,3};IntStream stream6 = Arrays.stream(arr);//4. 零散数据创建Stream<?> stream7 = Stream.of(1, 2, 3, 4);}

 注意 Stream.of(T... values) values为变长参数可以接收一个数组,但是这里只能接收引用类型的数组,如果是基础类型的数据由于不会自动装包会把整个数组视为一个数据

2. 中间方法

当我们获取到Stream流后就可以调用其中的一些方法来对其中的数据进行一些操作,其中的方法分为两大类,其一就是中间方法,中间方法的特点是会返回一个新的 Stream 流,允许你链式调用多个操作 :

  • Stream<T> filter(Predicate<T>):过滤满足条件的元素。
  • Stream<T> limit(long):限制元素数量。
  • Stream<T> skip(long):跳过前 n 个元素。
  • Stream<T> distinct():去重。
  • static<T> Stream<T> concat(Stream,Stream ):合并a和两个流作为一个流
  • Stream<T> sorted():排序。
  • Stream<T> map(Function<T, R>):将元素转换为另一种类型。

 注意:

  • 每个Stream流只能使用一次,中间方法返回的是一个新的Stream流
  • 修改Stream流中的数据不会影响原来集合或数组中的数据
 2.1 filter使用示例

 filter方法接收一个Predicate类型的参数,我们转到其定义:

可以看到这是一个函数式接口, 同时test方法的描述也说明了,如果参数匹配则返回true否则返回false,这里的含义即为,如果该数据(t)是符合要求的则通过,否则不通过:

    public static void filterTest() {List<String> list = new ArrayList<>();Collections.addAll(list, "张明", "张三丰", "张良", "张明朱诺", "杨过", "小龙女");//这里筛选以张开头且长度为3的字符串list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(x-> System.out.print(x + " "));}

这里我们使用lambad表达式重写test方法,先赛选了以张开头的数据,再赛选了长度为3的数据最后使用forEach输出

2.2 limit 和skip使用

limit接收一个long类型的参数表示只保留前n个元素,skip同样接收一个long类型的参数表示要跳过前n个元素:

    public static void limitAndSkipTest() {List<String> list = new ArrayList<>();Collections.addAll(list, "张明", "张三丰", "张良", "张明朱诺", "杨过", "小龙女");System.out.println("limit:");list.stream().limit(4).forEach(x-> System.out.print(x + " "));System.out.println("\nskip:");list.stream().skip(3).forEach(x-> System.out.print(x + " "));System.out.println("\nlimit-skip:");list.stream().limit(4).skip(3).forEach(x-> System.out.print(x + " "));System.out.println("\nskip-limit:");list.stream().skip(3).limit(4).forEach(x-> System.out.print(x + " "));}

运行结果:

2.3 distinct 和concat
    public static void distinctAndConcatTest() {List<String> list1 = new ArrayList<>();Collections.addAll(list1, "张三丰", "张三丰", "杨过", "张明朱诺", "杨过", "小龙女");List<String> list2 = new ArrayList<>();Collections.addAll(list2, "张明", "张三丰", "迪迦");System.out.println("\ndistinct:");list1.stream().distinct().forEach(x-> System.out.print(x + " "));System.out.println("\nconcat:");Stream.concat(list1.stream(), list2.stream()).forEach(x-> System.out.print(x + " "));}

运行结果:

 2.4 stored使用
    public static void sortedTest() {List<String> list1 = new ArrayList<>();Collections.addAll(list1, "张明", "张三丰", "迪迦");List<Integer> list2 = new ArrayList<>();Collections.addAll(list2, 1, 2, 3);System.out.println("\nsortedList1:");list1.stream().sorted().forEach(x-> System.out.print(x + " "));System.out.println("\nsortedList2:");list2.stream().sorted().forEach(x-> System.out.print(x + " "));System.out.println("\nsortedList2desc:");list2.stream().sorted(((o1, o2) -> o2 - o1)).forEach(x-> System.out.print(x + " "));}

sorted不传参数时默认是排降序,可以传入比较器自定义排序规则

2.5 map使用
    public static void MapTest() {List<String> list1 = new ArrayList<>();Collections.addAll(list1, "张明-16", "张三丰-23", "迪迦-3000");//获取每个人的年龄/*** 第一个参数对应原本的数据类型,第二个参数代表要转成的数据类型*/list1.stream().map(new Function<String, Integer>() {@Overridepublic Integer apply(String s) {return Integer.parseInt(s.split("-")[1]);}}).forEach(x-> System.out.print(x + " "));System.out.println();//使用lambada表达式list1.stream().map(s -> Integer.parseInt(s.split("-")[1])).forEach(x-> System.out.print(x + " "));}

运行结果:

3. 终结方法

可以理解为结束方法,不会再返回Stream流

常用的终结方法有:

  • forEach(Consumer<T>):遍历每个元素。
  • count():计算元素数量。
  • toArray():将元素转换为数组。
  • collect(Collector<T, A, R>):将元素收集到集合中。
 3.1 forEach/count/toArray()使用
    public static void CountAndToArrayTest() {List<String> list1 = new ArrayList<>();Collections.addAll(list1, "张三丰", "张三丰", "杨过", "张明朱诺", "杨过", "小龙女");List<Integer> list2 = new ArrayList<>();Collections.addAll(list2, 1, 2, 3);System.out.println(list1.stream().count());System.out.println(list2.stream().count());//<>为需要创建的数组的类型String[] str = list1.stream().toArray(new IntFunction<String[]>() {@Overridepublic String[] apply(int value) {//value代表数据的数量,我们返回一个长度大于等于value的数据即可return new String[value];}});System.out.println(Arrays.toString(str));//使用lambada表达式Integer[] arr = list2.stream().toArray(value -> new Integer[value]);System.out.println(Arrays.toString(arr));}
3.2 collect 使用

将流中的元素收集到集合中

    public static void CollectTest() {List<String> list1 = new ArrayList<>();Collections.addAll(list1, "张三丰-男-23", "杨过-男-32", "张三丰-男-23", "张明朱诺-女-19", "小龙女-女-18");//收集所有男性//ListList<String> list = list1.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toList());System.out.println(list);//SetSet<String> set = list1.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toSet());System.out.println(set);//Map//收集男性,名字作为键,年龄作为值Map<String, Integer> map1 = list1.stream().filter(s -> "男".equals(s.split("-")[1])).distinct()//map中key不能重复,所以先去重.collect(Collectors.toMap(new Function<String, String>() {@Overridepublic String apply(String s) {return s.split("-")[0];}},new Function<String, Integer>() {@Overridepublic Integer apply(String s) {return Integer.parseInt(s.split("-")[2]);}}));System.out.println(map1);//使用lambada表达式Map<String, Integer> map2 = list1.stream().filter(s -> "男".equals(s.split("-")[1])).distinct()//map中key不能重复,所以先去重.collect(Collectors.toMap(s -> s.split("-")[0],s -> Integer.parseInt(s.split("-")[2])));System.out.println(map2);}

这里特别说明toMap()方法,

可以看到toMap接收两个Function做为参数,这里通过参数名我们不难猜出,一个作为键,一个作为值,于是我们只需实现Function接口重写其中方法使其返回预期的键/值即可。

http://www.lryc.cn/news/579764.html

相关文章:

  • 低代码实战训练营教学大纲 (10天)
  • Linux内核驱动(前言、工程环境搭建及linux系统移植)(7.3)
  • 计算机科学导论(10)什么是BIOS
  • 设计模式-观察者模式、命令模式
  • STM32要学到什么程度才算合格?
  • HTTP详细介绍
  • 【BurpSuite 2025最新版插件开发】基础篇7:数据的持久化存储
  • serviceWorker缓存资源
  • P1073 [NOIP 2009 提高组] 最优贸易
  • 【数字后端】- 衡量design的congestion情况
  • 【HarmonyOS】应用开发拖拽功能详解
  • MySQL 8.0 OCP 1Z0-908 题目解析(17)
  • 高边驱动 低边驱动
  • IOC容器讲解以及Spring依赖注入最佳实践全解析
  • 【数据结构】哈希——闭散列/开散列模拟实现(C++)
  • 魔术方法__call__
  • Java的SpringAI+Deepseek大模型实战之会话记忆
  • Python入门Day2
  • 网络编程学习路线图
  • Windows 10 2016 长期服务版
  • 7.3实验部分
  • 工程化实践——标准化Eslint、PrettierTS
  • 50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | DragNDrop(拖拽占用组件)
  • Selenium 自动化测试中跳过机器人验证的完整指南:能用
  • 供应链管理:采购与供应链管理中的核心分析工具
  • js代码中的作用域
  • Linux: perf report数据对比,python
  • ArcGISPro应用指南:ArcGISPro制图全流程详解
  • Java综合练习04
  • 优化Facebook广告投放的五大关键策略