Javaでの私のHashtableはTuple構造を持つ値から利益を得るでしょう。そのためにJavaで使用できるデータ構造は何ですか?
Hashtable<Long, Tuple<Set<Long>,Set<Long>>> table = ...
Javaには汎用のTupleクラスがあるとは思いませんが、カスタムのものは次のように簡単な場合があります。
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;
}
}
もちろん、インスタンスをハッシュ化のキーとして使用する予定の場合は特に、等価性、不変性などに関してこのクラスを設計する方法には、いくつか重要な影響があります。
javatuples はJavaのタプル専用のプロジェクトです。
Unit<A> (1 element)
Pair<A,B> (2 elements)
Triplet<A,B,C> (3 elements)
Apache Commons は、 Pair を含む一般的なJavaユーティリティをいくつか提供していました。 Map.Entry
、Comparable
、Serializable
を実装しています。
組み込みのJava 2要素Tupleを探しているなら、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に含まれています:)
これとまったく同じ質問が他の場所にあります。これには、より堅牢なequals
、hash
が含まれています。
この議論では、「このような状況に遭遇するたびに、クラスTupleを不特定の名前で再利用するか、新しいクラスを特定の名前で作成する必要があるか」というメリック対ColinDのアプローチを反映しています。何年も前に私は後者のキャンプにいました。私は前者をサポートするように進化しました。
このオブジェクトはequals()の実用的な実装を提供し、equals()が含まれている各オブジェクトでtrueの場合にtrueを返します。
実際にモデル化している概念を説明するクラスを作成してそれを使用します。それはただ2つのSet<Long>
を格納してそれらにアクセサを提供することができますが、それらの各セットが正確に何であるか、そしてそれらが一緒にグループ化されている理由を示すために命名されるべきです。
@ 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;
}
}
この記事は今ではかなり古くなっていますが、あまり役に立ちませんが、その作業はここで行われていると思います: http://www.pds.ewi.tudelft.nl/pubs/papers/cpe2005。 pdf 、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);
タプルは次のとおりです。
このアプローチは増加します
私はJavaのタプルについての一般的な観点から始めて、あなたの具体的な問題への含意で終わります。
1)タプルが非ジェネリック言語で使用される方法は、タイプセーフではないため、Javaでは避けられています(例えばPythonではTuple = (4, 7.9, 'python')
)。それでも汎用Tuple( 推奨されない )のようなものを使用したい場合は、Object[]
またはList<Object>
を使用し、型安全性を保証するためにinstanceof
を使用して要素をキャストしてください。
通常、特定の設定のタプルは、常に同じ構造を含むことで同じ方法で使用されます。 Javaでは、明確に定義されたタイプセーフな値とメソッドを提供するために、この構造体をclass
に明示的に定義する必要があります。これは最初は厄介で不必要なようですが、 compile-time でエラーを防ぐことができます。
2)同じ(スーパー)クラスFoo
を含むTupleが必要な場合は、Foo[]
、List<Foo>
、またはList<? extends Foo>
(またはリストの不変の同等物)を使用してください。タプルは定義された長さではないので、この解決策は同等です。
3)あなたの場合、あなたはPair
(すなわち、明確に定義された長さのTuple 2)を必要としているようです。将来的にコードを再利用することができるので、これはmaericsの答えまたは補足的な答えの1つを最も効率的にします。
Google Guava Table を使用できます