Stream整理

初识Stream

Stream使用的对象

Steam是Java8以后的语法糖,用于某些匿名内部类的简化,是函数式编程的重要体现,重点关注于数据的操作流程,是非常成功的一个。
Stream的主要适用对象就是Arrays,集合类(List,Set,Stack,Queue)和Map的使用,能够解脱复杂的遍历循环以及对象的创建,使数据的处理更流程化
-Array的区别

    public static void filterFunc() {
        int[] arrayAlpha = new int[]{1, 2, 44, 30, 23, 101};
//      NOTE 筛选大于30的数字因为数组的长度在定义的时候已经不可改变,所以进行筛选就显得有点麻烦
        List<Integer> list = new ArrayList<>();
        for (int index = 0; index < arrayAlpha.length; index++) {
            if (arrayAlpha[index] > 30) {
                list.add((Integer) arrayAlpha[index]);
            }
        }
        int[] result = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            result[i] = list.get(i);
        }
        Arrays.stream(result).forEach(System.out::println);
    }
    上面进行写起来代码量很大,如果使用stream来进行处理就是一行代码就能解决!!!
     int [] arrayRes=Arrays.stream(arrayAlpha).filter(ele->ele>30).toArray();
     Arrays.stream(arrayRes).forEach(System.out::print);
  • List ,Set,Stack,Queue,Map,Stream也是会简单很多
        List<Integer>listAlpha=new ArrayList<>(List.of(1,2,6,9,4,109));
        List<Integer>listAlphaResult=listAlpha.stream().filter(ele->ele>5).collect(Collectors.toList());
//        List<Integer> tempResult = new ArrayList<>();
//        for (Integer ele : listAlpha) {
//            if (ele > 5) {
//                tempResult.add(ele);
//            }
//        }
        System.out.println(listAlphaResult);
        Set<String> setAlpha=new HashSet<>(List.of("alpha","beta","gamma","ph"));
        Set<String>setAlphaResult=setAlpha.stream().filter(ele->ele.contains("a")).collect(Collectors.toSet());
//        Set<String>stringSetRes=new HashSet<>();
//        for(String ele:setAlpha){
//            if (ele.contains("ph")){
//                stringSetRes.add(ele);
//            }
//        }
        System.out.println(setAlphaResult);
        Map<String,Integer> mapAlpha=new HashMap<>();
        mapAlpha.put("alpha",1);
        mapAlpha.put("beta",13);
        mapAlpha.put("gamma",19);
//        Map<String,Integer>mapAlphaResult=mapAlpha.stream
        Stream<Map.Entry<String,Integer>> stream=mapAlpha.entrySet().stream();
        Map<String,Integer>streamResult=stream.filter(ele->ele.getValue()>2)
                .collect(Collectors.toMap(ele->ele.getKey(),ele-> ele.getValue()));
//        Map<String,Integer> mapAlphaResult=new HashMap<>();
//        for(Map.Entry<String ,Integer> entry:mapAlpha.entrySet()){
//            if(entry.getValue()>10){
//                mapAlphaResult.put(entry.getKey(),entry.getValue());
//            }
//        }
//        System.out.println(mapAlphaResult);
        System.out.println(streamResult);
        //NOTE queue&stack
        Queue<String>stringQueue=new LinkedList<>();
        stringQueue.add("alpha");
        stringQueue.add("beta");
        stringQueue.add("gamma");
        stringQueue.add("alpha");
        List<String> alpha = stringQueue.stream().filter(ele -> ele.contains("alpha")).collect(Collectors.toList());
        System.out.println(alpha);
        Stack<String> stringStack=new Stack<>();
        stringStack.add("alpha");
        stringStack.add("beta");
        stringStack.add("gamma");
        stringStack.add("alpha");
        List<String> beta = stringStack.stream().filter(ele -> ele.equals("gamma")).collect(Collectors.toList());
        System.out.println(beta);

所以从上面的例子里可以看出来使用stream的简洁,而且代码的可读性非常好,有点像pipline一个阶段一个阶段执行,然后收集结果。

Stream的构成

- 逻辑结构图
在这里插入图片描述stream就是这样的一个结构,构建—>操作—>结果收集。
在这里插入图片描述
-stream的创建
Array,collection(List,Set,Queue,Stack),Map都是支持stream来处理的。
-stream的转换
filter()、map()、distinct()、sorted()、limit()、skip()、flatMap()
-stream的终止
在这里插入图片描述

Steam的创建—开始管道

这个就是前面所讲的,stream的使用范围

Stream的转换—中间管道

getAuthors()初始化Author的List,

  • filter()
    对Author的List获取元素(对象)的Name 的String>3
        List<Author> authorList = getAuthors();
        List<Author> authorRes = authorList.stream()
                .filter(ele -> ele.getName().length() > 3)
                .collect(Collectors.toList());
  • map()
    拿到Author的name,然后处理以后的List,
    重新建立一个Author的List
        List<Author> authorList = getAuthors();
        List<String> result = authorList.stream()
                .map(new Function<Author, String>() {
                    @Override
                    public String apply(Author author) {
                        return "-" + author.getName() + "-";
                    }
                })
                .collect(Collectors.toList());
        List<String> resultAlpha = authorList.stream().map(ele -> "start->" + ele.getName() + "<-end").collect(Collectors.toList());
        System.out.println(resultAlpha);
        List<Integer> resultBeta = authorList.stream()
                .map(ele -> ele.getAge())
                .collect(Collectors.toList());
        List<Author> resultGamma = authorList.stream()
                .map(ele -> new Author(ele.getName(), ele.getId(), ele.getAge() + 111, ele.getScore(), ele.getIntro(), null))
                .collect(Collectors.toList());
        System.out.println(resultGamma);
  • distinct()
    去除重复Name的List
        List<Author> authorList = getAuthors();
//        System.out.println(authorList);
        List<String> distinctAuthorName = authorList.stream()
                .map(author -> author.getName())
                .distinct().collect(Collectors.toList());
  • sorted()
    这里就跟前面一篇文章写的三种排列,1、stream两个object.attribute进行对比
    2、sorted(Comparator.comparing(object->object.attribute属性))3、实现implement Compareable接口的CompareTo
        List<Author> sortedAuthors = authors.stream()
                .sorted((o1, o2) -> o1.getAge() - o2.getAge())
                .collect(Collectors.toList());
        System.out.println(sortedAuthors);
        List<Author> sortedAuthors2 = authors.stream().sorted(Comparator.comparing(author -> author.getAge())).collect(Collectors.toList());
        System.out.println(sortedAuthors2);
        List<Author> authors1 = getAuthors();
        List<Author> authorsRes = authors1.stream().sorted().collect(Collectors.toList());
  • limit()
    选前几
        List<Author> authors = getAuthors();
        List<Author> authorsLimit = authors.stream().sorted().limit(2).collect(Collectors.toList());
        System.out.println(authorsLimit);
  • skip()
    跳过前几
        List<Author> authors = getAuthors();
        /**获取最大年龄的*/
        List<Author> skipResult = authors.stream().sorted().skip(1).collect(Collectors.toList());
        System.out.println(skipResult);
  • flatMap()
    这是一个将stream()后的元素创建新的stream()
    List authorList=…,其中Author的bookList元素也是一个List()
        /**这个就是stream的元素然后形成新的stream*/
        List<Author> fullAuthor = getFullAuthor();
//        System.out.println(fullAuthor);
        List<Book> bookList = fullAuthor.stream().flatMap(author -> author.getBooks().stream()).collect(Collectors.toList());
        System.out.println(bookList);
        List<String> bookCategoryList = bookList.stream()
                .flatMap(book -> Arrays.stream(book.getCategory().split(",")))
                .distinct().collect(Collectors.toList());
        System.out.println(bookCategoryList.size());

Steam的终止—关闭管道

  • forEach
    其实就是一个很简单的遍历
        List<Author> authors = dataInit();
        authors.stream().forEach(author -> System.out.println(author.getName()));
  • count()
    这里进行一部分的统计
        List<Author> authors = dataInit();
        /**这里转换成一个bookList,而后进行计算总共的书籍数目*/
        List<Book> bookList = authors.stream().flatMap(author -> author.getBookList().stream())
                .collect(Collectors.toList());
        long count = authors.stream().flatMap(author -> author.getBookList().stream()).count();
        System.out.println(count);
        /**NOTE 这里统计了一下每个作者下面的书籍数目,注意这两个的区别*/
        List<Integer>bookNum=authors.stream().map(author -> author.getBookList().size()).collect(Collectors.toList());
  • max或min
        /** 获取书籍的最大值域最小值*/
        List<Author> authors = dataInit();
        /** 获取书籍的最大值域最小值*/
        System.out.println(authors);
        List<Book>bookList=authors.stream().flatMap(author -> author.getBookList().stream()).collect(Collectors.toList());
        List<Integer> bookNum=authors.stream().map(author -> author.getBookList().size()).collect(Collectors.toList());
        System.out.println(bookList);
        Optional<Integer> maxValue = authors.stream()
                .flatMap(author -> author.getBookList().stream())
                .map(book -> book.getWordNum())
                .max(new Comparator<Integer>() {
                    @Override
                    public int compare(Integer o1, Integer o2) {
                        return o1 - o2;
                    }
                });
        Optional<Integer> minValue = authors.stream()
                .flatMap(author -> author.getBookList().stream())
                .map(book -> book.getWordNum()).min(((o1, o2) -> o1 - o2));
        System.out.println(maxValue.get());
        System.out.println(minValue.get());

  • collect()
  1. collect(Collectors.toList())
        List<Author> authors = dataInit();
        List<String> nameList = authors.stream().map(author -> author.getName()).collect(Collectors.toList());
        System.out.println(nameList);
        //结果
        output--->[alpha, beta, gamma, gamma, delta]
//这里可以看到,这里的结果是有重复值的,但是author 的List 创建是使用new来创建的,所以直接使用authors.stream().distinct().collect(Collectors.toList())并不会去重,因为这里实用的是equals()方法来进行判断,两个object是不可能相等所以这里使用另外一个办法进行去重,TreeSet(),这里就跟[前面文章](https://blog.csdn.net/muyuchenzi/article/details/128828880?spm=1001.2014.3001.5502)的List去重联系上来了。
        List<Author> authors = dataInit();
        authors.forEach(System.out::println);
        Set<Author> authorsName = new TreeSet<>((Comparator.comparing(Author::getName)));
//        authors.forEach(author -> authorsName.add(author.getName()));
        authorsName.addAll(authors);
        System.out.println("treeSet:"+authorsName);
        authorsName.forEach(System.out::println);
  • toSet()
    这里获取一个author的Name的Set()还有就是通过flatMap来获取BookList的Set。
    public static void toSetFunc(){
        List<Author> authors = dataInit();
        Set<String> authorListNameSet = authors.stream().map(author -> author.getName()).collect(Collectors.toSet());
        System.out.println(authorListNameSet);
        Set<Book> bookListSet = authors.stream()
                .flatMap(author -> author.getBookList().stream())
                .collect(Collectors.toSet());
        bookListSet.forEach(System.out::println);
    }
  • toMap()
    这里要用到前面的一个对Name的去重办法,因为Map的key是不能重复的,author的List有两个相同的值alpha,所以需要去重,不然报错
 public static void collectToMapFunc(){
 //这里首先用的是一个key=name,value=score来组成的Map
        List<Author> authors = dataInit();
        TreeSet<Author> authorTreeSet = new TreeSet<>(Comparator.comparing(Author::getName));
        authorTreeSet.addAll(authors);

        System.out.println(authorTreeSet.size());
        authorTreeSet.forEach(System.out::println);
        Map<String, Integer> collectMap = authorTreeSet.stream()
                .collect(Collectors.toMap(author -> author.getName(), author -> author.getScore()));
        System.out.println(collectMap);
        //这里还有一个需求就是name与author的booklist来组成
        Map<String, List<Book>> bookListMap = authorTreeSet.stream().collect(Collectors.toMap(new Function<Author, String>() {
            @Override
            public String apply(Author author) {
                return author.getName();
            }
        }, new Function<Author, List<Book>>() {
            @Override
            public List<Book> apply(Author author) {
                return author.getBookList();
            }
        }));
        for(String key:bookListMap.keySet()){
            System.out.println(key+": "+bookListMap.get(key));
        }
    }
  • anyMathc、allMatch、noneMatch
        List<Author> authors = dataInit();
        boolean nameHasBeta = authors.stream().anyMatch(author -> author.getName().equals("beta"));
        boolean biggerThan70 = authors.stream().allMatch(author -> author.getScore() > 70);
        boolean noneBiggerThan100 = authors.stream().noneMatch(author -> author.getScore() > 100);
        System.out.println(biggerThan70);
        System.out.println(nameHasBeta);
        System.out.println(noneBiggerThan100);
  • findAny
    这里是用到了一个optional,这个意思就是一个选项,如果存在的话—>ifPresent(new Consumer)进行

    public static void findAny(){
        List<Author> authors = dataInit();
        Optional<Author> optionalAuthor = authors.stream()
                .filter(author -> author.getScore()>70).findAny();
        optionalAuthor.ifPresent(new Consumer<Author>() {
            @Override
            public void accept(Author author) {
                System.out.println(author.getName());
            }
        });
    }
  • findFirst()
    找最小的,或者最大的,其实还有一个办法就是使用前面的max,或者min,然后filter就可以了。
        List<Author> authors = dataInit();
        List<Author> sortedAuthor2 = authors.stream().sorted(Comparator.comparing(author -> author.getScore())).collect(Collectors.toList());
        List<Author> sortedAuthor = authors.stream().sorted(Comparator.comparingInt(Author::getScore)).collect(Collectors.toList());
        Optional<Author> first = sortedAuthor.stream().findFirst();
        System.out.println(first);
        first.ifPresent(author -> System.out.println(author.getName()));
  • reduce
    reduce一般跟map相结合来进行计算:这里计算所有作者score的总和
    private static void reduceAlpha() {
        int[] arr = {1, 2, 34, 5, 9};
        int reduce = Arrays.stream(arr).reduce(0, ((left, right) -> left + right));
        System.out.println(reduce);
//        OptionalInt reduceResult = Arrays.stream(arr).reduce(Integer::sum);
//        System.out.println(reduceResult.getAsInt());
    }
    collect进行操作。
    private static void reduceAuthorScoreSum() {
        List<Author> authors = dataInit();
        Integer reduceResult = authors.stream().map(author -> author.getScore())
                .reduce(0, (left, right) -> left + right);
        System.out.println(reduceResult);
    }
        /**求最大值*/
        Integer result = authors.stream()
                .map(author -> author.getScore())
                .reduce(Integer.MIN_VALUE, (left, right) -> left > right ? left : right);
        System.out.println(result);
                /**求最大值*/
        Integer result2 = authors.stream()
                .map(author -> author.getScore())
                .reduce(Integer.MAX_VALUE, (left, right) -> left < right ? left : right);
        System.out.println(result2);
  • groupingBy()
    collect()也可以对结果进行分组
因为authorList里有相同的名字,所以这里通过名字或者id的长度进行分组
    public static void groupBy() {
        List<Author> authors = dataInit();
        authors.forEach(System.out::println);
        Map<Integer, List<String>> groupByScore = authors.stream().map(author -> author.getId()).collect(Collectors.groupingBy(new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                return s.length();
            }
        }));
        Map<Integer, List<String>> groupByName = authors.stream().map(author -> author.getName())
                .collect(Collectors.groupingBy(s -> s.length()));
        System.out.println(groupByName);
        System.out.println(groupByScore);
    }
  • counting
    counting 与maxBy
   private static void countFunc() {
        List<Author> authors = dataInit();
        Long tempVal = authors.stream().flatMap(author -> author.getBookList().stream()).collect(Collectors.counting());
        Long tempVal2 = authors.stream().collect(Collectors.counting());
        Optional<Author> maxBy = authors.stream().collect(Collectors.maxBy(Comparator.comparing(author -> author.getScore())));
        System.out.println(tempVal);
        System.out.println(tempVal2);
        System.out.println(maxBy);
    }

Stream调试

idea是支持stream按步骤查看的。
在这里插入图片描述

案例数据

  • Author的类
package StreamEnd;

import java.util.List;

/**
 * @author: l30043039
 * @date: 2023/2/12/10:57
 * @project: LambdaFunc
 */
public class Author {
    private String name;
    private String id;
    private Integer score;
    private List<Book> bookList;

    public Author(String name,String id,Integer score,List<Book>bookList){
        this.name=name;
        this.id=id;
        this.score=score;
        this.bookList=bookList;
    }
    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public void setScore(Integer score) {
        this.score = score;
    }

    public Integer getScore() {
        return score;
    }

    public void setBookList(List<Book> bookList) {
        this.bookList = bookList;
    }

    public List<Book> getBookList() {
        return bookList;
    }

    @Override
    public String toString() {
        String string = "Authors {" +
                "name = " + this.name +
                " id = " + this.id +
                " score = " + this.score +
                " bookList = " + this.bookList +
                "}";
        return string;
    }
}
  • Book类
package StreamEnd;

/**
 * @author: l30043039
 * @date: 2023/2/12/10:58
 * @project: LambdaFunc
 */
public class Book {
    private String name;
    private String intro;
    private String category;
    private int wordNum;
    public Book(String name,String intro,String category,int wordNum){
        this.name=name;
        this.intro=intro;
        this.category=category;
        this.wordNum=wordNum;
    }
    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getCategory() {
        return category;
    }

    public void setIntro(String intro) {
        this.intro = intro;
    }

    public String getIntro() {
        return intro;
    }

    public void setWordNum(int wordNum) {
        this.wordNum = wordNum;
    }

    public int getWordNum() {
        return wordNum;
    }

    @Override
    public String toString() {
        String string = "book[" +
                "name = " + this.name +
                " intro = " + this.intro +
                " category = " + this.category +
                " wordNum = " + this.wordNum +
                "]";
        return string;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值