2010-06-07 39 views
5

Chạy mã này:Java HashSet và kiểu dữ liệu Ngắn, không tương thích?

public class SomeSet { 

    public static void main(String[] args) { 

     Set<Short> s = new HashSet<Short>(); 

     for (short i = 0; i < 100; i++) { 

      s.add(i); 

      s.remove(i - 1); 

     } 

     System.out.println(s.size()); 

    } 

} 

sẽ in giá trị 100.

Tại sao nó in giá trị này?

+1

giống như những gì, bạn muốn chúng tôi thử nó ??? – pgras

Trả lời

10
s.remove(i - 1); 

Dòng trên sẽ cố gắng để loại bỏ các đối tượng từ Integer tập, bởi vì tất cả các tính toán số nguyên trong Java có int (hoặc long) kết quả. Vì tập hợp chứa các đối tượng Short, phương thức remove() sẽ không có hiệu lực.

Điều này (và các vấn đề tương tự) là lý do chính khiến bạn hầu như không bao giờ sử dụng short (và, nhiều hơn thế, Short). Sử dụng triển khai Set để chứa các số tự động phát sinh một chi phí khổng lồ (dễ dàng 1000%), do đó, thật vô nghĩa khi thử và tiết kiệm dung lượng bằng cách sử dụng Short thay vì Integer.

+0

... hoặc 'float' hoặc' double' ;-) –

6

Vấn đề là remove(i-1) gọi phương thức remove với một đối tượng Integer, vì i-1 là loại int (mà được tự động đóng hộp vào một Integer).

Để chắc chắn rằng bạn gọi remove với việc sử dụng Short đối tượng này:

s.remove((short) (i - 1)); 
+0

Hoặc rõ ràng hơn s.remove (Short.valueOf (i-1)); –

+0

@Steve: không biên dịch khi bạn cần một diễn viên rõ ràng. Làm cho nó rõ ràng hơn nhưng cũng tiết tú hơn. –

0

Loại i - 1int, vì vậy nó được autoboxed đến một Integer.

Thông thường bạn mong đợi một bộ sưu tập chung để ngăn bạn thực hiện các hoạt động có đối số sai loại, nhưng giao diện với Set<E> hơi lỏng lẻo.

Vì phương pháp remove của Set<E> mất Object thay vì E, trình biên dịch không cảnh báo bạn rằng bạn đang xóa loại khác với bộ chứa.

Để ép buộc nó là Short, hãy truyền giá trị số thành (short). (truyền tới (Short) không được phép và bạn phải truyền giá trị số để sử dụng Short.valueOf)

0

Lưu ý rằng phương pháp thêm được nhập chung boolean add(E o) để trong trường hợp của bạn, hãy đặt phương thức này sẽ mất một thời gian ngắn, trong khi phương pháp xóa không được nhập chung boolean remove(Object o) để i - 1 hộp số tự động thành Số nguyên. Đối với bất kỳ giá trị nào của i new Short(i).equals(new Integer(i)) sẽ luôn là sai.

Lưu ý rằng nếu bạn thử s.add(i - 1); bạn sẽ gặp lỗi trình biên dịch vì i - 1 trở thành một phiên bản của Số nguyên và các loại Số nguyên và Ngắn không khớp.

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