Java的Stream流

目录

1.什么是Stream

Stream的特点

2.Stream流vs传统集合操作

3.创建Stream流

4.Stream常用方法

4.1中间方法

过滤操作

排序操作

限制和跳过元素

去重操作

映射操作

流合并

关键点总结

[4.2 终结方法](#4.2 终结方法)

1.foreach

2.count统计个数

[3.max/min 最大/最小值](#3.max/min 最大/最小值)

[4.3 收集方法](#4.3 收集方法)


Stream是Java 8引入的一套新的API,用于处理集合数据的函数式编程风格操作。它让集合操作变得更简洁、高效,并支持并行处理

1.什么是Stream

Stream是一种高级迭代器,用于对数据源进行函数式操作。

Stream的特点

  1. 不存储数据:Stream本身不存储数据,数据来自数据源

  2. 函数式操作:支持lambda表达式和函数式编程

  3. 延迟执行:中间操作都是延迟执行的

  4. 可消费性:Stream只能被消费一次

2.Stream流vs传统集合操作

现在有一个装有String的列表["Tom", "Jerry", "Alice"],我要把Alice全部大写并且放到新的列表当中去,应该怎么办?

传统方式:

java 复制代码
        // 传统集合操作
        List<String> names = Arrays.asList("Tom", "Jerry", "Alice");
        List<String> result = new ArrayList<>();
        for (String name : names) {
            if (name.startsWith("A")) {
                result.add(name.toUpperCase());
            }
        }

Stream流操作:

java 复制代码
        // Stream操作
        List<String> result1 = names.stream()
                .filter(name -> name.startsWith("A"))
                .map(String::toUpperCase)
                .collect(Collectors.toList());

结果都是一样的[ALICE]

3.创建Stream流

详情看代码:

java 复制代码
        //1.获取集合的stream流
        List<String> list = new ArrayList<>();
        Stream<String> stream1 = list.stream();

        //2.获取Map的stream流
        Map<String,String> map=new HashMap<>();
        //获取键流
        Stream<String> stream2 = map.keySet().stream();
        //获取值流
        Stream<String> stream3 = map.values().stream();
        //获取键值对流
        Stream<Map.Entry<String, String>> stream4 = map.entrySet().stream();

        //3.获取数组的stream流
        Integer[] arr={1,2,3,4,5,6,7,8,9};
        Stream<Integer> stream5 = Arrays.stream(arr);
        Stream<Integer> stream6 = Stream.of(arr);

4.Stream常用方法

4.1中间方法

中间方法的意思是,调用完它们之后,返回的是一个新的流,可以进行用中间方法对其进行操作,所以它支持链式编辑。

java 复制代码
package com.qbcy;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class Demo2 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
        list.add("张翠山");

        //1.过滤方法
        list.stream().filter(s -> s.startsWith("张")&&s.length()==3)
                .forEach(s -> System.out.println(s));

        //2.排序方法
        List<Double> list1 = new ArrayList<>();
        list1.add(1.2);
        list1.add(4.3);
        list1.add(4.3);
        list1.add(4.3);
        list1.add(3.2);
        list1.add(2.1);
        list1.stream().sorted().forEach(s -> System.out.print(s+"   "));
        System.out.println();
        //降序排列
        list1.stream().sorted((s1,s2)->Double.compare(s2,s1)).forEach(s -> System.out.print(s+"   "));
        System.out.println();
        //获取降序排列后的前两个元素 limit
        list1.stream().sorted((s1,s2)->Double.compare(s2,s1)).limit(2).forEach(s -> System.out.print(s+"   "));
        System.out.println();
        //跳过前两个元素 skip
        list1.stream().sorted((s1,s2)->Double.compare(s2,s1)).skip(2).forEach(s -> System.out.print(s+"   "));
        System.out.println();
        //去重 distinct
        //如果希望能去重,则需要重写hashCode和equals方法
        list1.stream().distinct().forEach(s -> System.out.print(s+"   "));
        System.out.println();

        //映射方法:把流上面的元素拿出来变成新的元素再放到新流中
        list1.stream().map(s -> "加10后:"+(s+10)).forEach(System.out::println);

        //合并流,把两个流接起来
        Stream<Object> res=Stream.concat(list.stream(),list1.stream());
        System.out.println("-----------合并后的流-----------");
        res.forEach(System.out::println);


    }

}

过滤操作

使用filter方法筛选出以"张"开头且长度为3的字符串:

java 复制代码
list.stream().filter(s -> s.startsWith("张")&&s.length()==3)
        .forEach(s -> System.out.println(s));

排序操作

Double类型列表进行升序和降序排列:

java 复制代码
// 升序
list1.stream().sorted().forEach(s -> System.out.print(s+"   "));

// 降序
list1.stream().sorted((s1,s2)->Double.compare(s2,s1)).forEach(s -> System.out.print(s+"   "));

限制和跳过元素

使用limit获取前两个元素,skip跳过前两个元素:

java 复制代码
// 获取前两个
list1.stream().sorted((s1,s2)->Double.compare(s2,s1)).limit(2).forEach(s -> System.out.print(s+"   "));

// 跳过前两个
list1.stream().sorted((s1,s2)->Double.compare(s2,s1)).skip(2).forEach(s -> System.out.print(s+"   "));

去重操作

使用distinct去除重复元素:

java 复制代码
list1.stream().distinct().forEach(s -> System.out.print(s+"   "));

映射操作

通过map将每个元素转换为新格式:

java 复制代码
list1.stream().map(s -> "加10后:"+(s+10)).forEach(System.out::println);

流合并

使用Stream.concat合并两个流:

java 复制代码
Stream<Object> res=Stream.concat(list.stream(),list1.stream());
res.forEach(System.out::println);

关键点总结

  • filter用于条件筛选
  • sorted支持自然排序和自定义比较器
  • limitskip控制元素数量
  • distinct依赖equalshashCode实现去重
  • map实现元素转换
  • Stream.concat可合并多个流

4.2 终结方法

一旦调用终结方法,这个流就不能再使用了

首先创建Teacher类

java 复制代码
package com.qbcy;

/**
 * 创建Teacher类
 */
public class Teacher {
    private String name;
    private int age;
    private String sex;

    public Teacher() {
    }

    public Teacher(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    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 String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    @Override
    public String toString() {
        return "Teacher [name=" + name + ", age=" + age + ", sex=" + sex + "]";
    }
}

1.foreach

java 复制代码
package com.qbcy;

import java.util.ArrayList;
import java.util.List;

/**
 * 终结方法
 */
public class Demo3 {

    public static void main(String[] args) {
        List<Teacher> list = new ArrayList<>();
        list.add(new Teacher("张三", 18, "男"));
        list.add(new Teacher("张三丰", 50, "男"));
        list.add(new Teacher("张无忌", 20, "男"));
        list.add(new Teacher("周芷若", 18, "女"));
        list.add(new Teacher("赵敏", 16, "女"));
        list.add(new Teacher("张翠山", 40, "男"));

        //forEach 遍历过滤后的数据
        list.stream().filter(t->t.getAge()>30).forEach(System.out::println);
    }

}

这里把年龄大于30的教师过滤出来,使用forEach遍历输出:

2.count统计个数

java 复制代码
Long tCount=list.stream().filter(t->t.getAge()>30).count();
        System.out.println("30岁以上的教师数量为:"+tCount);

3.max/min 最大/最小值

java 复制代码
        //max 返回最大值 放到了 Optional 容器里面 ,这个容器里面能记住值value
        Optional<Teacher> res=list.stream().max((t1, t2)->Double.compare(t1.getAge(),t2.getAge()));
        Teacher maxAgeTeacher= res.get();
        System.out.println("最大年龄的教师为:"+maxAgeTeacher);
        System.out.println("-------------------------------");
        //min 返回最小值 放到了 Optional 容器里面 ,这个容器里面能记住值value
        Optional<Teacher> res1=list.stream().min((t1, t2)->Double.compare(t1.getAge(),t2.getAge()));
        Teacher minAgeTeacher= res1.get();
        System.out.println("最小年龄的教师为:"+minAgeTeacher);
        System.out.println("-------------------------------");

4.3 收集方法

java 复制代码
package com.qbcy;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Demo1 {
    //获取Stream流
    public static void main(String[] args) {
        //1.获取集合的stream流
        List<String> list = new ArrayList<>();
        //赋值
        list.add("张三");
        list.add("李四");
        list.add("王五");
        //过滤
        Stream<String> streamList=list.stream().filter(s->s.startsWith("张"));
        List<String> resList= streamList.collect(Collectors.toList());
        System.out.println(resList);
        System.out.println("--------------------------------------------------");

        //2.获取Map的stream流
        Map<String,String> map=new HashMap<>();
        //赋值
        map.put("1","张三");
        map.put("2","张三");
        map.put("3","张三");
        map.put("4","张三");
        //获取键流
        Stream<String> streamKeys = map.keySet().stream();
        List<String> resKeys= streamKeys.collect(Collectors.toList());
        System.out.println(resKeys);
        System.out.println("--------------------------------------------------");
        //获取值流
        Stream<String> stream3 = map.values().stream();
        List<String> resValues= stream3.collect(Collectors.toList());
        System.out.println(resValues);
        System.out.println("--------------------------------------------------");
        //获取键值对流
        Stream<Map.Entry<String, String>> stream4 = map.entrySet().stream();
        List<Map.Entry<String, String>> resEntry= stream4.collect(Collectors.toList());
        Map<String, String> resMap= resEntry.stream().collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
        System.out.println(resMap);
        System.out.println(resEntry);
        System.out.println("--------------------------------------------------");

        //3.获取数组的stream流
        Integer[] arr={1,2,3,4,5,6,7,8,9};
        Stream<Integer> stream5 = Arrays.stream(arr);
        Stream<Integer> stream6 = Stream.of(arr);
        List<Integer> resArr= stream5.collect(Collectors.toList());
        System.out.println(resArr);
        System.out.println("--------------------------------------------------");

    }
}
相关推荐
kevinzeng2 小时前
Redis的IO多路复用
java·redis
2501_916766542 小时前
【SpringMVC】异常处理和拦截器
java·spring
不惑_2 小时前
在 Docker 中运行 Java JAR 包实战教程
java·docker·jar
小老鼠不吃猫2 小时前
C++20 STL <numbers> 数学常量库
开发语言·c++·c++20
一勺菠萝丶2 小时前
解决Java中IP地址访问HTTPS接口的SSL证书验证问题
java·tcp/ip·https
墨着染霜华2 小时前
IntelliJ IDEA 设置导出与导入完整指南(备份 / 迁移 / 团队共享)
java·ide·intellij-idea
浮游本尊2 小时前
Java学习第32天 - 性能优化与架构设计
java
清水白石0082 小时前
《精通 Python 设计模式:从入门理解到实战落地》
开发语言·python