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

Bir dizide iki satırlı bir anahtar ve değer olarak farklı bir int olarak bir harita oluşturmaya çalışıyorum. Dizilerin hepsi eşsiz olacak. Ancak, bir java.lang.classcastexception hatası alıyorum. herhangi bir tavsiye?Java'da bir harita anahtarı olarak bir dizi kullanmak mümkün mü?

+4

'u uygulayabilirsiniz. TreeMap, Karşılaştırılabilir olması için kendi anahtarlarını gerektirir. Ya da bir Karşılaştırıcı sağlamanız gerekir. Özel durumun hata iletisi size bunu söylemelidir. Onu okudun mu? TreeMap'in javadoc'unu okudun mu? –

+1

Veya Karşılaştırma tuşları gerektirmeyen HashMap'i kullanın. Bir dizinin, aynı içeriğe sahip diğer dizilere değil, yalnızca kendisine eşit olarak kabul edileceğini unutmayın. –

+1

Anahtar olarak kullanmak için kendi nesne sınıfınızı yazın. Bu şekilde, nesne sınıfınız Karşılaştırılabilir'i uygulayabilir. –

cevap

1

GÜNCELLEME: Thomas söz gibi, bir TreeMap için özel bir Comparator geçebilir. Yani orijinal kod küçük bir değişiklik ile bir iş olabilir:

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; 
     } 
    } 

} 
:

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

, IntegerWordComparatorIntegerWord benzer bir şey (aşağıya bakınız) olacak ama Comparator arayüzünün bir uygulama olarak


Orijinal cevap

Kullanım yerine dizinin List ve HashMap yerine 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 

sonra, sipariş görmezden anahtar olarak Set kullanmak istiyorsanız

.

Eğer gerçekten TreeMap kullanmak istiyorsanız ve dizilerinizi sözlüksel olarak karşılaştırmak istiyorsanız, kendi sınıfınızı yazıp anahtar olarak kullanabilirsiniz. İşte bir örnek:

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(); 
    } 

} 

Kullanımı:

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

Kendi dizi sarmalayıcınızı yazmaya gerek yok: Bir "Karşılaştırıcı" öğesini bir "TreeMap" öğesine geçirebilirsiniz. – Thomas

+0

İyi nokta, bu en iyi çözüm. –

0

İşte TreeMap yerine HashMap kullanarak çalışan bir örnek. Eğer anahtar olarak diziyi kullanırsanız

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

Dizi eşittir uygulamak doesnt() ve hashCode(), çok teşekkür, sadece aynı dizinin geri değerini elde edebilirsiniz.

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 

Daha

böyle sarmalayıcı oluşturmak için:

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); 
    } 
} 

dip not TreeMap ile kullanmak için Karşılaştırılabilir

İlgili konular