102

이 질문에는 이미 답변이 있습니다.

내 소팅이 필요해.HashMap그것에 저장된 값에 따라. 그만큼HashMap전화에 저장된 연락처 이름을 포함합니다.

또한 값을 정렬하자 마자 키가 자동으로 정렬되거나 키와 값이 함께 묶여 있으므로 값의 변경 사항이 키에 반영되어야한다고 말할 수 있어야합니다.

HashMap<Integer,String> map = new HashMap<Integer,String>();
map.put(1,"froyo");
map.put(2,"abby");
map.put(3,"denver");
map.put(4,"frost");
map.put(5,"daisy");

필수 출력 :

2,abby;
5,daisy;
3,denver;
4,frost;
1,froyo;

12 답변


72

Java를 가정하면 다음과 같이 hashmap을 정렬 할 수 있습니다.

public LinkedHashMap<Integer, String> sortHashMapByValues(
        HashMap<Integer, String> passedMap) {
    List<Integer> mapKeys = new ArrayList<>(passedMap.keySet());
    List<String> mapValues = new ArrayList<>(passedMap.values());
    Collections.sort(mapValues);
    Collections.sort(mapKeys);

    LinkedHashMap<Integer, String> sortedMap =
        new LinkedHashMap<>();

    Iterator<String> valueIt = mapValues.iterator();
    while (valueIt.hasNext()) {
        String val = valueIt.next();
        Iterator<Integer> keyIt = mapKeys.iterator();

        while (keyIt.hasNext()) {
            Integer key = keyIt.next();
            String comp1 = passedMap.get(key);
            String comp2 = val;

            if (comp1.equals(comp2)) {
                keyIt.remove();
                sortedMap.put(key, val);
                break;
            }
        }
    }
    return sortedMap;
}

그냥 시작 예. 이 방법은 HashMap을 정렬하고 중복 값을 유지하므로 더 유용합니다.


  • 수정 된 버전을 참조하십시오. collections.sort (mapvalues)가 문제를 해결할 것이라고 생각하지 않습니다. - prof_jack
  • 이 코드는 keys.what에 따라 hashmap을 배열했습니다. (2, abby; 5, 데이지, 3, 덴버, 4, 서리, 1, froyo;) 즉 값은 이니셜에 따라 정렬되고 변경 사항이 반영됩니다. 열쇠에 ... - prof_jack
  • 편집 된 버전보기 - prof_jack
  • 나는 당신의 코드를 조금 편집했고, 원하는대로 작동하고있다. 톤 감사합니다. - prof_jack
  • 주어진 알고리즘은 두 개의 while 루프에서 값을 반복적으로 찾아보기 때문에 O (n ^ 2)의 시간 복잡도를 가지고 있음을 명심하십시오. 항목 집합을 목록으로 변환 한 다음 비교자를 기반으로 목록을 정렬하면보다 효율적인 솔루션이됩니다. - picmate 涅

144

아래 코드를 사용해 보면 잘 작동합니다. 오름차순과 내림차순을 모두 선택할 수 있습니다.

import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class SortMapByValue
{
    public static boolean ASC = true;
    public static boolean DESC = false;

    public static void main(String[] args)
    {

        // Creating dummy unsorted map
        Map<String, Integer> unsortMap = new HashMap<String, Integer>();
        unsortMap.put("B", 55);
        unsortMap.put("A", 80);
        unsortMap.put("D", 20);
        unsortMap.put("C", 70);

        System.out.println("Before sorting......");
        printMap(unsortMap);

        System.out.println("After sorting ascending order......");
        Map<String, Integer> sortedMapAsc = sortByComparator(unsortMap, ASC);
        printMap(sortedMapAsc);


        System.out.println("After sorting descindeng order......");
        Map<String, Integer> sortedMapDesc = sortByComparator(unsortMap, DESC);
        printMap(sortedMapDesc);

    }

    private static Map<String, Integer> sortByComparator(Map<String, Integer> unsortMap, final boolean order)
    {

        List<Entry<String, Integer>> list = new LinkedList<Entry<String, Integer>>(unsortMap.entrySet());

        // Sorting the list based on values
        Collections.sort(list, new Comparator<Entry<String, Integer>>()
        {
            public int compare(Entry<String, Integer> o1,
                    Entry<String, Integer> o2)
            {
                if (order)
                {
                    return o1.getValue().compareTo(o2.getValue());
                }
                else
                {
                    return o2.getValue().compareTo(o1.getValue());

                }
            }
        });

        // Maintaining insertion order with the help of LinkedList
        Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
        for (Entry<String, Integer> entry : list)
        {
            sortedMap.put(entry.getKey(), entry.getValue());
        }

        return sortedMap;
    }

    public static void printMap(Map<String, Integer> map)
    {
        for (Entry<String, Integer> entry : map.entrySet())
        {
            System.out.println("Key : " + entry.getKey() + " Value : "+ entry.getValue());
        }
    }
}

편집 : 버전 2

stream for-each와 같은 새로운 자바 기능 사용

값이 동일하면지도가 키순으로 정렬됩니다.

 import java.util.*;
 import java.util.Map.Entry;
 import java.util.stream.Collectors;

 public class SortMapByValue

 {
    private static boolean ASC = true;
    private static boolean DESC = false;
    public static void main(String[] args)
    {

        // Creating dummy unsorted map
        Map<String, Integer> unsortMap = new HashMap<>();
        unsortMap.put("B", 55);
        unsortMap.put("A", 20);
        unsortMap.put("D", 20);
        unsortMap.put("C", 70);

        System.out.println("Before sorting......");
        printMap(unsortMap);

        System.out.println("After sorting ascending order......");
        Map<String, Integer> sortedMapAsc = sortByValue(unsortMap, ASC);
        printMap(sortedMapAsc);


        System.out.println("After sorting descending order......");
        Map<String, Integer> sortedMapDesc = sortByValue(unsortMap, DESC);
        printMap(sortedMapDesc);
    }

    private static Map<String, Integer> sortByValue(Map<String, Integer> unsortMap, final boolean order)
    {
        List<Entry<String, Integer>> list = new LinkedList<>(unsortMap.entrySet());

        // Sorting the list based on values
        list.sort((o1, o2) -> order ? o1.getValue().compareTo(o2.getValue()) == 0
                ? o1.getKey().compareTo(o2.getKey())
                : o1.getValue().compareTo(o2.getValue()) : o2.getValue().compareTo(o1.getValue()) == 0
                ? o2.getKey().compareTo(o1.getKey())
                : o2.getValue().compareTo(o1.getValue()));
        return list.stream().collect(Collectors.toMap(Entry::getKey, Entry::getValue, (a, b) -> b, LinkedHashMap::new));

    }

    private static void printMap(Map<String, Integer> map)
    {
        map.forEach((key, value) -> System.out.println("Key : " + key + " Value : " + value));
    }
}


  • 좋은 대답은 collections 유틸리티를 사용하여 적절한 방법으로 작성했습니다. - Aditya
  • 내 문제를 시도하고지도 변수에 null 요소가 포함될 수 있으므로 추가해야하는 null 검사를 확인하지 않는 비교기 논리를 약간 수정해야한다는 것을 알았습니다. - Aditya
  • 유용하고 명확한 대답. - Emalka
  • 이 솔루션을 가장 간단하고 이해하기 쉬웠습니다. - vikramvi
  • 길이를 기준으로 정렬하려면 어떻게해야합니까?value, 예를 들어 String? - Srujan Barai

54

자바 8 :

Map<Integer, String> sortedMap = 
     unsortedMap.entrySet().stream()
    .sorted(Entry.comparingByValue())
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue,
                              (e1, e2) -> e1, LinkedHashMap::new));


  • 이런 식으로 사용할 수 있을까요?Arrays.sort(hm.values().toArray()); - Hengameh
  • 이 정렬은 거꾸로 될 수 있습니까? 내가 더 큰 것에서 더 작은 것까지 필요한 값 - Aquarius Power
  • @AquariusPowerreversed방법docs.oracle.com/javase/8/docs/api/java/util/…당신은에 의해 반환 된 비교 자에 그것을 적용 할 수있다.comparingByValue() - Vitalii Fedorenko
  • 돌아온Entry.comparingByValue().reversed()호환되지 않습니다..sorted(...)예상 params :( 나는 역 루프로 끝났다.for위에.entrySet().toArray(), 캐스트가 그것을 해결할 수 있습니다, 나는 더 많은 시간을 테스트해야합니다 :) - Aquarius Power
  • @AquariusPower 당신은 캐스팅 할 필요가 없다. 컴파일러에게 제네릭 타입에 대한 힌트를 준다.Entry.<Integer, String>comparingByValue().reversed() - Vitalii Fedorenko

24

너 기본적으로. 에이HashMap근본적으로 순서가 없습니다. 어떤 패턴이든 당신주문해야한다.아니의지해야한다.

다음과 같은 정렬 된지도가 있습니다.TreeMap, 그러나 그들은 전통적으로 가치보다는 열쇠에 의해 분류됩니다. 값별로 정렬하는 것이 상대적으로 드문 경우입니다. 특히 여러 키가 동일한 값을 가질 수 있으므로 더욱 그렇습니다.

당신이하려는 일에 대해 더 많은 맥락을 제시 할 수 있습니까? 정말로 키의 숫자 (문자열)를 저장하고 있다면 아마도SortedSet와 같은TreeSet너에게 도움이 될거야?

또는 두 클래스를 하나의 클래스에 캡슐화하여 동시에 둘 다 업데이트 할 수 있습니다.


  • 편집 된 버전보기 - prof_jack
  • 예를 들어, 이미지에 나타나는 색상을 정렬합니다. max_int 색상을 사용할 수 있으므로 속도가 빨라야합니다. - Rafael Sanches
  • @RafaelSanches : 댓글에 대한 문맥이 무엇인지 분명하지 않습니다. 무엇을 할 것인가?지도어쨌든이 경우에있어? 새로운 질문을하고 싶을 수도 있습니다. - Jon Skeet
  • 가장 좋은 방법으로 값으로 해시 맵을 정렬하는 데 유용한 예제를 제공합니다. - Rafael Sanches
  • 이런 식으로 사용할 수 있을까요?Arrays.sort(hm.values().toArray()); - Hengameh

11

package com.naveen.hashmap;

import java.util.*;
import java.util.Map.Entry;

public class SortBasedonValues {

    /**
     * @param args
     */
    public static void main(String[] args) {

        HashMap<String, Integer> hm = new HashMap<String, Integer>();
        hm.put("Naveen", 2);
        hm.put("Santosh", 3);
        hm.put("Ravi", 4);
        hm.put("Pramod", 1);
        Set<Entry<String, Integer>> set = hm.entrySet();
        List<Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(
                set);
        Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
            public int compare(Map.Entry<String, Integer> o1,
                    Map.Entry<String, Integer> o2) {
                return o2.getValue().compareTo(o1.getValue());
            }
        });

        for (Entry<String, Integer> entry : list) {
            System.out.println(entry.getValue());

        }

    }
}


  • 이 코드를 실행 해 보았습니다.import java.util.Map.Entry;'그러나 같은 코드가 실행되지 않습니다.import java.util.*;나중에 내 지식에 따라 전을 포함합니다. 그런데 왜 오류가 발생합니까? - NaveeNeo
  • 간단하고 우아한 - Caveman

9

map.entrySet().stream()
                .sorted((k1, k2) -> -k1.getValue().compareTo(k2.getValue()))
                .forEach(k -> System.out.println(k.getKey() + ": " + k.getValue()));


  • 나에게 가장 읽기 쉬운 솔루션이며, 업무를 수행합니다 (예 : 값으로 정렬 된 HashMap을 통해 실행 - user1813222

7

일종의 간단한 솔루션으로, 최종 결과가 필요한 경우 임시 TreeMap을 사용할 수 있습니다.

TreeMap<String, Integer> sortedMap = new TreeMap<String, Integer>();
for (Map.Entry entry : map.entrySet()) {
    sortedMap.put((String) entry.getValue(), (Integer)entry.getKey());
}

이렇게하면 sortedMap의 키로 정렬 된 문자열을 얻을 수 있습니다.


  • 모든 정수 값이 고유 한 경우에만 작동합니다. 그렇지 않으면 문자열을 덮어 씁니다. - Kyzderp

4

TreeMap을 확장하고 entrySet () 및 values () 메서드를 재정의합니다. 키와 값은 Comparable이어야합니다.

코드를 따르십시오 :

public class ValueSortedMap<K extends Comparable, V extends Comparable> extends TreeMap<K, V> {

    @Override
    public Set<Entry<K, V>> entrySet() {
        Set<Entry<K, V>> originalEntries = super.entrySet();
        Set<Entry<K, V>> sortedEntry = new TreeSet<Entry<K, V>>(new Comparator<Entry<K, V>>() {
            @Override
            public int compare(Entry<K, V> entryA, Entry<K, V> entryB) {
                int compareTo = entryA.getValue().compareTo(entryB.getValue());
                if(compareTo == 0) {
                    compareTo = entryA.getKey().compareTo(entryB.getKey());
                }
                return compareTo;
            }
        });
        sortedEntry.addAll(originalEntries);
        return sortedEntry;
    }

    @Override
    public Collection<V> values() {
        Set<V> sortedValues = new TreeSet<>(new Comparator<V>(){
            @Override
            public int compare(V vA, V vB) {
                return vA.compareTo(vB);
            }
        });
        sortedValues.addAll(super.values());
        return sortedValues;
    }
}

단위 테스트 :

public class ValueSortedMapTest {

    @Test
    public void basicTest() {
        Map<String, Integer> sortedMap = new ValueSortedMap<>();
        sortedMap.put("A",3);
        sortedMap.put("B",1);
        sortedMap.put("C",2);

        Assert.assertEquals("{B=1, C=2, A=3}", sortedMap.toString());
    }

    @Test
    public void repeatedValues() {
        Map<String, Double> sortedMap = new ValueSortedMap<>();
        sortedMap.put("D",67.3);
        sortedMap.put("A",99.5);
        sortedMap.put("B",67.4);
        sortedMap.put("C",67.4);

        Assert.assertEquals("{D=67.3, B=67.4, C=67.4, A=99.5}", sortedMap.toString());
    }

}


  • 이것은Map인터페이스. 적절한 구현entrySet():"이지도에 포함 된 매핑의 세트보기를 반환합니다.집합은지도에 의해 뒷받침되므로지도에 대한 변경 사항은 집합에 반영되며 그 반대의 경우도 마찬가지입니다.. "같은 일values(). - Radiodef
  • 내가 뭘 찾고 있었나? - Shashank

2

솔루션을 찾았지만지도에 큰 크기가있는 경우 성능이 확실하지 않아 정상적인 경우에 유용합니다.

   /**
     * sort HashMap<String, CustomData> by value
     * CustomData needs to provide compareTo() for comparing CustomData
     * @param map
     */

    public void sortHashMapByValue(final HashMap<String, CustomData> map) {
        ArrayList<String> keys = new ArrayList<String>();
        keys.addAll(map.keySet());
        Collections.sort(keys, new Comparator<String>() {
            @Override
            public int compare(String lhs, String rhs) {
                CustomData val1 = map.get(lhs);
                CustomData val2 = map.get(rhs);
                if (val1 == null) {
                    return (val2 != null) ? 1 : 0;
                } else if (val1 != null) && (val2 != null)) {
                    return = val1.compareTo(val2);
                }
                else {
                    return 0;
                }
            }
        });

        for (String key : keys) {
            CustomData c = map.get(key);
            if (c != null) {
                Log.e("key:"+key+", CustomData:"+c.toString());
            } 
        }
    }


  • 이 경우 오타가 있어야합니다. if ((val1! = null) & & (val2! = null)) {return val1.compareTo (val2); } 비교 방법 - Tanuj Verma

0

package SortedSet;

import java.util.*;

public class HashMapValueSort {
public static void main(String[] args){
    final Map<Integer, String> map = new HashMap<Integer,String>();
    map.put(4,"Mango");
    map.put(3,"Apple");
    map.put(5,"Orange");
    map.put(8,"Fruits");
    map.put(23,"Vegetables");
    map.put(1,"Zebra");
    map.put(5,"Yellow");
    System.out.println(map);
    final HashMapValueSort sort = new HashMapValueSort();
    final Set<Map.Entry<Integer, String>> entry = map.entrySet();
    final Comparator<Map.Entry<Integer, String>> comparator = new Comparator<Map.Entry<Integer, String>>() {
        @Override
        public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) {
            String value1 = o1.getValue();
            String value2 = o2.getValue();
            return value1.compareTo(value2);
        }
    };
    final SortedSet<Map.Entry<Integer, String>> sortedSet = new TreeSet(comparator);
    sortedSet.addAll(entry);
    final Map<Integer,String> sortedMap =  new LinkedHashMap<Integer, String>();
    for(Map.Entry<Integer, String> entry1 : sortedSet ){
        sortedMap.put(entry1.getKey(),entry1.getValue());
    }
    System.out.println(sortedMap);
}
}



-1

public static TreeMap<String, String> sortMap(HashMap<String, String> passedMap, String byParam) {
    if(byParam.trim().toLowerCase().equalsIgnoreCase("byValue")) {
        // Altering the (key, value) -> (value, key)
        HashMap<String, String> newMap =  new HashMap<String, String>();
        for (Map.Entry<String, String> entry : passedMap.entrySet()) {
            newMap.put(entry.getValue(), entry.getKey());
        }
        return new TreeMap<String, String>(newMap);
    }
    return new TreeMap<String, String>(passedMap);
}


-1

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;

public class CollectionsSort {

    /**
     * @param args
     */`enter code here`
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        CollectionsSort colleciotns = new CollectionsSort();

        List<combine> list = new ArrayList<combine>();
        HashMap<String, Integer> h = new HashMap<String, Integer>();
        h.put("nayanana", 10);
        h.put("lohith", 5);

        for (Entry<String, Integer> value : h.entrySet()) {
            combine a = colleciotns.new combine(value.getValue(),
                    value.getKey());
            list.add(a);
        }

        Collections.sort(list);
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }

    public class combine implements Comparable<combine> {

        public int value;
        public String key;

        public combine(int value, String key) {
            this.value = value;
            this.key = key;
        }

        @Override
        public int compareTo(combine arg0) {
            // TODO Auto-generated method stub
            return this.value > arg0.value ? 1 : this.value < arg0.value ? -1
                    : 0;
        }

        public String toString() {
            return this.value + " " + this.key;
        }
    }

}


  • 응답하기 전에 코드가 올바르게 실행되는지 확인하십시오. 또한 질문을 더 잘 이해할 수 있도록 의견을 추가하는 것도 고려하십시오. - Daniel F. Thornton

연결된 질문


관련된 질문

최근 질문