Java8 stream API以及常用方法

Java8引入了全新的Stream API,Stream API为Java编程提供了丰富的函数式编程操作。
Stream API与Java提供的其他集合类型有本质的区别,具体如下:
java.io的InputStream/OutputStream和java.util.stream的不同 :

java.io java.util.stream
存储 顺序读写byte / char 顺序输出任意Java对象
用途 序列化至文件 / 网络 内存计算 / 业务逻辑

java.util.List和java.util.stream的区别

java.util.List java.util.stream
元素 已分配并存储至内存 未分配,实时计算
用途 操作一组已存在的Java对象 惰性计算

Stream的特点:

  • 可以“存储”有限个或无限个元素
  • 可以转换为另一个Stream
  • 计算通常发生在最后结果的获取(惰性计算)

惰性计算: 一个Stream转换城另外一个Stream的时候只存储转换规则,并不做实质性的计算

Stream API的特点:

  • Stream API提供了一套新的流式处理抽象序列
  • Stream API支持函数式编程 / 链式操作
  • Stream API 可以表示无限序列,多数情况下是惰性求值的

创建Stream

创建Stream通常有两种方法种方法:

  1. 将现有数据结构转化成Stream
Stream<Integer> s = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> s = Arrays.stream(arr);
Stream<Integer> s = aList.stream();
  1. 通过Stream.generate()方法:
// 这种方法通常表示无限序列
Stream<T> s = Stream.generate(SuppLier<T> s);
// 创建全体自然数的Stream
class NatualSupplier implements Supplier<BigInteger> {
    BigInteger next = BigInteger.ZERO;
    @Override
    public BigInteger get() {
        next = next.add(BigInteger.ONE);
        return next;
    }
}
  1. 通过其他方法返回
Stream<String> lines = Files.lines(Path.get(filename))
...

map方法

把一种操作运算映射到Stream的每一个元素上,从而完成一个Stream到另一个Stream的转换
map方法接受的对象是Function接口,这个接口是一个函数式接口:

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

@FunctionalInterface
public interface Function<T, R> {
    // 将T转换为R
    R apply(T t);
}

map方法的使用:

// 获取Stream里每个数的平方的集合
Stream<Integer> ns = Stream.of(1, 2, 3, 4, 5);
ns.map(n -> n * n).forEach(System.out::println);

filter方法

filter方法用于过滤Stream中的元素,并用符合条件的元素生成一个新的Stream。
filter方法接受的参数是Predicate接口对象,这个接口是一个函数式接口:

Stream<T> filter(Predicate<? super T>) predicate;

@FunctionInterface
public interface Predicate<T>   {
    // 判断元素是否符合条件
    boolean test(T t);
}

filter方法的使用:

// 获取当前Stream所有偶数的序列
Stream<Integer> ns = Stream.of(1, 2, 3, 4, 5);
ns.filter(n -> n % 2 == 0).forEach(System.out::println);

reduce方法

reduce方法将一个Stream的每一个元素一次作用于BiFunction,并将结果合并。
reduce方法接受的方法是BinaryOperator接口对象。

Optional<T> reduce(BinaryOperator<T> accumulator);

@FuncationalInterface
public interface BinaryOperator<T> extends BiFunction<T, T, T> {
    // Bi操作,两个输入,一个输出
    T apply(T t, T u);
}

reduce的使用方法:

// 求当前Stream累乘的结果
Stream<Integer> ns = Stream.of(1, 2, 3, 4, 5);
int r = ns.reduce( (x, y) -> x * y ).get();
System.out.println(r);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,253评论 19 139
  • 1. Stream初体验 我们先来看看Java里面是怎么定义Stream的: A sequence of elem...
    kechao8485阅读 1,254评论 0 9
  • /Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home...
    光剑书架上的书阅读 4,003评论 2 8
  • 昨天是元宵节,和一个表姐一起去到了一个寺庙祈福。可能是因为过节吧,寺庙的人特别多,可不仅仅是游客,你会发现,有很多...
    小满心欢喜阅读 246评论 0 1
  • 理解转义字符 转义字符顾名思议就是转换字符的意义,一个转义字符书写上是两个字符,但只表示一个含义。我们已经使用过"...
    皮拉夫大王阅读 1,216评论 0 0