在Java中使用对或2元组

我在Java中的哈希表将受益于具有元组结构的值。 我可以在Java中使用哪种数据结构来做到这一点?

Hashtable<Long, Tuple<Set<Long>,Set<Long>>> table = ... 

我不认为在Java中有一个通用的元组类,但是一个自定义的类可能如下所示:

 public class Tuple<X, Y> { public final X x; public final Y y; public Tuple(X x, Y y) { this.x = x; this.y = y; } } 

当然,如何在平等,不变性等方面进一步devise这个类还有一些重要的含义,特别是如果你打算把实例用作散列的关键字。

javatuples是Java 中元组的专用项目。

 Unit<A> (1 element) Pair<A,B> (2 elements) Triplet<A,B,C> (3 elements) 

Apache Commons提供了一些常见的Java工具,包括Pair 。 它实现了Map.EntryComparableSerializable

如果您正在查找内置的Java二元元组,请尝试AbstractMap.SimpleEntry

作为@maerics很好的答案的扩展,我已经添加了一些有用的方法:

 public class Tuple<X, Y> { public final X x; public final Y y; public Tuple(X x, Y y) { this.x = x; this.y = y; } @Override public String toString() { return "(" + x + "," + y + ")"; } @Override public boolean equals(Object other) { if (other == this) { return true; } if (!(other instanceof Tuple)){ return false; } Tuple<X,Y> other_ = (Tuple<X,Y>) other; // this may cause NPE if nulls are valid values for x or y. The logic may be improved to handle nulls properly, if needed. return other_.x.equals(this.x) && other_.y.equals(this.y); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((x == null) ? 0 : x.hashCode()); result = prime * result + ((y == null) ? 0 : y.hashCode()); return result; } } 

另外2美分:从Java 7开始,在标准Lib:javafx.util.Pair中有一个类。

是的,这是标准的Java,现在JavaFx包含在JDK中:)

这里有一个完全相同的问题,其中包括一个更强大的equalshash ,maerics暗指:

http://groups.google.com/group/comp.lang.java.help/browse_thread/thread/f8b63fc645c1b487/1d94be050cfc249b

这个讨论继续反映了maerics与ColinD的方法:“我应该重新使用一个非特定名称的类组合,还是每次遇到这种情况时都要创build一个具有特定名称的新类”。 几年前,我在后者的营地。 我已经演变成支持前者。

Android Tuple Utils

这个对象提供了equals()的一个合理的实现,如果equals()对每个包含的对象都是true,则返回true。

为了补充@ maerics的答案,这里是可Comparable元组:

 import java.util.*; /** * A tuple of two classes that implement Comparable */ public class ComparableTuple<X extends Comparable<? super X>, Y extends Comparable<? super Y>> extends Tuple<X, Y> implements Comparable<ComparableTuple<X, Y>> { public ComparableTuple(X x, Y y) { super(x, y); } /** * Implements lexicographic order */ public int compareTo(ComparableTuple<X, Y> other) { int d = this.x.compareTo(other.x); if (d == 0) return this.y.compareTo(other.y); return d; } } 

创build一个描述你实际build模和使用的概念的类。 它可以只存储两个Set<Long>并为它们提供访问器,但是它应该被命名以指示这些集合中的每一个是什么以及它们为什么被组合在一起。

使用lombok可以很容易地声明一个Pair类:

 @Data(staticConstructor = "of") public class Pair<A, B> { private final A left; private final B right; } 

这将生成getter,名为“of”的静态构造函数, equals()hashcode()toString()

请参阅@Data文档以获取更多信息

你可以使用谷歌番石榴表

通过适当的格式,使其更适合新开发者,并修复Aram Kocharyan的equals()函数中的错误。

 package ReplaceThisPackageName; import java.util.Objects; public class Pair<X, Y> extends Object{ public final X left; public final Y right; public Pair(X left, Y right) { this.left = left; this.right = right; } @Override public String toString() { return "(" + left + "," + right + ")"; } @Override public boolean equals(Object other) { if (other == null) { return false; } if (other == this) { return true; } if (!(other instanceof Pair)) { return false; } Pair<X, Y> other_ = (Pair<X, Y>) other; return Objects.equals(other_.left, this.left) && Objects.equals(other_.right, this.right); } @Override public int hashCode() { final int prime = 13; int result = 1; result = prime * result + ((left == null) ? 0 : left.hashCode()); result = prime * result + ((right == null) ? 0 : right.hashCode()); return result; } } 

虽然这篇文章现在已经很老了,尽pipe我明白我并不是很有帮助,但我认为这里所做的工作是: http : //www.pds.ewi.tudelft.nl/pubs/papers/cpe2005.pdf ,在主stream的Java中会很不错。

你可以做这样的事情:

 int a; char b; float c; [a,b,c] = [3,'a',2.33]; 

要么

 [int,int,char] x = [1,2,'a']; 

要么

 public [int,boolean] Find(int i) { int idx = FindInArray(A,i); return [idx,idx>=0]; } [idx, found] = Find(7); 

这里的元组是:

  • 定义为基本types – 没有模板/generics
  • 如果在本地声明,则分配堆栈
  • 使用模式匹配进行分配

这种方法增加了

  • 性能
  • 可读性
  • performance

我将从关于Java中的元组的一般观点出发,结束对具体问题的暗示。

1)元组在非generics语言中使用的方式在Java中是避免的,因为它们不是types安全的(例如,在Python中: tuple = (4, 7.9, 'python') )。 如果你仍然想使用通用元组(这是不推荐的 ),你应该使用Object[]或者List<Object>并且在通过instanceof检查之后进行元素转换,以确保types安全。

通常,在某个设置中的元组总是以相同的方式使用,包含相同的结构。 在Java中,您必须在class明确定义此结构,以提供定义良好的types安全的值和方法。 这起初看起来令人讨厌且不必要,但是在编译时已经可以防止错误了。

2)如果你需要一个包含相同(超)类Foo的元组,使用Foo[]List<Foo>或者List<? extends Foo> List<? extends Foo> (或列表的不可变对象)。 由于元组不是定义长度,所以这个解决scheme是等价的。

3)在你的情况下,你似乎需要一个Pair (即一个明确定义长度2的元组)。 这使得maerics的答案或补充答案之一是最有效的,因为你可以在将来重用代码。