




已阅读5页,还剩14页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Java Lambda表达式初探前言本文受启发于Trisha Gee在JavaOne 2016的主题演讲Refactoring to Java 8。Java 8已经发行两年多,但很多人仍然在使用JDK7。对企业来说,技术上谨慎未必是坏事,但对个人学习而言,不去学习新技术就很可能被技术抛弃。Java 8一个重要的变更是引入Lambda表达式(lambda expression),这听起来似乎很牛,有种我虽然不知道Lambda表达式是什么,但我仍然觉得很厉害的感觉。不要怕,具体到语言层面上Lambda表达式不过是一种新的语法而已,有了它,Java将开启函数式编程的大门。为什么需要Lambda表达式不要纠结什么是Lambda表达式、什么是函数式编程。先来看一下Java 8新的语法特性带来的便利之处,相信你会过目不忘的。在有Lambda表达式之前,要新建一个线程,需要这样写:new Thread(new Runnable() Override public void run() System.out.println(Thread run(); ).start();有Lambda表达式之后,则可以这样写:new Thread( () - System.out.println(Thread run().start();正如你所见,之前无用的模板代码不见了!如上所示,Lambda表达式一个常见的用法是取代(某些)匿名内部类,但Lambda表达式的作用不限于此。Lambda表达式的原理刚接触Lambda表达式可能觉得它很神奇:不需要声明类或者方法的名字,就可以直接定义函数。这看似是编译器为匿名内部类简写提供的一个小把戏,但事实上并非如此,Lambda表达式实际上是通过invokedynamic指令来实现的。先别管这么多,下面是Lambda表达式几种可能的书写形式,“看起来”并不是很难理解。Runnable run = () - System.out.println(Hello World);/ 1ActionListener listener = event - System.out.println(button clicked);/ 2Runnable multiLine = () - / 3 System.out.println(Hello ); System.out.println(World);BinaryOperator add = (Long x, Long y) - x + y;/ 4BinaryOperator addImplicit = (x, y) - x + y;/ 5通过上例可以发现:Lambda表达式是有类型的,赋值操作的左边就是类型。Lambda表达式的类型实际上是对应接口的类型。Lambda表达式可以包含多行代码,需要用大括号把代码块括起来,就像写函数体那样。大多数时候,Lambda表达式的参数表可以省略类型,就像代码2和5那样。这得益于javac的类型推导机制,编译器可以根据上下文推导出类型信息。表面上看起来每个Lambda表达式都是原来匿名内部类的简写形式,该内部类实现了某个函数接口(Functional Interface),但事实比这稍微复杂一些,这里不再展开。所谓函数接口是指内部只有一个接口函数的接口。Java是强类型语言,无论有没有显式指明,每个变量和对象都必须有明确的类型,没有显式指定的时候编译器会尝试确定类型。Lambda表达式的类型就是对应函数接口的类型。Lambda表达式和StreamLambda表达式的另一个重要用法,是和Stream一起使用。Stream is a sequence of elements supporting sequential and parallel aggregate operations。Stream就是一组元素的序列,支持对这些元素进行各种操作,而这些操作是通过Lambda表达式指定的。可以把Stream看作Java Collection的一种视图,就像迭代器是容器的一种视图那样(但Stream不会修改容器中的内容)。下面例子展示了Stream的常见用法。例子1假设需要从一个字符串列表中选出以数字开头的字符串并输出,Java 7之前需要这样写:List list = Arrays.asList(1one, two, three, 4four);for(String str : list) if(Character.isDigit(str.charAt(0) System.out.println(str); 而Java 8就可以这样写:List list = Arrays.asList(1one, two, three, 4four);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()方法输出结果。使用Stream有两个明显的好处:减少了模板代码,只用Lambda表达式指明所需操作,代码语义更加明确、便于阅读。将外部迭代改成了Stream的内部迭代,方便了JVM本身对迭代过程做优化(比如可以并行迭代)。例子2假设需要从一个字符串列表中,选出所有不以数字开头的字符串,将其转换成大写形式,并把结果放到新的集合当中。Java 8书写的代码如下:List list = Arrays.asList(1one, two, three, 4four);Set newList = list.stream()/ 1.得到容器的Stream .filter(str - !Character.isDigit(str.charAt(0)/ 2.选出不以数字开头的字符串 .map(String:toUpperCase)/ 3.转换成大写形式 .collect(Collectors.toSet();/ 4.生成结果集上述代码首先1. 调用List.stream()方法得到容器的Stream,2. 然后调用filter()方法选出不以数字开头的字符串,3. 之后调用map()方法将字符串转换成大写形式,4. 最后调用collect()方法将结果转换成Set。这个例子还向我们展示了方法引用(method references,代码中标号3处)以及收集器(Collector,代码中标号4处)的用法,这里不再展开说明。通过这个例子我们看到了Stream链式操作,即多个操作可以连成一串。不用担心这会导致对容器的多次迭代,因为不是每个Stream的操作都会立即执行。Stream的操作分成两类,一类是中间操作(intermediate operations),另一类是结束操作(terminal operation),只有结束操作才会导致真正的代码执行,中间操作只会做一些标记,表示需要对Stream进行某种操作。这意味着可以在Stream上通过关联多种操作,但最终只需要一次迭代。如果你熟悉Spark RDD,对此应该并不陌生。参考文献:compact1, compact2, compact3java.util.streamInterface StreamType Parameters:T - the type of the stream elementsAll Superinterfaces:AutoCloseable, BaseStreamT,Streampublic interface Streamextends BaseStreamT,StreamA sequence of elements supporting sequential and parallel aggregate operations. The following example illustrates an aggregate operation using Stream and IntStream: int sum = widgets.stream() .filter(w - 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 containing 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, LongStream, 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 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 only 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 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 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 modification (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 example 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 always 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, forked 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 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(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 sequentially 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 mode 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 TypeInterface and Descriptionstatic interface Stream.BuilderA mutable builder for a Stream.Method SummaryAll MethodsStatic MethodsInstance MethodsAbstract MethodsDefault MethodsModifier and TypeMethod and DescriptionbooleanallMatch(Predicate predicate)Returns whether all elements of this stream match the provided predicate.booleananyMatch(Predicate predicate)Returns whether any elements of this stream match the provided predicate.static Stream.Builderbuilder()Returns a builder for a Stream. Rcollect(Collector collector)Performs a mutable reduction operation on the elements of this stream using a Collector. Rcollect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)Performs a mutable reduction operation on the elements of this stream.static Streamconcat(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.longcount()Returns the count of elements in this stream.Streamdistinct()Returns a stream consisting of the distinct elements (according to Object.equals(Object) of this stream.static Streamempty()Returns an empty sequential Stream.Streamfilter(Predicate predicate)Returns a stream consisting of the elements of this stream that match the given predicate.OptionalfindAny()Returns an Optional describing some element of the stream, or an empty Optional if the stream is empty.OptionalfindFirst()Returns an Optional describing the first element of this stream, or an empty Optional if the stream is empty. StreamflatMap(Function? super T,? extends Stream mapper)Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.DoubleStreamflatMapToDouble(Function mapper)Returns an DoubleStream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.IntStreamflatMapToInt(Function mapper)Returns an IntStream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.LongStreamflatMapToLong(Function mapper)Returns an LongStream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.voidforEach(Consumer action)Performs an action for each element of this stream.voidforEachOrdered(Consumer action)Performs an action for each element of this stream, in the encounter order of the stream if the stream has a defined encounter order.static Streamgenerate(Supplier s)Returns an infinite sequential unordered stream where each element is generated by the provided Supplier.static Streamiterate(T seed, UnaryOperator f)Returns an infinite sequential ordered Stream produced by iterative application of a function f to an initial element seed, producing a Stream consisting of seed, f(seed), f(f(seed), etc.Streamlimit(long maxSize)Returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length. Streammap(Function mapper)Returns a stream consisting of the results of applying the given function to the elements of this stream.DoubleStreammapToDouble(ToDoubleFunction mapper)Returns a DoubleStream consisting of the results of applying the given function to the elements of this stream.IntStreammapToInt(ToIntFunction mapper)Returns an IntStream consisting of the results of applying the given function to the elements of this stream.LongStreammapToLong(ToLongFunction mapper)Returns a LongStream consisting of the results of applying the given function to the elements of this stream.Optionalmax(Comparator comparator)Returns the maximum element of this stream according to the provided Comparator.Optionalmin(Comparator comparator)Returns the minimum element of this stream according to the provided Comparator.booleannoneMatch(Predicate predicate)Returns whether no elements of this stream match the provided predicate.static Streamof(T. values)Returns a sequential ordered stream whose elements are the specified values.static Streamof(T t)Returns a sequential Stream containing a single element.Streampeek(Consumer action)Returns a stream consisting of the elements of this stream, additionally performing the provided action on each element as elements are consumed from the resulting stream.Optionalreduce(BinaryOperator accumulator)Performs a reduction on the elements of this stream, using an associative accumulation function, and returns an Optional describing the reduced value, if any.Treduce(T identity, BinaryOperator accumulator)Performs a reduction on the elements of this stream, using the provided identity value and an associative accumulation function, and returns the reduced value. Ureduce(U identity, BiFunction accumulator, BinaryOperator combiner)Performs a reduction on the elements of this stream, using the provided identity, accumulation and combining functions.Streamskip(long n)Returns a stream consisting of the remaining elements of this stream after discarding the first n elements of the stream.Streamsorted()Returns a stream consisting of the elements of this stream, sorted according to natural order.Streamsorted(Comparator comparator)Returns a stream consisting of the elements of this stream, sorted according to the provided Comparator.ObjecttoArray()Returns an array containing the elements of this stream. AtoArray(IntFunction generator)Returns an array containing the elements of this stream, using the provided generator function to allocate the returned array, as well as any additional arrays that might be required for a partitioned execution or for resizing.Methods inherited from interface java.util.stream.BaseStreamclose, isParallel, iterator, onClose, parallel, sequential, spliterator, unorderedMethod DetailfilterStream filter(Predicate predicate)Returns a stream consisting of the elements of this stream that match the given predicate.This is an intermediate operation.Parameters:predicate - a non-interfering, stateless predicate to apply to each element to determine if it should be includedReturns:the new streammap Stream map(Function mapper)Returns a stream consisting of the results of applying the given function to the elements of this stream.This is an intermediate operation.Type Parameters:R - The element type of the new streamParameters:mapper - a non-interfering, stateless function to apply to each elementReturns:the new streammapToIntIntStream mapToInt(ToIntFunction mapper)Returns an IntStream consisting of the results of applying the given function to the elements of this stream.This is an intermediate operation.Parameters:mapper - a non-interfering, stateless function to apply to each elementReturns:the new streammapToLongLongStream mapToLong(ToLongFunction mapper)Returns a LongStream consisting of the results of applying the given function to the elements of this stream.This is an intermediate operation.Parameters:mapper - a non-interfering, stateless function to apply to each elementReturns:the new streammapToDoubleDoubleStream mapToDouble(ToDoubleFunction mapper)Returns a DoubleStream consisting of the results of applying the given function to the elements of this stream.This is an intermediate operation.Parameters:mapper - a non-interfering, stateless function to apply to each elementReturns:the new streamflatMap Stream flatMap(Function? super T,? extends Stream mapper)Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. Each mapped stream is closed after its contents have been placed into this stream. (If a mapped stream is null an empty stream is used, instead.)This is an intermediate operation.API Note:The flatMap() operation has the effect of applying a one-to-many transformation to the elements of the stream, and then flattening the resulting elements into a new stream.Examples.If orders is a stream of purchase orders, and each purchase order contains a collection of line items, then the following produces a stream containing all the line items in all the orders: orders.flatMap(order - order.getLineItems().stream(). If path is the path to a file, then the following produces a stream of the words contained in that file: Stream lines = Files.lines(path, StandardCharsets.UTF_8); Stream words = lines.flatMap(line - Stre
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 果菜种植品种改良分析报告
- 建筑机械操作模拟器性能评估报告
- 水利工程质量问题整改报告及指导
- 高三数学复习计划及重点内容
- 2024年二年级品社下册《为小区服务的人》说课稿 沪教版
- 2026安全生产法考试题及答案
- 民法继承权考试题及答案
- 木寨门施工方案设计
- 建筑防火规范与应用实务
- 6.1碳单质的多样性(第2课时 碳单质的化学性质)说课稿-2024-2025学年九年级化学人教版(2024)上册
- 水暖专业试题及答案
- 2025年秋国家开放大学《形势与政策》形考大作业答案
- 化工安全网络培训课件
- 2025年超细氢氧化铝行业研究报告及未来行业发展趋势预测
- 2025-2026学年人美版(2024)小学美术二年级上册(全册)教学设计(附目录P188)
- 肺康复护理进展
- 2025人教版二年级数学上册《1-6表内除法》教案
- 2025年高考(新课标Ⅱ卷)英语试题及答案
- 电子元器件供货方案与保证措施
- 2025便利店便利店员工劳动合同范本
- 小学二年级体育教案全集全册1
评论
0/150
提交评论