当前位置:  开发笔记 > 编程语言 > 正文

Java中C++ Pair <L,R>的等价物是什么?

如何解决《Java中C++Pair<L,R>的等价物是什么?》经验,为你挑选了15个好方法。

有没有一个很好的理由为什么PairJava中没有?这个C++构造的等价物是什么?我宁愿避免重新实现自己.

似乎1.6提供类似的东西(AbstractMap.SimpleEntry),但这看起来很复杂.



1> Luc Touraill..:

在一个线程中comp.lang.java.help,Hunter Gratzner提出了一些反对PairJava中构造的存在的论据.主要论点是一个类Pair没有传达关于两个值之间关系的任何语义(你怎么知道"第一"和"第二"是什么意思?).

更好的做法是为每个应用程序编写一个非常简单的类,就像Mike提出的Pair类一样.Map.Entry是一个在其名称中带有其含义的对的示例.

总而言之,在我看来,最好有一个类Position(x,y),一个类Range(begin,end)和一个类,Entry(key,value)而不是一个通用的Pair(first,second),它不会告诉我它应该做什么.


格拉兹纳正在分裂头发.我们很高兴将单个值作为基元或内置类返回,而不将其封装在类中.如果我们要返回一个十几个元素的元组,没有人会不同意它应该有自己的类.中间的某处是(模糊)分界线.我认为我们的蜥蜴大脑可以轻松应对Pairs.
我同意伊恩的观点.Java允许你返回int; 每次使用时,它都不会强制您为int创建别名.对不是很不一样.
如果我们可以将一对直接解包到您的局部变量,或者将它转发给一个带有两个参数的方法,那么Pair将是一个有用的类.因为我们不能像这样解压缩它,创建一个有意义的类并将值保持在一起看起来并不太糟糕.并且,如果你真的想要一对,尽管有限制,总有对象[2] +演员:-)

2> 小智..:

这是Java.您必须使用描述性类和字段名称来创建自己的定制Pair类,并且不要介意通过编写hashCode()/ equals()或一次又一次地实现Comparable来重新发明轮子.


+1用于模拟Java的冗长.-1实际上没有回答问题.
这不回答"为什么"这个问题.(除非你认为'这是java'的答案)
第一句话是回答"为什么?"的问题.这是Java,就是这样.
如果您指向包含Pair类的Apache Commong Lang,那么Java-mockery就可以了.
或者你可以使用`SimpleImmutableEntry`
如果您从电影300中大喊那位愤怒的斯巴达人,那就更好了。“这……是……JAVA!”

3> arturh..:

HashMap兼容Pair类:

public class Pair {
    private A first;
    private B second;

    public Pair(A first, B second) {
        super();
        this.first = first;
        this.second = second;
    }

    public int hashCode() {
        int hashFirst = first != null ? first.hashCode() : 0;
        int hashSecond = second != null ? second.hashCode() : 0;

        return (hashFirst + hashSecond) * hashSecond + hashFirst;
    }

    public boolean equals(Object other) {
        if (other instanceof Pair) {
            Pair otherPair = (Pair) other;
            return 
            ((  this.first == otherPair.first ||
                ( this.first != null && otherPair.first != null &&
                  this.first.equals(otherPair.first))) &&
             (  this.second == otherPair.second ||
                ( this.second != null && otherPair.second != null &&
                  this.second.equals(otherPair.second))) );
        }

        return false;
    }

    public String toString()
    { 
           return "(" + first + ", " + second + ")"; 
    }

    public A getFirst() {
        return first;
    }

    public void setFirst(A first) {
        this.first = first;
    }

    public B getSecond() {
        return second;
    }

    public void setSecond(B second) {
        this.second = second;
    }
}


您可能想要删除setter,并进行第一和第二次final,从而使该对不可变.(如果有人在将组件用作哈希键后更改了组件,则会发生奇怪的事情).
返回"("+"first.toString()+","+ second.toString()+")"in toString()方法可能会抛出NullPointerExceptions.这样更好:返回"("+ + first +","+ second +")";
抱歉随机的nooby问题,但为什么你在构造函数中调用super()?
另外,要么将对标记为"final",要么将第一行等于'if(other!= null && this.getClass()== other.getClass())'
@Ibrahim:在这种情况下,它是多余的---如果你把`super()`拿出来,行为就完全一样了.通常情况下,如果它是可选的,我会把它丢掉,就像在这里一样.

4> Michael Pief..:

使用Lombok,我能想到的最短的一对是:

@Data
@AllArgsConstructor(staticName = "of")
public class Pair {
    private F first;
    private S second;
}

它具有的所有优点的答案从@arturh(可比性除外),它有hashCode,equals,toString和静态的"构造".



5> Matunos..:

Apache Commons Lang 3.0+有几个Pair类:http: //commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/package-summary.html



6> Peter Lawrey..:

另一种实现Pair的方法.

公共不可变字段,即简单的数据结构.

可比.

简单的哈希和等于.

简单的工厂,所以你不必提供类型.例如Pair.of("你好",1);

public class Pair implements Comparable> {

    public final FIRST first;
    public final SECOND second;

    private Pair(FIRST first, SECOND second) {
        this.first = first;
        this.second = second;
    }

    public static  Pair of(FIRST first,
            SECOND second) {
        return new Pair(first, second);
    }

    @Override
    public int compareTo(Pair o) {
        int cmp = compare(first, o.first);
        return cmp == 0 ? compare(second, o.second) : cmp;
    }

    // todo move this to a helper class.
    private static int compare(Object o1, Object o2) {
        return o1 == null ? o2 == null ? 0 : -1 : o2 == null ? +1
                : ((Comparable) o1).compareTo(o2);
    }

    @Override
    public int hashCode() {
        return 31 * hashcode(first) + hashcode(second);
    }

    // todo move this to a helper class.
    private static int hashcode(Object o) {
        return o == null ? 0 : o.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Pair))
            return false;
        if (this == obj)
            return true;
        return equal(first, ((Pair) obj).first)
                && equal(second, ((Pair) obj).second);
    }

    // todo move this to a helper class.
    private boolean equal(Object o1, Object o2) {
        return o1 == null ? o2 == null : (o1 == o2 || o1.equals(o2));
    }

    @Override
    public String toString() {
        return "(" + first + ", " + second + ')';
    }
}


我喜欢静态工厂方法`of`.它提醒**Google Guava**不可变的收藏品.
你在某些时候将`o1`转换为`Comparable`,即使没有任何东西表明它会实际实现该接口.如果这是一个要求,`FIRST`类型参数应该是`FIRST extends Comparable <?>`.
31是hashCode的坏常量.例如,如果使用由Pair 键入的HashMap用于2D地图,则会发生许多冲突.例如(a*65497)^ b将更适合.

7> cyberoblivio..:

http://www.javatuples.org/index.html怎么样我发现它非常有用.

javatuples为您提供从1到10个元素的元组类:

Unit (1 element)
Pair (2 elements)
Triplet (3 elements)
Quartet (4 elements)
Quintet (5 elements)
Sextet (6 elements)
Septet (7 elements)
Octet (8 elements)
Ennead (9 elements)
Decade (10 elements)


有趣,但至少有5个课程比我想象的要多.
@Boann:好的,我保持纠正.我曾经使用`Pair`并且可以设想每50年使用一次`Triplet`.现在我使用Lombok并在每次需要一对时创建一个小的4行类.所以"10太多"是确切的.
我们需要一个`Bottom(0元素)`类吗?:)
@maaartinus至少比我使用的多10个.
哇,这太丑了.我知道他们试图让它变得明确,但是像C#中那样超载params的元组本来会更好.

8> cletus..:

这取决于你想用它做什么.这样做的典型原因是迭代地图,您只需执行此操作(Java 5+):

Map map = ... ; // just an example
for (Map.Entry entry : map.entrySet()) {
  System.out.printf("%s -> %s\n", entry.getKey(), entry.getValue());
}


"这样做的典型原因是迭代地图".真?

9> sherpya..:

android提供了Pair类(http://developer.android.com/reference/android/util/Pair.html),这里的实现:

public class Pair {
    public final F first;
    public final S second;

    public Pair(F first, S second) {
        this.first = first;
        this.second = second;
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof Pair)) {
            return false;
        }
        Pair p = (Pair) o;
        return Objects.equal(p.first, first) && Objects.equal(p.second, second);
    }

    @Override
    public int hashCode() {
        return (first == null ? 0 : first.hashCode()) ^ (second == null ? 0 : second.hashCode());
    }

    public static  Pair  create(A a, B b) {
        return new Pair(a, b);
    }
}


将其更改为自2011年开始使用Java(1.7)以来的Objects.equals(...)。

10> Mr_and_Mrs_D..:

最大的问题可能是无法确保A和B的不变性(请参阅如何确保类型参数是不可变的)因此hashCode()可能会插入集合之后为同一对提供不一致的结果(这会产生未定义的行为) ,请参阅根据可变字段定义等于).对于特定(非泛型)Pair类,程序员可以通过仔细选择A和B为不可变来确保不变性.

无论如何,从@ PeterLawrey的答案中清除泛型的警告(java 1.7):

public class Pair,
                    B extends Comparable>
        implements Comparable> {

    public final A first;
    public final B second;

    private Pair(A first, B second) {
        this.first = first;
        this.second = second;
    }

    public static ,
                    B extends Comparable>
            Pair of(A first, B second) {
        return new Pair(first, second);
    }

    @Override
    public int compareTo(Pair o) {
        int cmp = o == null ? 1 : (this.first).compareTo(o.first);
        return cmp == 0 ? (this.second).compareTo(o.second) : cmp;
    }

    @Override
    public int hashCode() {
        return 31 * hashcode(first) + hashcode(second);
    }

    // TODO : move this to a helper class.
    private static int hashcode(Object o) {
        return o == null ? 0 : o.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Pair))
            return false;
        if (this == obj)
            return true;
        return equal(first, ((Pair) obj).first)
                && equal(second, ((Pair) obj).second);
    }

    // TODO : move this to a helper class.
    private boolean equal(Object o1, Object o2) {
        return o1 == o2 || (o1 != null && o1.equals(o2));
    }

    @Override
    public String toString() {
        return "(" + first + ", " + second + ')';
    }
}

非常欢迎添加/更正:)特别是我对我的使用不太确定Pair.

有关此语法原因的详细信息,请参阅确保对象实现Comparable以及详细说明如何max(Comparable a, Comparable b)在Java中实现泛型函数?



11> RAJAN_PARMAR..:

好消息JavaFX具有关键价值。

只需将javafx添加为依赖项并导入javafx.util.Pair

并像中那样简单地使用c++

Pair  

例如

Pair  pr = new Pair()

pr.get(key);// will return corresponding value



12> 小智..:

在我看来,Java中没有Pair,因为如果你想直接在对上添加额外的功能(例如Comparable),你必须绑定类型.在C++中,我们只是不关心,如果组成一对的类型没有operator <,那么pair::operator <也不会编译.

没有边界的可比较的示例:

public class Pair implements Comparable> {
    public final F first;
    public final S second;
    /* ... */
    public int compareTo(Pair that) {
        int cf = compare(first, that.first);
        return cf == 0 ? compare(second, that.second) : cf;
    }
    //Why null is decided to be less than everything?
    private static int compare(Object l, Object r) {
        if (l == null) {
            return r == null ? 0 : -1;
        } else {
            return r == null ? 1 : ((Comparable) (l)).compareTo(r);
        }
    }
}

/* ... */

Pair> a = /* ... */;
Pair> b = /* ... */;
//Runtime error here instead of compile error!
System.out.println(a.compareTo(b));

Comparable与编译时检查的示例是否类型参数具有可比性:

public class Pair<
        F extends Comparable, 
        S extends Comparable
> implements Comparable> {
    public final F first;
    public final S second;
    /* ... */
    public int compareTo(Pair that) {
        int cf = compare(first, that.first);
        return cf == 0 ? compare(second, that.second) : cf;
    }
    //Why null is decided to be less than everything?
    private static <
            T extends Comparable
    > int compare(T l, T r) {
        if (l == null) {
            return r == null ? 0 : -1;
        } else {
            return r == null ? 1 : l.compareTo(r);
        }
    }
}

/* ... */

//Will not compile because Thread is not Comparable
Pair> a = /* ... */;
Pair> b = /* ... */;
System.out.println(a.compareTo(b));

这很好,但是这次你可能不会在Pair中使用非可比类型作为类型参数.在某些实用程序类中,可能会使用大量的Comparators for Pair,但C++人员可能无法获得它.另一种方法是在类型层次结构中编写许多类,在类型参数上使用不同的边界,但是有太多可能的边界及其组合......



13> Peter Goetz..:

正如许多其他人已经说过的那样,如果Pair类是否有用,它实际上取决于用例.

我认为对于私有帮助函数来说,使用Pair类是完全合法的,如果这样可以使代码更具可读性,并且不值得创建具有所有样板代码的另一个值类.

另一方面,如果您的抽象级别要求您清楚地记录包含两个对象或值的类的语义,那么您应该为它编写一个类.通常情况下,如果数据是业务对象.

一如既往,它需要熟练的判断.

对于第二个问题,我建议使用Apache Commons库中的Pair类.那些可能被视为Java的扩展标准库:

https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/Pair.html

您可能还想看看Apache Commons的EqualsBuilder,HashCodeBuilder和ToStringBuilder,它们简化了为业务对象编写值类的过程.



14> CarrKnight..:

JavaFX(与Java 8捆绑在一起)具有Pair



15> Sathyanaraya..:

您可以使用javafx实用程序类,Pair其作用与c ++中的pair <>相同。https://docs.oracle.com/javafx/2/api/javafx/util/Pair.html

推荐阅读
可爱的天使keven_464
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有