Java 8 Stream

Java 8 Stream

parallelStream

顺序不保证

java.util.function(用于接口编程不适用的场景尤佳)

IO  Function       // <T, R> 输入输出
IO  UnaryOperator  // <T> = Function<T, T>

IIO BiFunction     // <T, U, R> 2 个输入,1 个输出
IIO BinaryOperator // <T> = BiFunction<T, T, T>

I\  Consumer       // <T> 消费
II\ BiConsumer     // <T, U> 2 个输入的消费

IO  Predicate      // <T> 断言
IIO BiPredicate    // <T, U> 2 个输入的断言

\O  Supplier       // <T> 工厂

collect

    // 1 个参数方法必须是 non-static 2 个参数方法必须是 static,不管如何其中第 2 个参数合并到第一个

    list.parallelStream()
    .collect(
        () -> new Page<DB>(),
        (r, e) -> r.add(e),
        (rto, rfrom) -> rto.addAll(rto, rfrom))// 用于 parallelStream,都是 new 出来的,所以安全
    .data
        .forEach(e -> System.out.println(e.name));

    list.parallelStream()
    .collect(
        Page<DB>::new,
        Page::add,
        Page::addAll)// 用于 parallelStream,都是 new 出来的,所以安全
    .data
        .forEach(e -> System.out.println(e.name));

reduce

  • 用 Class::Function 的话 Function 都是 2 个参数且是 static
  • 1 个参数:默认返回 Optional.value = null
    Optional<DB> result = list.parallelStream().reduce((firstOrAnyRefAsResult, e) -> {
      // parallelStream: firstOrAnyRefAsResult = 随机的无序的任意一个元素
      // stream: firstOrAnyRefAsResult = 有序的第一个元素

      // 不安全

      // firstOrAnyRefAsResult.price += e.price;
      // return firstOrAnyRefAsResult;

      // 安全

      DB x = new DB(null, null, 0);
      x.price += firstOrAnyRefAsResult.price + e.price;
      return x;
    });
    if (result.isPresent())
      System.out.println(result.get().price + " - " + (result.get() == one));
    else
      System.out.println("Not Exists");
  • 2 个参数:默认返回 identity
    // 没有元素时作为默认值返回,有元素用于(每个线程)result
    DB identity = new DB("种子", null, 1);

    // method 2
    DB result2 = list.parallelStream().reduce(identity, (refIdentityOrNewResult, e2) -> {
      // 要结合 1 个参数的方法理解

      // refIdentityOrNewResult = identity
      // 错误
      // refIdentityOrNewResult.price += e.price;
      // return refIdentityOrNewResult;

      // refIdentityOrNewResult (每个线程)第一次调用=identity, 其它调用=总是下面的 new
      // 正确
      // DB x = new DB(null, null, 0);
      // x.price += refIdentityOrNewResult.price + e.price;
      // return x;

      // refIdentityOrNewResult (每个线程)第一次调用=identity, 其它调用=总是下面的 new(即当前线程是单例)
      // 正确
      if (refIdentityOrNewResult == identity) {
        refIdentityOrNewResult = new DB(null, null, 0);
      }
      refIdentityOrNewResult.price += e2.price;
      return refIdentityOrNewResult;
    });

    System.out.println(result2.price + " - " + (result2 == one));
  • 3 个参数:默认返回 identity
    // 没有元素时作为默认值返回,有元素用于(每个线程)result
    DB identity = new DB("种子", null, 1);

    DB result3 = list.parallelStream().reduce(identity, (refIdentityOrNewResult, e) -> {
      // 等于 2 个参数的方法理解

      // 错误
      // refIdentityOrNewResult.price += e.price;
      // return refIdentityOrNewResult;

      // 正确
      // DB x = new DB(null, null, 0);
      // x.price += refIdentityOrNewResult.price + e.price;

      // 正确
      if (refIdentityOrNewResult == identity)
        refIdentityOrNewResult = new DB(null, null, 0);
      refIdentityOrNewResult.price += e.price;
      return refIdentityOrNewResult;
    }, (r1, r2) -> {
      // 此方法用于并行

      // 如果第二个做过判断处理 refIdentityOrNewResult 的话这里 r1 r2 就都是 add 里面 new 出来的,每个 new 出来的这里只会合并一次,所以安全
      // 正确
      // r1.price += r2.price;
      // return r1;
      // 正确
      DB x = new DB(null, null, 0);
      x.price += r1.price + r2.price;
      return x;
    });

    System.out.println(result3.price + " - " + (result3 == one));
  • groupingBy
    根据值分区
  • partitioningBy
    根据 boolean 分区,就 2 类
// groupingBy 并转换结果
Map<String, List<String>> userIdToHourseListMap = userList.stream()
                .filter(Objects::nonNull)
                .filter(e -> e.getId() != null)
                .filter(e -> e.getHourse() != null)
                .collect(Collectors.groupingBy(User::getId,
                                Collectors.mapping(User::getHourse, Collectors.toList())));
Map<String, IntSummaryStatistics> userIdToHourseListMap = userList.stream()
                .filter(Objects::nonNull)
                .filter(e -> e.getId() != null)
                .filter(e -> e.getScore() != null)
                .collect(Collectors.groupingBy(User::getId,
                        Collectors.summarizingInt(User::getScore)));
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值