我正在Java SE 8中使用惰性函数操作,我想将一个索引I映射到一个对/元组(I,值[I]),然后根据第二个值[I]元素进行筛选,最后只输出索引。

我还必须忍受这个问题:Java中的c++ Pair<L,R>等价于什么?在大胆的新时代的lambdas和溪流?

更新:我给出了一个相当简单的例子,在下面的一个答案中,@dkatzel提供了一个简洁的解决方案。然而,它并不能一概而论。因此,让我补充一个更普遍的例子:

package com.example.test;

import java.util.ArrayList;
import java.util.stream.IntStream;

public class Main {

  public static void main(String[] args) {
    boolean [][] directed_acyclic_graph = new boolean[][]{
        {false,  true, false,  true, false,  true},
        {false, false, false,  true, false,  true},
        {false, false, false,  true, false,  true},
        {false, false, false, false, false,  true},
        {false, false, false, false, false,  true},
        {false, false, false, false, false, false}
    };

    System.out.println(
        IntStream.range(0, directed_acyclic_graph.length)
        .parallel()
        .mapToLong(i -> IntStream.range(0, directed_acyclic_graph[i].length)
            .filter(j -> directed_acyclic_graph[j][i])
            .count()
        )
        .filter(n -> n == 0)
        .collect(() -> new ArrayList<Long>(), (c, e) -> c.add(e), (c1, c2) -> c1.addAll(c2))
    );
  }

}

这给出了不正确的输出[0,0,0],它对应于三列的计数都是假的。我需要的是这三列的下标。正确的输出应该是[0,2,4]。我怎样才能得到这个结果?


当前回答

Eclipse Collections具有Pair和原语/对象对的所有组合(对于所有8个原语)。

Tuples工厂可以创建Pair的实例,PrimitiveTuples工厂可以用于创建所有原语/对象对的组合。

我们在Java 8发布之前添加了这些。它们对于实现基元映射的键/值迭代器非常有用,我们也支持所有基元/对象组合。

如果您愿意增加额外的库开销,您可以使用Stuart公认的解决方案,并将结果收集到一个原始IntList中,以避免装箱。我们在Eclipse Collections 9.0中添加了新方法,以允许从Int/Long/Double流创建Int/Long/Double集合。

IntList list = IntLists.mutable.withAll(intStream);

注意:我是Eclipse Collections的提交者。

其他回答

许多第三方库支持元组。例如jOOλ,支持0到16度的元组,例如:

// Assuming this static import
import static org.jooq.lambda.tuple.Tuple.*;

// Write:
var t = tuple(1, "a", 2L);
Integer i = t.v1;
String s = t.v2;
Long l = t.v3;

其他也有元组的库,例如:

反应堆 Javatuples Apache Flink Vavr

你可以看看这些内置类:

AbstractMap。SimpleEntry AbstractMap。SimpleImmutableEntry

Eclipse Collections具有Pair和原语/对象对的所有组合(对于所有8个原语)。

Tuples工厂可以创建Pair的实例,PrimitiveTuples工厂可以用于创建所有原语/对象对的组合。

我们在Java 8发布之前添加了这些。它们对于实现基元映射的键/值迭代器非常有用,我们也支持所有基元/对象组合。

如果您愿意增加额外的库开销,您可以使用Stuart公认的解决方案,并将结果收集到一个原始IntList中,以避免装箱。我们在Eclipse Collections 9.0中添加了新方法,以允许从Int/Long/Double流创建Int/Long/Double集合。

IntList list = IntLists.mutable.withAll(intStream);

注意:我是Eclipse Collections的提交者。

Vavr(以前称为Javaslang) (http://www.vavr.io)也提供元组(til大小为8)。这是javadoc: https://static.javadoc.io/io.vavr/vavr/0.9.0/io/vavr/Tuple.html。

这是一个简单的例子:

Tuple2<Integer, String> entry = Tuple.of(1, "A");

Integer key = entry._1;
String value = entry._2;

为什么JDK本身直到现在还没有提供简单的元组,这对我来说是一个谜。编写包装器类似乎是一项日常工作。

Yes.

地图。条目可以作为Pair使用。

Unfortunately it does not help with Java 8 streams as the problem is that even though lambdas can take multiple arguments, the Java language only allows for returning a single value (object or primitive type). This implies that whenever you have a stream you end up with being passed a single object from the previous operation. This is a lack in the Java language, because if multiple return values was supported AND streams supported them we could have much nicer non-trivial tasks done by streams.

在那之前,它几乎没有什么用处。

Java 16带来了记录,这是解决这个问题和其他问题的一个很好的解决方案。一个非常强烈的理由瞄准即将到来的Java 17 LTS