Java中没有Pair<L,R>,有什么好理由吗?与这个c++构造等价的是什么?我宁愿避免重新实现我自己的。

似乎1.6提供了类似的东西(AbstractMap.SimpleEntry<K,V>),但这看起来相当复杂。


当前回答

试试VAVR元组。

vavr不仅有一组很好的元组类型,而且对函数式编程也有很好的支持。

其他回答

简单的方法Object[] -可以作为一个几何体元组使用

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

javatuples提供了从一到十个元素的元组类:

Unit<A> (1 element)
Pair<A,B> (2 elements)
Triplet<A,B,C> (3 elements)
Quartet<A,B,C,D> (4 elements)
Quintet<A,B,C,D,E> (5 elements)
Sextet<A,B,C,D,E,F> (6 elements)
Septet<A,B,C,D,E,F,G> (7 elements)
Octet<A,B,C,D,E,F,G,H> (8 elements)
Ennead<A,B,C,D,E,F,G,H,I> (9 elements)
Decade<A,B,C,D,E,F,G,H,I,J> (10 elements)

如果有人想要一个简单易用的版本,我在https://github.com/lfac-pt/Java-Pair上提供了我的版本。此外,非常欢迎改进!

正如许多人已经指出的那样,Pair类是否有用实际上取决于用例。

我认为,对于私有帮助函数,如果使用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,它们简化了为业务对象编写值类的过程。

最大的问题可能是不能确保A和B上的不可变(参见如何确保类型参数是不可变的),因此hashCode()在插入到集合后可能会为相同的Pair给出不一致的结果(这将给出未定义的行为,参见定义可变字段中的equals)。对于一个特定的(非泛型的)Pair类,程序员可以通过仔细选择a和B为不可变来确保不可变性。

不管怎样,从@PeterLawrey的回答中清除泛型的警告(java 1.7):

public class Pair<A extends Comparable<? super A>,
                    B extends Comparable<? super B>>
        implements Comparable<Pair<A, B>> {

    public final A first;
    public final B second;

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

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

    @Override
    public int compareTo(Pair<A, B> 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<?, ? >。

有关为什么这种语法的更多信息,请参阅确保对象实现可比和详细解释如何在Java中实现一个通用的max(可比a,可比b)函数?