IT Share you

HashSet은 삽입 순서를 유지합니까?

shareyou 2020. 12. 7. 21:12
반응형

HashSet은 삽입 순서를 유지합니까?


않습니다 HashSet사용하여 반복 할 때 .NET 3.5에 도입 컬렉션 삽입 순서를 유지 foreach?

문서 상태는 컬렉션이 정렬되지 않도록하지만, 삽입 순서에 대해 아무 말도하지 않습니다. 시험판 BCL 블로그 항목 은 순서가 지정되지 않았 음을 나타내지 만이 문서 에서는 삽입 순서를 유지하도록 설계되었다고 설명합니다. 나의 제한된 테스트에 따르면 순서는 보존되지만 우연 일 수 있습니다.


이 HashSet MSDN 페이지는 구체적으로 다음과 같이 말합니다.

집합은 중복 요소를 포함하지 않고 요소가 특정 순서가 아닌 컬렉션입니다.


나는 그것이 순서를 유지한다고 주장하는 기사가 단지 명백한 잘못이라고 생각합니다. 간단한 테스트의 경우 내부 구조로 인해 삽입 순서가 잘 보존 될 수 있지만 보장되지는 않으며 항상 그렇게 작동하지는 않습니다. 반례를 생각해 보겠습니다.

편집 : 여기에 반례가 있습니다.

using System;
using System.Collections.Generic;

class Test
{
    static void Main()
    {
        var set = new HashSet<int>();

        set.Add(1);
        set.Add(2);
        set.Add(3);
        set.Remove(2);
        set.Add(4);


        foreach (int x in set)
        {
            Console.WriteLine(x);
        }
    }
}

3이 4보다 먼저 삽입 되었음에도 불구하고 1, 4, 3이 인쇄됩니다.

그것은이다 가능 하면 모든 항목을 제거하지 않을 경우,이 삽입 순서를 유지됩니다. 확실하지는 않지만 완전히 놀라지는 않을 것입니다. 그러나 나는 그것에 의존하는 것이 매우 나쁜 생각이라고 생각합니다.

  • 그런 식으로 작동하도록 문서화되어 있지 않으며 문서에는 정렬되지 않았다고 명시 적으로 명시되어 있습니다.
  • 나는 내부 구조 나 소스 코드 (분명히 가지고 있지 않음)를 보지 않았습니다. 이러한 주장을 확고하게하기 전에 신중하게 연구해야합니다.
  • 구현은 프레임 워크 버전간에 매우 쉽게 변경 될 수 있습니다. 이것에 의존 string.GetHashCode하는 것은 변경되지 않는 구현에 의존하는 것과 같을 것 입니다. 일부 사람들은 .NET 1.1 일로 돌아가서 구현 .NET 2.0에서 변경 되었을 때 불 태워졌습니다 .

설명서에는

HashSet <(Of <(T>)>) 컬렉션은 정렬되지 않으며 중복 요소를 포함 할 수 없습니다. 응용 프로그램의 성능보다 순서 또는 요소 복제가 더 중요한 경우 Sort 메서드와 함께 List <(Of <(T>)>) 클래스를 사용하는 것이 좋습니다.

따라서 현재 구현에서 요소의 순서를 실제로 보존하는지 여부는 중요하지 않습니다. 그렇게하는 것으로 문서화되지 않았기 때문이며, 지금처럼 보이더라도 이는 향후 언제든지 변경 될 수 있습니다 (핫픽스에서 프레임 워크).

구현 세부 사항이 아니라 문서화 된 계약 에 따라 프로그래밍해야합니다 .


특히 SortedSet<T>.NET4에 컬렉션이 있습니다 .

이렇게하면 정렬이 가능하지만 삽입 순서 정렬이 아닐 가능성이 높습니다. 커스텀 IComparer사용할 수 있기 때문에 이론적으로는 무엇이든 할 수 있습니다.


아니요, 해시 세트는 적어도 예측할 수는 없지만 삽입 순서를 유지하지 않습니다. LinkedHashSet (Java) 또는 이와 동등한 것을 사용할 수 있습니다. LinkedHashSet은 순서를 유지합니다.

If you want order, you shouldn't even be using a set in the first place ... its not made for ordered elements, except in exceptional cases.

EDIT: sounds like I'm preaching :-/ Sorry.


Reading the source code for HashSet.AddIfNotPresent you can see insertion order is preserved assuming there haven't been any deletions.

Thus new HashSet<string> { "Tom", "Dick", "Harry" } preserves order, but if you then remove Dick and add Rick, the order will be ["Tom", "Rick", "Harry"].

참고URL : https://stackoverflow.com/questions/657263/does-hashset-preserve-insertion-order

반응형