stream流常见操作(详细)

本文介绍 Java 中 Stream API 的多种实用操作,包括过滤、限制、跳过、连接、去重、排序及转换等方法,并通过具体示例展示了 Lambda 表达式的简洁应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. Filiter   过滤
  2. Limit(long maxSize)&&skip   长度不超过maxSize&&跳过指定数量元素
  3. Concat && distinct    连接两个流&&返回流中的不同元素
  4. Sorted自然排序及comparator   排序
  5. Map流终止操作forEach和count      遍历&&统计
  6. Map&&mapToInt

Lambda表达式

        格式(形式参数)->{代码块},->表示指向动作,代码块表示我们的方法内容。

        形参只有一个可以省略()和参数类型,代码块里只有一条语句的情况下可以省略return。

  • Stream之Filiter

        filter(Predicate<? super T> predicate)

        返回由与此给定谓词匹配的此流的元素组成的。可以起到判断过滤作用

 ArrayList<String> list = new ArrayList<>();
        list.add("张三");
        list.add("猪");
        list.add("猪猪侠");
        list.add("赵孙乾");
        ArrayList<String> list1 = new ArrayList<>();
        //输出姓张的
        list.stream().filter((s)->{
            return s.startsWith("猪");
        }).forEach(System.out::println);
        System.out.println("-----");
       //省略版Lambda
       list.stream().filter(s -> s.startsWith("猪")).forEach(System.out::println);
        System.out.println("-----");
       //输出姓猪的且长度为三的姓名
       list.stream().filter(s->s.startsWith("猪")).filter(s->s.length()==3).forEach(s -> System.out.println(s));

结果:

  • Stream之Limit&&skip ​​​​
limit(long maxSize)

返回由此流的元素组成的,截短长度不能超过 maxSize

skip(long n)

在丢弃流的第一个 n元素后,返回由该流的 n元素组成的

ArrayList<String> list = new ArrayList<>();
        list.add("张三");
        list.add("猪");
        list.add("猪猪侠");
        list.add("王静王");
        list.add("猪侠猪");
        list.add("赵孙乾");

        //取前三个元素
        list.stream().limit(3).forEach(System.out::println);
        System.out.println("----");
        //跳过前两个元素
        list.stream().skip(2).forEach(System.out::println);
        System.out.println("----");
        //跳过前两个 去后面的前三个
        list.stream().skip(2).limit(3).forEach(System.out::println);
        System.out.println("----");

结果:

  • Stream之Concat&&distinct
concat(Stream<? extends T> a, Stream<? extends T> b)

创建一个懒惰连接的流,其元素是第一个流的所有元素,后跟第二个流的所有元素。

distinct()

返回由该流的不同元素(根据 Object.equals(Object) )组成的流。

        //取前三个为第一个流
        Stream<String> stream1 = list.stream().limit(3);
        //取除第一个之后的为第二个流
        Stream<String> stream2 = list.stream().skip(1);
        //合并1 2流
        Stream.concat(stream1,stream2).forEach(System.out::println);
        System.out.println("-----");
        //合并1 2流 并且去除重复元素
        Stream.concat(stream1,stream2).distinct().forEach(s -> System.out.println(s));

结果:

        会发现出现了IllegalStateException错误并且提示流已经被操作或者被关闭

        此时我们需要引出流的三个过程来解释这个问题

  • 生成流:

            通过数据源(集合,数组等)生成流     list.stream()

  • 中间操作:

           一个流中间可以跟零个或者多个中间操作,目的是打开流,经过数据过滤/映射,返回一个新的,交给下一个操作使用。                list.stream.filiter()等

  • 终结操作:

          一个流只能有一个终结操作,操作执行后,流就被用"光"了,无法再被操作,所以这一定是流的最后一个操作。                                       forEach()等

 出现IllegalStateException问题原因:

        所以我们可以找到出现这个问题的原因了。

我们先已经对stream1和stream2进行合并了,所以流已经被用光了

第二次调用就会提示错误

 

  •  Sorted自然排序及comparator
sorted()

返回由此流的元素组成的流,根据自然顺序排序。

sorted(Comparator<? super T> comparator)

返回由该流的元素组成的流,根据提供的 Comparator进行排序。

ArrayList<String> list = new ArrayList<>();
        list.add("dsadsads");
        list.add("wsdjj");
        list.add("sdskk");
        list.add("a");

        //stream自然排序
         list.stream().sorted().forEach(System.out::println);
        System.out.println("----");
        //按字符串长度排序 长度一样按照自然排序                                                                                                                                                                                                                                                                                                                                                   
        list.stream().sorted((s1,s2)->{
            int num=s1.length()-s2.length();
            int num2=num==0?s1.compareTo(s2):num;
            return num2;
         }).forEach(System.out::println);

结果:

 

  •  Map流终止操作forEach和count
forEach(Consumer<? super T> action)

对此流的每个元素执行操作。

count()

返回此流中的元素数。

        ArrayList<String>list=new ArrayList<>();
        list.add("10");
        list.add("20");
        list.add("30");
        //过滤并统计元素总数
        long count = list.stream().filter(s -> s.equals("10")).count();
        list.stream().filter(s -> s.equals("10")).forEach(System.out::println);
        System.out.println(count);

 结果:

  •  Map&&mapToInt
map(Function<? super T,? extends R> mapper)

返回由给定函数应用于此流的元素的结果组成的流。

mapToInt(ToIntFunction<? super T> mapper)

返回一个 IntStream ,其中包含将给定函数应用于此流的元素的结果。

        ArrayList<String>list=new ArrayList<>();
        list.add("10");
        list.add("20");
        list.add("30");
        //list集合里的字符串转为Integer
        list.stream().map(Integer::parseInt).forEach(System.out::println);
        System.out.println("----");
       //mapToInt也有此一样的功能
        list.stream().mapToInt(Integer::parseInt).forEach(System.out::println);
        System.out.println("-----");
        //统计元素此流的元素结果
        int sum = list.stream().mapToInt(Integer::parseInt).sum();
        System.out.println(sum);

结果:

<think>好的,我需要回答用户关于Java Stream的主要应用场景及作用的问题。首先,我应该回顾一下用户提供的引用资料,确保回答准确。 引用[1]提到Stream能简化代码,使代码更简洁,但可读性可能对不熟悉的人有影响。引用[2]指出Stream API是Java 8引入的,用于高效、函数式处理集合。引用[3]说明Stream分为创建、中间操作和终止操作三部分。 接下来,我需要整理Stream的主要应用场景。根据引用资料和我的知识,常见的用途包括数据过滤、转换、聚合、并行处理等。比如过滤集合中的元素,可以用filter();转换数据可以用map();聚合操作如求和、求最大值可以用reduce()或collect()。另外,Stream的并行能提升处理大数据集的效率。 还要注意Stream操作分为中间操作和终止操作,中间操作是惰性的,只有在终止操作触发时才会执行。需要解释这一点,避免用户误解。 用户可能想知道实际例子,所以需要举一些代码示例,比如使用Stream处理列表,过滤出偶数并转换为平方数。同时,要提到Stream在复杂业务场景中的应用,比如多层嵌套循环的简化,或者数据库查询结果的链式处理。 另外,引用[3]提到创建的方式,可以从集合、数组生成,或者使用Stream.of()。这点也可以简要说明,但用户主要问的是应用场景,所以可能不需要太多创建的细节。 最后,要确保回答结构清晰,分点列出应用场景,每个场景配以示例代码和解释。同时,按照用户要求,使用中文,数学公式用$...$,但这里可能用不上数学公式,所以重点在代码块和格式正确。 需要检查是否有遗漏的重要应用场景,比如并行处理、排序、分组等。例如,使用Collectors.groupingBy()进行数据分组,或者使用sorted()进行排序。这些也是Stream常见用途。 总结一下,回答的结构应该是: 1. 数据筛选与过滤 2. 数据转换与映射 3. 数据聚合与统计 4. 并行处理加速 5. 链式处理简化代码 6. 分组与分类 每个部分给出示例代码,并引用相关资料中的信息。最后生成相关问题,帮助用户进一步学习。</think>### Stream的主要应用场景及作用 Java Stream通过**声明式编程风格**简化集合操作,主要应用于以下六个典型场景: --- #### 1. **数据筛选与过滤** 使用`filter()`方法快速提取符合条件的数据: ```java List<Integer> numbers = Arrays.asList(1,2,3,4,5); List<Integer> evenNumbers = numbers.stream() .filter(n -> n % 2 == 0) .collect(Collectors.toList()); // 输出[2,4] ``` --- #### 2. **数据转换与映射** 通过`map()`实现元素类型转换或计算: ```java List<String> names = Arrays.asList("Alice", "Bob"); List<Integer> nameLengths = names.stream() .map(String::length) .collect(Collectors.toList()); // 输出[5,3] ``` --- #### 3. **数据聚合与统计** 利用`reduce()`和`collect()`进行汇总操作: ```java List<Integer> prices = Arrays.asList(100,200,300); int total = prices.stream().reduce(0, Integer::sum); // 输出600 Map<String, Long> countByCategory = products.stream() .collect(Collectors.groupingBy(Product::getCategory, Collectors.counting())); ``` --- #### 4. **并行处理加速** 通过`parallelStream()`自动实现多线程处理[^2]: ```java List<Data> bigData = getHugeDataset(); long count = bigData.parallelStream() .filter(d -> d.getValue() > 100) .count(); ``` --- #### 5. **链式处理简化代码** 取代多层嵌套循环,例如二维列表扁平化处理[^3]: ```java List<List<String>> nestedList = Arrays.asList( Arrays.asList("a","b"), Arrays.asList("c","d") ); List<String> flatList = nestedList.stream() .flatMap(Collection::stream) .collect(Collectors.toList()); // 输出[a,b,c,d] ``` --- #### 6. **分组与分类** 使用`Collectors.partitioningBy()`实现数据分块: ```java Map<Boolean, List<Student>> passOrFail = students.stream() .collect(Collectors.partitioningBy(s -> s.getScore() >= 60)); ``` --- ### 核心优势对比 | 传统方式 | Stream方式 | |---------|-------------| | 需要显式循环控制 | 声明式函数操作 | | 代码冗余度高 | 链式调用简洁 | | 并行实现复杂 | 自动线程管理 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值