JDK8之Stream

本文介绍java 8 Stream API提供的诸多操作,利用这些操作可以让你快速的完成复制的数据查询,如筛选、切片、映射、查找、匹配和规约。包括一些特殊流的用法:数值流、文件流、数组流,无限流。

筛选和切片

用谓词筛选

Stream接口提供了filter方法,该方法接收一个谓词作为参数,并返回一个包含所有符合谓词的元素的流。

比如,筛选出所有的素菜:

List<Dish> dishes = menu.stream().filter(Dish::isVegetarian).collect(toList());

元素去重

Stream还支持distinct方法,它会返回不重复的元素的流(根据元素的hashCode和equals方法)。
例如,筛选出下面列表中的所有不重复的偶数:

List<Integer> numbers = Arrays.asList(1,2,5,2,6,3,3,2,4);
numbers.stream()
    .filter(i -> i % 2 == 0)
    .distinct() // 根据元素的hashcode和equals方法过滤重复元素

截断流

Stream还支持limit方法,返回一个不超过给定长度的流。所需的长度作为参数传递给limit。如果流是有序的,则最多会返回前n个元素。
比如,筛选出热量超过300卡路里的头三道菜:

List<Dish> highCaloriesTop3 = menu.stream() // 由菜单得到一个流
    .filter(dish ->  dish.getCalories() > 300) // 接收Lambda,从流中排除某些元素
    .limit(3) // 截断流,使元素不超过指定数量
    .collect(Collectors.toList()); // 将流转换为其他形式

跳过元素

Stream还支持skip方法,返回一个扔掉了前n个元素的流。如果流中元素不足n个,则返回空流。
比如,找出超过300卡路里的菜,但忽略前2道。

List<Dish> highCalories = menu.stream()
    .filter(dish -> dish.getCalories() > 300)
    .skip(2)
    .collect(Collectors.toList());

映射

对流中的每个元素应用函数

Stream支持map方法,接收一个函数作为参数,会对流中的每个元素应用该函数,并映射为一个新的元素。
比如,获取每道菜的名称:

List<String> dishNames = menu.stream().map(Dish::getName).collect(toList());

流的扁平化

流支持flatMap方法,可以将流中的每个值都转换为一个流,然后把所有的流连接起来形成一个流。

例1:
给定如下单词列表[‘Hello’,’World’],如何得到不重复的字符?

List<String> strings = Arrays.asList("Hello", "World");
// Arrays::stream将一个数组转换为一个流
List<String> words = strings.stream()
    .map(s -> s.split("")) // 得到字符数组
    .flatMap(Arrays::stream) // 将字符数组中的每个元素都换成另外一个流,然后把所有的流连接起来形成一个新的流
    .distinct()
    .collect(Collectors.toList());

上面如果只是使用map方法,只能得到2个字符数组,而使用flatMap就可以将数组中的每个元素映射为一个流,然后把所有的流合起来形成一个新的流。

例2:
给定2个数字列表,[1,2,3],[4,5],如何返回所有的数对?[(1,4),(1,5),(2,4),(2,5),(3,4),(3,5)]

List<Integer> numList1 = Arrays.asList(1, 2, 3);
List<Integer> numList2 = Arrays.asList(4, 5);
List<int[]> nums = numList1.stream()
    .flatMap(i -> numList2.stream().map(j -> new int[]{i, j}))
    .collect(Collectors.toList());

查找和匹配

查找谓词是否至少匹配一个元素

使用anyMatch()方法。
比如,菜单中是否有素菜?

boolean isExistVegetarian = menu.stream().anyMatch(d -> d.isVegetarian());

检查谓词是否匹配所有元素

使用allMatch()方法。

比如,是否所有的菜卡路由都小于1000?

boolean allLess1000 = menu.stream().allMatch(d -> d.getCalories() < 1000);

检查谓词是否券都不匹配所有元素

使用noneMatch,与allMatch对应。

比如,是否是否所欲的菜卡路由都是小于1000?

boolean all
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值