Stream流的使用

1.当接口中的方法只有一个参数时,可以省略类型与小括号
2.如果只有一个return,直接省略;
3.只有一句话省略分号和括号

1.Stream流->对集合进行操作
2.将数据按照流的形式进行链式的操作——>方便对集合和数组操作
3.对参数alter enter可以重新匿名内部类
4.流中的每一个方法的调用类似于工厂的一个组件,每个组件的完成需要终结方法的调用
终结方法:eg:foreach()

1.双列集合类似Map这种需要先转为单列结合entrySet,再转为Stream流
2.map:将元素转为map形式,并且能够对元素进行计算重写
3.disnect去重本质用的equals方法进行元素判断重写

1.sorted会将元素类型转为comparable
文档:
返回由该流的元素组成的流,按自然顺序排序。如果该流的元素不是
{@code Comparable},则在执行终端操作时可能会抛出 {@code java.lang.ClassCastException}。
<p>对于有序流,排序是稳定的。对于无序流,不保证稳定性。
<p>这是一个<a href="package-summary.htmlStreamOps">有状态的中间操作<a>。 @return 新的流

2.解决:
implements Comparable<Author>

3.例子:
    @Override
    public int compareTo(Author o) {
   //传入的-本地的,降序
        return o.getAge()-this.getAge();
    }
   我们还可以sorted中时间Comparator接口进行重写compare方法

1.skip(n):将流中前n个元素去除

1.flatMap:可以将元素套娃,将流中的元素类型进行改变 xxx->xxx.xx.stream()
场景:比如得到作者中的书籍,得到书籍中的所属类型

2.count:求流中的元素个数

1.max():获取流元素中的最大值
  min():获取流元素最小值,具体可以实现comparator接口

2.collect():将信息变为指定类型
实现Collections.ToMap(xx,xx):里面两个参数对应的map的key与value

1.anyMatch():与filter()意思相近,但是它是可以返回值的,filter只是起到一个过滤的逻辑

allMatch():判断流中所有元素是否满足要求

1.findAnyWay():获取流元素,返回Optional,可以对里面流元素进行操作
 比如:ifPresent()->根据判断执行逻辑...

2.findFirst():查找流中第一个元素

1.reduce():将stream流中的元素给组合起来,根据我们传入的初始值,按照我们自己的计算方式以此拿取流中的数据进行运算;
max和min的源代码就是基于reduce方法实现的

注意:
1.流是惰性的,终结操作后就没了(比如:foreach)——>可以根据目前状况重新创建一个流

1.Optional:可以帮助避免空指针异常
实际开发也可以用这个,在数据dao中返回Optional

2.如果确定返回一定不是null,也可以用Optional.of()

3.Optional.ofNullable():万能,是不是null都能封装
例子:
类似于->return author==null?Optional.empty():Optional.of(author);

4.OrElseThrow():如果有数据就返回数据,如果没数据就抛出异常
5.OrElseGet():判读是否为空,为空返回一个新的
 例子:Optional<Author> author1 = author.orElseGet(() -> Optional.of(new Author()));


注意:Optional后续操作返回的对象都是一个新的Optional
比如:  Optional<Author> optional = getAuthorOptional();
           optional.filter(author -> author.getAge()>18)
                   //前面对流中元素进行过滤,后面进行判断看输出否
                   .ifPresent(author -> System.out.println("名字是:"+author.getName()));

6.Optional后续判断如果为null,那么后续操作就不会执行

7.Optional中的消息的安全消费可以使用ifPresent()

函数式接口
1.只有一个抽象方法的就是函数式接口@FunctionalInterface(只有一个方法)
这些就可以用lambda简化

2.Consumer:消费接口

3.Function:计算转换接口,我们可以吧传入的参数进行转换(比如转为list,map...)
例子:
 authorList.stream()
  //将元素转为map形式,值为String类型
   .map(new Function<Author, String>() {
             @Override
              public String apply(Author author) {
               return author.getName();
          }
  })

4.predicate 判断接口,一般用于过滤流中元素
我们可以在后面接and、or、negate进行多重判断,或判断,非判断
例子:authorList.stream()
               .filter(((Predicate<Author>) author -> author.getName().length() > 9).or(author -> author.getAge()>19)).forEach(author -> System.out.println("被消费的作者名字为:"+author.getName()));


1.方法引用基本格式
  authorList.stream()
                .map(Author::getAge)
                .map(age->age+10)
                .forEach(age-> System.out.println("年龄为:"+age));

1.并行流:
其实就是把任务分配给多个线程执行
可以和线程池一起使用,但是结合代码我发现他可能自己是实现了一个线程池,所以结果出现了多个池的线程共享一个数据的情况
package com.wuyuhang.stream;

import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author diao 2022/6/21
 */
@Slf4j(topic = "c.StreamDemoTest")
public class StreamDemoTest {

    public static void main(String[] args) {
        List<Author> authorList = getAuthors();

        test01(authorList);

        testArrToStream();

        testMapToStream();

        testAuthor(authorList);

        //元素转为map形式,对元素进行操作
        valueToMapPrint(authorList);

        //去重内部用的equals
        JudgeToDisnect(authorList);

        //排序无重复
        sortAndDisnect(authorList);

        //对流元素进行降序,无重复,打印年龄最大
        limitAndDPrint(authorList);

        //除去最大的其他元素:skip
        skipMax(authorList);

        //对书籍元素进行去重打印(每个作者的书籍)
        authorBooks(authorList);

        //打印所有作者的所有书籍(Book)flatMap
        flatMapToBooks(authorList);

        //打印所有书籍,flatMap优化版本
        flatMapGBooks(authorList);

        //得到书籍的所有类型进行去重打印
        getCatagoryForStream(authorList);

        testBooks(authorList);

        //计算当前流中元素个数,删除重复元素
        countStream(authorList);

        /**
         * 得到书籍的评分,需要将得到书籍评分的流元素(flatMap)
         * 我们也可以得到书的流,然后得到书的评分,最后利用Comparator接口实现比较排序即可
         */
        bookMaxStore(authorList);

        //获取放入作者名字的List集合
        AuthorNameToList(authorList);

        /**
         * 将作者信息转为map形式,键为名字,值为书籍
         * 将Author->键设置为它的名字
         */
//        authorToMap(authorList);

        /**
         * 判断是否有大盂29的作家
         */
        anyMatch(authorList);

        /**
         * 全局判断
         */
        allMatchToAuther(authorList);

        /**
         * 判断作家是不是都没有超过100岁
         */
        nonmatchToAge(authorList);

        /**
         * findAny():对流中元素进行获取->返回Optional
         * 根据Optional的api进行后续的消费操作
         */
        findAny(authorList);

        /**
         * 排序并且打印排序的第一个数据
         * (Optional)然后判断进行打印
         */
        sortAndFirst(authorList);

        /**
         *reduce的使用
         * 求所有作者的年龄的和
         * 注意:需要对流中元素进行改变,因为目前是author,我们需要改为年龄
         * 改完后reduce就可以实现Integer累加操作了
         */
        reduceGetSum(authorList);

        /**
         * reduce求得作者年龄的最大值
         */
        reduceGetMax(authorList);

        /**
         * 拿第一个元素作为初始值,将后面的元素进行运算
         */
        reduceOneImport(authorList);

        /**
         * 测试是否会影响原数据
         */
        zhongJie(authorList);

        authorList.stream()
                .map(Author::getAge)
                .map(age -> age + 10)
                .forEach(age -> System.out.println("年龄为:" + age));

        /**
         * 双重测试
         */
        twoFilter(authorList);

        /**
         * 或者测试
         */
        orTest(authorList);

        /**
         * 并行流
         */
        threadPool.submit(new Runnable() {
            @Override
            public void run() {
                Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9);
                //将流转为并行流
                Optional<Integer> reduce = stream.parallel()
                        .peek(num -> {
                            //Consumer消费打印当前线程名字
                            System.out.println(num + Thread.currentThread().getName());
                        })
                        .filter(integer -> integer > 5)
                        .reduce((result, element) -> result + element);
                System.out.println("最后总结果为:" + reduce);
            }
        });

        System.out.println("================");

        Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9);
        //将流转为并行流
        Optional<Integer> reduce = stream.parallel()
                .peek(num -> {
                    //Consumer消费打印当前线程名字
                    System.out.println(num + Thread.currentThread().getName());
                })
                .filter(integer -> integer > 5)
                .reduce((result, element) -> result + element);
        System.out.println("最后总结果为:" + reduce);

    }

    private static void orTest(List<Author> authorList) {
        authorList.stream()
                .filter(((Predicate<Author>) author -> author.getName().length() > 9).or(author -> author.getAge() > 19)).forEach(author -> System.out.println("被消费的作者名字为:" + author.getName()));
    }

    private static void twoFilter(List<Author> authorList) {
        authorList.stream()
                .filter(new Predicate<Author>() {
                    @Override
                    public boolean test(Author author) {
                        return author.getAge() > 17;
                    }
                    //双重判断
                }.and(new Predicate<Author>() {

                    @Override
                    public boolean test(Author author) {
                        return author.getName().length() > 1;
                    }
                })).forEach(author -> System.out.println(author.getAge() + "名字:" + author.getName()));
    }

    private static void zhongJie(List<Author> authorList) {
        authorList.stream()
                .map(author -> author.getAge())
                .map(ag -> ag + 10)
                .forEach(ag -> System.out.println(ag));
    }

    private static void reduceOneImport(List<Author> authorList) {
        authorList.stream()
                .map(author -> author.getAge())
                //第一个初始值为流中的一个元素,也就是默认的result
                .reduce((result, element) -> {
                    //取最小值
                    return result > element ? element : result;
                })
                .ifPresent(age -> System.out.println("最小年龄存在,为:" + age));
    }

    private static void reduceGetMax(List<Author> authorList) {
        authorList.stream()
                .map(author -> author.getAge())
                .distinct()
                .reduce(Integer.MIN_VALUE, new BinaryOperator<Integer>() {
                    @Override
                    public Integer apply(Integer result, Integer element) {
                        //用三元运算符求得元素中的最大值
                        return result < element ? result : result;
                    }
                });
    }

    private static void reduceGetSum(List<Author> authorList) {
        Integer sum = authorList.stream()
                //将stream流元素变为年龄
                .map(author -> author.getAge())
                .distinct()
                //element为流中的元素
                .reduce(0, new BinaryOperator<Integer>() {
                    @Override
                    public Integer apply(Integer result, Integer element) {
                        return result + element;
                    }
                });
        System.out.println("年龄之和为:" + sum);
    }

    private static void sortAndFirst(List<Author> authorList) {
        Optional<Author> first = authorList.stream()
                //进行排序
                .sorted((o1, o2) -> o1.getAge() - o2.getAge())
                //取到排序中的第一个数据
                .findFirst();

        //对Optional数据进行判断
        first.ifPresent(author -> System.out.println("输出第一个作者:" + author.getName()));
    }

    private static void findAny(List<Author> authorList) {
        Optional<Author> optionalAuthor = authorList.stream()
                //filter过滤判断一些元素(>18的就保存在流中)
                .filter(author -> author.getAge() > 18)
                .findAny();

        //进行判断(Optional调用这个api)
        //如果存在这个数据就会执行这个消费的操作
        optionalAuthor.ifPresent(author -> System.out.println(author.getName()));
    }

    private static void nonmatchToAge(List<Author> authorList) {
        boolean match = authorList.stream()
                .noneMatch(author -> author.getAge() > 100);
        System.out.println("是否满足:" + match);
    }

    private static void allMatchToAuther(List<Author> authorList) {
        boolean flag = authorList.stream()
                //对流中元素,对元素年龄进行判断
                .allMatch(author -> author.getAge() >= 18);
        System.out.println(flag);
    }

    private static void anyMatch(List<Author> authorList) {
        boolean match = authorList.stream()
                //filter不是终结操作,没有返回值
                .anyMatch(author -> author.getAge() > 29);
        System.out.println("是否满足:" + match);

        boolean match1 = authorList.stream()
                .anyMatch(author -> author.getAge() > 36);
        System.out.println(match1);
    }

//    private static void authorToMap(List<Author> authorList) {
//        authorList.stream()
//                .collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()));
//    }

    private static void AuthorNameToList(List<Author> authorList) {
        List<String> collect = authorList.stream()
                //将author的名字放入map集合中做元素
                .map(author -> author.getName())
                //转为list集合
                .collect(Collectors.toList());
        System.out.println("collect集合中元素为:" + collect);
    }

    private static void bookMaxStore(List<Author> authorList) {
        Optional<Integer> max = authorList.stream()
                //得到书流元素
                .flatMap(author -> author.getBooks().stream())

                //map中为流元素(book)的评分
                .map(book -> {
                    return book.getScore();//得到book的评分
                })

                //再做一个比较器,将评分比较
                .max((o1, o2) -> o1 - o2);
        System.out.println("得到最大的评分:" + max);
    }

    private static void countStream(List<Author> authorList) {
        long count = authorList.stream()
                //将作者的书籍平展开来作为流元素,然后去重书籍
                .flatMap(author -> author.getBooks().stream())
                .distinct()
                .count();
        System.out.println("书籍数量是:" + count);
    }

    private static void testBooks(List<Author> authorList) {
        authorList.stream()
                .map(author -> author.getBooks())
                .distinct()
                .forEach(books -> System.out.println("作者的书籍为:" + books));
    }

    private static void getCatagoryForStream(List<Author> authorList) {
        authorList.stream()
                .flatMap(author -> author.getBooks().stream())
                .distinct()
                //此时流元素中是book,我们得到book中而书籍类型拿出来(也就是一个数组),然后将书籍类型种族安慰流元素
                .flatMap(book -> Arrays.stream(book.getCategory().split(",")))
                .distinct()
                .forEach(s -> System.out.println("类型为:" + s));
    }

    private static void flatMapGBooks(List<Author> authorList) {
        authorList.stream()
                //将流元素进行平展
                .flatMap(author -> author.getBooks().stream())
                .distinct()
                .forEach(book -> System.out.println("优化后书籍为:" + book));
    }

    private static void authorBooks(List<Author> authorList) {
        authorList.stream()
                //得到每个作者的所有书籍,所以map中的每个元素都是书籍
                .map(new Function<Author, List<Book>>() {
                    @Override
                    public List<Book> apply(Author author) {
                        return author.getBooks();
                    }
                })
                .distinct()
                .forEach(books -> System.out.println("作者书籍为:" + books));
    }

    private static void flatMapToBooks(List<Author> authorList) {
        authorList.stream()
                //flatmap:对多个流进行合并处理
                .flatMap((Function<Author, Stream<Book>>) author -> {
                    //书全被合在一起
                    return author.getBooks().stream();
                })
                .distinct()
                .forEach(book -> System.out.println("书籍为:" + book));
    }

    private static void skipMax(List<Author> authorList) {
        authorList.stream()
                .distinct()
                .sorted((o1, o2) -> o2.getAge() - o1.getAge())
                .skip(1)
                .forEach(author -> System.out.println(author));
    }

    private static void limitAndDPrint(List<Author> authorList) {
        authorList.stream()
                .distinct()
                //降序年龄排序
                .sorted((o1, o2) -> o1.getAge() - o2.getAge())
                //两个最大元素
                .limit(2)
                .forEach(author -> System.out.println("最大的元素为:" + author));
    }

    private static void sortAndDisnect(List<Author> authorList) {
        authorList.stream()
                .distinct()
                //o1是传入项
                .sorted((o1, o2) -> o1.getAge() - o2.getAge())
                .forEach(author -> System.out.println("排序后的作者:" + author));
    }

    private static void JudgeToDisnect(List<Author> authorList) {
        authorList.stream()
                //里面每个元素都会进行判断
                .distinct()
                .forEach(author -> System.out.println(author));
    }

    private static void valueToMapPrint(List<Author> authorList) {
        authorList.stream()
                //将元素转为map形式,值为String类型
                .map(new Function<Author, String>() {
                    @Override
                    public String apply(Author author) {
                        return author.getName();
                    }
                })
                //map中元素进行遍历
                .forEach(s -> System.out.println("转化后值为:" + s));

        authorList.stream()
                .map(new Function<Author, Integer>() {
                    @Override
                    public Integer apply(Author author) {
                        return author.getAge();
                    }
                })
                .forEach(s -> {
                    System.out.println("转化后值为:" + s);
                });

        //对元素进行重新计算
        authorList.stream()
                .map(author -> author.getAge() + 10)
                .forEach(integer -> System.out.println(integer));
    }

    private static void testAuthor(List<Author> authorList) {
        //中间操作
        authorList.stream()
                .filter(author -> author.getName().length() > 1)
                .forEach(author -> System.out.println(author.getName()));
    }

    private static void testMapToStream() {
        //map集合
        HashMap<String, Integer> map = new HashMap<>();
        map.put("蜡笔小新", 19);
        map.put("Fairy同学", 17);
        map.put("Stream流", 16);
//        先转为entrySet,目的是单列集合(键值对算一个,一个一个来)
        Set<Map.Entry<String, Integer>> entrySet = map.entrySet();

        //将entrySet转为Stream流
        Stream<Map.Entry<String, Integer>> stream = entrySet.stream();

        stream.filter(new Predicate<Map.Entry<String, Integer>>() {
                    @Override
                    public boolean test(Map.Entry<String, Integer> entry) {
                        return entry.getValue() > 16;
                    }
                })
                .forEach(entry -> System.out.println(entry.getKey() + "===" + entry.getValue()));
    }

    private static void testArrToStream() {
        /**
         * 数组转为Stream流
         */
        Integer[] arr = {1, 2, 3, 5, 6};
        Stream<Integer> stream = Arrays.stream(arr);
        stream.distinct()
                .filter(integer -> integer > 3)
                .forEach(integer -> System.out.println(integer));
    }

    private static void test01(List<Author> authorList) {
        /**
         * 把集合转换为流
         * 流进行操作,lambda进行简化
         */
        //打印每一个作者名字
        authorList.stream()
                .distinct()
                .filter(author -> {//把每一个作者传入进行过滤判断
                    return author.getAge() < 18;
                })
                .forEach(author -> System.out.println(author.getName()));
    }


    private static List<Author> getAuthors() {
        //作者数据初始化
        Author author = new Author(1L, "蒙多", 33, "一个从菜刀中明悟哲理的祖安人", null);
        Author author2 = new Author(2L, "亚拉索", 15, "狂风也追逐不上他的思考速度", null);
        Author author3 = new Author(3L, "易", 14, "是这个世界在限制他的思维", null);
        Author author4 = new Author(3L, "易", 14, "是这个世界在限制他的思维", null);

        //书籍列表集合
        List<Book> books1 = new ArrayList<>();
        List<Book> books2 = new ArrayList<>();
        List<Book> books3 = new ArrayList<>();

        //将书给到对应而集合中
        books1.add(new Book(1L, "刀的两侧是光明与黑暗", "哲学,爱情", 88, "用一把刀划分了爱恨"));
        books1.add(new Book(2L, "一个人不能死在同一把刀下", "个人成长,爱情", 99, "讲述如何从失败中明悟真理"));

        books2.add(new Book(3L, "那风吹不到的地方", "哲学", 85, "带你用思维去领略世界的尽头"));
        books2.add(new Book(3L, "那风吹不到的地方", "哲学", 85, "带你用思维去领略世界的尽头"));
        books2.add(new Book(4L, "吹或不吹", "爱情,个人传记", 56, "一个哲学家的恋爱观注定很难把他所在的时代理解"));

        books3.add(new Book(5L, "你的剑就是我的剑", "爱情", 56, "无法想象一个武者能对他的伴侣这么的宽容"));
        books3.add(new Book(6L, "风与剑", "个人传记", 100, "两个哲学家灵魂和肉体的碰撞会激起怎么样的火花呢?"));
        books3.add(new Book(6L, "风与剑", "个人传记", 100, "两个哲学家灵魂和肉体的碰撞会激起怎么样的火花呢?"));

        //给作者分配书籍集合
        author.setBooks(books1);
        author2.setBooks(books2);
        author3.setBooks(books3);
        author4.setBooks(books3);

        //将所有作者作为一个集合
        List<Author> authorList = new ArrayList<>(Arrays.asList(author, author2, author3, author4));
        return authorList;
    }

    //自定义线程池
    public static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 50, 300, TimeUnit.SECONDS,
            new ArrayBlockingQueue<Runnable>(50),
            new ThreadFactory() {
                @Override
                public Thread newThread(Runnable r) {
                    return new Thread(r, "schema_task_pool_" + r.hashCode());
                }
            }, new ThreadPoolExecutor.DiscardOldestPolicy());

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fairy要carry

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值