2013-02-25 3 views
0

이것이 중복 된 경우 사과 드리지만이 특정 문제에 특별히 답변 한 답변을 찾을 수 없습니다.HashSets 컬렉션 정렬

나는 Set 값과 쌍을 이루는 문자열 키를 포함하는 HashMap을 가지고있다. 세트의 길이에 따라지도에서 값을 정렬하고 싶습니다. 고려 :

HashMap<String, Set<String>> myMap; 

은 포함 :

{"A", {"Dukmerriot", "King", "Pumpkin"}} 
{"B", {"Steve"}} 
{"C", {"Jib", "Jab", "John", "Julie"}} 
{"D", {"Apple", "Amy", "Unicorn", "Charlie", "Raptor"}} 
{"E", {}} 

내가 효율적으로 myMap에서 (큰 수에서 작은 세트의 순서를 지정) 목록 {"D", "C", "A", "B", E"}을 얻을 수 있어야합니다.

집합을 구현하고 compareTo 메서드를 재정의하는 래퍼 클래스를 만드는 것 외에 길이에 따라 집합 컬렉션을 정렬하는 방법이 있습니까?

편집 :이 컬렉션을 유지 관리하기 위해 HashMap을 사용할 필요가 없음을 지정해야합니다. TreeMap이나 뭔가를 사용할 수는 있지만 Set이 Comparable을 구현하지 않기 때문에 가능한지 확실하지 않습니다.

+0

_ "효율적으로 myMap에서'{"D ","C ","A ","B ", E"}'를 얻을 수 있기를 원합니다. 집합은 순서가 없으므로 거기에'myMap.keySet()'을 사용하면됩니다. –

+0

기본적으로 그 순서대로 목록을 원합니다. – Devin

+2

집합을 정렬 할 수 있습니다. 예를 들어 TreeSet은 SortedSet입니다. –

답변

2
final Map<String, Set<String>> map = new HashMap<>(); 

map.put("A", ImmutableSet.of("Dukmerriot", "King", "Pumpkin")); 
map.put("B", ImmutableSet.of("Steve")); 
map.put("C", ImmutableSet.of("Jib", "Jab", "John", "Julie")); 
map.put("D", ImmutableSet.of("Apple", "Amy", "Unicorn", "Charlie", "Raptor")); 
map.put("E", new HashSet<String>()); 

List<String> keys = new ArrayList<>(map.keySet()); 
Collections.sort(keys, new Comparator<String>() { 

    @Override 
    public int compare(String o1, String o2) { 
     return Integer.valueOf(map.get(o2).size()).compareTo(map.get(o1).size()); 
    } 
}); 

for (String key : keys) { 
    System.out.println(key); 
} 

인쇄

D 
C 
A 
B 
E 

난 그냥 코드를 짧게하기 위해, 구글 구아바의 ImmutableSet을 사용했다. 유용하다고 생각되는대로 Multimap을보고 싶을 수 있습니다.

0

HashMaps는 정렬 할 수 없습니다. 그들은 키에 의해 가치를보기 위해 최적화되어 있습니다.

0

HashMaps은 내부 주문을 유지하지 않으므로 그렇게 할 수 없습니다. 당신이 할 수있는 가장 좋은 일은 map.values()으로 모든 값을 얻는 것입니다, 그것을 반복하고 어떤 것이 가장 긴지 확인하십시오.

HashMap<T, V> map = ... 
Collection<V> values = map.values(); 

int maxLen = Integer.MIN_VALUE; 
Set<String> winner = null; 
for(V v : values) { 
    if(v.size() > maxLen) { 
    winner = v; 
    } 
} 

TV 및 임의의 타입이다. 귀하의 경우, T는 String과 같고, V는 Set과 같습니다.

+0

이것은 정렬되지 않습니다. 이것은 가장 큰 크기의 키 값을 결정합니다. – Perception

+0

내 머리말이 바뀌 었습니다. 정렬 또는 복사 된 값을지도에서. 그것은 TreeMap 아니,'TreeSet'을 사용했습니다. –

+0

이것은 가장 길게 줄 것입니다,하지만 정렬 된 목록을 얻으려면 n^2 작업이 될 수 있습니다. 로그를 구현한다. n) 올바른 키 순서를 유지하면서 집합에 대한 정렬 알고리즘을 사용했지만 Java가 제공하는 간단한 방법이 있는지 궁금합니다. – Devin

6

집합을 구현하고 compareTo 메서드를 재정의하는 래퍼 클래스를 만드는 것 이외의 길이로 세트 모음을 정렬하는 방법이 있습니까?

그건 완전히 실행 가능한 방법입니다.

List<Set<String>> mySets = new ArrayList<>(myMap.values()); 
mySets.sort(new Comparator<Set<String>>() { 
    @Override 
    public int compare(Set<String> a, Set<String> b) { 
     return Integer.compare(a.size(), b.size()); 
    } 
}); 

...하지만 지금은 각 세트에 해당하는 키를 분실했습니다 당신은 또한 Comparator 사용할 수 있습니다. 이제지도 항목을 정렬 해 봅시다!

List<Entry<String, Set<String>>> entries = new ArrayList<>(myMap.entrySet()); 
entries.sort(new Comparator<Entry<String, Set<String>>>() { 
    @Override 
    public int compare(Entry<String, Set<String>> a,Entry<String, Set<String>> b) { 
     return Integer.compare(a.getValue().size(), b.getValue().size()); 
    } 
}); 

당신은 지금 "쉽게"얻을 수있는 키 :

List<String> sortedKeys = new ArrayList<>(); 
for (Entry<String, Set<String>> e : entries) { 
    sortedKeys = e.getKey(); 
} 

이 목록은 키의 라이브 뷰되지 않습니다, 그러나 그것은 받아 들일 수 있다면 당신의 최선의 방법이 될 것입니다 제한.

+0

굉장! 감사. 나는 그것을 소용돌이 치게 할 것이고, 그것이 나를 위해 일하는 지 알 것이다. – Devin

+0

mySets 대신 "entries.sort (...)"를 의미합니까? – Devin

+0

@Devin 죄송합니다, 예, 했어요. –

0

SetString을 모두 보유하는 사용자 지정 개체를 만듭니다. 클래스를 구현하자 Comparable, 구현은 설정 크기를 usign입니다. 그런 다음 List을 사용하여 채우고 Collections.sort()을 사용하여 원하는 결과를 얻으십시오.

class A implements Comparable { 
    Set set; 
    String string; 

    ...constructor etc.... 

    @Override 
    public int compare(A a,A b) { 
     return Integer.compare(a.set.size(), b.set.size()); 
    } 
}