Java小强个人技术博客站点    手机版
当前位置: 首页 >> 理论 >> Java8中Stream使用示例

Java8中Stream使用示例

7510 理论 | 2023-2-17

ava 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。
Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。
Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。


先创建测试对象


package com.example.springboot.Entity;

import lombok.*;

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

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Author implements Comparable<Author>{
    private int id;
    private String name;
    private int age;
    /**
     * 书籍列表
     */
    private List<Book> bookList;

    public static List<Author> getAuthers() {
        Author a1 = Author.builder().id(1).name("张三").age(20).build();
        Book b1 = Book.builder().id(100).name("倾城之恋").build();
        Book b2 = Book.builder().id(200).name("挪威的森林").build();
        List<Book> list1 = new ArrayList<Book>(){};
        list1.add(b1);
        list1.add(b2);
        a1.setBookList(list1);
        Author a2 = Author.builder().id(2).name("阿凡达").age(22).build();
        Author a3 = Author.builder().id(3).name("李冰冰").age(33).build();
        Author a4 = Author.builder().id(4).name("肉丝").age(34).build();
        Book b3 = Book.builder().id(300).name("红楼梦").build();
        List<Book> list3 = new ArrayList<Book>(){};
        list3.add(b1);
        list3.add(b3);
        a3.setBookList(list3);
        Author a5 = Author.builder().id(5).name("老刘").age(35).build();
        Author a6 = Author.builder().id(6).name("大张").age(55).build();
        List<Author> arrList = new ArrayList<>();
        arrList.add(a1);
        arrList.add(a2);
        arrList.add(a3);
        arrList.add(a4);
        arrList.add(a5);
        arrList.add(a6);
        return arrList;
    }

    /**
     * 自己实现Comparable接口
     * @param o 排序对象
     * @return 对比值
     */
    @Override
    public int compareTo(Author o) {
        return o.getAge() - this.getAge();
    }

    /**
     * 重写equals,ID一样就是相同数据
     * @param obj 对比数据
     * @return 是否为同一条数据
     */
    public boolean equals(Object obj) {
        //判断内存地址
        if (obj == this) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        //判断是否是同一类型的对象
        if (obj instanceof Author) {
            //强制转换成Person类型
            Author per = (Author) obj;
            //判断他们的属性值    注:这里的age为什么要用==?可以在评论区回答
            if (this.id == per.id) {
                return true;
            }
        }
        return false;
    }
}


测试对象


package com.example.springboot.Entity;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

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

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Book {
    private int id;
    private String name;
    /**
     * 作者
     */
    private int autId;

    public static List<Book> getBookList(){
        Book b1 = Book.builder().id(1).name("倾城之恋").autId(1).build();
        Book b2 = Book.builder().id(2).name("荆棘鸟").autId(1).build();
        Book b3 = Book.builder().id(3).name("挪威的森林").autId(2).build();
        Book b4 = Book.builder().id(4).name("红楼梦").autId(3).build();
        List<Book> arrList = new ArrayList<>();
        arrList.add(b1);
        arrList.add(b2);
        arrList.add(b3);
        arrList.add(b4);
        return arrList;
    }

    /**
     * 重写equals,ID一样就是相同数据
     * @param obj 对比数据
     * @return 是否为同一条数据
     */
    public boolean equals(Object obj) {
        //判断内存地址
        if (obj == this) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        //判断是否是同一类型的对象
        if (obj instanceof Book) {
            //强制转换成Person类型
            Book per = (Book) obj;
            //判断他们的属性值    注:这里的age为什么要用==?可以在评论区回答
            if (this.id == per.id) {
                return true;
            }
        }
        return false;
    }

}

测试代码


package com.example.springboot;

import com.alibaba.fastjson.JSON;
import com.example.springboot.Entity.Author;
import com.example.springboot.Entity.Book;
import org.junit.jupiter.api.Test;

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

public class StreamTest {

    /**
     * findAny 随机 找到 一个 数据
     * findFirst 找到 第一个 数据
     */
    @Test
    public void testFindAny(){
        Optional<Author> optionalAuthor = Author.getAuthers().stream()
                .distinct()
                .filter(author -> author.getAge() >= 35)
                .findFirst();
                // .findAny();
        optionalAuthor.ifPresent(author -> System.out.println(author));
    }

    /**
     * anyMatch 流中数据是否有 一个 匹配数据
     * allMatch 流中数据必须 全部 匹配
     * noneMatch 流中数据 没有 匹配
     */
    @Test
    public void testMatch(){
        boolean isHava = Author.getAuthers().stream()
                .distinct()
                .noneMatch(author -> author.getAge() >= 35);
                // .allMatch(author -> author.getAge() >= 35);
                // .anyMatch(author -> author.getAge() >= 35);
        System.out.println("是否找到数据:" + isHava);
    }

    /**
     * max 计算流中元素最大值,min类似
     */
    @Test
    public void testMax(){
        Optional<Integer> max = Author.getAuthers().stream()
                .distinct()
                .map(author -> author.getAge())
                // Idea会提示替换为下面写法
                //  .max((age1, age2) -> age1 - age2);
                .max(Comparator.comparingInt(age -> age));
        System.out.println(max.get());
    }

    /**
     * count 统计流中元素个数
     */
    @Test
    public void testCount(){
        long count = Author.getAuthers().stream()
                .distinct()
                .count();
        System.out.println("共有数据:" + count);
    }

    /**
     * reduce 将流中数据按照规则计算出一个结果
     */
    @Test
    public void testReduce(){
        int re = Author.getAuthers().stream()
                .distinct()
                .map(author -> author.getAge())
                // 计算作者年龄 总和,参数0是初始值
                .reduce(0, (age1, age2) -> age1 + age2);
        System.out.println("年龄总和:" + re);

        re = Author.getAuthers().stream()
                .distinct()
                .map(author -> author.getAge())
                // 计算作者年龄 最大,参数0是初始值
                .reduce(0, (age1, age2) -> age1 > age2 ? age1 : age2);
        System.out.println("年龄最大:" + re);

        Optional<Integer> optionalInteger = Author.getAuthers().stream()
                .distinct()
                .map(author -> author.getAge())
                // 计算作者年龄 最小,一个参数没有初始值
                .reduce((age1, age2) -> age1 > age2 ? age2 : age1);
        System.out.println("年龄最小:" + optionalInteger.get());
    }

    /**
     * sorted 将流中数据按照规则排序
     */
    @Test
    public void testSorted(){
        Author.getAuthers().stream()
                // 使用对象实现的compareTo方法
                // .sorted()
                // 使用Lambda编写逻辑
                // .sorted((aut1, aut2) -> aut1.getAge() - aut2.getAge())
                // 使用提供的工具,reversed()降序
                .sorted(Comparator.comparingInt(Author::getAge).reversed())
                // 跳过一个后取前三个
                .skip(1)
                .limit(3)
                .forEach(author -> System.out.println(author));
    }

    /**
     * collect 将流转换为一个Set
     */
    @Test
    public void testCollectToSet() {
        Set<Author> authorsSet = Author.getAuthers().stream()
                .collect(Collectors.toSet());
        System.out.println(JSON.toJSONString(authorsSet, true));
    }

    /**
     * collect 将流转换为一个Map
     */
    @Test
    public void testCollectToMap() {
        Map<Integer, Author> autMap = Author.getAuthers().stream()
                // 先去重,否则有重复对象时报错
                .distinct()
                // 这里指定以作者ID为Key,以作者对象为Value
                .collect(Collectors.toMap(Author::getId, author -> author));
        System.out.println(JSON.toJSONString(autMap, true));

        // 如果按指定规则收集时,会有多个结果,就使用分组,指定分组规则
        Map<Integer, List<Book>> bookMap = Book.getBookList().stream()
                // 一个作者会写多本书
                .collect(Collectors.groupingBy(Book::getAutId));
        System.out.println(JSON.toJSONString(bookMap, true));
    }

    /**
     * collect 将流转换为一个List
     */
    @Test
    public void testCollectToList() {
        List<String> autNameList = Author.getAuthers().stream()
                .map(author -> author.getName())
                .collect(Collectors.toList());
        System.out.println(JSON.toJSONString(autNameList));
    }

    /**
     * flatMap 返回流,该流将包含通过映射函数替换源流的每个元素而获得的元素,并展平结果
     * distinct 通过equals方法判断是否为同一个对象,所以,可以重写Object的方法来定制
     */
    @Test
    public void testFlatMap() {
        Author.getAuthers().stream()
                // 注意这里依然要做为空判断
                .flatMap(author -> null == author.getBookList() ? null : author.getBookList().stream())
                .distinct()
                .forEach(book -> System.out.println(book));
    }

    /**
     * map 将流中对象进行转换
     */
    @Test
    public void testMap() {
        Author.getAuthers().stream()
                // 这里Map操作后返回的流里面都是String
                .map(author -> author.getName())
                .forEach(name -> System.out.println(name));
    }

    /**
     * filter 过滤流中数据
     */
    @Test
    public void testFilter() {
        Author.getAuthers().stream()
                // 可以添加多个过滤条件
                .filter(author -> author.getAge() >= 35)
                .filter(author -> author.getName().length() >= 2)
                .forEach(author -> System.out.println(author));
    }

    /**
     * forEach 遍历流中数据
     */
    @Test
    public void testForEach() {
        Author.getAuthers().stream()
                .forEach(author -> System.out.println(author));
    }

}



END

推荐您阅读更多有关于“ stream Java8 并行 聚合操作 ”的文章

上一篇:博客在阿里云申请免费SSL证书 下一篇:Integer.parseInt和Integer.valueOf区别

猜你喜欢

发表评论: