ste*_*fen 6 java java-8 java-stream
如何通过位置从Stream中提取两个元素?例如,我试图从a中提取元素0和1(这些数字是任意的!)Stream<String>.一个天真的方法是:
List<String> strings = Arrays.asList("s0", "s1", "s2", "s3", "s4");
Consumer<String> c0 = s -> System.out.println("c0.accept(" + s + ")");
Consumer<String> c1 = s -> System.out.println("c1.accept(" + s + ")");
strings.stream().skip(0).peek(c0).skip(1).peek(c1).findAny();
Run Code Online (Sandbox Code Playgroud)
这会产生以下输出:
c0.accept(s0)
c0.accept(s1)
c1.accept(s1)
Run Code Online (Sandbox Code Playgroud)
我明白这是因为s0它将进入流,遇到skip(0),然后peek(c0)(它给出第一行)然后skip(1),它将跳过这个元素,然后显然继续从流的开头的下一个元素.
我以为我可以使用这些消费者来提取字符串,但c0会被第二个元素覆盖:
String[] extracted = new String[2];
c0 = s -> extracted[0];
c1 = s -> extracted[1];
Run Code Online (Sandbox Code Playgroud)
编辑:
这些是流的特征:
鉴于您的限制,您可以将limit()与自定义收集器结合起来,如下所示:
public static <T, A, R> Collector<T, ?, R> collectByIndex(Set<Integer> wantedIndices,
Collector<T, A, R> downstream) {
class Acc {
int pos;
A acc = downstream.supplier().get();
}
return Collector.of(Acc::new, (acc, t) -> {
if(wantedIndices.contains(acc.pos++))
downstream.accumulator().accept(acc.acc, t);
}, (a, b) -> {throw new UnsupportedOperationException();}, // combining not supported
acc -> downstream.finisher().apply(acc.acc));
}
Run Code Online (Sandbox Code Playgroud)
这Set<Integer> wantedIndices是包含所需元素索引的集合(不限于 2)。用法:
Set<Integer> wantedIndices = new HashSet<>(Arrays.asList(1, 3));
Stream<String> input = Stream.of("s0", "s1", "s2", "s3", "s4");
List<String> result = input.limit(Collections.max(wantedIndices)+1)
.collect(collectByIndex(wantedIndices, Collectors.toList()));
// [s1, s3]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
469 次 |
| 最近记录: |