java8 stream index_Java8 Stream基本使用

1. 什么是Stream

Stream是一个数据处理接口,本身不存储任何数据。大概有20多个方法,每个都很好用,并且含有函数式编程里的filter,map,reduce方法。Stream的数据有三个来源:Collection, Array或者根据需要生成。

2. 创建Stream

在Java8中,添加了许多能够产生Stream的方法,如Pattern类中的splitAsStream方法,下面是三种典型常见的生成Stream的形式。

2.1 Collection创建Stream

Java8在Collection接口中添加了stream方法,可以从任何集合生成一个Stream。

List elements = Lists.newArrayList("element1", "element2", "element3");

Stream stream = elements.stream();

2.2 Array创建Stream

int[] nums = {1, 2, 3, 4};

Arrays.stream(nums);

// 使用数组的子集,包含start index,不包含end index。

Arrays.stream(nums, 0, 2);

2.3 直接生成Stream

有限Stream。给定元素,直接生成Stream。如果不是同一类型元素,就是Stream。

Stream stream = Stream.of(1, 2, 3);

无限Stream。使用Stream中的generate静态方法,需要传入一个Supplier接口实例。

// 常量Stream

Stream generate = Stream.generate(() -> "Echo");

// 随机数字的Stream

Stream generate2 = Stream.generate(Math::random);

无限Stream。使用Stream中的iterate静态方法,第一个参数是种子(起始元素),第二个参数是UnaryOperator接口实例。

// 0, 1, 2, 3, 4, ...

Stream iterate = Stream.iterate(0, n -> n + 1);

3. Filter、Map、Reduce方法

Stream的转换,是指从一个Stream中读取数据,经过处理后产生一个新的Stream。对Stream执行任何操作,都不会更改底层的数据集合(Collection或者Array),都是生成新的Stream,JDK中称为不干扰(noninterference)。

3.1 Stream::filter(Predicate p)

过滤一个Stream,新生成的Stream只含有符合条件的元素。

Stream words = Stream.of("int", "double", "String", "BigNumber");

Stream newWords = words.filter(w -> w.length() > 5);

3.2 Stream::map(Function f)

对Stream中的每个元素T,执行Function:: R apply(T)方法,生成的元素R组成一个新的Stream。Python的map是对多个list元素执行function,Stream的map只是对自己元素执行function。

Stream numbers = Stream.of(1, 2, 3, 4);

Stream map = numbers.map(n -> n++ + "");

3.3 Stream::reduce(BinaryOperator accumulator)

对Stream中的元素,两个两个循环处理,最后组合成一个元素。例如,对所有元素求和。

Stream nums = Stream.of(1, 2, 3, 4);

nums.reduce((x, y) -> x + y);

// 指定第一个元素

nums.reduce(0, (x, y) -> x + y);

4. 提取子Stream和合并Stream

获取Stream里前n个元素,组成新的Stream。如果n小于Stream的size,就返回原来的Stream。

Stream randoms = Stream.generate(Math::random).limit(10);

丢掉前n个元素,组成新的Stream。如果n大于Stream的size,就返回一个空的Stream。

Stream words = Stream.of("", "", "hello").skip(2);

将两个Stream合并成一个Stream

Stream stream1 = Stream.of(1, 2);

Stream stream2 = Stream.of(5, 6);

Stream concat = Stream.concat(stream1, stream2);

5. 并行Stream – 并行处理

默认情况下,都是创建一个串行Stream,方法Collection.paralleStream()除外。调用一个Stream中的parallel方法,就可将其转换成一个并行Stream。对并行Stream施加的任何方法,都是并行执行的,Java自己决定用多少线程来处理。

Stream nums = Stream.of(1, 2, 3, 4, 5, 6);

// 无序,打印每个元素

nums.parallel().forEach(n -> System.out.println(n));

// 强制有序处理

nums.parallel().forEachOrdered(System.out::println);

对于串行Stream,调用forEach()方法,始终是有序遍历。下面是并行求和的例子:

// 1, 2, 3 ... 100

Stream nums = Stream.iterate(1, n -> n + 1).limit(100);

Stream filtered = nums.parallel().filter(n -> n % 2 == 0);

注意:并行Stream使用上和串行Stream没有区别,但是并行Stream中应用的方法,必须是线程安全的。下面是个反面例子:

Stream words = Stream.of("Hello", "the", "world", "!");

int[] count = {0};

// 多个线程并行累加count[0]

words.parallel().forEach(s -> count[0] += s.length());

System.out.println(count[0]);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值