Stream流使用——(未完)

Stream流使用——(未完)

Stream介绍

Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。

Stream特性:

  • 不是数据结构:它没有内部存储,它只是用操作管道从 source(数据结构、数组、generator function、IO channel)抓取数据。它也绝不修改自己所封装的底层数据结构的数据。例如 Stream 的 filter 操作会产生一个不包含被过滤元素的新 Stream,而不是从 source 删除那些元素。
  • 不支持索引访问:但是很容易生成数组或者 List 。
  • 惰性化:很多 Stream 操作是向后延迟的,一直到它弄清楚了最后需要多少数据才会开始。Intermediate 操作永远是惰性化的。
  • 并行能力。当一个 Stream 是并行化的,就不需要再写多线程代码,所有对它的操作会自动并行进行的。
  • 可以是无限的:集合有固定大小,Stream 则不必。limit(n) 和 findFirst() 这类的 short-circuiting 操作可以对无限的 Stream 进行运算并很快完成。
  • 注意事项:所有 Stream 的操作必须以 lambda 表达式为参数。

Stream 流操作类型:

  • Intermediate:一个流可以后面跟随零个或多个 intermediate 操作。其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个操作使用。这类操作都是惰性化的(lazy),就是说,仅仅调用到这类方法,并没有真正开始流的遍历。
  • Terminal:一个流只能有一个 terminal 操作,当这个操作执行后,流就被使用“光”了,无法再被操作。所以这必定是流的最后一个操作。Terminal操作的执行,才会真正开始流的遍历,并且会生成一个结果,或者一个 side effect。

1. 构造Stream流的方式

Stream stream = Stream.of("a", "b", "c");
String[] strArray = new String[] { "a", "b", "c" };
stream = Stream.of(strArray);
stream = Arrays.stream(strArray);
List<String> list = Arrays.asList(strArray);
stream = list.stream();

2. Stream流的之间的转换

注意:一个Stream流只可以使用一次,这段代码为了简洁而重复使用了数次,因此会抛出 stream has already been operated upon or closed 异常。

Stream<String> stream2 = Stream.of("a", "b", "c");
// 转换成 Array
String[] strArray1 = stream2.toArray(String[]::new);
// 转换成 Collection
List<String> list1 = stream2.collect(Collectors.toList());
List<String> list2 = stream2.collect(Collectors.toCollection(ArrayList::new));   
Set set1 = stream2.collect(Collectors.toSet());
Stack stack1 = stream2.collect(Collectors.toCollection(Stack::new));
// 转换成 String
String str = stream.collect(Collectors.joining()).toString();

3. Stream流的排序

a. Stream流的实体操作

//实体根据年龄 倒序
List<User> collect1 = users.stream().sorted(Comparator.comparing(User::getName).reversed()).collect(Collectors.toList());
//实体根据年龄 正序
List<User> collect2 = users.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());

b. Stream流的直接操作

//直接排序 倒序
List<Integer> collect3 = list.stream().sorted(Comparator.comparing(Integer::intValue).reversed()).collect(Collectors.toList());
//直接排序 正序
List<Integer> collect4 = list.stream().sorted().collect(Collectors.toList());
List<Integer> collect5 = list.stream().sorted(Comparator.comparing(Integer::intValue)).collect(Collectors.toList());

4. Stream流的limit使用

limit 方法用于获取指定数量的流。

//Stream流的limit使用
List<User> collect6 = users.stream().limit(2).collect(Collectors.toList());
List<Integer> collect7 = list.stream().limit(2).collect(Collectors.toList());

5. Stream流的skip使用

skip方法用于从前面扔掉指定数量的流。

//扔掉前n条数据
List<User> collect8 = users.stream().skip(3).collect(Collectors.toList());
List<Integer> collect9 = list.stream().skip(3).collect(Collectors.toList());

6. Steam流进行过滤

List<User> collect10 = users.stream().filter(user -> "王五".equals(user.getName())).collect(Collectors.toList());
List<Integer> collect11 = list.stream().filter(val -> val != 4).collect(Collectors.toList());

7. Stream流的map使用

map方法用于映射每个元素到对应的结果,一对一。

//修改当前值
List<User> collect12 = users.stream().map(e ->{
    if (e.getAge() == 18) {
        e.setAge(999);
    }
    return e;
}).collect(Collectors.toList());

//赋值新的实体
List<UserTwo> collect13 = users.stream().map(e -> {
    UserTwo userTwo = new UserTwo();
    BeanUtils.copyProperties(e, userTwo);
    return userTwo;
}).collect(Collectors.toList());

List<Integer> collect14 = list.stream().map(e -> e * e).collect(Collectors.toList());

8. Stream流的分组使用

Map<Integer, List<User>> collect15 = users.stream().collect(Collectors.groupingBy(User::getAge));
        Map<Integer, List<Integer>> collect16 = list.stream().collect(Collectors.groupingBy(Integer::intValue));

9. Stream流的根据实体去重

//业务需要去重的代码
List<User> collect= userList.stream().filter(distinctByKey1(s -> s.getBizUserId())).collect(Collectors.toList());
        
//必要的
static <T> Predicate<T> distinctByKey1(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

yizhi-w

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

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

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

打赏作者

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

抵扣说明:

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

余额充值