2012-07-01 44 views
6

Câu hỏi của tôi là: Cách nhanh chóng để xác định xem một số có được đặt trong số Collection hay không để biết có thêm nó vào bộ sưu tập và duy trì tính duy nhất hay không. Tôi không muốn lặp qua danh sách nếu tôi có thể giúp.Cách tốt để lưu trữ các số nguyên duy nhất

Tôi có một số List<Integer> được gọi là numberList. Tôi muốn nó lưu trữ các số nguyên duy nhất và không bao giờ cho phép các bản sao được thêm vào. Tôi muốn làm điều gì đó như thế này:

private void add(int number) { 
    if (!numberList.contains(number)) { 
    numberList.add(number); 
    } 
} 

Nhưng rõ ràng công việc này wont vì numberList chứa một danh sách các đối tượng Integer nên không phụ thuộc vào số lượng từng là một đối tượng duy nhất.

Cảm ơn!

+0

Tôi nghĩ rằng phương thức 'contains (...)' sử dụng phương thức 'equals (...)' của đối tượng để xem nó có được bộ sưu tập nắm giữ hay không, vì vậy phương thức của bạn ở trên cũng nên tránh trùng lặp. –

+0

Huh, có lẽ cái gì khác là sai với mã của tôi đó là năng suất kết quả bất ngờ sau đó. Cảm ơn vì tiền hỗ trợ! – kentcdodds

+1

nếu mã của bạn giống như của tôi, sau đó có * luôn luôn * cái gì khác sai! Vui lòng quay lại với thông tin khác nếu bạn cần trợ giúp tìm kiếm! –

Trả lời

12

Một là lưu trữ số nguyên trong một số Set<Integer> chẳng hạn như . Bộ không cho phép trùng lặp.

Sửa
Ngoài ra, phương pháp contains(...) của Bộ sưu tập sử dụng bình đẳng của đối tượng (...) phương pháp để xem nếu nó được tổ chức bởi bộ sưu tập hay không, vì vậy phương pháp của bạn ở trên sẽ ngăn chặn bản sao là tốt, nếu bạn cần để sử dụng Danh sách làm bộ sưu tập của bạn. Hãy tự mình thử nghiệm và bạn sẽ thấy nó như vậy.

Ví dụ:

List<Integer> numberList = new ArrayList<Integer>(); 
    int[] myInts = {1, 1, 2, 3, 3, 3, 3, 4}; 
    for (int i : myInts) { 
    if (!numberList.contains(i)) { 
     numberList.add(i); 
     } 
    } 

    System.out.println(numberList); 

sẽ trở lại: [1, 2, 3, 4]

Ngoài ra, một vấn đề có thể với HashSets là họ không ra lệnh, vì vậy nếu đặt hàng là rất quan trọng, bạn sẽ muốn xem xét sử dụng một trong các loại Bộ đặt hàng khác.

+0

Ngoài sự tò mò, bạn nghĩ việc triển khai nào sẽ nhanh hơn? Nó sẽ nhanh hơn để thỏa thuận 'Set' với các bản sao hoặc sử dụng' contains' trên một Danh sách trước khi thêm? – kentcdodds

+0

@kentcdodds: Tôi tin rằng HashSet sẽ nhanh hơn vì băm là một hoạt động rất nhanh, nhưng tôi không thể nói với sự đảm bảo 100% vì tôi chưa bao giờ nghiên cứu O lớn cho các thuật toán. Nhưng xung quanh, một trong những nhà khoa học máy tính sẽ trả lời điều này sớm, không nghi ngờ gì. –

+0

Cảm ơn lời khuyên! – kentcdodds

3

Hình thức nhỏ gọn nhất không phải là BitSet? Đó là hiệu quả về lưu trữ vì nó sẽ mở rộng vô thời hạn. Nó cũng sẽ không sử dụng lưu trữ không cần thiết.

Bạn có đang làm việc trong môi trường đa luồng không? Nếu có thì các cấu trúc khác có thể tốt hơn/hiệu quả hơn.

+0

Bạn đã nhận tôi! Đó là một môi trường đa luồng, đó là lý do tại sao tôi làm điều này. Tôi muốn kiểm tra xem một sợi đã thêm số chưa. – kentcdodds

+0

Trong trường hợp đó bạn gần như chắc chắn đang tìm kiếm 'ConcurrentHashMap', có lẽ được bọc trong một tập hợp có nguồn gốc sử dụng [newSetFromMap] (http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html # newSetFromMap% 28java.util.Map% 29) nhưng bạn luôn có thể thêm 'Boolean.TRUE' vào' Bản đồ' thay thế nếu bạn muốn. – OldCurmudgeon

+1

BitSet rất hiệu quả đối với các tập số nhỏ, dày đặc. Nhưng 'new BitSet(). Add (Integer.MAXVALUE);' đã phân bổ 268MB. Vì vậy, nó nên được sử dụng cẩn thận. – Arne

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