C # Đặt bộ sưu tập?


488

Có ai biết nếu có một Setbộ sưu tập tương đương tốt với Java trong C # không? Tôi biết rằng bạn có thể bắt chước một phần nào đó bằng cách sử dụng một Dictionaryhoặc một HashTablebằng cách điền vào nhưng bỏ qua các giá trị, nhưng đó không phải là một cách rất thanh lịch.

Câu trả lời:


142

Hãy thử Hashset :

Lớp Hashset (Of T) cung cấp các hoạt động tập hiệu năng cao. Một tập hợp là một bộ sưu tập không chứa các phần tử trùng lặp và các phần tử của chúng không theo thứ tự cụ thể ...

Dung lượng của một đối tượng Hashset (Of T) là số phần tử mà đối tượng có thể giữ. Dung lượng của đối tượng Hashset (Of T) tự động tăng lên khi các phần tử được thêm vào đối tượng.

Lớp Hashset (Of T) dựa trên mô hình của các bộ toán học và cung cấp các hoạt động tập hiệu suất cao tương tự như truy cập các khóa của bộ sưu tập Từ điển (Of TKey, TValue) hoặc Hashtable . Nói một cách đơn giản, lớp Hashset (Of T) có thể được coi là bộ sưu tập Từ điển (Of TKey, TValue) không có giá trị.

Bộ sưu tập Hashset (Of T) không được sắp xếp và không thể chứa các phần tử trùng lặp ...


8
Thật không may, HashSets không được thêm cho đến gần đây. Nếu bạn đang làm việc trong một phiên bản cũ hơn của khung, bạn sẽ phải gắn bó với Từ điển munged <> hoặc Hashtable của bạn.
Greg D

413

Nếu bạn đang sử dụng .NET 3.5, bạn có thể sử dụng HashSet<T>. Đúng là .NET không phục vụ cho các bộ cũng như Java.

Các PowerCollections Wintellect có thể giúp quá.


16
Tôi nghi ngờ rằng Set là một từ khóa trong một số ngôn ngữ, có thể gây ra vấn đề.
Jon Skeet

3
@ Biến mất: Không phải vậy. Xem phần 2.4.3 của thông số C # 3. Nó chỉ có ý nghĩa đặc biệt cho các thuộc tính.
Jon Skeet

28
Lý do gọi nó là Hashset, thay vì chỉ Set, giống như trong Java- "Set" mô tả một giao diện, trong khi "Hashset" mô tả một triển khai - cụ thể, đây là một Set được hỗ trợ bởi Hash Map. Theo cách này, chúng tôi biết (hoặc rất mong đợi) rằng việc chèn và truy cập sẽ mất thời gian truy cập O (1), so với "LinkedListset" sẽ khiến chúng tôi mong đợi việc chèn và truy cập mất thời gian O (n).
David Souther

5
Ý bạn là gì ".NET không phục vụ cho các bộ cũng như Java." Bộ này có phần nào không hoàn hảo so với Java không?
Louis Rhys

34
@Louis: Bạn đang nói về bộ nào? Java có rất nhiều triển khai Set khác nhau cho các tình huống khác nhau. .NET có một trong .NET 3.5 (Hashset) và hai trong .NET 4 (Hashset và Sortedset). Việc chúng tôi phải đợi đến .NET 3.5 để bắt đầu là khá đáng ngạc nhiên.
Jon Skeet

26

Nếu bạn đang sử dụng .NET 4.0 trở lên:

Trong trường hợp bạn cần sắp xếp thì sử dụng SortedSet<T>. Mặt khác, nếu bạn không, sau đó sử dụng HashSet<T>vì nó O(1)để tìm kiếm và thao tác các hoạt động. Trong khi đó SortedSet<T>O(log n)để tìm kiếm và thao tác hoạt động.



13

Tôi sử dụng một trình bao bọc xung quanh a Dictionary<T, object>, lưu trữ null trong các giá trị. Điều này cho phép O (1) thêm, tra cứu và xóa trên các phím và cho tất cả ý định và mục đích hoạt động giống như một bộ.


2
Bạn phải có nghĩa là nó gần tương đương với std :: unordered_set. std :: set được đặt hàng. Ví dụ: bạn có thể nhanh chóng tìm thấy điểm bắt đầu và điểm kết thúc của một phạm vi và lặp lại từ đầu đến cuối, truy cập các mục theo thứ tự khóa. SortedDictionary tương đương với std :: set.
doug65536


-5

Tôi biết đây là một chủ đề cũ, nhưng tôi đã gặp phải cùng một vấn đề và thấy Hashset rất không đáng tin cậy vì được cung cấp cùng một hạt giống, GetHashCode () đã trả về các mã khác nhau. Vì vậy, tôi nghĩ, tại sao không sử dụng Danh sách và ẩn phương thức add như thế này

public class UniqueList<T> : List<T>
{
    public new void Add(T obj)
    {
        if(!Contains(obj))
        {
            base.Add(obj);
        }
    }
}

Vì Danh sách chỉ sử dụng phương thức Bằng để xác định đẳng thức, nên bạn có thể xác định phương thức Bằng trên loại T của mình để đảm bảo bạn nhận được kết quả mong muốn.


13
Lý do bạn sẽ không muốn sử dụng này là bởi vì List.ContainsO(n)phức tạp mà phương tiện mà bạn Addphương pháp bây giờ trở thành O(n)phức tạp là tốt. Giả sử bộ sưu tập bên trong không cần phải thay đổi kích thước, Addcho cả hai ListHashMapnên có O(1)độ phức tạp. TLDR: Điều này sẽ hoạt động, nhưng nó hack và kém hiệu quả.
Richard Marskell - Drackir

6
Chắc chắn, nếu các đối tượng của bạn không trả về một giá trị thích hợp cho GetHashCode, bạn không nên đặt chúng vào một thùng chứa dựa trên hàm băm. Sẽ tốt hơn để sửa GetHashCode hơn là sử dụng một thùng chứa kém hiệu quả hơn.
bmm6o
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.