자바 세트 주문 유지?


179

Java 세트가 주문을 유지합니까? 메소드가 Set을 나에게 반환하고 데이터가 정렬되었지만 Set을 반복하면 데이터가 정렬되지 않습니다. 이것을 관리하는 더 좋은 방법이 있습니까? Set 이외의 것을 반환하기 위해 메소드를 변경해야합니까?


3
"요소는 특정한 순서로 반환되지 않습니다 (이 세트가 보증을 제공하는 일부 클래스의 인스턴스가 아닌 한)." 세트의 반복자 메소드가 말하는 것입니다. here
keyser

답변:


256

Set인터페이스는 어떤 순서 보증을 제공하지 않습니다.

하위 인터페이스 SortedSet는 일부 기준에 따라 정렬 된 세트를 나타냅니다. Java 6에는 구현하는 두 개의 표준 컨테이너가 있습니다 SortedSet. 그들은이다 TreeSetConcurrentSkipListSet.

SortedSet인터페이스 외에도 LinkedHashSet클래스도 있습니다. 요소가 세트에 삽입 된 순서를 기억하고 해당 순서대로 요소를 리턴합니다.


21
또한 Java 8 의 다른 문자열 해싱 으로 인해 세트 및 맵의 기본 (정렬되지 않은) 순서가 변경됩니다. 정렬되지 않은 순서에 의존하는 경우 코드는 Java 8에서 다르게 동작합니다.
rustyx

나는 순서가 아닌 클래스가 정상이라는 것을 알지만, 내가 기대했던 행동은 소개되었을 때 순서를 어지럽히 지 않고 그대로 두는 것이 었습니다. 대신 요소가 집계 될 때마다 요소를 섞습니다. 귀하의 솔루션은 최적의 상태가 아닙니다. 왜냐하면 그들이 소개 된 것과 같은 방식으로 전체 구조를 구현해야하기 때문입니다 : S
White_King

@White_King : 세트는 "삽입 순서"라는 개념을 포함하지 않는 수학적 개념이므로 Java 인터페이스가 해당 규칙을 따르는 것이 합리적입니다. 순서화 된 세트가 있지만 순서는 관계 (Java의 비교기)에 의해 지정되며 세트 이론의 정의를 Java의 정의와 다시 일치시킵니다. 삽입 순서를 유지하려는 기대는 아마도 목록에서 왔지만 세트는 목록이 아닙니다.
Konrad Höffner

103

LinkedHashSet 이 필요합니다.


43
A ListSet(회원 자격의 고유성을 보장하지는 않습니다)가 아닙니다.
제한적 속죄

10
많은 비즈니스 고유 사례에서 List는 Set 대신 주문을 유지하기 위해 사용될 수 없습니다. LinkedHashSet은 주문을 유지하고 고유 한 상점을 저장합니다.
gubs

18

많은 회원들이 제안한 것처럼 LinkedHashSet 을 사용 하여 컬렉션의 순서를 유지합니다. U는이 구현을 사용하여 세트를 포장 할 수 있습니다.

SortedSet 구현은 정렬 순서에 사용할 수 있지만 목적에 따라 LinkedHashSet을 사용하십시오 .

또한 문서에서

"이 구현은 TreeSet과 관련된 비용 증가없이 HashSet에서 제공하는 지정되지 않은 일반적으로 혼란스러운 순서에서 클라이언트를 보호합니다. 원본과 상관없이 원본과 동일한 순서의 세트 사본을 생성하는 데 사용할 수 있습니다. 세트의 구현 : "

출처 : http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html


9

세트는 단지 인터페이스입니다. 순서를 유지하려면 해당 인터페이스와 하위 인터페이스 SortedSet의 특정 구현 (예 : TreeSet 또는 LinkedHashSet)을 사용해야합니다. 다음과 같이 세트를 감쌀 수 있습니다.

Set myOrderedSet = new LinkedHashSet(mySet);

7

다음은 SetJava에서 사용 가능한 표준 구현 의 순서 특성에 대한 간략한 요약입니다 .

  1. 삽입 순서 유지 : LinkedHashSetCopyOnWriteArraySet (스레드 안전)
  2. 항목을 TreeSet , EnumSet (enum에만 해당) 및 ConcurrentSkipListSet (스레드 안전) 세트로 정렬 유지
  3. 특정 순서로 항목을 유지하지 않습니다 : HashSet (시도한 것)

특정한 경우에는 먼저 항목을 정렬 한 다음 1 또는 2 (대부분은 LinkedHashSet또는 TreeSet)를 사용할 수 있습니다. 또는 더 효율적으로 또는 더 효율적으로 정렬되지 않은 데이터를 추가 TreeSet하여 자동으로 정렬을 처리 할 수 ​​있습니다.


7

주문 사용을 유지하려면 List또는 LinkedHashSet.


1
그건 LinkedHashSet아니고 ... Map.
Marko Topolnik

나는 목록이 아닌 세트가 필요하다. 또한 내가 생각하는 물체의 주입 순서를 유지하는 세트가 필요하다
White_King

5

LinkedHashSet은 모든 요소에서 이중 연결 List를 유지 관리하는 HashSet의 정렬 버전입니다. 반복 순서를 염려 할 때 HashSet 대신이 클래스를 사용하십시오.


3

에 대한 javadoc에서 Set.iterator():

이 세트의 요소에 대한 반복자를 리턴합니다. 요소는 특정 순서로 리턴되지 않습니다 (이 세트가 보증을 제공하는 일부 클래스의 인스턴스가 아닌 한).

그리고 shuuchan이 이미 언급했듯이 a TreeSetSet보장 순서를 구현합니다 .

요소는 사용 된 생성자에 따라 고유 한 순서를 사용하거나 설정된 생성 시간에 제공된 비교기로 정렬됩니다.


3

일반적으로 set은 긴급 성을 신속하게 찾기 위해 HashSet과 같은 순서를 유지하지 않지만 LinkedHashSet을 시도하면 넣은 순서를 유지합니다.


1

두 가지가 있습니다.

  1. 세트의 요소를 정렬하십시오. 이를 위해 SortedSet 및 유사한 구현이 있습니다.
  2. 삽입 순서를 세트로 유지하십시오. LinkedHashSet 및 CopyOnWriteArraySet (스레드 안전)을 사용할 수 있습니다.



-2

SortedSet의 주문 만 할 수 있습니다Set


문제는 삽입 순서를 유지하는 것입니다 (정렬 됨).
assylias
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.