Сортировать карту по ключу и значению - PullRequest
4 голосов
/ 01 июля 2011

Я хочу отсортировать карту по ключу и значению. Сначала по ключу, потом по значению. Например, это должен быть результат;

1,2 1,3 2,1 2,2

У кого-нибудь есть предложения о том, как этого добиться эффективно? Я видел людей, использующих TreeMap для сортировки ключей, однако мне также нужны значения.

Или можно использовать любой другой метод сортировки пар по ключу и значению.

Ответы [ 9 ]

6 голосов
/ 01 июля 2011
import java.util.SortedSet;
import java.util.TreeSet;

public class SortMapOnKeyAndValue {

    public static void main(String[] args) {
        SortedSet<KeyValuePair> sortedSet = new TreeSet<KeyValuePair>();
        sortedSet.add(new KeyValuePair(1, 2));
        sortedSet.add(new KeyValuePair(2, 2));
        sortedSet.add(new KeyValuePair(1, 3));
        sortedSet.add(new KeyValuePair(2, 1));

        for (KeyValuePair keyValuePair : sortedSet) {
            System.out.println(keyValuePair.key+","+keyValuePair.value);
        }
    }
}
class KeyValuePair implements Comparable<KeyValuePair>{
    int key, value;

    public KeyValuePair(int key, int value) {
        super();
        this.key = key;
        this.value = value;
    }

    public int compareTo(KeyValuePair o) {
        return key==o.key?value-o.value:key-o.key;
    }
}
3 голосов
/ 23 ноября 2012

То, что вы ищете, является SortedSetMultimap, частью библиотеки Google Guava. Реализация, которую они включают, называется TreeMultimap:
http://docs.guava -libraries.googlecode.com / ГИТ-история / выпуск / Javadoc / COM / Google / общие / собирать / TreeMultimap.html

Если вы не знакомы с ней, Guava - это фантастическая библиотека с множеством замечательных вещей, которые, как вы иногда думаете, должны быть в стандартных библиотеках Java. Я думаю, что Java 8, на самом деле, будет включать некоторые вещи из Гуавы (по крайней мере, мне показалось, что это дрейф этого элемента: http://openjdk.java.net/jeps/108).

1 голос
/ 01 июля 2011

Звучит так, будто вам нужна мультикарта какого-то типа, например,

SortedMap<Key, SortedSet<Value>> map = new TreeMap<Key, SortedSet<Value>>();

map.put(1, new TreeSet<Integer>(Arrays.asList(1, 2)));
map.put(2, new TreeSet<Integer>(Arrays.asList(2, 1)));

System.out.println(map);

печать

{ 1 = {1, 2}, 2 = {1, 2}}
0 голосов
/ 18 октября 2018

Пожалуйста, следуйте этому коду: - Этот код сначала отсортирует карту по ключу, а затем по значению.Просто напишите основной метод и вызовите этот метод следующим образом: -

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

public class SortMapByKeyAndValue
{
    public static void main(String[] args)
    {
        aMapSortProgramByKeyAndValue();
    }

    private static void aMapSortProgramByKeyAndValue()
    {
        Map<String, Integer> myMap = new HashMap<String, Integer>();
        // putting values in the Map
        myMap.put("Jayant", 80);
        myMap.put("Abhishek", 90);
        myMap.put("Anushka", 80);
        myMap.put("Amit", 75);
        myMap.put("Spandan", 50);
        myMap.put("Hari", 55);
        myMap.put("Keshav", 60);

        System.out.println("Map data without Sort :-");
        for (Entry<String, Integer> myEntryMapData : myMap.entrySet())
        {
            System.out.println("The Map data is Key: " + myEntryMapData.getKey() + " Value: "
                    + myEntryMapData.getValue());
        }

        List<Entry<String, Integer>> myMapDataAsList = new ArrayList<Map.Entry<String, Integer>>();
        myMapDataAsList.addAll(myMap.entrySet());

        System.out.println("Map data Stored in List, The whole List is : " + myMapDataAsList);

        Iterator<Entry<String, Integer>> myListIterator = myMapDataAsList.iterator();
        System.out.println("Map data Stored in List, Print through iterator :-");

        for (; myListIterator.hasNext();)
        {
            Entry<String, Integer> myListData = myListIterator.next();
            System.out.println("The List data is Key: " + myListData.getKey() + " Value: " + myListData.getValue());
        }

        Collections.sort(myMapDataAsList, new Comparator<Entry<String, Integer>>()
        {

            @Override
            public int compare(Entry<String, Integer> dataOne, Entry<String, Integer> dataTwo)
            {
                return dataOne.getKey().compareTo(dataTwo.getKey());
            }

        });

        System.out.println("After Sort by the Key the Map data is : ");
        myListIterator = myMapDataAsList.iterator();
        for (; myListIterator.hasNext();)
        {
            Entry<String, Integer> myListData = myListIterator.next();
            System.out.println("The List data is Key: " + myListData.getKey() + " Value: " + myListData.getValue());
        }

        Collections.sort(myMapDataAsList, new Comparator<Entry<String, Integer>>()
        {

            @Override
            public int compare(Entry<String, Integer> dataOne, Entry<String, Integer> dataTwo)
            {
                return dataOne.getValue().compareTo(dataTwo.getValue());
            }

        });

        System.out.println("After Sort by the vale the Map data is : ");
        myListIterator = myMapDataAsList.iterator();
        for (; myListIterator.hasNext();)
        {
            Entry<String, Integer> myListData = myListIterator.next();
            System.out.println("The List data is Key: " + myListData.getKey() + " Value: " + myListData.getValue());
        }
    }
}
0 голосов
/ 01 июля 2011

Общая идея заключается в том, чтобы преобразовать карту в список, отсортировать список и поместить отсортированный список обратно в карту.

Карта ---> Список ---> Сортировать ---> Карта

Пример

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

public class SortMyMap{

   public static void main(String[] args) {

    System.out.println("Unsort Map......");
    Map<String,String> unsortMap = new HashMap<String,String>();
    unsortMap.put("1", "1");
    unsortMap.put("2", "A");
    unsortMap.put("3", "2");

    Iterator iterator=unsortMap.entrySet().iterator();

        for (Map.Entry entry : unsortMap.entrySet()) {
            System.out.println("Key : " + entry.getKey() 
                + " Value : " + entry.getValue());
        }

        System.out.println("Sorted Map......");
        Map<String,String> sortedMap =  sortByComparator(unsortMap);

        for (Map.Entry entry : sortedMap.entrySet()) {
            System.out.println("Key : " + entry.getKey() 
                + " Value : " + entry.getValue());
        }
   }

   private static Map sortByComparator(Map unsortMap) {

        List list = new LinkedList(unsortMap.entrySet());

        //sort list based on comparator
        Collections.sort(list, new Comparator() {
             public int compare(Object o1, Object o2) {
               return ((Comparable) ((Map.Entry) (o1)).getValue())
               .compareTo(((Map.Entry) (o2)).getValue());
             }
    });

        //put sorted list into map again
    Map sortedMap = new LinkedHashMap();
    for (Iterator it = list.iterator(); it.hasNext();) {
         Map.Entry entry = (Map.Entry)it.next();
         sortedMap.put(entry.getKey(), entry.getValue());
    }
    return sortedMap;
   }    
}
0 голосов
/ 01 июля 2011

Другие ответы указали на проблему с дублирующимися ключами, но я предполагаю, что у вас есть пары, которые вы хотите отсортировать, и бит карты был просто ошибкой.Самое чистое решение, которое я могу придумать, - это создать собственный класс Pair, который реализует Comparator и сравнивает ключ и значение двух пар.Затем вы можете использовать Collections.sort для сортировки.

0 голосов
/ 01 июля 2011

Если вы готовы пойти на риск, вы можете использовать конструктор, который позволяет вам указать компаратор: http://download.oracle.com/javase/1.5.0/docs/api/java/util/TreeMap.html#TreeMap%28java.util.Comparator%29

Сказав, что то, что вы хотите сделать, уродливо, как ад и незаконно, потому что: * порядок не будет соответствовать equals (), который является обязательным для SortedSet) * порядок может измениться из-за изменения значений в карте, и я не знаю, допускает ли это его реализация.

Я думаю, что тебе нужно что-то еще.Возможно, вам будет лучше, если вы создадите объект, который имеет ключ и значение и должным образом реализует equals (), hashcode () и Comparable, и используете с ним SortedSet.


РЕДАКТИРОВАТЬ: я ответилобщий вопрос (сортировка карты по ключу и значению), не глядя на ваши образцы.Как написали другие, у вас не может быть дубликатов ключей на карте.

0 голосов
/ 01 июля 2011

у вас не может быть такой карты

 1->11
 1->21

ключ '1' является общим, поэтому 21 заменит 11

0 голосов
/ 01 июля 2011

Это невозможно, поскольку карта не может содержать дубликаты ключей. TreeMap всегда сортируется по значению ключа (при условии, что тип ключа Comparable).


Но для этих задач мы обычно берем карту, значения которой являются списками:

Map<Integer, List<Integer>> map = new TreeMap<Integer, List<Integer>>();

// add some values in random order
List<Integer> list = new ArrayList<Integer>();
list.add(2);
list.add(1);
map.put(2,list);
list = new ArrayList<Integer>();
list.add(2);
list.add(1);
map.put(1,list);

// result
for (Integer key:map.keySet()) {   // map is already sorted
  List<Integer> value = map.get(key);
  Collections.sort(value);         // list of values needs sorting
  for (Integer innerValue:value) {
    System.out.printf("%s : %s%n", key, innerValue);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...