Java 8 的新特性和改进总览

欢迎进入Java社区论坛,与200万技术人员互动交流 >>进入

  流试图尽可能做很少的工作。有一些细微优化,如当可以判定元素已经有序的时候,省略一个sorted()操作。在包含limit(x) 或 substream(x,y)的操作中,有些时候对一些不会决定结果的元素,流可以避免执行中间的map操作。在这里我不准备实现公平判断;它通过许多细微的但却很重要的方法表现得很聪明,而且它仍在进步。

  回到并行流的概念,重要的是要意识到并行不是毫无代价的。从性能的立场它不是无代价的,你不能简单的将顺序流替换为并行流,且不做进一步思考就期望得到相同的结果。在你能(或者应该)并行化一个流以前,需要考虑很多特性,关于流、它的操作以及数据的目标方面。例如:访问顺序确实对我有影响吗?我的函数是无状态的吗?我的流有足够大,并且我的操作有足够复杂,这些能使得并行化是值得的吗?

  有针对int,long和double的专业原始的Stream版本:

  IntStream

  LongStream

  DoubleStream

  可以在众多函数中,通过专业原始的map和flatMap函数,在一个stream对象与一个原始stream对象之间来回转换。给几个虚设例子:

  List strings = Arrays.asList("a", "b", "c");

  strings.stream() //

  Stream .mapToInt(String::length) // IntStream .longs() //

  LongStream .mapToDouble(x -> x / 10.0) // DoubleStream .boxed() //

  Stream .mapToLong(x -> 1L) // LongStream .mapToObj(x -> "") //

  Stream …

  原始的stream也为获得关于stream的基础数据统计提供方法,那些stream是指作为数据结构的。你可以发现count, sum, min, max, 以及元素平均值全部是来自于一个终端的操作。

  原始类型的剩余部分没有原始版本,因为这需要一个不可接受的JDK数量的膨胀。IntStream, LongStream, 和 DoubleStream被认为非常有用应当被包含进去,其他的数字型原始stream可以由这三个通过扩展的原始转换来表示。

  在flatMap操作中使用的 FlatMapper 接口是具有一个抽象方法的功能性接口:

  void flattenInto(T element, Consumer sink);

  在一个flatMap操作的上下文中,stream为你提供element和 sink,然后你定义该用element 和 sink做什么。element是指在stream中的当前元素,而sink代表当flatMap操作结束之后在stream中应该显示些什么。例如:

  Set colors = …;

  List people = …;

  Stream stream = people.stream().flatMap(

  (Person person, Consumer sink) -> { // Map each person to the colors they like. for (Color color : colors) { if (person.likesColor(color)) {

  sink.accept(color);

  }

  }

  });

  注意上面lambda中的参数类型是指定的。在大多数其它上下文中,你可以不需要指定类型,但这里由于FlatMapper的自然特性,编译器需要你帮助判定类型。如果你在使用flatMap又迷惑于它为什么不编译,可能是因为你没有指定类型。

  最令人感到困惑,复杂而且有用的终端stream操作之一是collect。它引入了一个称为Collector的新的非功能性接口。这个接口有些难理解,但幸运的是有一个Collectors工具类可用来产生所有类型的有用的Collectors。例如:

  List strings = values.stream()

  .filter(…)

  .map(…)

  .collect(Collectors.toList());

  如果你想将你的stream元素放进一个Collection,Map或String,那么Collectors可能具有你需要的。在javadoc中浏览那个类绝对是值得的。

  泛型接口改进

  建议摘要:JEP 101: 通用化目标-Type 接口

  这是一个以前不能做到的,对编译器判定泛型能力的努力改进。在以前版本的Java中有许多情形编译器不能给某个方法计算出泛型,当方法处于嵌套的或串联方法调用这样的上下文的时候,即使有时候对程序员来说它看起来“很明显”。那些情况需要程序员明确的指定一个“类型见证”(type witness)。它是一种通用的特性,但吃惊的是很少有Java程序员知道(我这么说是基于私下的交流并且阅读了一些StackOverflow的问题)。它看起来像这样:

  // In Java 7: foo(Utility.bar());

  Utility.foo().bar();

慢慢学会了长大。流转的时光,

Java 8 的新特性和改进总览

相关文章:

你感兴趣的文章:

标签云: