标签: java-stream

Arrays.asList与Arrays.stream一起使用forEach()

如果您有一个Array并且想要使用Java8 forEach()方法,那么哪种方法更好或更有效:

Arrays.asList(new String[]{"hallo","hi"}).forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

要么

Arrays.stream(new String[]{"hallo","hi"}).forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

差异是显着的还是有更好的解决方案来解决这个问题?

java lambda java-8 java-stream

14
推荐指数
2
解决办法
8564
查看次数

连接并行流

假设我有两个int[]数组input1和input2.我想从第一个中取正数,从第二个中取出不同的数字,将它们合并在一起,排序并存储到结果数组中.这可以使用流执行:

int[] result = IntStream.concat(Arrays.stream(input1).filter(x -> x > 0), 
                   Arrays.stream(input2).distinct()).sorted().toArray();
Run Code Online (Sandbox Code Playgroud)

我想加快任务,所以我考虑使流并行.通常这只意味着我可以.parallel()在流构造和终端操作之间插入任何地方,结果将是相同的.IntDream.concat的JavaDoc 表示如果任何输入流是并行的,则生成的流将是并行的.所以,我认为做parallel()任何input1流或input2流或级联的流将产生相同的结果.

实际上我错了:如果我添加.parallel()到结果流,似乎输入流保持顺序.此外,我可以将输入流(它们中的任何一个或两者)标记为.parallel(),然后将结果流转换为.sequential(),但输入保持平行.所以实际上有8种可能性:input1,input2和连接流都可以是并行的:

int[] sss = IntStream.concat(Arrays.stream(input1).filter(x -> x > 0),
                Arrays.stream(input2).distinct()).sorted().toArray();
int[] ssp = IntStream.concat(Arrays.stream(input1).filter(x -> x > 0),
                Arrays.stream(input2).distinct()).parallel().sorted().toArray();
int[] sps = IntStream.concat(Arrays.stream(input1).filter(x -> x > 0), 
                Arrays.stream(input2).parallel().distinct()).sequential().sorted().toArray();
int[] spp = IntStream.concat(Arrays.stream(input1).filter(x -> x > 0), 
                Arrays.stream(input2).parallel().distinct()).sorted().toArray();
int[] pss = IntStream.concat(Arrays.stream(input1).parallel().filter(x -> x > 0),
                Arrays.stream(input2).distinct()).sequential().sorted().toArray(); …
Run Code Online (Sandbox Code Playgroud)

java parallel-processing java-8 java-stream

14
推荐指数
1
解决办法
1000
查看次数

如何将Java流转换为滑动窗口?

将流转换为滑动窗口的推荐方法是什么?

例如,在Ruby中你可以使用each_cons:

irb(main):020:0> [1,2,3,4].each_cons(2) { |x| puts x.inspect }
[1, 2]
[2, 3]
[3, 4]
=> nil
irb(main):021:0> [1,2,3,4].each_cons(3) { |x| puts x.inspect }
[1, 2, 3]
[2, 3, 4]
=> nil
Run Code Online (Sandbox Code Playgroud)

在Guava中,我发现只有Iterators#partition,它是相关的但没有滑动窗口:

final Iterator<List<Integer>> partition =
   Iterators.partition(IntStream.range(1, 5).iterator(), 3);
partition.forEachRemaining(System.out::println);
-->
[1, 2, 3]
[4]
Run Code Online (Sandbox Code Playgroud)

java java-8 java-stream

14
推荐指数
4
解决办法
7406
查看次数

Java Streams:获取按内部映射键分组的值

我有Map<A, Map<B, C>>,我想Map<B, List<C>>使用Java Streams 从中获取.

我尝试按如下方式进行:

public <A, B, C> Map<B, List<C>> groupsByInnerKey(Map<A, Map<B, C>> input) {
    return input.values()
            .stream()
            .flatMap(it -> it.entrySet().stream())
            .collect(Collectors.groupingBy(Map.Entry::getKey));
}
Run Code Online (Sandbox Code Playgroud)

我期待的是:

  • flatMap给人Stream的Map.Entry<B, C>
  • collect(Collectors.groupingBy(...))获取应用于Map.Entry<B, C>和返回的函数B,从而收集C到的值List<C>.

但它没有编译,字面意思:

无法从静态上下文引用非静态方法

在Map.Entry::getKey最后一行.

有人可以解释什么是错的或什么是实现我想要的正确方法?

java grouping java-8 java-stream collectors

14
推荐指数
2
解决办法
4029
查看次数

Java流过滤特定索引的项目

我正在寻找一种简洁的方法来过滤掉特定索引中List中的项目.我的示例输入如下所示:

List<Double> originalList = Arrays.asList(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0);
List<Integer> filterIndexes = Arrays.asList(2, 4, 6, 8);
Run Code Online (Sandbox Code Playgroud)

我想筛选出的索引项2,4,6,8.我有一个for循环跳过与索引匹配的项目,但我希望有一种简单的方法可以使用流来完成.最终结果如下:

List<Double> filteredList = Arrays.asList(0.0, 1.0, 3.0, 5.0, 7.0, 9.0, 10.0);
Run Code Online (Sandbox Code Playgroud)

java java-8 java-stream

14
推荐指数
2
解决办法
1万
查看次数

为什么Stream#reduce没有隐式接受处理超类型元素的累积函数?

考虑这些类和累积函数,它们代表了我原始上下文的简化(但是再现了同样的问题):

abstract static class Foo {
    abstract int getK();
}
static class Bar extends Foo {
    int k;
    Bar(int k) { this.k = k; }
    int getK() { return this.k; }
}

private static Foo combined(Foo a1, Foo a2) {
    return new Bar(a1.getK() + a2.getK());
}
Run Code Online (Sandbox Code Playgroud)

我试图通过依赖单独的函数来执行项目的累积(最初的数据索引报告)combined,该函数直接处理类型的元素Foo.

Foo outcome = Stream.of(1,2,3,4,5)
        .map(Bar::new)
        .reduce((a,b) -> combined(a, b))
        .get();
Run Code Online (Sandbox Code Playgroud)

事实证明,此代码导致编译错误(OpenJDK"1.8.0_92"):"lambda表达式中的错误返回类型:Foo无法转换为Bar".编译器坚持尝试使用Bar累积元素来减少流,即使Foo累积函数的参数和返回类型都有公共类型.

我还发现,只要我明确地将流映射到Foos 流中,我仍然可以采用这种方法:

Foo outcome = Stream.of(1,2,3,4,5)
        .<Foo>map(Bar::new)
        .reduce((a,b) -> combined(a, …
Run Code Online (Sandbox Code Playgroud)

java type-inference java-8 java-stream

14
推荐指数
3
解决办法
630
查看次数

Java flatmap Iterator <Pair <Stream <A>,Stream <B >>>对<Stream <A>,Stream <B >>

我正在尝试使用以下签名实现一个方法:

public static <A,B> Pair<Stream<A>, Stream<B>> flatten(Iterator<Pair<Stream<A>, Stream<B>>> iterator);
Run Code Online (Sandbox Code Playgroud)

方法的目标是将每个流类型展平为单个流并将输出包装成一对.我只有一个迭代器(不是Iterable),我不能改变方法签名,所以我必须在一次迭代中执行展平.

我目前最好的实施是

public static <A,B> Pair<Stream<A>, Stream<B>> flatten(Iterator<Pair<Stream<A>, Stream<B>> iterator) {
    Stream<A> aStream = Stream.empty();
    Stream<B> bStream = Stream.empty();
    while(iterator.hasNext()) {
        Pair<Stream<A>, Stream<B>> elm = iterator.next();
        aStream = Stream.concat(aStream, elm.first);
        bStream = Stream.concat(bStream, elm.second);
    }
    return Pair.of(aStream, bStream);
}
Run Code Online (Sandbox Code Playgroud)

虽然这在技术上是正确的,但我对此并不十分满意,原因有两个:

  1. Stream.concat警告不要这样做,因为它可能导致StackOverflowError.
  2. 在风格上,我宁愿它是纯粹的功能,如果可能的话,而不是必须遍历迭代器并重新分配流.

感觉Stream#flatMap应该适合这里(在使用Guava的Streams.stream(Iterator)将输入Iterator转换为Stream之后,但由于中间的Pair类型,它似乎不起作用.

另外一个要求是任何迭代器/流可能非常大(例如,输入可能包含从一对极大的流到一个项目流中的许多流的任何地方),因此理想情况下,解决方案不应包含收集结果. - 记忆收藏.

java java-8 java-stream

14
推荐指数
2
解决办法
1211
查看次数

Java流是连续阶段的吗?

我对中间阶段的顺序的状态的问题-从施加到一个阶段的操作的所有输入流(项目)或是所有级/操作施加到各流项目?

我知道这个问题可能不容易理解,所以我举一个例子.在以下流处理中:

List<String> strings = Arrays.asList("Are Java streams intermediate stages sequential?".split(" "));
strings.stream()
           .filter(word -> word.length() > 4)
           .peek(word -> System.out.println("f: " + word))
           .map(word -> word.length())
           .peek(length -> System.out.println("m: " + length))
           .forEach(length -> System.out.println("-> " + length + "\n"));
Run Code Online (Sandbox Code Playgroud)

我对这段代码的期望是它会输出:

f: streams
f: intermediate
f: stages
f: sequential?

m: 7
m: 12
m: 6
m: 11

-> 7
-> 12
-> 6
-> 11
Run Code Online (Sandbox Code Playgroud)

相反,输出是:

f: streams
m: 7
-> 7

f: intermediate
m: …
Run Code Online (Sandbox Code Playgroud)

java lambda java-8 java-stream

14
推荐指数
1
解决办法
1768
查看次数

Java流操作调用

任何人都可以指向官方Java文档,该文档描述了Stream将为每个元素调用每个"非干扰和无状态"中间操作的次数.

例如:

Arrays.asList("1", "2", "3", "4").stream()
        .filter(s -> check(s))
        .forEach(s -> System.out.println(s));

public boolean check(Object o) {
    return true;
} 
Run Code Online (Sandbox Code Playgroud)

以上目前将调用check方法4次.

是否有可能在JDK的当前版本或未来版本中,该check方法的执行次数多于或少于从List或任何其他标准Java API创建的流中的元素数量?

java java-8 java-stream

14
推荐指数
1
解决办法
395
查看次数

如何懒惰地评估嵌套的 flatMap

我试图从两个潜在的无限流中召唤一个笛卡尔积,然后我通过limit().

到目前为止,这(大约)是我的策略:

@Test
void flatMapIsLazy() {
        Stream.of("a", "b", "c")
            .flatMap(s -> Stream.of("x", "y")
                .flatMap(sd -> IntStream.rangeClosed(0, Integer.MAX_VALUE)
                    .mapToObj(sd::repeat)))
            .map(s -> s + "u")
            .limit(20)
            .forEach(System.out::println);
}
Run Code Online (Sandbox Code Playgroud)

这不起作用。

显然,我的第二个流在第一次在管道上使用时就被当场进行了最终评估。它不会产生我可以按照自己的节奏使用的惰性流。

我认为.forEach这段代码中的原因ReferencePipeline#flatMap是:

@Override
public void accept(P_OUT u) {
    try (Stream<? extends R> result = mapper.apply(u)) {
        if (result != null) {
            if (!cancellationRequestedCalled) {
               result.sequential().forEach(downstream);
            }
            else {
                var s = result.sequential().spliterator();
                do { } while (!downstream.cancellationRequested() && s.tryAdvance(downstream));
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望上面的代码返回 20 …

java cartesian-product lazy-evaluation java-stream

14
推荐指数
1
解决办法
312
查看次数