2017-05-23 5 views
3

私はHashMap<Float[], Integer>を持っています。おそらくそれをTreeMapに変換する必要があります。 TreeMapのキー(配列)はどのようにソートされますか?彼らの最初の要素によって?キーが配列のときのマップキーの並べ替え

私は簡単なテストを実行するつもりだったが、それは何らかの形でエラーが発生しました:

public class treeMapTest { 
    public static void main(String[] args) { 
     Integer arr1[] = {9, 0, 3}; 
     Integer arr2[] = {2, 2, 2}; 
     Integer arr3[] = {4, 2, 1}; 

     TreeMap<Integer[], Integer> tm = new TreeMap<Integer[], Integer>(); 
     tm.put(arr1, 7); 
     tm.put(arr2, 7); 
     tm.put(arr3, 7); 

     System.out.println(tm); 
    } 
} 

ありがとうございました。

+5

奇妙な、私は;-) – domsson

答えて

5

配列には自然順序付けがありません(つまり、Comparableインターフェイスを実装していません)。そのため、パラメータなしのコンストラクタを使用してTreeMapをインスタンス化するとコードで例外がスローされます。

オーダーを自分で定義するには、Comparator<Integer[]>TreeMapコンストラクタに指定する必要があります。それはあなたがTreeMapに切り替えている良いことだので、(配列がequals()hashCode()のデフォルトの実装をオーバーライドしていないので)

ところで、HashMapのキーとして配列を使用することは悪い考えです。

+2

右の前に*何とか*エラーを見たことがありません。さもなければ、あなたは 'スレッド"のメイン "java.lang.ClassCastException:[Ljava.lang.Integer; java.lang.Comparable'にキャストできません。 – vikingsteve

+0

はい、例外はあります。ありがとうございました。 – Vic

+0

@Vicそれはあなたが知っている重要な情報です) – AxelH

1

配列には自然順序付けはありません。これを解決して予測可能にする方法の1つは、次のようなことです:

TreeMap<Integer[], Integer> tm = new TreeMap<>((a1, a2) -> Integer.compare(a1[0], a2[0])); 

これは、各配列の最初の要素を比較します。配列が空の場合は、それを少し変更して例外をスローしないようにする必要があります。

2

これは構文的には正しいかもしれませんが、実用的ではありません。 マップはequals()メソッドを使用して、2つのキーが等しいかどうかを判断します。 配列は、オブジェクトクラスのequals()およびhashcode()メソッドを継承します。したがって、特定のキー(配列オブジェクト)を検索する場合は、最初の配列オブジェクトの参照が渡されない限り、そのキーを見つけることはできません。

Integer arr1[] = {9, 0, 3}; 

Integer arr1_copy[] = {9, 0, 3}; 

2つの異なるオブジェクトであり、デフォルトequals()は失敗します。

しかし、配列をキーとして使用する必要がある場合は、配列のメンバーとしてクラスを作成し、このクラスのメソッドhashcode()equals()をオーバーライドし、このクラスをキーとして使用します。

+0

これはまだ注文問題には答えていません;) – AxelH

+0

「メンバーとして配列を持つクラスを作成したら」、質問は本当に速くなります;) – AxelH

+0

@AxelHあなたは正しい – theLearner

1

キーはハッシュコードで識別されます。つまり、配列の実際の内容ではなく、配列を表すArrayオブジェクトのハッシュコードを意味します。

あなたが扱っているシナリオではうまくいくかもしれないが、あなたが念頭に置いたものではない可能性が最も高いです。

配列内の要素を移動することで、ハッシュマップの値バケット内のアイテムのソートを変更しようとしていると思われる場合は間違いです。

1

TreemapでComparatorを指定してください。

public static void main(String[] args) { 
      Integer arr1[] = {9, 0, 3}; 
      Integer arr2[] = {2, 2, 2}; 
      Integer arr3[] = {4, 2, 1}; 

      TreeMap<Integer[], Integer> tm = new TreeMap<Integer[], Integer>(new Comparator<Integer[]>() { 

       @Override 
       public int compare(Integer[] o1, Integer[] o2) { 
        int cmp=o1[0].compareTo(o2[0]); 
        return cmp; 
       } 
      }); 
      tm.put(arr1, 7); 
      tm.put(arr2, 7); 
      tm.put(arr3, 7); 
      for(Integer[] o1:tm.keySet()) 
      System.out.println(o1[0]); 
     } 
関連する問題