JDK8特性:Stream流简介以及常见用法

1.Stream流是什么?

  • 这个stream流和io流是完全不同的概念。
    io流的工作是硬盘到内存以及内存到硬盘的操作,而stream流是针对集合的一种管道操作。
    类似于mybatis-plus可以简化sql操作,stream流也可以简化对集合的操作。
  • Stream是一个流,在java.util.Stream包路径下
    主要作用就是对集合数据进行查找过滤等操作,一种高效且易用的数据处理方式。

2. Stream流常用方法

方法作用
filter()接收lambda,从流中排除某些操作
limit()截断流,使其元素不超过给定对象
skip(n)跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流,与limit(n)互补
distinct筛选,通过流所生成元素的hashCode()和equals去除重复元素
map接受Lambda,将元素转换成其他形式或提取信息。接受一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
sorted()自然排序(Comparable)
sorted(Comparator com)定制排序(Comparator)
allMatch检查是否匹配所有元素
anyMatch检查是否至少匹配一个元素
noneMatch检查是否没有匹配所有元素
findFirst返回第一个元素
findAny返回当前流中的任意元素
count返回流中元素的总个数
max返回流中最大值
min返回流中最小值
reduce归约操作可以将流中元素反复结合起来,得到一个值
collect将流转换为其他形式,接收一个Collector接口实现,用于给Stream中汇总的方法

用法
我们定义这样一个实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String name;
private String email;
private Integer age;
}
//我们想创建三个User对象放到一个List中,先创建这三个user对象
User user1 = new User(1, "张三", "111@qq.com", 30);
User user2 = new User(2, "李四", "112@qq.com", 43);
User user3 = new User(3, "王五", "113@qq.com", 33);
//传统做法放到List中
List<User> userList = new ArrayList<>();
userList.add(user1);
userList.add(user2);
userList.add(user3);
//使用stream流
List<User> userList = Stream.of(user1, user2, user3).collect(Collectors.toList());
  1. of()
    static Stream of(T… values)
    它的作用是为给定元素创建顺序流,它传入的是可变长度参数,它返回的是一个Stream对象,可以带泛型。在上面这个例子中,返回的是Stream对象。
  2. collect()
    R collect(Supplier supplier,
    BiConsumer<R, ? super T> accumulator,
    BiConsumer<R, R> combiner);
    <R, A> R collect(Collector<? super T, A, R> collector);
    它的作用是,Stream流操作完数据后,如果需要将流的数据进行保存,我们使用这个方法,将流中的数据保存到集合中,其常用的实参有这么三种,我们可以见名思意。
    1.Collectors.toList()
    2.Collectors.toSet()
    3.Collectors.toMap()
    我们看一下toList()方法的源码
public static <T>
Collector<T, ?, List<T>> toList() {
return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
(left, right) -> { left.addAll(right); return left; },
CH_ID);
}

取集合对象某一字段放到另一集合
将上面userList的name字段提取出来放到一个新的List集合中
传统做法

List <String>  userNameList = new ArrayList<>();
for (User user : userList) {
	userNameList.add(user.getName());
}

使用stream

List<String> userNameList = userList.stream().map(User::getName).collect(Collectors.toList());
  1. stream()
    这个方法是接口Collection中的一个方法,目的就是把List或Set集合对象转化为流,便于进行后续的流操作。这也是开发中最常见的创建流的方式。
 default Stream<E> stream() {
	return StreamSupport.stream(spliterator(), false);
}
  1. filter()
    Stream filter(Predicate<? super T> predicate);
    filter的方法定义是这样的,参数是一个断言型接口,实参可以使用lambda表达式或者方法引用。
    这个过滤,是把符合断言为true的元素保留下来。
  2. count()
    如果我们在前面不加任何过滤条件,这个count()毫无用处,因为它获得的是集合内所有元素个数总和,我们用集合的 size() 方法即可获得。
    但我们加了条件后,就可以知道满足条件的元素有多少。
    long count = userList.stream().filter(user -> !user.getName().contains(“五”)).count();
    这样就知道名字里不带“五”的用户有几个了。
    还是上面这个userList,如果我想把这个List转换成Map,key是user的id,value是user的name,使用传统方式的话,需要遍历整个List集合,拿到元素再放入Map。
    我们使用上文提到的 Collectors.toMap() 处理这个。不过我们需要先注意两个问题
    Map的key重复问题
    我们通过key重复,value覆盖的方式解决。
    空指针异常,userList可能有null的存在。
    我们通过filter过滤的方式解决。
    Map<Integer, String> map = userList.stream()
    .filter(Objects::nonNull)
    .collect(Collectors.toMap(User::getId, User::getName, (key1, key2) -> key2));
  3. anyMatch()
    有一个成功就返回true
    // true
    boolean flag = userList.stream().anyMatch(user -> user.getAge() > 40);
  4. allMatch()
    所有都成功才返回true// false
    boolean flag = userList.stream().allMatch(user -> user.getAge() > 40);
  5. noneMatch()
    所有都失败才返回true
    // false
    boolean flag = userList.stream().noneMatch(user -> user.getAge() > 40);
  • 16
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

玉米渣渣粥

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

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

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

打赏作者

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

抵扣说明:

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

余额充值