java中jdk8新特性之一stream流的使用方式,常用方法,终结方法

什么是stream? 也叫Stream流,是JDK8开始新增的一套API(java.util.stream.*)可以用于操作集合或者数组的数据。

优势:

Stream流大量结合了Lamdba表达式的语法风格来编程,提供了一套更加强大的,更加简单的方式操作集合或数组中的数据, 代码更加简洁,可读性更好。

初体验Stream流: 需求:在一组list集合中把所有以张开头,且是3个字的元素存储到一个新的集合中

我们先不使用Stream流演示一下:

java 复制代码
public static void main(String[] args) {
 
 List<String> names = new ArrayList<>();
        Collections.addAll(names,"无极","单独","范德萨","VS是否","孙子","孙尚香","孙纷纷");
        System.out.println(names);
        // 找出姓张,存入到一个信息的集合中
        ArrayList<String> list = new ArrayList<>();
        for (String name : names) {
            if (name.startsWith("孙") && name.length() == 3){
                list.add(name);
            }
        }
        System.out.println(list);
 
}

/** [无极, 单独, 范德萨, VS是否, 孙子, 孙尚香, 孙纷纷]

  • [孙尚香, 孙纷纷]

*/

下面我们使用Stream流来完成这个需求:

java 复制代码
public class StreamDemo1 {
public static void main(String[] args) {
 
 List <String> nameList = names.stream().filter(s -> s.startsWith("孙"))
            .filter(a -> a.length() == 3).collect(Collectors.toList());
        System.out.println(nameList);
 
}
 
// [孙尚香, 孙纷纷]
 
}

Stream流的使用步骤:

获取Stream流: 获取集合的Stream流:

获取list集合的stream流:

java 复制代码
 public static void main(String[] args) {
 
         // 1 如何获取list集合的stream流
        ArrayList<String> names = new ArrayList<>();
        Collections.addAll(names,"无极","单独","范德萨","VS是否","孙子","孙尚香","孙方法");
        Stream<String> stream = names.stream();
 
}

如何获取set集合的stream流:

java 复制代码
Set<String> set = new HashSet<>();
        Collections.addAll(set,"张德华","张信息","组织者","马德","德玛西亚");
        Stream<String> stream1 = set.stream();
        stream1.filter(s -> s.contains("德")).forEach(s -> System.out.println(s));
 
    /**
     * 张德华
     * 马德
     * 德玛西亚
     */

获取map集合的Stream流:

java 复制代码
  Map<String,Double> map = new HashMap<>();
        map.put("迪丽热巴",171.4);
        map.put("古力娜扎",168.9);
        map.put("马尔科是",177.8);
        map.put("卡尔",173.4);
        Set<String> keys = map.keySet();
        Stream<String> kStream = keys.stream();
        Collection<Double> values = map.values();
        Stream<Double> allValues = values.stream();
 
//第二种方式:  示例:获取map集合中键值包含巴的人的信息
Set<Map.Entry<String, Double>> entries = map.entrySet();
        Stream<Map.Entry<String, Double>> kvs = entries.stream();
        kvs.filter(s -> s.getKey().contains("巴")).
                forEach(e -> System.out.println(e.getKey() + "--->" + e.getValue()));
 
//迪丽热巴--->171.4

获取数组的Stream流:

java 复制代码
 
   String[] names2 = {"孙尚香","孙凤的","大山","多少"};
        Stream<String> streamName1 = Arrays.stream(names2);
        Stream<String> streamName2 = Stream.of(names2);
        streamName1.forEach(s -> System.out.print(s+" "));
 
// 孙尚香 孙凤的 大山 多少 

Stream流常见的中间方法: 中间方法指的是调用完成后会返回新的Stream流,可以继续使用(支持链式编程)

filter的使用:

需求:过滤姓名以张开头,并且名字长度等于3的名字

java 复制代码
 List<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌", "周芷若","赵敏","张强","张三丰");
        // 1、过滤方法   //过滤姓名以张开头,并且名字长度等于3的名字
       list.stream().filter(s -> s.startsWith("张") && s.length() == 3).forEach(e -> System.out.println(e));
 
 
//张无忌
//张三丰

socred 排序

先准备一个 Movie类和Actor类:

Movies类:

java 复制代码
public class Movie implements Comparable<Movie>{
    private String name;
    private Double score;
    private String actor;
 
    public Movie() {
    }
 
    public Movie(String name, Double score, String actor) {
        this.name = name;
        this.score = score;
        this.actor = actor;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public Double getScore() {
        return score;
    }
 
    public void setScore(Double score) {
        this.score = score;
    }
 
    public String getActor() {
        return actor;
    }
 
    public void setActor(String actor) {
        this.actor = actor;
    }
 
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Movie movie = (Movie) o;
        return Objects.equals(name, movie.name) && Objects.equals(score, movie.score) && Objects.equals(actor, movie.actor);
    }
 
    @Override
    public int hashCode() {
        return Objects.hash(name, score, actor);
    }
 
    @Override
    public String toString() {
        return "Movie{" +
                "name='" + name + '\'' +
                ", score=" + score +
                ", actor='" + actor + '\'' +
                '}';
    }
 
    @Override
    public int compareTo(Movie o) {
        return Double.compare(this.score,o.score);
    }
}

Actor类:

java 复制代码
public class Actor {
    private String name;
    private Double actor;
 
    public Actor() {
    }
 
    public Actor(String name, Double actor) {
        this.name = name;
        this.actor = actor;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public Double getActor() {
        return actor;
    }
 
    public void setActor(Double actor) {
        this.actor = actor;
    }
 
    @Override
    public String toString() {
        return "Actor{" +
                "name='" + name + '\'' +
                ", actor=" + actor +
                '}';
    }
}

准备一个集合,排序。

java 复制代码
 List<Movie> movies = new ArrayList<>();
        movies.add(new Movie("摔跤吧,爸爸", 9.5, "阿米尔汗"));
        movies.add(new Movie("三傻宝莱坞", 8.5, "阿米尔汗2"));
        movies.add(new Movie("三傻宝莱坞", 8.5, "阿米尔汗2"));
        movies.add(new Movie("阿甘正传", 7.5, "汤姆汉克斯"));
        // 集合中如果存储对象,
        // 方式一:对象类可以实现Comparable接口,指定比较规则  // sorted方法就可以按照规则进行排序,否则报错!
        movies.stream().sorted().forEach(e -> System.out.println(e));
 
        // 方式二:自带比较器
        movies.stream().sorted((o1,o2)  ->  Double.compare(o2.getScore(),o1.getScore()));
 
 
    /**
     * Movie{name='阿甘正传', score=7.5, actor='汤姆汉克斯'}
     * Movie{name='三傻宝莱坞', score=8.5, actor='阿米尔汗2'}
     * Movie{name='三傻宝莱坞', score=8.5, actor='阿米尔汗2'}
     * Movie{name='摔跤吧,爸爸', score=9.5, actor='阿米尔汗'}
     */

limit 截取:

需求:截取前两个

java 复制代码
 movies.stream().sorted().limit(3).forEach(System.out::println);
 
 
/**
 * Movie{name='阿甘正传', score=7.5, actor='汤姆汉克斯'}
 * Movie{name='三傻宝莱坞', score=8.5, actor='阿米尔汗2'}
 * Movie{name='三傻宝莱坞', score=8.5, actor='阿米尔汗2'}
 */

skip 跳过:

需求:跳过前两个

java 复制代码
 movies.stream().skip(2).forEach(e -> System.out.println(e));
 
/**
 * Movie{name='三傻宝莱坞', score=8.5, actor='阿米尔汗2'}
 * Movie{name='阿甘正传', score=7.5, actor='汤姆汉克斯'}
 */

distinct 去重:

java 复制代码
 movies.stream().distinct().forEach(e -> System.out.println(e));
 
 
/**
 * Movie{name='摔跤吧,爸爸', score=9.5, actor='阿米尔汗'}
 * Movie{name='三傻宝莱坞', score=8.5, actor='阿米尔汗2'}
 * Movie{name='阿甘正传', score=7.5, actor='汤姆汉克斯'}
 */

map加工方法(映射): 需求:把流上的数据加工成新数据。

java 复制代码
 
 movies.stream().sorted((Movie o1, Movie o2) -> Double.compare(o2.getScore(),o1.getScore()))
                .map(m -> new Actor(m.getName(),m.getScore())).forEach(e -> System.out.println(e));
 
 
    /**
     * Actor{name='摔跤吧,爸爸', actor=9.5}
     * Actor{name='三傻宝莱坞', actor=8.5}
     * Actor{name='三傻宝莱坞', actor=8.5}
     * Actor{name='阿甘正传', actor=7.5}
     */

合并流:

需求:把两个流连接起来

java 复制代码
 
  Stream<String> s1 = Stream.of("张三", "楚留香", "西门吹牛");
        Stream<String> s2 = Stream.of("李四", "石观音");
        // public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
        Stream<String> concat = Stream.concat(s1, s2);
        concat.forEach(e -> System.out.println(e));
 
 
/**
 * 张三
 * 楚留香
 * 西门吹牛
 * 李四
 * 石观音
 */

Stream流常见的终结方法: 终结方法指的是调用完成后,不会返回新的Stream了,没法继续使用流了。

forEach:方法

需求:打印出来集合中的数据

java 复制代码
  List<Movie> movies = new ArrayList<>();
        movies.add(new Movie("摔跤吧,爸爸", 9.5, "阿米尔汗"));
        movies.add(new Movie("三傻宝莱坞", 8.5, "阿米尔汗2"));
        movies.add(new Movie("三傻宝莱坞", 8.5, "阿米尔汗2"));
        movies.add(new Movie("阿甘正传", 7.5, "汤姆汉克斯"));
        // 1、forEach
       movies.forEach(e -> System.out.println(e));
ini 复制代码
    /**
     * {name='摔跤吧,爸爸', score=9.5, actor='阿米尔汗'}
     * Movie{name='三傻宝莱坞', score=8.5, actor='阿米尔汗2'}
     * Movie{name='三傻宝莱坞', score=8.5, actor='阿米尔汗2'}
     * Movie{name='阿甘正传', score=7.5, actor='汤姆汉克斯'}
     */

count 取数量:

需求:求出集合中的数据的数量

System.out.println(movies.stream().count());

// 4 max 求最大值:

需求:根据评分升序排序

java 复制代码
 
  Movie max = movies.stream().max((o1,o2) -> Double.compare(o1.getScore(), o2.getScore())).get();
        System.out.println(max);
 
 
//{name='摔跤吧,爸爸', score=9.5, actor='阿米尔汗'}

min 求最小值:

需求:按照评分排序,找到最小值

scss 复制代码
    Movie min = movies.stream().min((o1, o2) -> Double.compare(o1.getScore(), o2.getScore())).get();
    System.out.println(min);

// {name='阿甘正传', score=7.5, actor='汤姆汉克斯'} collect 收集流:

需求:收集Stream流:把流中的数据恢复到集合或者数组中去

java 复制代码
 List<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
        list.add("张三丰");
 
        // 收集到List集合   //把姓张的学生收集到一个新的集合中
        List<String> list2 = list.stream().filter(s -> s.startsWith("张")).collect(Collectors.toList());
        System.out.println(list2);
 
        // 收集到Set集合(流只能用一次)
        Set<String> set1 = list.stream().filter(s -> s.startsWith("张") && s.length() == 3).collect(Collectors.toSet());
        System.out.println(set1);
 
//[张无忌, 张强, 张三丰, 张三丰]
[张三丰, 张无忌]

//

收集到数组中:

java 复制代码
 
   Stream<String> arr = list.stream().filter(s -> s.startsWith("张"));
        Object[] array = arr.toArray();
        System.out.println(Arrays.toString(array));
 
// [张无忌, 张强, 张三丰, 张三丰]
// 拓展 收集到Map集合。Movice需要重写 equals 和 hashCode 方法
List<Movie> movies1 = new ArrayList<>();
movies1.add(new Movie("摔跤吧,爸爸", 9.5, "阿米尔汗"));
movies1.add(new Movie("三傻宝莱坞", 18.5, "阿米尔汗2"));
movies1.add(new Movie("三傻宝莱坞", 18.5, "阿米尔汗2"));
movies1.add(new Movie("阿甘正传", 7.5, "汤姆汉克斯"));
 
Map<String, Double> collect = movies1.stream()
        .distinct().collect(Collectors.toMap(movie -> movie.getName(), movie -> movie.getScore()));
System.out.println(collect);
 
// {摔跤吧,爸爸=9.5, 阿甘正传=7.5, 三傻宝莱坞=18.5}
相关推荐
Alive~o.05 分钟前
Go语言进阶&依赖管理
开发语言·后端·golang
许苑向上11 分钟前
Dubbo集成SpringBoot实现远程服务调用
spring boot·后端·dubbo
郑祎亦1 小时前
Spring Boot 项目 myblog 整理
spring boot·后端·java-ee·maven·mybatis
本当迷ya1 小时前
💖2025年不会Stream流被同事排挤了┭┮﹏┭┮(强烈建议实操)
后端·程序员
计算机毕设指导62 小时前
基于 SpringBoot 的作业管理系统【附源码】
java·vue.js·spring boot·后端·mysql·spring·intellij-idea
paopaokaka_luck2 小时前
[371]基于springboot的高校实习管理系统
java·spring boot·后端
捂月4 小时前
Spring Boot 深度解析:快速构建高效、现代化的 Web 应用程序
前端·spring boot·后端
瓜牛_gn4 小时前
依赖注入注解
java·后端·spring
Estar.Lee4 小时前
时间操作[取当前北京时间]免费API接口教程
android·网络·后端·网络协议·tcp/ip
喜欢猪猪4 小时前
Django:从入门到精通
后端·python·django