맵은 키-값 쌍의 모음이며 사전 또는 연관 배열 등이라고도 합니다. 가장 일반적인 데이터 구조 중 하나입니다. Java에서 값을 기준으로 지도를 정렬하는 방법은 무엇입니까? 간단한 것 같지만 쉽지는 않아요!
예를 들어 Map의 키는 단어를 나타내는 String 유형이고 값은 단어가 나타나는 횟수를 나타내는 int 유형입니다. 이제 우리는 횟수를 기준으로 정렬하려고 합니다. 단어가 나타납니다:
Map map = new TreeMap(); map.put("me", 1000); map.put("and", 4000); map.put("you", 3000); map.put("food", 10000); map.put("hungry", 5000); map.put("later", 6000);
값으로 정렬한 결과는 다음과 같습니다.
key value me 1000 you 3000 and 4000 hungry 5000 later 6000 food 10000
먼저 SortedMap 구조를 사용할 수 없습니다. SortedMap은 값으로 정렬된 Map이 아니라 키로 정렬된 Map이기 때문에 우리가 원하는 것은 값으로 정렬된 Map입니다.
SortedMap을 사용하면 이 작업을 수행할 수 없나요?
아니요. 맵은 키를 기준으로 정렬되기 때문입니다.
방법 1:
다음 Java 코드:
import java.util.Iterator; import java.util.Set; import java.util.TreeSet; public class Main { public static void main(String[] args) { Set set = new TreeSet(); set.add(new Pair("me", "1000")); set.add(new Pair("and", "4000")); set.add(new Pair("you", "3000")); set.add(new Pair("food", "10000")); set.add(new Pair("hungry", "5000")); set.add(new Pair("later", "6000")); set.add(new Pair("myself", "1000")); for (Iterator i = set.iterator(); i.hasNext();) System.out.println(i.next()); } } class Pair implements Comparable { private final String name; private final int number; public Pair(String name, int number) { this.name = name; this.number = number; } public Pair(String name, String number) throws NumberFormatException { this.name = name; this.number = Integer.parseInt(number); } public int compareTo(Object o) { if (o instanceof Pair) { int cmp = Double.compare(number, ((Pair) o).number); if (cmp != 0) { return cmp; } return name.compareTo(((Pair) o).name); } throw new ClassCastException("Cannot compare Pair with " + o.getClass().getName()); } public String toString() { return name + ' ' + number; } }
비슷한 C++ 코드:
typedef pair<string, int> PAIR; int cmp(const PAIR& x, const PAIR& y) { return x.second > y.second; } map<string,int> m; vector<PAIR> vec; for (map<wstring,int>::iterator curr = m.begin(); curr != m.end(); ++curr) { vec.push_back(make_pair(curr->first, curr->second)); } sort(vec.begin(), vec.end(), cmp);
위 이 메소드의 본질적인 의미는 Map 구조의 키-값 쌍(Map.Entry)을 사용자 정의 클래스(구조)로 캡슐화하거나 Map.Entry 클래스를 직접 사용한다는 것입니다. 사용자 정의 클래스는 정렬 방법, 즉 값을 기준으로 정렬하는 방법을 알고 있습니다. 특히 Comparable 인터페이스를 구현하거나 자체적으로 Comparator 객체를 생성한 다음 정렬된 집합(SortedSet, TreeSet은 SortedSet의 구현)을 사용합니다. Map 구조를 사용하여 Map의 값별 정렬 목적을 달성합니다. 즉, Map을 사용하는 대신 Map.Entry를 객체로 취급하므로 객체의 정렬된 컬렉션을 구현하거나 객체의 컬렉션을 정렬하는 것이 문제가 됩니다. 삽입이 완료된 후 자연스럽게 정렬되도록 SortedSet을 사용할 수도 있고, List 또는 배열을 사용한 다음 정렬할 수도 있습니다(Collections.sort() 또는 Arrays.sort()).
자체 클래스에 정보를 캡슐화합니다.
비교를 구현하고 자연 순서에 대한 규칙을 작성하거나
기준에 따라 비교기를 작성합니다.
컬렉션을 사용하거나 Collections.sort() 메서드를 사용하세요.
방법 2:
다음 코드를 사용하여 값별로 정렬할 수도 있습니다.
public static Map sortByValue(Map map) { List list = new LinkedList(map.entrySet()); Collections.sort(list, new Comparator() { public int compare(Object o1, Object o2) { return ((Comparable) ((Map.Entry) (o1)).getValue()) .compareTo(((Map.Entry) (o2)).getValue()); } }); Map result = new LinkedHashMap(); for (Iterator it = list.iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); result.put(entry.getKey(), entry.getValue()); } return result; } public static Map sortByValue(Map map, final boolean reverse) { List list = new LinkedList(map.entrySet()); Collections.sort(list, new Comparator() { public int compare(Object o1, Object o2) { if (reverse) { return -((Comparable) ((Map.Entry) (o1)).getValue()) .compareTo(((Map.Entry) (o2)).getValue()); } return ((Comparable) ((Map.Entry) (o1)).getValue()) .compareTo(((Map.Entry) (o2)).getValue()); } }); Map result = new LinkedHashMap(); for (Iterator it = list.iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); result.put(entry.getKey(), entry.getValue()); } return result; } Map map = new HashMap(); map.put("a", 4); map.put("b", 1); map.put("c", 3); map.put("d", 2); Map sorted = sortByValue(map); System.out.println(sorted); // output : {b=1, d=2, c=3, a=4} 或者还可以这样: Map map = new HashMap(); map.put("a", 4); map.put("b", 1); map.put("c", 3); map.put("d", 2); Set<Map.Entry<String, Integer>> treeSet = new TreeSet<Map.Entry<String, Integer>>( new Comparator<Map.Entry<String, Integer>>() { public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) { Integer d1 = o1.getValue(); Integer d2 = o2.getValue(); int r = d2.compareTo(d1); if (r != 0) return r; else return o2.getKey().compareTo(o1.getKey()); } }); treeSet.addAll(map.entrySet()); System.out.println(treeSet); // output : [a=4, c=3, d=2, b=1]
또한 Groovy에서는 값별 맵 정렬이 구현됩니다. 물론 본질은 동일하지만 매우 간단합니다.
Groovy에서는 맵의 정렬 방법을 사용합니다. (groovy 1.6 필요),
def result = map.sort(){ a, b -> b.value.compareTo(a.value) }
예:
["a":3,"b":1,"c":4, "d":2].sort { a,b -> a.value - b.value }
결과는 다음과 같습니다: [b:1, d:2, a:3, c :4]
Python에서도 비슷합니다:
h = {"a":2,"b":1,"c":3} i = h.items() // i = [('a', 2), ('c', 3), ('b', 1)] i.sort(lambda (k1,v1),(k2,v2): cmp(v2,v1) ) // i = [('c', 3), ('a', 2), ('b', 1)]
위 글은 Java에서 값에 따른 Map 정렬에 대해 간략하게 설명하고 있으며, 편집기에서 제공하는 내용이 전부입니다. 이 내용이 귀하에게 참고가 되기를 바라며 PHP 중국어 웹사이트를 지원해 주시기를 바랍니다.
Java의 값별 지도 정렬에 대한 더 많은 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!