Does Java SE 8 have Pairs or Tuples?

前端 未结 9 835
独厮守ぢ
独厮守ぢ 2020-11-28 18:37

I am playing around with lazy functional operations in Java SE 8, and I want to map an index i to a pair / tuple (i, value[i]), then <

相关标签:
9条回答
  • 2020-11-28 19:25

    It appears that the full example can be solved without the use of any kind of Pair structure. The key is to filter on the column indexes, with the predicate checking the entire column, instead of mapping the column indexes to the number of false entries in that column.

    The code that does this is here:

        System.out.println(
            IntStream.range(0, acyclic_graph.length)
                .filter(i -> IntStream.range(0, acyclic_graph.length)
                                      .noneMatch(j -> acyclic_graph[j][i]))
                .boxed()
                .collect(toList()));
    

    This results in output of [0, 2, 4] which is I think the correct result requested by the OP.

    Also note the boxed() operation that boxes the int values into Integer objects. This enables one to use the pre-existing toList() collector instead having to write out collector functions that do the boxing themselves.

    0 讨论(0)
  • UPDATE: This answer is in response to the original question, Does Java SE 8 have Pairs or Tuples? (And implicitly, if not, why not?) The OP has updated the question with a more complete example, but it seems like it can be solved without using any kind of Pair structure. [Note from OP: here is the other correct answer.]


    The short answer is no. You either have to roll your own or bring in one of the several libraries that implements it.

    Having a Pair class in Java SE was proposed and rejected at least once. See this discussion thread on one of the OpenJDK mailing lists. The tradeoffs are not obvious. On the one hand, there are many Pair implementations in other libraries and in application code. That demonstrates a need, and adding such a class to Java SE will increase reuse and sharing. On the other hand, having a Pair class adds to the temptation of creating complicated data structures out of Pairs and collections without creating the necessary types and abstractions. (That's a paraphrase of Kevin Bourillion's message from that thread.)

    I recommend everybody read that entire email thread. It's remarkably insightful and has no flamage. It's quite convincing. When it started I thought, "Yeah, there should be a Pair class in Java SE" but by the time the thread reached its end I had changed my mind.

    Note however that JavaFX has the javafx.util.Pair class. JavaFX's APIs evolved separately from the Java SE APIs.

    As one can see from the linked question What is the equivalent of the C++ Pair in Java? there is quite a large design space surrounding what is apparently such a simple API. Should the objects be immutable? Should they be serializable? Should they be comparable? Should the class be final or not? Should the two elements be ordered? Should it be an interface or a class? Why stop at pairs? Why not triples, quads, or N-tuples?

    And of course there is the inevitable naming bikeshed for the elements:

    • (a, b)
    • (first, second)
    • (left, right)
    • (car, cdr)
    • (foo, bar)
    • etc.

    One big issue that has hardly been mentioned is the relationship of Pairs to primitives. If you have an (int x, int y) datum that represents a point in 2D space, representing this as Pair<Integer, Integer> consumes three objects instead of two 32-bit words. Furthermore, these objects must reside on the heap and will incur GC overhead.

    It would seem clear that, like Streams, it would be essential for there to be primitive specializations for Pairs. Do we want to see:

    Pair
    ObjIntPair
    ObjLongPair
    ObjDoublePair
    IntObjPair
    IntIntPair
    IntLongPair
    IntDoublePair
    LongObjPair
    LongIntPair
    LongLongPair
    LongDoublePair
    DoubleObjPair
    DoubleIntPair
    DoubleLongPair
    DoubleDoublePair
    

    Even an IntIntPair would still require one object on the heap.

    These are, of course, reminiscent of the proliferation of functional interfaces in the java.util.function package in Java SE 8. If you don't want a bloated API, which ones would you leave out? You could also argue that this isn't enough, and that specializations for, say, Boolean should be added as well.

    My feeling is that if Java had added a Pair class long ago, it would have been simple, or even simplistic, and it wouldn't have satisfied many of the use cases we are envisioning now. Consider that if Pair had been added in the JDK 1.0 time frame, it probably would have been mutable! (Look at java.util.Date.) Would people have been happy with that? My guess is that if there were a Pair class in Java, it would be kinda-sort-not-really-useful and everybody will still be rolling their own to satisfy their needs, there would be various Pair and Tuple implementations in external libraries, and people would still be arguing/discussing about how to fix Java's Pair class. In other words, kind of in the same place we're at today.

    Meanwhile, some work is going on to address the fundamental issue, which is better support in the JVM (and eventually the Java language) for value types. See this State of the Values document. This is preliminary, speculative work, and it covers only issues from the JVM perspective, but it already has a fair amount of thought behind it. Of course there are no guarantees that this will get into Java 9, or ever get in anywhere, but it does show the current direction of thinking on this topic.

    0 讨论(0)
  • 2020-11-28 19:34

    Vavr (formerly called Javaslang) (http://www.vavr.io) provides tuples (til size of 8) as well. Here is the javadoc: https://static.javadoc.io/io.vavr/vavr/0.9.0/io/vavr/Tuple.html.

    This is a simple example:

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

    Why JDK itself did not come with a simple kind of tuples til now is a mystery to me. Writing wrapper classes seems to be an every day business.

    0 讨论(0)
提交回复
热议问题