C # 세트 컬렉션?


488

SetC #에 Java의 콜렉션 과 동등한 것이 있는지 아는 사람이 있습니까? 나는 당신 이 값을 채우고 무시하면서 a Dictionary또는 a HashTable를 사용하여 세트를 모방 할 수는 있지만 매우 우아한 방법은 아닙니다.

답변:


142

HashSet 사용해보기 :

HashSet (Of T) 클래스는 고성능 세트 작업을 제공합니다. 집합은 중복 요소가없고 특정 순서가 아닌 컬렉션입니다.

HashSet (Of T) 객체의 용량은 객체가 보유 할 수있는 요소의 수입니다. 요소가 객체에 추가되면 HashSet (Of T) 객체의 용량이 자동으로 증가합니다.

HashSet (Of T) 클래스는 수학 집합의 모델을 기반으로하며 Dictionary (Of TKey, TValue) 또는 Hashtable 컬렉션 의 키에 액세스하는 것과 유사한 고성능 집합 작업을 제공합니다 . 간단히 말해서 HashSet (Of T) 클래스는 값이없는 Dictionary (Of TKey, TValue) 컬렉션 으로 생각할 수 있습니다 .

HashSet (Of T) 컬렉션은 정렬되지 않으며 중복 요소를 포함 할 수 없습니다 ...


8
불행히도 HashSets는 최근까지 추가되지 않았습니다. 이전 버전의 프레임 워크에서 작업하는 경우 녹은 Dictionary <> 또는 Hashtable을 사용해야합니다.
Greg D

413

.NET 3.5를 사용하는 경우을 사용할 수 있습니다 HashSet<T>. .NET이 Java뿐만 아니라 세트를 제공하지 않는다는 것은 사실입니다.

인 Wintellect의 PowerCollections는 너무 도움이 될 수 있습니다.


16
Set은 일부 언어의 키워드이므로 문제가 발생할 수 있습니다.
Jon Skeet

3
@Manish : 아닙니다. C # 3 사양의 섹션 2.4.3을 참조하십시오. 속성에는 특별한 의미가 있습니다.
Jon Skeet

28
Set 대신 HashSet을 호출하는 이유는 Java에서와 동일합니다. "Set"는 인터페이스를 설명하고 "HashSet"은 구현을 설명합니다. 구체적으로 이것은 해시 맵이 지원하는 Set입니다. 이런 식으로 삽입 및 액세스에 O (1) 액세스 시간이 걸리고 삽입 및 액세스에 O (n) 시간이 걸릴 것으로 예상되는 "LinkedListSet"이 필요하다는 것을 알고 있습니다.
David Souther

5
".NET은 Java뿐만 아니라 세트도 제공하지 않습니다."는 무엇을 의미합니까? 이 세트는 Java에 비해 어떻게 든 불완전합니까?
루이스리스

34
@Louis : 어떤 세트에 대해 이야기하고 있습니까? 자바가 많은 다양한 상황 설정의 다른 구현을. .NET에는 .NET 3.5 (HashSet) 1 개와 .NET 4 (HashSet 및 SortedSet) 2 개가있었습니다. .NET 3.5까지 시작해야한다는 사실은 놀랍습니다.
Jon Skeet

26

.NET 4.0 이상을 사용하는 경우 :

정렬이 필요한 경우을 사용하십시오 SortedSet<T>. 그렇지 않으면 검색 하지 않고 조작 하기 HashSet<T>때문에 사용하지 마십시오 O(1). 반면 에 검색 및 조작 SortedSet<T>O(log n)조작 할 수 있습니다.



13

Dictionary<T, object>값 주위에 null을 저장 하는 래퍼를 사용 합니다. 이것은 O (1) 키에 대한 추가, 조회 및 제거를 제공하며 모든 의도와 목적에 세트처럼 작동합니다.


2
std :: unordered_set과 거의 동일해야합니다. std :: set이 주문되었습니다. 예를 들어, 키 순서로 항목을 방문하여 범위의 시작 및 끝 지점을 빠르게 찾고 시작부터 끝까지 반복 할 수 있습니다. SortedDictionary std :: set과 거의 같습니다.
doug65536

11

CodePlex 에서 PowerCollections 를 살펴보십시오 . Set 및 OrderedSet 외에도 Deque, MultiDictionary, Bag, OrderedBag, OrderedDictionary 및 OrderedMultiDictionary와 같은 유용한 컬렉션 유형이 몇 가지 있습니다.

더 많은 콜렉션을 위해 C5 Generic Collection Library도 있습니다.


-5

나는 이것이 오래된 스레드라는 것을 알고 있지만 동일한 문제가 발생했으며 동일한 시드가 주어지면 GetHashCode ()가 다른 코드를 반환했기 때문에 HashSet이 매우 신뢰할 수 없다는 것을 알았습니다. 그래서 List를 사용하고 이와 같은 add 메소드를 숨기지 않는 이유는 무엇입니까?

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

List는 동등성을 결정하기 위해서만 Equals 메소드를 사용하기 때문에 원하는 결과를 얻을 수 있도록 T 유형에서 Equals 메소드를 정의 할 수 있습니다.


13
이것을 사용하고 싶지 않은 이유 List.ContainsO(n)복잡 하기 때문에 Add메서드가 O(n)복잡해 지기 때문 입니다 . 내부 수집을 가정하면, 크기를 조정할 필요가 없습니다 Add모두 ListHashMap이어야 O(1)복잡성. TLDR : 작동하지만 해킹이 덜되고 효율성이 떨어집니다.
Richard Marskell-Drackir

6
물론 개체가 GetHashCode에 적절한 값을 반환하지 않으면 해시 기반 컨테이너에 넣지 않아야합니다. 덜 효율적인 컨테이너를 사용하는 것보다 GetHashCode를 수정하는 것이 좋습니다.
bmm6o
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.