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());
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();
您可以:
// Can also be DoubleSummaryStatistics from mapToDouble()
IntSummaryStatistics stats = personList.stream()
                                       .mapToInt(p-> p.getAge())
                                       .summaryStatistics();
stats.getAverage();
stats.getMin();
stats.getMax();
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
如果您不想实现该流,则在某些情况下,可以使用多种方法一次对同一流进行处理。例如,您可以参考这个或这个问题的详细资料。
正如其他人指出的那样,流对象本身无法重用。
但获得重用流效果的一种方法是将流创建代码提取到函数中。
您可以通过创建包含流创建代码的方法或函数对象来完成此操作。然后您可以多次使用它。
例子:
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() ...
}
| 归档时间: | 
 | 
| 查看次数: | 29378 次 | 
| 最近记录: |