java流

Java流入门 让我们先从一点理论开始。Java流的定义是什么?一个简短的定义就是"来自于一个数据源的能够支持聚合操作的一串元素"。让我们把它拆开来说: 一串元素:Java流为一串特定类型值的集合提供了一个接口。然后,Java流实际上并不存储元素,它们会在需要时被用上。 数据源:Java流要使用一个提供数据的源,诸如集合对象,数组或I/O资源。 聚合操作:Java流支持类SQL的操作,以及来自于函数编程语言的通用操作,诸如过滤,映射,归一,查找,匹配,排序,等等。 另外,与集合操作非常不同的是,Java流操作拥有两项基本特质: 管道:许多Java流操作会返回它们自己,这就使得这些操作能够链接在一起以组成一个大型管道。这样就可以进行一些诸如惰性和短路之类的优化,后面我们会进行探究。 内部遍历:集合是显式地进行遍历(外部遍历),但不同于集合,Java流是在幕后进行遍历。让我们重新看看之前的示例代码来解释这些原理。图2形象地解释了清单2的更多细节。 首先,通过调用Java流()方法,我们从交易列表中得到了一个Java流对象。那么数据源就是交易列表,它将向Java流中提供一串元素。然后,我们对该Java流应用了一系列的聚合操作:过滤(提供一个谓语去过滤元素),排序(提供一个比较器去对元素进行排序),以及映射(解析出信息)。所有的操作都会返回该Java流,以便能够链接这些操作去组成一个管道,这可被看作是对数据源的一个查询。 在调用collect()操作之前,没有实际工作会被执行。collect()方法将开始处理这个管道以返回一个结果(某个不是Java流的对象,在此处,是一个List对象)。现在还不需要去关注collect()方法,我们会在以后的文章去一探究竟。此时,你会发现collect会将各种数据加工方法作为参数,将收集到的Java流元素归结为一个结果。此处,toList()就描述了一个将Java流对象转化为List对象的加工方法。 在探究与Java流有关的各个方法之前,最好是停下来深入思考一下Java流和集合之间观念上的不同之处。 Java流 vs. 集合 已有的Java集合概念与新的Java流概念都为一串元素提供了接口。那它们有何不同吗?简单地说,集合是关于数据的,而Java流是关于计算的。 想想这种情况,一部存储在DVD中的电影。这就是一个集合(可能是字节,可能是帧--在此处,我们不必关心这些),因为它包含有全部的数据结构。现在再想想这种情况,这部电影被转化成了数据流,通过互联网去观看它。此时它就是一个(字节或帧的)流。流视频播放器只需要下载一些晚于用户当前所观看位置的帧就可以了。这样,你就可以在大部分值被计算出来之前先展示流开头处的值(想想流化一场现场直播的足球比赛)。 粗看之,集合与流的区别就是与何时处理数据有关。集合是内存中的数据结构,它包含有当前数据结构中的全部值--将所有元素加入到集合之前,必须先对所有元素进行处理,相反地,Java流只是逻辑上固定的数据结构,它里面的元素只会根据需要进行处理。 使用Collection接口,要求用户实现遍历(例如,使用增强的for循环,即foreach);这被称之为外部循环。相反地,Stream类库使用内部遍历--它已经为你实现好了遍历,它会关心存储流的结果值的位置;你仅需要提供一个函数告诉它要做些什么就行了。清单4(对集合的外部遍历)和清单5(对Java流的内部遍历)中的代码形象地展示了这一不同之处。 清单4 List transactionIds = new ArrayList<>(); for(Transaction t: transactions){ transactionIds.add(t.getId()); } 清单5 List transactionIds = transactions.stream() .map(Transaction::getId) .collect(toList()); 在清单4中,我们显式且顺序地遍历了交易列表,抽取了每个交易ID,然后将它加到一个收集器中。相反地,当使用流时,没有显式的遍历。清单5中的代码构建了一个查询,其中的map操作被设定为一个参数,它会抽取交易ID,然后collect操作会把结果Stream对象转化成一个List对象。 你现在应该知道什么是Java流,以及如何去使用它。现在让我们看看Java流所支持的操作之间的区别,这样你就能构建自己的数据查询了。

posted @ 2014-07-28 16:58  java程序源代码  阅读(358)  评论(0编辑  收藏  举报