HashSet을 정렬하는 방법?


106

목록의 경우 Collections.sort(List)방법 을 사용합니다 . 정렬하려면 어떻게해야 HashSet합니까?


20
A HashSet는 정렬되지 않은 컬렉션입니다.
Alexis C.

2
a Set에는 .get()기본적으로 정렬 알고리즘에 필요한 임의 액세스 방법 (즉, 주어진 인덱스의 요소)이
없기 때문에 불가능

3
먼저 목록으로 변환 한 다음 정렬해야하는 경우 정렬 할 수 있습니다.
demongolem

HashSet정의 된 주문이 없기 때문에 할 수 없습니다 . 귀하의 질문은 측면에서 모순을 구체화합니다.
론의 후작

1
TreeSet을 사용하고 소스를 제어 할 수없는 경우 여기에서 변환 사용법을 참조하십시오. stackoverflow.com/a/52987487/5153955
Tenflex

답변:


114

HashSet은 요소의 순서를 보장하지 않습니다. 이 보장이 필요하면 TreeSet을 사용하여 요소를 보유하는 것이 좋습니다.

그러나이 항목에 대해 정렬 된 요소가 필요한 경우 일시적으로 목록을 만들고 정렬합니다.

Set<?> yourHashSet = new HashSet<>();

...

List<?> sortedList = new ArrayList<>(yourHashSet);
Collections.sort(sortedList);

1
또한 Strings 컬렉션을 사용하는 경우List<String> sortedList = new ArrayList<String>(yourHashSet);
wisbucky

65

모든 개체를에 추가 TreeSet하면 정렬 된 세트가 생성됩니다. 아래는 원시 예입니다.

HashSet myHashSet = new HashSet();
myHashSet.add(1);
myHashSet.add(23);
myHashSet.add(45);
myHashSet.add(12);

TreeSet myTreeSet = new TreeSet();
myTreeSet.addAll(myHashSet);
System.out.println(myTreeSet); // Prints [1, 12, 23, 45]

2
를 사용 TreeSet myTreeSet = new TreeSet(myHashSet);하면 모든 요소를 ​​Treeset에 다시 추가하지 않아도됩니다.
Mounika 19-06-05

17

대신 TreeSet을 사용할 수 있습니다 .


1
요소를 넣는 것만으로도 그 안에 요소가있는 순서에 따라 유연하게 정렬 할 수는 없습니다. 위의 솔루션이 있습니다.
Jess

16

정렬하는 Java 8 방법은 다음과 같습니다.

fooHashSet.stream()
  .sorted(Comparator.comparing(Foo::getSize)) //comparator - how you want to sort it
  .collect(Collectors.toList()); //collector - what you want to collect it to

*Foo::getSize YourItem의 HashSet을 크기별로 자연스럽게 정렬하는 방법의 예입니다.

* Collectors.toList()정렬 결과를 목록으로 수집하여 캡처해야합니다.List<Foo> sortedListOfFoo =


제발, 논리를 추가하여 특정 순서로 정렬 하시겠습니까?
Jess

@Jess 나는 Jess의 특정 순서가 무엇인지 모르겠습니다. 비교기를 사용하여 원하는대로 정렬 할 수 있습니다.
LazerBanana

나는 오름차순 또는 내림차순 정의하는 방법, 의미
제스

14

java.util.TreeSet실제 개체로 사용하십시오 . 이 컬렉션을 반복하면 값이 잘 정의 된 순서로 돌아옵니다.

사용하는 경우 java.util.HashSet순서는 거의 확실하게 사전식이 아닌 내부 해시 함수에 따라 다릅니다 (콘텐츠 기반).


왜 그들이 String가치 를 저장한다고 가정 합니까?
Sotirios Delimanolis 2014 년

나는 아마도 나의 사전 적 사용이 부정확하지는 않지만 ;-)
P45 Imminent

3
그것은 매우 잘못되었습니다. 사전 (sp?) 순서로 키를 저장하지 않습니다. 자연스러운 순서 ( Comparable키가 구현하는 인터페이스에 따라 다름 )를 사용하거나 제공된 Comparator.
Sotirios Delimanolis

편집했습니다. 더 잘 생각하십니까? 아니면 제가 답변을 삭제해야합니까?
P45 Imminent

1
경우 당신은 이동 HashSet하기 위해 TreeSet, 클래스가 구현해야하는 Comparable인터페이스를하거나 사용자 정의를 제공합니다 Comparator. 그렇지 않으면를 정렬 할 수 없으므로 a HashSet로 변환 List하고 정렬하십시오.
Luiggi Mendoza

5

Java 8 수집기와 TreeSet을 사용할 수 있습니다.

list.stream().collect(Collectors.toCollection(TreeSet::new))


new TreeSet<>(hashSet)더 간결하고 아마도 더 효율적일 것입니다.
devconsole

4

다른 답변에서 언급했듯이 TreeSet을 사용할 수 있습니다.

사용 방법에 대한 자세한 설명은 다음과 같습니다.

TreeSet<String> ts = new TreeSet<String>();
ts.add("b1");
ts.add("b3");
ts.add("b2");
ts.add("a1");
ts.add("a2");
System.out.println(ts);
for (String s: ts)
    System.out.println(s);

산출:

[a1, a2, a3, a4, a5]
a1
a2
b1
b2
b3

4

HashSet의 요소는 정렬 할 수 없습니다. 요소를 HashSet에 넣을 때마다 전체 세트의 순서를 엉망으로 만들 수 있습니다. 성능을 위해 의도적으로 설계되었습니다. 주문에 신경 쓰지 않으면 HashSet이 빠른 삽입 및 검색을위한 가장 효율적인 세트입니다.

TreeSet은 요소를 삽입 할 때마다 모든 요소를 ​​자동으로 정렬합니다.

아마도 당신이하려는 것은 한 번만 정렬하는 것입니다. 이 경우 TreeSet은 항상 새로 추가 된 요소의 배치를 결정해야하기 때문에 최상의 옵션이 아닙니다.

가장 효율적인 솔루션은 ArrayList를 사용하는 것입니다. 새 목록을 만들고 모든 요소를 ​​추가 한 다음 한 번 정렬합니다. 고유 한 요소 만 유지하려는 경우 (세트처럼 모든 중복 항목을 제거한 다음 목록을 LinkedHashSet에 넣으면 이미 정렬 한 순서가 유지됩니다)

List<Integer> list = new ArrayList<>();
list.add(6);
list.add(4);
list.add(4);
list.add(5);
Collections.sort(list);
Set<Integer> unique = new LinkedHashSet<>(list); // 4 5 6
// The above line is not copying the objects! It only copies references.

이제 목록 형식으로 원하는 경우 정렬 된 집합을 얻은 다음 목록으로 변환하십시오.


3

@LazerBanana의 답변에 따라 객체의 ID로 정렬 된 세트의 내 자신의 예를 넣을 것입니다.

Set<Clazz> yourSet = [...];

yourSet.stream().sorted(new Comparator<Clazz>() {
    @Override
    public int compare(Clazz o1, Clazz o2) {
        return o1.getId().compareTo(o2.getId());
    }
}).collect(Collectors.toList()); // Returns the sorted List (using toSet() wont work)

3

사용하고 싶지 않은 경우를 대비하여 TreeSet시도해 볼 수 있습니다.

set = set.stream().sorted().collect(Collectors.toCollection(LinkedHashSet::new));

2

내 소견으로, LazerBanana의 대답은 다른 모든 답변을 가리키는 때문에 받아 최고 등급의 대답 &해야한다 java.util.TreeSet(또는 목록에 처음으로 변환 한 후 전화를 Collections.sort(...)변환 목록) 종류의 당신의 어떤 객체로 영업 이익을 물어 귀찮게하지 않았다 HashSet있습니다 즉, 해당 요소에 사전 정의 된 자연 순서가 있거나없는 경우 & 이는 선택적 질문이 아니라 필수 질문입니다.

당신은 그냥 이동 및 퍼팅 시작할 수 HashSet에 요소를 TreeSet이미 구현하지 않는 경우에는 요소 유형 Comparable이 명시 적으로 전달되지 않은 경우 인터페이스를 나 ComparatorTreeSet생성자.

에서 TreeSet의 JavaDoc,

요소의 자연스러운 순서에 따라 정렬 된 새 빈 트리 세트를 구성합니다. 집합에 삽입 된 모든 요소는 Comparable 인터페이스를 구현해야합니다. 또한 이러한 모든 요소는 상호 비교 가능해야합니다. e1.compareTo (e2)는 집합의 요소 e1 및 e2에 대해 ClassCastException을 발생시키지 않아야합니다. 사용자가이 제약을 위반하는 집합에 요소를 추가하려고하면 (예를 들어, 사용자가 요소가 정수인 집합에 문자열 요소를 추가하려고 시도하는 경우) add 호출은 ClassCastException을 throw합니다.

그렇기 때문에 모든 Java8 스트림 기반 답변 (현장에서 비교기를 정의하는 경우)만이 POJO에서 비교 가능을 구현하는 것이 선택 사항이되기 때문에 의미가 있습니다. 프로그래머는 필요할 때 비교기를 정의합니다. TreeSet이 근본적인 질문 을 하지 않고 모으려는 시도 도 잘못되었습니다 (Ninja의 대답). 개체 유형을 가정 할 수 String또는 Integer도 올바르지 않습니다.

그렇게 말했지만,

  1. 정렬 성능
  2. 메모리 풋 프린트 (정렬이 완료 될 때마다 원본 세트를 유지하고 새로운 분류 세트를 생성하거나 세트를 제자리에 정렬하려는 등)

다른 관련 포인트도 있어야합니다. API를 가리키는 것만이 의도적이어서는 안됩니다.

원본 집합에는 이미 고유 한 요소 만 포함되어 있고 해당 제약 조건도 정렬 된 집합에 의해 유지되므로 데이터가 중복되므로 원본 집합을 메모리에서 지워야합니다.


1
1. Add all set element in list -> al.addAll(s);
2. Sort all the elements in list using -> Collections.sort(al);


 public class SortSetProblem {
 public static void main(String[] args) {
    ArrayList<String> al = new ArrayList();
    Set<String> s = new HashSet<>();
    s.add("ved");
    s.add("prakash");
    s.add("sharma");
    s.add("apple");
    s.add("ved");
    s.add("banana");
    System.out.println("Before Sorting");
    for (String s1 : s) {
        System.out.print("  " + s1);
    }

    System.out.println("After Sorting");
    al.addAll(s);
    Collections.sort(al);
    for (String set : al) {
        System.out.print(" " + set);
    }
  }
 }

입력-ved prakash sharma 사과 ved 바나나

출력-사과 바나나 prakash sharma ved


1

당신이 원하는 원하는 경우 끝 Collection의 형태가 될 수 있습니다 Set당신은 자신을 정의하려면 natural order그보다는 TreeSet다음 -

1. 변환하려면 HashSetList
정렬 2. 사용자 정의 List사용 Comparator
3. 변환 다시 ListLinkedHashSet순서를 유지하기 위해
4.를 표시를 LinkedHashSet

샘플 프로그램-

package demo31;

import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

public class App26 {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        addElements(set);
        List<String> list = new LinkedList<>();
        list = convertToList(set);
        Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                int flag = s2.length() - s1.length();
                if(flag != 0) {
                    return flag;
                } else {
                    return -s1.compareTo(s2);
                }
            }
        });
        Set<String> set2 = new LinkedHashSet<>();
        set2 = convertToSet(list);
        displayElements(set2);
    }
    public static void addElements(Set<String> set) {
        set.add("Hippopotamus");
        set.add("Rhinocerous");
        set.add("Zebra");
        set.add("Tiger");
        set.add("Giraffe");
        set.add("Cheetah");
        set.add("Wolf");
        set.add("Fox");
        set.add("Dog");
        set.add("Cat");
    }
    public static List<String> convertToList(Set<String> set) {
        List<String> list = new LinkedList<>();
        for(String element: set) {
            list.add(element);
        }
        return list;
    }
    public static Set<String> convertToSet(List<String> list) {
        Set<String> set = new LinkedHashSet<>();
        for(String element: list) {
            set.add(element);
        }
        return set;
    }
    public static void displayElements(Set<String> set) {
        System.out.println(set);
    }
}

출력-

[Hippopotamus, Rhinocerous, Giraffe, Cheetah, Zebra, Tiger, Wolf, Fox, Dog, Cat]

여기서 컬렉션은-

첫 번째- String길이의
내림차순 두 번째- String알파벳 계층의 내림차순 으로 정렬되었습니다.


0

다음과 같은 방법으로이를 수행 할 수 있습니다.

방법 1 :

  1. 목록을 만들고 모든 해시 세트 값을 여기에 저장합니다.
  2. Collections.sort ()를 사용하여 목록 정렬
  3. 삽입 순서를 유지하므로 목록을 LinkedHashSet에 다시 저장합니다.

방법 2 :

  • treeSet을 만들고 여기에 모든 값을 저장합니다.

다른 방법은 해시 세트와 목록간에 데이터를주고받는 데 많은 시간을 소비하기 때문에 방법 2가 더 바람직합니다.


0

HashSet의 요소가 자동으로 정렬되도록 결정할 수 없습니다. 그러나 TreeSet 또는 ArrayList 또는 LinkedList 등과 같은 목록으로 변환하여 정렬 할 수 있습니다.

// Create a TreeSet object of class E
TreeSet<E> ts = new TreeSet<E> ();

// Convert your HashSet into TreeSet
ts.addAll(yourHashSet);

System.out.println(ts.toString() + "\t Sorted Automatically");

0

같은 용도로 구아바 라이브러리를 사용할 수 있습니다.

Set<String> sortedSet = FluentIterable.from(myHashSet).toSortedSet(new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        // descending order of relevance
        //required code
    }
});


0

다음과 같이 TreeSet으로 래핑 할 수 있습니다.

Set mySet = new HashSet();
mySet.add(4);
mySet.add(5);
mySet.add(3);
mySet.add(1);
System.out.println("mySet items "+ mySet);   

TreeSet treeSet = new TreeSet(mySet);   
System.out.println("treeSet items "+ treeSet);   

output :
mySet 항목 [1, 3, 4, 5]
treeSet 항목 [1, 3, 4, 5]

Set mySet = new HashSet();
mySet.add("five");
mySet.add("elf");
mySet.add("four");
mySet.add("six");
mySet.add("two");
System.out.println("mySet items "+ mySet);

TreeSet treeSet = new TreeSet(mySet);
System.out.println("treeSet items "+ treeSet);

출력 :
mySet 항목 [6, 4, 5, 2, elf]
treeSet 항목 [elf, 5, 4, 6, 2]

이 방법에 대한 요구 사항은 집합 / 목록의 개체가 비교 가능해야한다는 것입니다 (Comparable 인터페이스 구현).


-4

이 간단한 명령이 나를 위해 트릭을 수행했습니다.

myHashSet.toList.sorted

나는 이것을 print 문 내에서 사용 했으므로 실제로 순서를 유지해야하는 경우 TreeSets 또는이 스레드에서 제안 된 다른 구조를 사용해야 할 수 있습니다.


1
HashSet 또는 Set에 메서드가있는 위치가 표시되지 않습니다 toList.
Thomas Eizinger 2015 년

1
불행히도 Java의 문제를 해결하지 못하는 Scala처럼 보입니다.
Roberto

toList 메소드, 어떻게 가능합니까?
Ved Prakash
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.