Java SE 8有Pairs或Tuples吗? [英] Does Java SE 8 have Pairs or Tuples?

查看:102
本文介绍了Java SE 8有Pairs或Tuples吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Java SE 8中玩懒惰的函数操作,我想要 map 索引 i 到基于第二个<$ c $>的一对/元组(i,value [i]),然后过滤器 c> value [i] 元素,最后输出索引。



我必须忍受这个:在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,true,false,true},
{false,false,false,true,
{false,false,false,false,true,true},
{false,false,false,false,true},
{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] ,这对应于所有三列的 counts 。我需要的是这三列的索引。正确的输出应该是 [0,2,4] 。如何获得此结果?

解决方案

更新:此答案是对原始问题的回应, Java SE 8是否有Pairs或Tuples?(隐含的,如果不是的话,为什么不呢?)OP已经用更完整的例子更新了这个问题,但似乎可以在不使用任何类型的Pair结构。 [来自OP的注意事项:这里是其他正确答案。]






简短的答案是否定的。您必须自己推出或引入其中一个实现它的库。



拥有 Pair Java SE中的类被提出并拒绝了至少一次。请参阅此讨论主题 OpenJDK邮件列表。权衡不明显。一方面,在其他库和应用程序代码中有许多Pair实现。这证明了需求,并且将这样的类添加到Java SE将增加重用和共享。另一方面,拥有Pair类增加了从Pairs和Collections中创建复杂数据结构的诱惑,而无需创建必要的类型和抽象。 (这是一个 Kevin Bourillion的消息从那个线程。)



我建议大家阅读整个电子邮件线程。这是非常有见识的,没有任何异议。这很有说服力。当它开始时,我想,是的,Java SE中应该有一个Pair类,但是当线程到达结束时,我改变了主意。



注意不过,JavaFX具有 javafx.util.Pair 类。 JavaFX的API与Jav​​a SE API分开发展。



从链接问题可以看出什么是Java中C ++ Pair的等价物?围绕什么显然是这样的,有相当大的设计空间一个简单的API。对象应该是不可变的吗?它们应该是可序列化的吗?它们应该是可比的吗?班级是否最终决定?这两个要素是否应该订购?它应该是一个接口还是一个类?为什么要停止对?为什么不使用三元组,四元组或N元组?

当然,这些元素的命名是不可避免的:
$ b $ (一,二)

  • (左,右) li>
  • (car,cdr)

  • (foo,bar)

  • etc。


    几乎没有提到的一个大问题是对与原语的关系。如果您有一个代表二维空间中一个点的(int x,int y)数据,则表示为 Pair< Integer,Integer> code>消耗三个对象而不是两个32位字。此外,这些对象必须驻留在堆上,并且会导致GC开销。



    看起来很清楚,像Streams一样,对于原始专业化来说,对。我们希望看到:

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

    即使是 IntIntPair 仍然需要堆上的一个对象。



    当然,这些让人想起 java.util中函数接口的增加。函数在Java SE 8中的包。如果你不想要一个臃肿的API,你会抛弃哪些?你也可以争辩说这还不够,还应该添加专门技术,例如布尔



    我的感觉是,如果Java早就添加了Pair类,那么它会很简单,甚至是简单化,并且它不会满足我们现在想象的许多用例。考虑一下,如果Pair已经在JDK 1.0时间框架中添加了,它可能会是可变的! (查看java.util.Date。)人们会对此感到满意吗?我的猜测是,如果在Java中有一个Pair类,它就会有点不太实用,并且每个人都会继续自己来满足他们的需求,外部库中会有各种Pair和Tuple实现,人们仍然会争论/讨论如何修复Java的Pair类。换句话说,就是我们今天在同一个地方。

    同时,一些工作正在解决基本问题,这是更好的支持。 JVM(并且最终是Java语言)用于值类型。请参阅此价值状态文档。这是初步的,投机性的工作,它只涵盖JVM视角的问题,但它背后已经有相当多的想法。当然,没有任何保证可以进入到Java 9中,或者到任何地方,但它确实显示了这个主题的当前思路。


    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 filter based on the second value[i] element, and finally output just the indices.

    Must I still suffer this: What is the equivalent of the C++ Pair<L,R> in Java? in the bold new era of lambdas and streams?

    Update: I presented a rather simplified example, which has a neat solution offered by @dkatzel in one of the answers below. However, it does not generalize. Therefore, let me add a more general example:

    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))
        );
      }
    
    }
    

    This gives incorrect output of [0, 0, 0] which corresponds to the counts for the three columns that are all false. What I need are the indices of these three columns. The correct output should be [0, 2, 4]. How can I get this result?

    解决方案

    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.

    这篇关于Java SE 8有Pairs或Tuples吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆