Map<Integer[], Integer> map = new TreeMap<Integer[], Integer>();
私は2つのintをキーとして配列に、別のintを値としてマップを作成しようとしています。配列はすべて一意になります。しかし、私はjava.lang.classcastexceptionエラーを受けています。何かアドバイス?Javaでマップキーとして配列を使用することはできますか?
Map<Integer[], Integer> map = new TreeMap<Integer[], Integer>();
私は2つのintをキーとして配列に、別のintを値としてマップを作成しようとしています。配列はすべて一意になります。しかし、私はjava.lang.classcastexceptionエラーを受けています。何かアドバイス?Javaでマップキーとして配列を使用することはできますか?
UPDATE:トーマス述べたとして、あなたはTreeMap
にカスタムComparator
を渡すことができます。だからあなたの元のコードを少し変更して作業することができます。この場合
Map<Integer[], Integer> map = new TreeMap<Integer[], Integer>(new IntegerWordComparator());
、IntegerWordComparator
がIntegerWord
に類似したもの(下記参照)になりますが、Comparator
インタフェースの実装として:
public class IntegerWordComparator implements Comparator<Integer[]> {
@Override
public int compare(Integer[] iw1, Integer[] iw2) {
int commonLength = Math.min(iw1.length, iw2.length);
for (int i = 0; i < commonLength; i++) {
if (iw1[i] > iw2[i]) {
return 1;
} else if (iw1[i] < iw2[i]) {
return -1;
}
}
if (iw1.length > iw2.length) {
return 1;
} else if (iw1.length < iw2.length) {
return -1;
} else {
return 0;
}
}
}
利用List
の代わりに、配列、およびHashMap
の代わりに、TreeMap
:
Map<List<Integer>, Integer> map = new HashMap<List<Integer>, Integer>();
// add three items two of which are the same
map.put(Arrays.asList(new Integer[]{1, 2, 3}), 1);
map.put(Arrays.asList(new Integer[]{3, 4, 7}), 2);
map.put(Arrays.asList(new Integer[]{1, 2, 3}), 4);
// print the size
System.out.println(map.size()); // 2
あなたが順序を無視したい場合は、キーとして使用Set
。
TreeMap
を本当に使いたい場合は、辞書を辞書編集的に比較したい場合は、独自のクラスを作成してキーとして使用できます。次に例を示します。
public class IntegerWord implements Comparable<IntegerWord> {
protected final Integer[] integers;
public IntegerWord(Integer... integers) {
this.integers = integers;
}
@Override
public int compareTo(IntegerWord other) {
int commonLength = Math.min(integers.length, other.integers.length);
for (int i = 0; i < commonLength; i++) {
if (integers[i] > other.integers[i]) {
return 1;
} else if (integers[i] < other.integers[i]) {
return -1;
}
}
if (integers.length > other.integers.length) {
return 1;
} else if (integers.length < other.integers.length) {
return -1;
} else {
return 0;
}
}
@Override
public boolean equals(Object other) {
if (other instanceof IntegerWord) {
return (compareTo((IntegerWord)other) == 0);
} else {
return false;
}
}
@Override
public String toString() {
return Arrays.asList(integers).toString();
}
}
使用法:
Map<IntegerWord, Integer> map = new TreeMap<IntegerWord, Integer>();
map.put(new IntegerWord(2, 5), 11);
map.put(new IntegerWord(1, 2, 3), 22);
map.put(new IntegerWord(1, 2, 3, 4), 33);
map.put(new IntegerWord(1, 2, 3), 44); // 1, 2, 3 again!
map.put(new IntegerWord(3, 9, 3, 4), 55);
map.put(new IntegerWord(0, 1), 66);
map.put(new IntegerWord(), 77); // will be the first!
System.out.println(map);
独自の配列ラッパーを書く必要はありません。 'Comparator'を' TreeMap'に渡すことができます。 – Thomas
良い点は、これが最適な解決策です。 –
はここTreeMapのではなく、HashMapの使用、作業例です。
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
Map<Integer[], Integer> map = new HashMap<Integer[], Integer>();
Integer[] array1 = {1, 2, 3};
Integer[] array2 = {4, 5, 6};
map.put(array1, 42);
map.put(array2, -1000);
System.out.println("array1: "+map.get(array1));
}
}
アレイが(等号を実装)とhashCode()does notの、あなたがキーとして配列を使用する場合は、あなただけ正確に同じ配列に戻って値を取得することができますので。
Integer[] key1 = {1, 2, 3};
Integer[] key2 = {1, 2, 3};
System.out.println(key1.equals(key2)); //false
System.out.println(key1.hashCode() == key2.hashCode()); //false
Map<Integer[], String> map = new HashMap<>();
map.put(key1, "value");
System.out.println(map.get(key1)); //value
System.out.println(map.get(key2)); //null
このようなラッパーを作成することがベター:
class IntArrayKey {
Integer[] array;
public IntArrayKey(Integer... array) {
this.array = array;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
IntArrayKey that = (IntArrayKey) o;
return Arrays.equals(array, that.array);
}
@Override
public int hashCode() {
return Arrays.hashCode(array);
}
}
P.S.をTreeMapで使用する場合、Comparableを実装できます
TreeMapはそのキーがComparableである必要があります。または、コンパレータを用意する必要があります。例外のエラーメッセージにそのことを示す必要があります。それを読んだことはありますか?あなたはTreeMapのjavadocを読んだことがありますか? –
または、比較可能なキーを必要としないHashMapを使用してください。配列は、同じ内容の他の配列ではなく、それ自身と等しいとみなされることに注意してください。 –
キーとして使用する独自のオブジェクトクラスを作成します。そうすれば、オブジェクトクラスはComparableを実装できます。 –