// Can also be DoubleSummaryStatistics from mapToDouble()
IntSummaryStatistics stats = personList.stream()
.mapToInt(p-> p.getAge())
.summaryStatistics();
stats.getAverage();
stats.getMin();
stats.getMax();
Stream<MyType> stream = // get the stream from somewhere
List<MyType> list = stream.collect(Collectors.toList()); // materialize the stream contents
list.stream().doSomething // create a new stream from the list
list.stream().doSomethingElse // create one more stream from the list
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
// The normal way to use a stream:
List<String> result1 = list.stream()
.filter(i -> i % 2 == 1)
.map(i -> i * i)
.limit(10)
.map(i -> "i :" + i)
.collect(toList());
// The stream operation can be extracted to a local function to
// be reused on multiple sources:
Function<List<Integer>, List<String>> listOperation = l -> l.stream()
.filter(i -> i % 2 == 1)
.map(i -> i * i)
.limit(10)
.map(i -> "i :" + i)
.collect(toList());
List<String> result2 = listOperation.apply(list);
List<String> result3 = listOperation.apply(Arrays.asList(1, 2, 3));
// Or the stream operation can be extracted to a static method,
// if it doesn't refer to any local variables:
List<String> result4 = streamMethod(list);
// The stream operation can also have Stream as argument and return value,
// so that it can be used as a component of a longer stream pipeline:
Function<Stream<Integer>, Stream<String>> streamOperation = s -> s
.filter(i -> i % 2 == 1)
.map(i -> i * i)
.limit(10)
.map(i -> "i :" + i);
List<String> result5 = streamOperation.apply(list.stream().map(i -> i * 2))
.filter(s -> s.length() < 7)
.sorted()
.collect(toCollection(LinkedList::new));
}
public static List<String> streamMethod(List<Integer> l) {
return l.stream()
.filter(i -> i % 2 == 1)
.map(i -> i * i)
.limit(10)
.map(i -> "i :" + i)
.collect(toList());
}
public void test(Stream<Integer> stream) {
// Create a copy of the stream elements
List<Integer> streamCopy = stream.collect(toList());
// Use the copy to get multiple streams
List<Integer> result1 = streamCopy.stream() ...
List<Integer> result2 = streamCopy.stream() ...
}
7条答案
按热度按时间pxiryf3j1#
如果希望具有重用流的效果,可以将流表达式 Package 在一个提供者中并调用
myStreamSupplier.get()
只要你想要一个新的。例如:nbysray52#
根据文件:
流只能操作一次(调用中间或终端流操作)。
如果流实现检测到流正在被重用,它可能会抛出illegalstateexception。
所以答案是否定的,流不是用来重用的。
rkue9o1l3#
正如其他人所说,“不,你不能”。
但是记住手边的
summaryStatistics()
对于许多基本操作:所以不是:
你可以:
wqnecbli4#
这条溪流的全部意思是它是一次性的。这允许您创建不可重入的源(例如,从网络连接读取行),而无需中间存储。但是,如果您希望重用流内容,可以将其转储到中间集合以获取“硬拷贝”:
如果您不想具体化流,在某些情况下,可以同时对同一个流执行多个操作。例如,您可以参考此问题或此问题了解详细信息。
mbzjlibv5#
想想看,这种“重用”流的意愿就是用一个好的内联操作来实现所需结果的意愿。所以,基本上,我们在这里讨论的是,在我们写了一个终端操作之后,我们能做些什么来继续处理?
1) 如果终端操作返回一个集合,那么问题马上就解决了,因为每个集合都可以转换回流(jdk8)。
2) 如果您的终端操作返回一个optional,通过对optional类的jdk 9增强,您可以将可选结果转换为流,并获得所需的nice内联操作:
3) 如果您的终端操作返回其他内容,我真的怀疑您是否应该考虑使用流来处理这样的结果:
8ftvxx2r6#
正如其他人所注意到的,流对象本身不能被重用。
但是获得重用流效果的一种方法是将流创建代码提取到函数中。
您可以通过创建包含流创建代码的方法或函数对象来实现这一点。你可以多次使用它。
例子:
另一方面,如果已经有一个流对象要多次迭代,那么必须将流的内容保存在某个集合对象中。
然后,您可以从该集合中获得具有相同内容的多个流。
例子:
qgzx9mmu7#
函数式java库提供了自己的流,这些流执行您所要求的操作,即它们是内存化的和懒惰的。您可以使用它的转换方法在JavaSDK对象和fj对象之间进行转换,例如。
Java8.JavaStream_Stream(stream)
将返回一个可重用的fj流,给定一个jdk8流。