Stream入门(1)

写在前面

学习Stream,首先需要了解lambda表达式

概况

Stream API是对集合对象功能的增强,它是多线程的,能够更加快速的完成对集合的排序、过滤、limit、统计等各种操作。

提要

stream的链式方法中,包括建造者类型的方法和terminal operation方法,
如下方的sorted()、filter()等,这些方法执行后依然返回到一个stream,
但如forEach或者是collect(toList());等,则返回void类型,且一个Stream只能执行一次该方法,否则会抛出异常,如以下代码

        Stream<Dish> dishStream = Stream.of(new Dish("prawns", false, 300, Dish.Type.FISH),
                new Dish("salmon", false, 450, Dish.Type.FISH));
        dishStream.forEach(System.out::println);
        dishStream.forEach(System.out::println);

这段代码对stream进行了两次 terminal operation 方法的输出,只完成了一次 ,第二次时抛出以下异常

Dish{name='prawns', vegetarian=false, calories=300, type=FISH}
Dish{name='salmon', vegetarian=false, calories=450, type=FISH}
Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
	at java.util.stream.AbstractPipeline.sourceStageSpliterator(AbstractPipeline.java:279)
	at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
	at main.java.com.wangwenjun.java8.SimpleStream.main(SimpleStream.java:35)

简单例子

构建list集

以下所有操作均对应该list进行操作

        List<Dish> menu = Arrays.asList(
                new Dish("pork", false, 800, Dish.Type.MEAT),
                new Dish("beef", false, 700, Dish.Type.MEAT),
                new Dish("chicken", false, 400, Dish.Type.MEAT),
                new Dish("french fries", true, 530, Dish.Type.OTHER),
                new Dish("rice", true, 350, Dish.Type.OTHER),
                new Dish("season fruit", true, 120, Dish.Type.OTHER),
                new Dish("pizza", true, 550, Dish.Type.OTHER),
                new Dish("prawns", false, 300, Dish.Type.FISH),
                new Dish("salmon", false, 450, Dish.Type.FISH));

1.对数据进行排序后输出

这里使用了stream的sorted及collect方法对集合进行处理,并返回到集合

List<Dish> collect = menu.stream().sorted(comparing(Dish::getCalories)).collect(toList());
collect.forEach(System.out::print);

//输出内容如下

Dish{name='season fruit', vegetarian=true, calories=120, type=OTHER}Dish{name='prawns', vegetarian=false, calories=300, type=FISH}Dish{name='rice', vegetarian=true, calories=350, type=OTHER}Dish{name='chicken', vegetarian=false, calories=400, type=MEAT}Dish{name='salmon', vegetarian=false, calories=450, type=FISH}Dish{name='french fries', vegetarian=true, calories=530, type=OTHER}Dish{name='pizza', vegetarian=true, calories=550, type=OTHER}Dish{name='beef', vegetarian=false, calories=700, type=MEAT}Dish{name='pork', vegetarian=false, calories=800, type=MEAT}
Process finished with exit code 0

查找卡路里小于400,并从小到大排序后将其名称输出

首先使用我们常规做法

private static List<String> getDishNamesByCollections(List<Dish> menu) {
        List<Dish> lowCalories = new ArrayList<>();

        //filter and get calories less 400过滤卡路里小于400的dish对象
        for (Dish d : menu) {
            if (d.getCalories() < 400)
                lowCalories.add(d);
        }
        //sort
        Collections.sort(lowCalories, (d1, d2) -> Integer.compare(d1.getCalories(), d2.getCalories()));

        List<String> dishNameList = new ArrayList<>();
        for (Dish d : lowCalories) {
            dishNameList.add(d.getName());
        }
        return dishNameList;
    }

接下来使用stream形式进行需求的处理

    private static List<String> getDishNamesByStream(List<Dish> menu) {
        return menu.stream()().filter(d -> d.getCalories() < 400)
                .sorted(comparing(Dish::getCalories))
                .map(Dish::getName).collect(toList());
    }

可以看到节省到了很多代码,同时在多cpu的情况下,stream是并行处理的,效率更高

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

灵湖映北辰

年轻人,要讲武德!!!

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

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

打赏作者

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

抵扣说明:

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

余额充值