Java 流式编程简单使用

Java 流式编程简单使用

  1. 概念

Java的Stream流是在Java 8中引入的一种用于处理集合数据的功能强劲且易于使用的工具,旨在简化集合框架的操作。它的设计目的是为了提供一种更简洁、更灵活和更可读的方式来处理集合数据。之前都是用时迭代器或者循环来遍历,通过使用Stream API,我们可以以流水线方式处理数据,并进行各种转换和聚合操作。

在Java中,Stream流分为两种类型:

流(Stream):表明顺序流,按照数据源的顺序进行操作,适用于串行操作。

并行流(ParallelStream):表明并行流,可以同时对数据源的多个元素进行操作,适用于并行计算。

  1. 优势和缺点

优势

简洁:使用流的聚合操作可以极大地减少代码量;

高效:流的并行操作可以利用多核处理器提高运行效率;

函数式编程:流的操作方法遵循函数式编程的思想,使代码更加简洁、易读和可维护;

可复用:可以使用复合操作将多个流操作链在一起。

缺点

可读性降低:对于复杂的操作,使用Stream可能比传统的循环方式可读性稍差;

一次性使用:一旦流被使用过,就不能再次使用,需要重新创建一个新的流;

可能会影响性能:虽然并行流可以提高运行效率,但在某些情况下,额外的分组和合并操作可能会造成性能下降。

  1. 常用API详解

Intermediate操作:如filter()、map()、sorted(),用于对元素进行筛选、映射、排序等操作。

Terminal操作:如forEach()、count()、collect(),用于对流进行最终的输出、统计和收集操作。

Short-circuiting操作:如findFirst()、anyMatch()、allMatch(),用于在满足条件时立即终止流的操作。


    @Test
    void contextLoads() {
        Predicate<Integer> predicate = x -> x > 185;
        // TbItem student = new TbItem(1L, 100, new BigDecimal(16.3D), new BigDecimal(3.6D), new BigDecimal(4.0D));
        TbInfo student = new TbInfo(1, "张三", 19, 167);
        System.out.println(
                "9龙的身高高于185吗?:" + predicate.test(student.getStature()));

        Consumer<String> consumer = System.out::println;
        consumer.accept("命运由我不由天");

        Function<TbInfo, String> function = TbInfo::getName;
        String name = function.apply(student);
        System.out.println(name);

        Supplier<Integer> supplier =
                () -> Integer.valueOf(BigDecimal.TEN.toString());
        System.out.println(supplier.get());

        UnaryOperator<Boolean> unaryOperator = uglily -> !uglily;
        Boolean apply2 = unaryOperator.apply(true);
        System.out.println(apply2);

        BinaryOperator<Integer> operator = (x, y) -> x * y;
        Integer integer = operator.apply(2, 3);
        System.out.println(integer);

        test(() -> "我是一个演示的函数式接口");
    }

    /**
     * 将流转换为list。还有toSet(),toMap()等。及早求值。
     */
    @Test
    void testMain() {
        List<TbInfo> studentList = Stream.of(new TbInfo(1, "路飞", 22, 175),
                new TbInfo(2, "红发", 40, 180),
                new TbInfo(3, "白胡子", 50, 185)).collect(Collectors.toList());
        System.out.println(studentList);
    }

    /**
     * filter 过滤筛选
     * 筛选出身高小于140
     */
    @Test
    void testMain1() {
        List<TbInfo> list = new ArrayList<>();
        list.add(new TbInfo(1, "ddd", 19, 167));
        list.add(new TbInfo(1, "aa", 89, 145));
        list.add(new TbInfo(1, "vvv", 45, 165));
        list.add(new TbInfo(1, "4ere", 44, 138));
        List<TbInfo> collect = list.stream().filter(item -> item.getStature() < 140)
                .collect(Collectors.toList());
        System.out.println(collect);
    }

    /**
     * map
     * 将list对象集合转换为list字符串集合
     */
    @Test
    void testMain2() {
        List<TbInfo> list = getList();

        List<String> collect = list.stream().map(item -> item.getName())
                .collect(Collectors.toList());

        System.out.println(collect);
    }

    private List<TbInfo> getList() {
        List<TbInfo> list = new ArrayList<>();
        list.add(new TbInfo(1, RandomUtil.randomString(3), RandomUtil.randomInt(100), RandomUtil.randomInt(200)));
        list.add(new TbInfo(1, RandomUtil.randomString(3), RandomUtil.randomInt(100), RandomUtil.randomInt(200)));
        list.add(new TbInfo(1, RandomUtil.randomString(3), RandomUtil.randomInt(100), RandomUtil.randomInt(200)));
        list.add(new TbInfo(1, RandomUtil.randomString(3), RandomUtil.randomInt(100), RandomUtil.randomInt(200)));
        return list;
    }

    /**
     * flatMap
     * 将多个流合并为一个流
     */
    @Test
    void testMain3() {
        List<TbInfo> list = getList();

        List<TbInfo> list2 = getList();

        List<TbInfo> collect = Stream.of(list, list2)
                .flatMap(item -> item.stream()).collect(Collectors.toList());
        System.out.println(collect.size());
        System.out.println(collect);

    }

    /**
     * max,min
     * 集合中求最大或最小值
     */
    @Test
    void testMain4() {
        List<TbInfo> list = getList();
        Optional<TbInfo> max = list.stream().max(Comparator.comparing(item -> item.getAge()));

        Optional<TbInfo> min = list.stream().min(Comparator.comparing(item -> item.getAge()));

        //判断是否有值
        if (max.isPresent()) {
            System.out.println(max.get());
        }
        if (min.isPresent()) {
            System.out.println(min.get());
        }
    }

    /**
     * 演示自定义函数式接口使用
     *
     * @param worker
     */
    public static void test(Worker worker) {
        String work = worker.work();
        System.out.println(work);
    }

    public interface Worker {
        String work();
    }


    /**
     * count
     * 统计年龄
     */
    @Test
    void testMain5() {
        List<TbInfo> list = getList();
        for (int i = 0; i < 10; i++) {
            list.addAll(getList());
        }

        long count = list.stream().filter(item -> item.getAge() < 45).count();
        System.out.println("年龄小于45岁的人数是:" + count);
    }

    /**
     * reduce
     * reduce 操作可以实现从一组值中生成一个值
     */
    @Test
    void testMain6() {
        Integer ddd = Stream.of(1, 2, 3).reduce(0, (acc, x) -> acc + x);

        System.out.println(ddd);
    }

    /*-------------------------------------------优美的分割线-----------------------------------------------------------*/
    /*收集器,一种通用的、从流生成复杂值的结构。只要将它传给 collect 方法,
    所有 的流就都可以使用它了。标准类库已经提供了一些有用的收集器*/
    List<TbInfo> getDefaultList() {
        List<TbInfo> list = new ArrayList<>();
        list.add(new TbInfo(1, "张三", 16, 168));
        list.add(new TbInfo(2, "李四", 19, 134));
        list.add(new TbInfo(3, "王五", 45, 175));
        list.add(new TbInfo(4, "李白", 20, 164));
        list.add(new TbInfo(5, "李三思", 16, 192));
        list.add(new TbInfo(6, "王五2", 34, 137));
        return list;
    }

    /**
     * 转换成块
     * 将人员分为大于等于18的两类
     * <code>
     * {
     * false=[
     * TbInfo(id=2, name=李四, age=19, stature=134),
     * TbInfo(id=3, name=王五, age=45, stature=175),
     * TbInfo(id=4, name=李白, age=20, stature=164),
     * TbInfo(id=6, name=王五2, age=34, stature=137)
     * ],
     * true=[
     * TbInfo(id=1, name=张三, age=16, stature=168),
     * TbInfo(id=5, name=李三思, age=16, stature=192)
     * ]
     * }
     * </code>
     */

    @Test
    void testMain7() {
        List<TbInfo> list = new ArrayList(getDefaultList());
        Map<Boolean, List<TbInfo>> collect = list.stream().collect(Collectors.partitioningBy(item -> 18 >= item.getAge()));
        System.out.println(collect);
    }

    /**
     * 数据分组
     * 按照年龄分组
     * <p>
     * {16=[TbInfo(id=1, name=张三, age=16, stature=168),
     * TbInfo(id=5, name=李三思, age=16, stature=192)],
     * 34=[TbInfo(id=6, name=王五2, age=34, stature=137)],
     * 19=[TbInfo(id=2, name=李四, age=19, stature=134)],
     * 20=[TbInfo(id=4, name=李白, age=20, stature=164)],
     * 45=[TbInfo(id=3, name=王五, age=45, stature=175)]}
     * </p>
     */
    @Test
    void testMain8() {
        List<TbInfo> list = new ArrayList(getDefaultList());
        Map<Integer, List<TbInfo>> collect = list.stream().collect(Collectors.groupingBy(item -> item.getAge()));
        System.out.println(collect);
    }

    /**
     *字符串拼接
     * <p>
     *     [张三,李四,王五,李白,李三思,王五2]
     * </p>
     */
    @Test
    void testMain9() {
        List<TbInfo> list = new ArrayList(getDefaultList());
        //joining接收三个参数,第一个是分界符,第二个是前缀符,第三个是结束符。
        String collect = list.stream().map(TbInfo::getName).collect(Collectors.joining(",", "[", "]"));
        System.out.println(collect);
    }
© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
趣评测五花肉的头像 - 宋马
评论 抢沙发

请登录后发表评论

    暂无评论内容