2011-01-08 43 views
7

Tôi đang cố gắng để làm cho một hashtable trong java, nơi các phím int [], nhưng nó không hoạt động. Tôi đã thực hiện một chương trình thử nghiệm nhỏ để hiển thị vấn đề của tôi:Hashtable với mảng int là chìa khóa trong java

public class test{ 
     public static void main(String[] args){ 
       int[] test0 = {1,1}; 
       int[] test1 = {1,1}; 
       Hashtable<int[], String> ht = new Hashtable<int[], String>(); 
       String s0 = "foo"; 

       ht.put(test0, s0); 

       System.out.println("the result from ht.get(test1)"); 
       System.out.println(ht.get(test1)); 
       System.out.println("the result from ht.get(test0)"); 
       System.out.println(ht.get(test0)); 
     } 
} 

Ý định của tôi là cả hai ht.get Calles nên trả lại kết quả tương tự, kể từ khi hai mảng đều bình đẳng, nhưng họ không. Đây là kết quả từ việc chạy mã:

the result from ht.get(test1) 
null 
the result from ht.get(test0) 
foo 

Tôi có thiếu gì ở đây hoặc không thể sử dụng int [] làm khóa trong hastable?

Trả lời

14

Bạn có thể sử dụng int [] làm khóa, nhưng nó phải là cùng một mảng, không chỉ có cùng nội dung. (Có nghĩa là nó sẽ không làm những gì bạn muốn)

Mảng không bằng() hoặc có cùng hashCode() dựa trên nội dung của chúng nếu chúng là cùng một mảng.

Cách duy nhất bạn có thể thực hiện việc này là sử dụng Danh sách < Số nguyên> làm khóa hoặc trình bao bọc cho int [] của bạn. TIntArrayList.

hãy thử cách sau.

List<Integer> test0 = Arrays.asList(1,1); 
List<Integer> test1 = Arrays.asList(1,1); 
Map<List<Integer>, String> ht = new HashMap<List<Integer>, String>(); 

BTW: Hashtable là một lớp kế thừa IMHO, không sử dụng trừ khi bạn phải làm vậy.

+4

+1 câu trả lời hoàn hảo –

+3

Danh sách (thường cũng có thể thay đổi). Sự khác biệt quan trọng là ['List.equals'] (http://download.oracle.com/javase/6/docs/api/java/util/List.html#equals%28java.lang.Object%29) và ['List.hashCode'] (http://download.oracle.com/javase/6/docs/api/java/util/List.html#hashCode%28%29) được yêu cầu sử dụng bình đẳng nguyên tố. –

+0

@Matthew, điểm tốt.Đã loại bỏ đề cập đến tính đột biến. –

0

Bạn có thể tạo các chuỗi ra khỏi các mảng trước khi băm (trừ chiều dài của mảng là tốn dài), thêm vào gói trong một danh sách

Nếu bạn chọn sau này có một phương pháp tĩnh của Arrays mô tả ở đây From java static Arrays class at http://download.oracle.com/javase/1.5.0/docs/api/java/util/Arrays.html#toString(int[])

h1.put(Arrays.toString(test1), s0); 

Bây giờ bạn có thể băm này và mảng tương đương sẽ băm thành cùng một thứ. Bạn sẽ không thể tạo lại mảng từ khóa, tuy nhiên (trừ khi Java có một số loại eval bây giờ?)

.
.
.
.

Đối curiousities sake, đây là tôi ngớ ngẩn cán của riêng tôi cho đến khi tôi tìm thấy các phương pháp trên:

public String intArrayToString(int[] x) 
{ 
    String ans = '['; 
    for(i = 0; i < size(x); i++) 
     ans += '' + i + ','; 
    return ans + ']'; 
} 

HashTable<String,String> h1 = new HashTable<String,String> h1; 
h1.put(intArrayToString(test1), s0); 

Nếu có một số loại toString tĩnh mà thực hiện điều này tôi xin lỗi. PS - Java có giảm chức năng (và lambdas), vòng lặp foreach hay eval (để tạo lại các khóa thành mảng nếu cần) chưa? Họ sẽ làm cho giải pháp này đẹp hơn ...

+0

Vâng, có phương pháp tĩnh 'Arrays.toString'. Xin lỗi chấp nhận, thuyền trưởng jon_darkstar. –

+0

hah bạn đánh tôi vào nó một chút = P –

+0

biến mảng thành chuỗi cũng là giải pháp mà tôi đã nghĩ về bản thân mình, nhưng tôi không thích ý nghĩ về chi phí unnessesary tạo chuỗi mỗi khi tôi phải truy cập vào thứ gì đó các hashtable –

0

Nguyên nhân là mảng test0test1hashcodes khác nhau. Nếu 2 khóa có mã băm khác nhau, chúng không bao giờ có thể giống nhau.

Các vấn đề liên quan