2016-04-02 4 views
0
Map<Integer[], Integer> map = new TreeMap<Integer[], Integer>(); 

私は2つのintをキーとして配列に、別のintを値としてマップを作成しようとしています。配列はすべて一意になります。しかし、私はjava.lang.classcastexceptionエラーを受けています。何かアドバイス?Javaでマップキーとして配列を使用することはできますか?

+4

TreeMapはそのキーがComparableである必要があります。または、コンパレータを用意する必要があります。例外のエラーメッセージにそのことを示す必要があります。それを読んだことはありますか?あなたはTreeMapのjavadocを読んだことがありますか? –

+1

または、比較可能なキーを必要としないHashMapを使用してください。配列は、同じ内容の他の配列ではなく、それ自身と等しいとみなされることに注意してください。 –

+1

キーとして使用する独自のオブジェクトクラスを作成します。そうすれば、オブジェクトクラスはComparableを実装できます。 –

答えて

1

UPDATEトーマス述べたとして、あなたはTreeMapにカスタムComparatorを渡すことができます。だからあなたの元のコードを少し変更して作業することができます。この場合

Map<Integer[], Integer> map = new TreeMap<Integer[], Integer>(new IntegerWordComparator()); 

IntegerWordComparatorIntegerWordに類似したもの(下記参照)になりますが、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); 
+1

独自の配列ラッパーを書く必要はありません。 'Comparator'を' TreeMap'に渡すことができます。 – Thomas

+0

良い点は、これが最適な解決策です。 –

0

はここ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)); 
    } 
} 
0

アレイが(等号を実装)と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を実装できます