1、 () -).start();正如你所见,之前无用的模板代码不见了!如上所示,Lambda表达式一个常见的用法是取代(某些)匿名内部类,但Lambda表达式的作用不限于此。Lambda表达式的原理刚接触Lambda表达式可能觉得它很神奇:不需要声明类或者方法的名字,就可以直接定义函数。这看似是编译器为匿名内部类简写提供的一个小把戏,但事实上并非如此,Lambda表达式实际上是通过invokedynamic指令来实现的。先别管这么多,下面是Lambda表达式几种可能的书写形式,“看起来”并不是很难理解。Runnable run = () -Hello World/ 1ActionListener
2、 listener = event -button clicked/ 2Runnable multiLine = () - / 3Hello World;BinaryOperator add = (Long x, Long y) - x + y;/ 4 addImplicit = (x, y) -/ 5通过上例可以发现:Lambda表达式是有类型的,赋值操作的左边就是类型。Lambda表达式的类型实际上是对应接口的类型。Lambda表达式可以包含多行代码,需要用大括号把代码块括起来,就像写函数体那样。大多数时候,Lambda表达式的参数表可以省略类型,就像代码2和5那样。这得益于javac的类
3、型推导机制,编译器可以根据上下文推导出类型信息。表面上看起来每个Lambda表达式都是原来匿名内部类的简写形式,该内部类实现了某个函数接口(Functional Interface),但事实比这稍微复杂一些,这里不再展开。所谓函数接口是指内部只有一个接口函数的接口。Java是强类型语言,无论有没有显式指明,每个变量和对象都必须有明确的类型,没有显式指定的时候编译器会尝试确定类型。Lambda表达式的类型就是对应函数接口的类型。Lambda表达式和StreamLambda表达式的另一个重要用法,是和Stream一起使用。Stream is a sequence of elements suppo
4、rting sequential and parallel aggregate operations。Stream就是一组元素的序列,支持对这些元素进行各种操作,而这些操作是通过Lambda表达式指定的。可以把Stream看作Java Collection的一种视图,就像迭代器是容器的一种视图那样(但Stream不会修改容器中的内容)。下面例子展示了Stream的常见用法。例子1假设需要从一个字符串列表中选出以数字开头的字符串并输出,Java 7之前需要这样写:List list = Arrays.asList(1one, twothree4fourfor(String str : list)
5、 if(Character.isDigit(str.charAt(0) System.out.println(str);而Java 8就可以这样写:list.stream()/ 1.得到容器的Steam .filter(str - Character.isDigit(str.charAt(0)/ 2.选出以数字开头的字符串 .forEach(str - System.out.println(str);/ 3.输出字符串上述代码首先1. 调用List.stream()方法得到容器的Stream,2. 然后调用filter()方法过滤出以数字开头的字符串,3. 最后调用forEach()方法输出结
6、果。使用Stream有两个明显的好处:减少了模板代码,只用Lambda表达式指明所需操作,代码语义更加明确、便于阅读。将外部迭代改成了Stream的内部迭代,方便了JVM本身对迭代过程做优化(比如可以并行迭代)。例子2假设需要从一个字符串列表中,选出所有不以数字开头的字符串,将其转换成大写形式,并把结果放到新的集合当中。Java 8书写的代码如下:Set newList = list.stream()/ 1.得到容器的Stream !Character.isDigit(str.charAt(0)/ 2.选出不以数字开头的字符串 .map(String:toUpperCase)/ 3.转换成大写
7、形式 .collect(Collectors.toSet();/ 4.生成结果集上述代码首先1. 调用List.stream()方法得到容器的Stream,2. 然后调用filter()方法选出不以数字开头的字符串,3. 之后调用map()方法将字符串转换成大写形式,4. 最后调用collect()方法将结果转换成Set。这个例子还向我们展示了方法引用(method references,代码中标号3处)以及收集器(Collector,代码中标号4处)的用法,这里不再展开说明。通过这个例子我们看到了Stream链式操作,即多个操作可以连成一串。不用担心这会导致对容器的多次迭代,因为不是每个St
8、ream的操作都会立即执行。Stream的操作分成两类,一类是中间操作(intermediate operations),另一类是结束操作(terminal operation),只有结束操作才会导致真正的代码执行,中间操作只会做一些标记,表示需要对Stream进行某种操作。这意味着可以在Stream上通过关联多种操作,但最终只需要一次迭代。如果你熟悉Spark RDD,对此应该并不陌生。参考文献:compact1, compact2, compact3java.util.streamInterface StreamType Parameters:T - the type of the str
9、eam elementsAll Superinterfaces:AutoCloseable, BaseStreamT,Streampublic interface Streamextends BaseStream w.getColor() = RED) .mapToInt(w - w.getWeight() .sum(); In this example, widgets is a Collection. We create a stream of Widget objects via Collection.stream(), filter it to produce a stream con
10、taining only the red widgets, and then transform it into a stream of int values representing the weight of each red widget. Then this stream is summed to produce a total weight.In addition to Stream, which is a stream of object references, there are primitive specializations for IntStream, LongStrea
11、m, and DoubleStream, all of which are referred to as streams and conform to the characteristics and restrictions described here.To perform a computation, stream operations are composed into a stream pipeline. A stream pipeline consists of a source (which might be an array, a collection, a generator
12、function, an I/O channel, etc), zero or more intermediate operations (which transform a stream into another stream, such as filter(Predicate), and a terminal operation (which produces a result or side-effect, such as count() or forEach(Consumer). Streams are lazy; computation on the source data is o
13、nly performed when the terminal operation is initiated, and source elements are consumed only as needed.Collections and streams, while bearing some superficial similarities, have different goals. Collections are primarily concerned with the efficient management of, and access to, their elements. By
14、contrast, streams do not provide a means to directly access or manipulate their elements, and are instead concerned with declaratively describing their source and the computational operations which will be performed in aggregate on that source. However, if the provided stream operations do not offer
15、 the desired functionality, the BaseStream.iterator() and BaseStream.spliterator() operations can be used to perform a controlled traversal.A stream pipeline, like the widgets example above, can be viewed as a query on the stream source. Unless the source was explicitly designed for concurrent modif
16、ication (such as a ConcurrentHashMap), unpredictable or erroneous behavior may result from modifying the stream source while it is being queried.Most stream operations accept parameters that describe user-specified behavior, such as the lambda expression w - w.getWeight() passed to mapToInt in the e
17、xample above. To preserve correct behavior, these behavioral parameters:must be non-interfering (they do not modify the stream source); andin most cases must be stateless (their result should not depend on any state that might change during execution of the stream pipeline).Such parameters are alway
18、s instances of a functional interface such as Function, and are often lambda expressions or method references. Unless otherwise specified these parameters must be non-null.A stream should be operated on (invoking an intermediate or terminal stream operation) only once. This rules out, for example, f
19、orked streams, where the same source feeds two or more pipelines, or multiple traversals of the same stream. A stream implementation may throw IllegalStateException if it detects that the stream is being reused. However, since some stream operations may return their receiver rather than a new stream
20、 object, it may not be possible to detect reuse in all cases.Streams have a BaseStream.close() method and implement AutoCloseable, but nearly all stream instances do not actually need to be closed after use. Generally, only streams whose source is an IO channel (such as those returned by Files.lines
21、(Path, Charset) will require closing. Most streams are backed by collections, arrays, or generating functions, which require no special resource management. (If a stream does require closing, it can be declared as a resource in a try-with-resources statement.)Stream pipelines may execute either sequ
22、entially or in parallel. This execution mode is a property of the stream. Streams are created with an initial choice of sequential or parallel execution. (For example, Collection.stream() creates a sequential stream, and Collection.parallelStream() creates a parallel one.) This choice of execution m
23、ode may be modified by the BaseStream.sequential() or BaseStream.parallel() methods, and may be queried with the BaseStream.isParallel() method.Since:1.8See Also:IntStream, LongStream, DoubleStream, java.util.streamNested Class SummaryNested ClassesModifier and Type Interface and Descriptionstatic i
24、nterface Stream.BuilderA mutable builder for a Stream.Method SummaryAll MethodsStatic MethodsInstance MethodsAbstract MethodsDefault MethodsModifier and Type Method and Descriptionboolean allMatch(Predicate predicate)Returns whether all elements of this stream match the provided predicate.boolean an
25、yMatch(PredicateReturns whether any elements of this stream match the provided predicate.static Stream.Builder builder()Returns a builder for a Stream. R collect(Collector collector)Performs a mutable reduction operation on the elements of this stream using a Collector.R R collect(Supplier supplier,
26、 BiConsumerR,? accumulator, BiConsumer combiner)Performs a mutable reduction operation on the elements of this stream. Stream concat(Stream a, Stream b)Creates a lazily concatenated stream whose elements are all the elements of the first stream followed by all the elements of the second stream.long
27、count()Returns the count of elements in this stream.Stream distinct()Returns a stream consisting of the distinct elements (according to Object.equals(Object) of this stream. empty()Returns an empty sequential Stream. filter(PredicateReturns a stream consisting of the elements of this stream that match the given predicate.Optional findAny()Returns an Optional describing some element of the stream, or an empty Optional if the stream is empty. findFirst()Returns an Optional describing the first element of this stream, or an empty Optional if the stream is empty. flatMap
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1