Fra*_*sco 59 java reusability java-stream
我正在学习新的Java 8功能,在尝试使用streams(java.util.stream.Stream)和收集器时,我意识到流不能使用两次.
有没有办法重复使用它?
Han*_*k D 70
如果您想要重用流,可以将流表达式包装在供应商中,并myStreamSupplier.get()在需要新的流时调用.例如:
Supplier<Stream<String>> sup = () -> someList.stream();
List<String> nonEmptyStrings = sup.get().filter(s -> !s.isEmpty()).collect(Collectors.toList());
Set<String> uniqueStrings = sup.get().collect(Collectors.toSet());
Run Code Online (Sandbox Code Playgroud)
And*_*ejs 25
正如其他人所说,"不,你不能".
但是记住summaryStatistics()许多基本操作的方便是有用的:
所以代替:
List<Person> personList = getPersons();
personList.stream().mapToInt(p -> p.getAge()).average().getAsDouble();
personList.stream().mapToInt(p -> p.getAge()).min().getAsInt();
personList.stream().mapToInt(p -> p.getAge()).max().getAsInt();
Run Code Online (Sandbox Code Playgroud)
您可以:
// Can also be DoubleSummaryStatistics from mapToDouble()
IntSummaryStatistics stats = personList.stream()
.mapToInt(p-> p.getAge())
.summaryStatistics();
stats.getAverage();
stats.getMin();
stats.getMax();
Run Code Online (Sandbox Code Playgroud)
Stream的整个想法是一次性的。这使您无需中间存储即可创建不可重新输入的源(例如,从网络连接读取线路)。但是,如果要重用Stream内容,则可以将其转储到中间集合中以获得“硬拷贝”:
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
Run Code Online (Sandbox Code Playgroud)
如果您不想实现该流,则在某些情况下,可以使用多种方法一次对同一流进行处理。例如,您可以参考这个或这个问题的详细资料。
正如其他人指出的那样,流对象本身无法重用。
但获得重用流效果的一种方法是将流创建代码提取到函数中。
您可以通过创建包含流创建代码的方法或函数对象来完成此操作。然后您可以多次使用它。
例子:
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());
}
Run Code Online (Sandbox Code Playgroud)
另一方面,如果您已经有一个要迭代多次的流对象,那么您必须将流的内容保存在某个集合对象中。
然后,您可以从集合中获取具有相同内容的多个流。
例子:
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() ...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
29378 次 |
| 最近记录: |