JDK8不久前正式发布了,这一次更新为我们带来了相当多的东西,其中一个非常庞大也是非常复杂的框架Stream,特别值得一提,他可以将一些让人烦躁的事情变得简洁,好,进入正题。
现在需要除去一个无序数组中大于800的数
传统方法:
for(int i = 0; i < list.size(); i++) { if(list.get(i) > 800) { list.remove(i); } }
使用Stream与lambda
list.stream().filter((n) -> n <= 800);
如此痛快已经显而易见了,但对于没有了解lambda表达式的童鞋们对类似代码有些抵触,接下来我们还使用传统的Java代码介绍几个比较常用的API。
public static void learnMore(List<Integer> list) { // 创建流式调用对象 list.stream() // 过滤,只保留值大于800的元素。 .filter(new Predicate<Integer>() { @Override public boolean test(Integer t) { return t > 800; } }) // 排序,默认升序,可传入Comparator。 .sorted() // 通过map方法将集合中的对象转换为String类型 .map(new Function<Integer, String>() { @Override public String apply(Integer t) { return new StringBuilder("String[").append(t).append("]").toString(); } }) // 获取集合中最多n个元素。 .limit(10) .forEach(new Consumer<String>() { @Override public void accept(String t) { System.out.println(t); } }); System.out.println("List size:" + list.size()); }
程序输出:
String[801]
String[802]
String[803]
String[804]
String[805]
String[806]
String[807]
String[808]
String[809]
String[810]
List size:1000
通过输出我们可以看到整个流程中所有的操作得到了处理,且所有操作均没有涉及对原集合的变动,探查源代码发现stream对象是靠原集合创建迭代器进行所有操作,因此不对原集合内容进行改动。
接下来我们看一个比较有意思的事情:
public static void whyNoPrint(List<Integer> list) { list.stream() .filter(new Predicate<Integer>() { @Override public boolean test(Integer t) { System.out.println(t); return true; } }); }
该方法执行过后程序没有任何输出,其实本人最初并不知道这个细节,而是在研究另外一个事情的时候发现的,稍微想一想就能看出这个程序有问题,流对象在filter后就不做任何事情了,所以这个筛选操作也失去了意义,应该是JDK在设计时考虑到的细节,非常值得我们学习。
接下来的东西实在是让人太兴奋了:并行流
这个东西是在研究stream.reduce方法时候发现的,reduce提供三个方法的重载,分别为1个参数,两个参数与三个参数,在尝试使用三个参数的reduce方法时候我发现了一个问题,就是最后一个参数传入的BinaryOperator.apply方法根本没有被调用!通过一番苦苦的读源代码工作后我发现reduce方法的第三个参数仅仅在stream以并行模式工作时才会生效!为什么?他是做什么的?我们来看下面的代码:
public static void learnReduce_3(List<Integer> list) { // 并行流 Stream<Integer> parallelStream = list.stream().parallel(); // 串行流 Stream<Integer> sequentialStream = list.stream(); long start = System.currentTimeMillis(); parallelStream.reduce(0, new BiFunction<Integer, Integer, Integer>() { @Override public Integer apply(Integer t, Integer u) { // 在这里停顿10毫秒来提高并行与串行计算的差异。 // 虽然流提供了并行计算支持,但如果你需要处理的问题非常简单,还是推荐使用串行模式。 // 因为那样避免了并行计算自身的开销,会更快。 try { Thread.sleep(10); } catch (InterruptedException e) { } return t + u; } }, new BinaryOperator<Integer>() { @Override public Integer apply(Integer left, Integer right) { System.out.println(Thread.currentThread().getName()); return left + right; } }); System.out.println("Parallel stream processed with " + (System.currentTimeMillis() - start) + "ms."); start = System.currentTimeMillis(); sequentialStream.reduce(0, new BiFunction<Integer, Integer, Integer>() { @Override public Integer apply(Integer t, Integer u) { try { Thread.sleep(10); } catch (InterruptedException e) { } return t + u; } }, new BinaryOperator<Integer>() { @Override public Integer apply(Integer t, Integer u) { System.out.println("Can't print this line."); return 0; } }); System.out.println("Sequential stream processed with " + (System.currentTimeMillis() - start) + "ms."); }
程序输出:
ForkJoinPool.commonPool-worker-3
ForkJoinPool.commonPool-worker-7
ForkJoinPool.commonPool-worker-2
main
ForkJoinPool.commonPool-worker-6
ForkJoinPool.commonPool-worker-4
ForkJoinPool.commonPool-worker-1
ForkJoinPool.commonPool-worker-1
ForkJoinPool.commonPool-worker-5
ForkJoinPool.commonPool-worker-3
ForkJoinPool.commonPool-worker-3
ForkJoinPool.commonPool-worker-7
ForkJoinPool.commonPool-worker-7
ForkJoinPool.commonPool-worker-2
ForkJoinPool.commonPool-worker-2
ForkJoinPool.commonPool-worker-2
ForkJoinPool.commonPool-worker-5
ForkJoinPool.commonPool-worker-5
ForkJoinPool.commonPool-worker-5
ForkJoinPool.commonPool-worker-5
ForkJoinPool.commonPool-worker-4
ForkJoinPool.commonPool-worker-4
ForkJoinPool.commonPool-worker-4
main
main
ForkJoinPool.commonPool-worker-6
ForkJoinPool.commonPool-worker-7
ForkJoinPool.commonPool-worker-7
ForkJoinPool.commonPool-worker-7
ForkJoinPool.commonPool-worker-7
ForkJoinPool.commonPool-worker-7
Parallel stream processed with 1350ms.
Sequential stream processed with 10003ms.
通过线程名称可以看出,流以并行模式运行的时候使用到了ForkJoin框架。
那么就更加明确了,当流在并行模式下工作时,JDK使用了多个线程进行并行处理,这将牵扯到多个计算结果合并的问题,所以reduce方法的第三个参数(BinaryOperator.apply)作用是将两个线程的计算结果合并。
更多信息参考:http://www.infoq.com/cn/articles/forkjoin-to-parallel-streams
至此,Stream基本上都已经搞清楚了,但是我们公司还在使用JDK6,呵呵!
相关推荐
首先,我们需要了解Java中的日期时间API。在Java 8之前,我们通常使用`java.util.Date`和`java.text.SimpleDateFormat`来处理日期。然而,这些类存在一些设计上的问题,因此Java 8引入了新的日期时间API,包括`java....
Java 8 引入了一种新的集合...通过深入了解 Java 8 Stream API 及其源码实现,开发者可以更有效地处理大数据,提高代码的可读性和可维护性。在实际项目中,合理运用 Stream API 可以帮助我们写出更优雅、高效的代码。
今天,我们将深入了解 Java8 Stream flatmap 中间操作的用法解析。 flatmap 操作的定义 在 Java8 的 Stream API 中,flatmap 操作是通过 `flatMap` 方法实现的,该方法的定义如下: `<R> Stream<R> flatMap...
Java 8引入了一种新的集合处理方式,那就是Stream API,它极大地改变了我们处理集合数据的方式,使得代码更加简洁、高效且易于理解。Stream API是Java 8中的一个核心特性,它提供了一种声明式编程风格,可以用于大量...
Java 8 Stream 表达式实现 if/else 逻辑...如果您想了解更多关于Java 8 Stream 表达式和lambda 表达式的知识,可以查看以下资源: * Oracle 的 Java 8 文档 * Java 8 Stream API 的官方文档 * Lambda 表达式的实践指南
Speedment的使用首先要求对Java 8有一定的了解,特别是Stream API。Stream API是Java 8引入的新特性,它允许以声明性方式处理集合数据,类似于SQL查询。在Speedment中,数据库查询被转换为Stream操作,这使得在内存...
在 Java 8 引入的 Stream API 中,java.util.stream.Collectors.minBy() 方法是一个强大的工具,用于在集合操作中找到流中按照指定比较器最小的元素。与 maxBy() 方法相对应,minBy() 提供了一种声明式的方式来确定...
在 Java 8 引入的 Stream API 中,Collectors 类提供了多种强大的工具,用于处理集合数据。其中,Collectors.maxBy() 方法尤其引人注目,因为它允许开发者以声明式的方式轻松找到流中的最大元素。本文将深入探讨 ...
在Java 8中引入的Stream API极大地简化了集合的处理,使得代码更加简洁和易于理解。Collectors.toSet()作为Stream API中的一个重要组成部分,它的作用是将流(Stream)中的元素收集到一个集合中,而这个默认集合就是...
在Java 8引入的Stream API中,Collectors类提供了多种收集器(Collector),用于将流(Stream)的元素汇总成各种形式的结果。Collectors.collectingAndThen()是其中一种强大的收集器,它允许开发者在收集过程完成后...
Java 8 引入的 Stream API 极大地简化了集合操作,其中 Collectors.averagingDouble() 方法为计算平均值提供了一种高效且表达性强的方式。本文将深入探讨 Collectors.averagingDouble() 方法的工作原理、使用场景...
在Java 8引入的Stream API中,Collectors类提供了一种强大的方式来处理集合数据。Collectors.collectingAndThen()方法尤其独特,它允许开发者在完成基本的收集操作后,对结果进行进一步的转换或后处理。这种方法的...
这份官方版本的Java8中文API文档是开发者了解和掌握这些新特性的宝贵资源。以下是其中的一些关键知识点: 1. **Lambda表达式**:Java 8最大的亮点之一就是引入了Lambda表达式,它简化了函数式编程,使得可以以更...
在Java 8中,Stream API 的引入极大地增强了集合的处理能力,尤其是在处理大量数据时。Collectors.groupingByConcurrent() 方法是这一API中一个强大的工具,它允许开发者以并行的方式对数据进行分组,从而提高性能和...
首先,让我们了解如何安装Java Development Kit (JDK)。JDK是Java开发的基础,包含了编译器、调试工具和其他必要的库。在Windows系统中,Java8的安装通常涉及以下步骤: 1. **下载**:访问Oracle官方网站...
"Java 8 Stream性能优化" 在 Java 8 中,Stream API 是一个非常强大的功能,它可以帮助开发者快速处理大量数据。但是,许多开发者在使用 Stream 时,发现其性能并不是很好。这是因为 Stream 的性能是受到多种因素...
要深入了解Java 8,可以参考官方文档、教程以及各种在线课程,如Oracle官方教程、Stack Overflow问答、GitHub上的开源项目等,不断提升对Java 8新特性的理解和应用能力。 总之,Java 8的推出极大地推动了Java语言的...
标签"java_p2p"、"java_stream"、"stream_media_player"和"stream_p2p"分别强调了Java编程语言、流处理、流媒体播放器和P2P流媒体的应用。 P2P技术是一种网络架构,其中每个参与者既是服务的消费者也是服务的提供者...
- **Stream API**:Java 8 提供了 Stream API,允许对集合进行函数式编程操作,如过滤、映射、归约等。Stream 可以处理数组、集合甚至 I/O 流,极大地提高了数据处理的灵活性。 2. **默认方法**: - 在接口中,...
Java 8是Oracle公司推出的Java开发工具包(Java Development Kit...在Linux环境下,了解如何正确安装和配置Java 8 JDK也是每个开发者的基础技能。同时,要关注安全更新,定期检查和更新JDK版本,以防止潜在的安全风险。