2012-11-04 50 views
38

thể trùng lặp:
Storing primitive values in a Java collection?HashMap không làm việc với int, char

Trong java khi tôi sử dụng như sau: -

public HashMap<char, int> buildMap(String letters) 
{ 
    HashMap<char, int> checkSum = new HashMap<char, int>(); 

    for (int i = 0; i < letters.length(); ++i) 
    { 
     checkSum.put(letters.charAt(i), primes[i]); 
    } 

    return checkSum; 
} 

tôi nhận lỗi liên quan đến loại không phù hợp. Tôi giải quyết vấn đề của tôi bằng cách sử dụng ký tự và số nguyên thay vì char và int tương ứng. Tuy nhiên, tôi đang gặp khó khăn trong việc tìm ra lý do tại sao HashMap không thể xử lý các kiểu dữ liệu nguyên thủy.

+1

Được rồi, mọi người ... OP hỏi [* why *] (http://stackoverflow.com/questions/2721546/why-dont-generics-support-primitive-types). –

+0

@PaulBellora Bản sao đó cũng là về lý do tại sao –

Trả lời

88

Thông số chung chỉ có thể liên kết với các loại tham chiếu, không phải kiểu nguyên thủy, vì vậy bạn cần phải sử dụng các loại trình bao bọc tương ứng. Thay vào đó, hãy thử HashMap<Character, Integer>.

Tuy nhiên, tôi đang gặp khó khăn trong việc tìm ra lý do tại sao HashMap không thể xử lý các loại dữ liệu nguyên thủy.

Điều này là do type erasure. Java không có generics ngay từ đầu nên HashMap<Character, Integer> thực sự là một HashMap<Object, Object>. Trình biên dịch thực hiện một loạt các kiểm tra bổ sung và các phôi ngầm để chắc chắn rằng bạn không đặt sai loại giá trị hoặc loại sai, nhưng khi chạy chỉ có một lớp HashMap và nó lưu trữ các đối tượng.

Các ngôn ngữ khác "chuyên" các loại như vậy trong C++, vector<bool> rất khác với vector<my_class> nội bộ và chúng không có chung loại vector<?> siêu loại. Java định nghĩa mọi thứ để một số List<T>is aList bất kể những gì T là để tương thích ngược với mã tiền chung chung. Yêu cầu tương thích ngược này là phải có một lớp triển khai thực hiện cho tất cả các tham số của một kiểu generic ngăn chặn kiểu chuyên môn của khuôn mẫu cho phép các tham số chung kết hợp với các nguyên thủy.

+0

OP đề cập đến điều đó, nhưng tự hỏi tại sao nguyên thủy không hoạt động. –

+0

@PaulBellora, vui lòng xem các chỉnh sửa của tôi. –

+1

Cập nhật tốt đẹp! +1 –

2

Hashmaps chỉ có thể sử dụng classes, không phải primitives. Điều này page từ programmerinterview.com có ​​thể được sử dụng trong hướng dẫn bạn để tìm câu trả lời. Thành thật mà nói, tôi đã không tìm ra câu trả lời cho vấn đề này một cách chi tiết.

10

Generics không thể sử dụng các kiểu nguyên thủy dưới dạng từ khóa.

Sử dụng

public HashMap<Character, Integer> buildMap(String letters) 
{ 
    HashMap<Character, Integer> checkSum = new HashMap<Character, Integer>(); 

    for (int i = 0; i < letters.length(); ++i) 
    { 
     checkSum.put(letters.charAt(i), primes[i]); 
    } 

    return checkSum; 
} 
2

Bạn không thể đặt các kiểu dữ liệu vào bộ sưu tập. Tuy nhiên, bạn có thể khai báo chúng bằng cách sử dụng các trình bao bọc đối tượng tương ứng của chúng và vẫn thêm các giá trị nguyên thủy, miễn là boxing cho phép bạn.

2

Các lớp Bộ sưu tập chung không thể được sử dụng với nguyên thủy. Sử dụng các lớp wrapper Character và Integer để thay thế.

Map<Character , Integer > checkSum = new HashMap<Character, Integer>();

2

Generics thể được định nghĩa chỉ sử dụng Wrapper lớp.Nếu bạn không muốn xác định sử dụng các loại Wrapper, bạn có thể sử dụng định nghĩa thô như sau

@SuppressWarnings("rawtypes") 
public HashMap buildMap(String letters) 
{ 
    HashMap checkSum = new HashMap(); 

    for (int i = 0; i < letters.length(); ++i) 
    { 
     checkSum.put(letters.charAt(i), primes[i]); 
    } 
    return checkSum; 
} 

Hoặc xác định HashMap sử dụng các loại wrapper, và lưu trữ các loại nguyên thủy. Các giá trị nguyên thủy sẽ được quảng bá cho các loại trình bao bọc của chúng.

public HashMap<Character, Integer> buildMap(String letters) 
{ 
    HashMap<Character, Integer> checkSum = new HashMap<Character, Integer>(); 

    for (int i = 0; i < letters.length(); ++i) 
    { 
    checkSum.put(letters.charAt(i), primes[i]); 
    } 
    return checkSum; 
} 
3

Generics chỉ hỗ trợ loại đối tượng chứ không phải nguyên thủy. Không giống như các mẫu C++, generics không liên quan đến việc tạo mã và chỉ có một mã HashMap bất kể số kiểu generic bạn sử dụng.

Trove4J thực hiện việc này bằng cách tạo trước các bộ sưu tập đã chọn để sử dụng nguyên thủy và hỗ trợ TCharIntHashMap để có thể bọc để hỗ trợ Map<Character, Integer> nếu bạn cần.

TCharIntHashMap: Một địa chỉ mở được triển khai Thực hiện bản đồ cho các khóa char và giá trị int.

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