私のプログラムでは、Map を 2 つのキー (整数) で使用したいと考えています。私の最初のアイデアは、整数を何らかの方法で文字列に結合することでした。
String key = k1.toString()+"-"+k2.toString();
この解決策は私には良くありませんでした:1)醜い。2) 遅い (数値をテキストとして扱う)。
ここで、stackoverflow で他のアプローチを発見しました。それらは、整数を 1 つのクラス (1 つの目的クラス (MyKey)、またはより一般的なクラス (Pair)) にカプセル化することに基づいていました。
いくつかの速度テストを実行しようとしましたが、私のダミー ソリューションが最速のようです。最初のショットの後、変換整数文字列を新しいクラス (MyString) にカプセル化し、このソリューションに対してもテストを実行しようとしました。
マップの定義は次のとおりです。
Map<Pair<Integer,Integer>,String> map1 = new HashMap<>();
Map<MyKey,String> map2 = new HashMap<>();
Map<String,String> map3 = new HashMap<>();
Map<MyString,String> map4 = new HashMap<>();
テスト結果は次のとおりです(複数回実行され、安定しているようです):
map: put+get=total
1: 52+154=206
2: 29+77=106
3: 23+49=72
3: 17+55=72
文字列を使用したソリューションは高速です。文字列キーの直接連結は、検索時は速く、入力時は遅くなります。
私の質問は次のとおりです。
1) String を使用したソリューションの方が速いのはなぜですか? (hashCode() の 1 回の呼び出し?)
2) String を使用したソリューションであってはならない理由はありますか?
追加情報:
マップ内のレコード数は約 6000 でした。
テストは、多くの存在しないキーの値も取得しようとしました。テスト結果が変わる可能性はありますか?
私のプログラムでは、M 値が true である boolean[N] の順列を生成します。一度、特定の N,M の結果を取得します。また必要になったときのために保管しておきたいと思います。
そして、これが私の例で使用されているクラスの完全なコードです:
class Pair<L,R> {
private final L left;
private final R right;
public Pair(L left, R right) {
this.left = left;
this.right = right;
}
public L getLeft() { return left; }
public R getRight() { return right; }
@Override
public int hashCode() { return left.hashCode() ^ right.hashCode(); }
@Override
public boolean equals(Object o) {
if (o == null) return false;
if (!(o instanceof Pair)) return false;
Pair pairo = (Pair) o;
return this.left.equals(pairo.getLeft()) &&
this.right.equals(pairo.getRight());
}
}
class MyKey {
public Integer k1;
public Integer k2;
public MyKey(Integer k1, Integer k2) {
this.k1 = k1;
this.k2 = k2;
}
@Override
public int hashCode() {
return k1.hashCode() + 17 * k2.hashCode();
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (o == null || !(o instanceof MyKey)) {
return false;
}
MyKey cp = MyKey.class.cast(o);
return k1.equals(cp.k1) && k2.equals(cp.k2);
}
}
class MyString {
private String value;
public MyString(Integer k1, Integer k2) {
value=k1+"-"+k2;
}
@Override
public int hashCode() {
return value.hashCode();
}
@Override
public boolean equals(Object o) {
return o.equals(value);
}
}