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}
相关推荐
金銀銅鐵8 小时前
[Java] 用 GUI 展示 EnumSet 增减元素时的内部变化(上)
java·后端·ai编程
念何架构之路9 小时前
go-grpc设计思想
开发语言·后端·golang
system_error_x9 小时前
SpringBoot 集成 Thymeleaf 简洁入门
java·spring boot·后端
步行cgn11 小时前
Spring MVC 视图机制的核心接口与类
java·开发语言·后端·spring·mvc
码事漫谈12 小时前
AI 读你的提示词,其实很没耐心
后端
用户83562907805112 小时前
如何使用 Python 格式化 Excel 单元格中的长文本
后端·python
我命由我1234512 小时前
Python 开发 - Python 的 pathlib
java·开发语言·后端·python·学习·java-ee·学习方法
IT_陈寒12 小时前
Java性能优化完全指南
前端·人工智能·后端
电子IT笔记12 小时前
对接群晖NAS,上传和删除踩坑记录
前端·后端
Mk5987813 小时前
P4:把 Agent 的记忆搬进 Redis —— AgentScope-Java 工程化实战
后端