Сортировать карту < Ключ, Значение > по значениям

PrintWriter pw = new PrintWriter(new FileOutputStream(new File("persons.txt"),true));

true - флаг добавления. См. Документацию .

1528
задан 10 revs, 9 users 33% 24 February 2018 в 14:48
поделиться

20 ответов

Для сортировки на ключи я нашел лучшее решение с TreeMap (я попытаюсь получить решение для основанной на значении сортировки, готовой также):

public static void main(String[] args) {
    Map<String, String> unsorted = new HashMap<String, String>();
    unsorted.put("Cde", "Cde_Value");
    unsorted.put("Abc", "Abc_Value");
    unsorted.put("Bcd", "Bcd_Value");

    Comparator<String> comparer = new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            return o1.compareTo(o2);
        }};

    Map<String, String> sorted = new TreeMap<String, String>(comparer);
    sorted.putAll(unsorted);
    System.out.println(sorted);
}

Вывод был бы:

{Abc=Abc_Value, Bcd=Bcd_Value, Cde=Cde_Value}

-2
ответ дан 3 revs, 2 users 65% 24 February 2018 в 14:48
поделиться

Если Ваши значения Карты реализуют Сопоставимый (например, Строка), это должно работать

Map<Object, String> map = new HashMap<Object, String>();
// Populate the Map
List<String> mapValues = new ArrayList<String>(map.values());
Collections.sort(mapValues);

, Если сами значения карты не реализуют Сопоставимый, но у Вас есть экземпляр Сопоставимых, которые могут отсортировать их, заменить последнюю строку этим:

Collections.sort(mapValues, comparable);
-9
ответ дан 2 revs 24 February 2018 в 14:48
поделиться

От http://www.programmersheaven.com/download/49349/download.aspx

private static <K, V> Map<K, V> sortByValue(Map<K, V> map) {
    List<Entry<K, V>> list = new LinkedList<>(map.entrySet());
    Collections.sort(list, new Comparator<Object>() {
        @SuppressWarnings("unchecked")
        public int compare(Object o1, Object o2) {
            return ((Comparable<V>) ((Map.Entry<K, V>) (o1)).getValue()).compareTo(((Map.Entry<K, V>) (o2)).getValue());
        }
    });

    Map<K, V> result = new LinkedHashMap<>();
    for (Iterator<Entry<K, V>> it = list.iterator(); it.hasNext();) {
        Map.Entry<K, V> entry = (Map.Entry<K, V>) it.next();
        result.put(entry.getKey(), entry.getValue());
    }

    return result;
}
182
ответ дан 3 revs, 3 users 60% 24 February 2018 в 14:48
поделиться

Хорошо, эта версия работает с двумя новыми объектами Карты и двумя повторениями и видами на значениях. Надежда, выполнять хорошо, хотя записи карты должны быть циклично выполнены дважды:

public static void main(String[] args) {
    Map<String, String> unsorted = new HashMap<String, String>();
    unsorted.put("Cde", "Cde_Value");
    unsorted.put("Abc", "Abc_Value");
    unsorted.put("Bcd", "Bcd_Value");

    Comparator<String> comparer = new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            return o1.compareTo(o2);
        }};

    System.out.println(sortByValue(unsorted, comparer));

}

public static <K, V> Map<K,V> sortByValue(Map<K, V> in, Comparator<? super V> compare) {
    Map<V, K> swapped = new TreeMap<V, K>(compare);
    for(Entry<K,V> entry: in.entrySet()) {
        if (entry.getValue() != null) {
            swapped.put(entry.getValue(), entry.getKey());
        }
    }
    LinkedHashMap<K, V> result = new LinkedHashMap<K, V>();
    for(Entry<V,K> entry: swapped.entrySet()) {
        if (entry.getValue() != null) {
            result.put(entry.getValue(), entry.getKey());
        }
    }
    return result;
}

решение использует TreeMap с Компаратором и разбирается во всех пустых ключах и значениях. Во-первых, функциональность упорядочивания от TreeMap привыкла к виду на значения, затем отсортированная Карта используется для создания результата как LinkedHashMap, который сохраняет, имеет тот же порядок значений.

Greetz, GHad

-2
ответ дан GHad 24 February 2018 в 14:48
поделиться

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

public class MapUtilities {

public static <K, V extends Comparable<V>> List<Entry<K, V>> sortByValue(Map<K, V> map) {
    List<Entry<K, V>> entries = new ArrayList<Entry<K, V>>(map.entrySet());
    Collections.sort(entries, new ByValue<K, V>());
    return entries;
}

private static class ByValue<K, V extends Comparable<V>> implements Comparator<Entry<K, V>> {
    public int compare(Entry<K, V> o1, Entry<K, V> o2) {
        return o1.getValue().compareTo(o2.getValue());
    }
}

}

И вот смущающе неполный модульный тест:

public class MapUtilitiesTest extends TestCase {
public void testSorting() {
    HashMap<String, Integer> map = new HashMap<String, Integer>();
    map.put("One", 1);
    map.put("Two", 2);
    map.put("Three", 3);

    List<Map.Entry<String, Integer>> sorted = MapUtilities.sortByValue(map);
    assertEquals("First", "One", sorted.get(0).getKey());
    assertEquals("Second", "Two", sorted.get(1).getKey());
    assertEquals("Third", "Three", sorted.get(2).getKey());
}

}

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

14
ответ дан 3 revs 24 February 2018 в 14:48
поделиться

В зависимости от контекста, с помощью java.util.LinkedHashMap<T>, который rememebers порядок, в который объекты помещаются в карту. Иначе, если бы необходимо отсортировать значения на основе их естественного упорядочивания, я рекомендовал бы вести отдельный Список, который может быть отсортирован через Collections.sort().

5
ответ дан Ryan Delucchi 24 February 2018 в 14:48
поделиться

Сортировка ключей требует, чтобы Компаратор искал каждое значение для каждого сравнения. Больше масштабируемого решения использовало бы entrySet непосредственно, с тех пор значение будет сразу доступно для каждого сравнения (хотя я не создал резервную копию этого числами).

Вот универсальная версия такой вещи:

public static <K, V extends Comparable<? super V>> List<K> getKeysSortedByValue(Map<K, V> map) {
    final int size = map.size();
    final List<Map.Entry<K, V>> list = new ArrayList<Map.Entry<K, V>>(size);
    list.addAll(map.entrySet());
    final ValueComparator<V> cmp = new ValueComparator<V>();
    Collections.sort(list, cmp);
    final List<K> keys = new ArrayList<K>(size);
    for (int i = 0; i < size; i++) {
        keys.set(i, list.get(i).getKey());
    }
    return keys;
}

private static final class ValueComparator<V extends Comparable<? super V>>
                                     implements Comparator<Map.Entry<?, V>> {
    public int compare(Map.Entry<?, V> o1, Map.Entry<?, V> o2) {
        return o1.getValue().compareTo(o2.getValue());
    }
}

существуют способы уменьшить вращение памяти для вышеупомянутого решения. Первый ArrayList создал, мог, например, быть снова использован как возвращаемое значение; это потребовало бы подавления некоторых предупреждений дженериков, но это могло бы стоить того для допускающего повторное использование кода библиотеки. Кроме того, Компаратор не должен быть перераспределен при каждом вызове.

Вот более эффективное хотя менее привлекательная версия:

public static <K, V extends Comparable<? super V>> List<K> getKeysSortedByValue2(Map<K, V> map) {
    final int size = map.size();
    final List reusedList = new ArrayList(size);
    final List<Map.Entry<K, V>> meView = reusedList;
    meView.addAll(map.entrySet());
    Collections.sort(meView, SINGLE);
    final List<K> keyView = reusedList;
    for (int i = 0; i < size; i++) {
        keyView.set(i, meView.get(i).getKey());
    }
    return keyView;
}

private static final Comparator SINGLE = new ValueComparator();

Наконец, если необходимо непрерывно получать доступ к отсортированной информации (вместо того, чтобы просто сортировать его время от времени), можно использовать дополнительную много карту. Сообщите мне, нужно ли Вам больше деталей...

31
ответ дан 7 revs 24 February 2018 в 14:48
поделиться

Используйте java.util. TreeMap.

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

-11
ответ дан yoliho 24 February 2018 в 14:48
поделиться

Когда я сталкиваюсь с этим, я просто создаю список на стороне. При соединении их в пользовательской Реализации Map она будет иметь хорошее чувство к нему... Можно использовать что-то как следующее, выполняя вид только при необходимости. (Отметьте: Я действительно не протестировал это, но это компилирует... могла бы быть глупая небольшая ошибка там где-нибудь)

(Если Вы хотите отсортированный и по ключам и по значениям, имеете класс, расширяют TreeMap, не определяйте методы доступа и имейте мутаторный вызов super.xxxxx вместо map_. xxxx)

package com.javadude.sample;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class SortedValueHashMap<K, V> implements Map<K, V> {
    private Map<K, V> map_ = new HashMap<K, V>();
    private List<V> valueList_ = new ArrayList<V>();
    private boolean needsSort_ = false;
    private Comparator<V> comparator_;

    public SortedValueHashMap() {
    }
    public SortedValueHashMap(List<V> valueList) {
        valueList_ = valueList;
    }

    public List<V> sortedValues() {
        if (needsSort_) {
            needsSort_ = false;
            Collections.sort(valueList_, comparator_);
        }
        return valueList_;
    }

    // mutators
    public void clear() {
        map_.clear();
        valueList_.clear();
        needsSort_ = false;
    }

    public V put(K key, V value) {
        valueList_.add(value);
        needsSort_ = true;
        return map_.put(key, value);
    }

    public void putAll(Map<? extends K, ? extends V> m) {
        map_.putAll(m);
        valueList_.addAll(m.values());
        needsSort_ = true;
    }

    public V remove(Object key) {
        V value = map_.remove(key);
        valueList_.remove(value);
        return value;
    }

    // accessors
    public boolean containsKey(Object key)           { return map_.containsKey(key); }
    public boolean containsValue(Object value)       { return map_.containsValue(value); }
    public Set<java.util.Map.Entry<K, V>> entrySet() { return map_.entrySet(); }
    public boolean equals(Object o)                  { return map_.equals(o); }
    public V get(Object key)                         { return map_.get(key); }
    public int hashCode()                            { return map_.hashCode(); }
    public boolean isEmpty()                         { return map_.isEmpty(); }
    public Set<K> keySet()                           { return map_.keySet(); }
    public int size()                                { return map_.size(); }
    public Collection<V> values()                    { return map_.values(); }
}
2
ответ дан Scott Stanchfield 24 February 2018 в 14:48
поделиться

Библиотека наборов свободного городского населения содержит решение, названное TreeBidiMap. Или, Вы могли взглянуть на Google Collections API. Это имеет TreeMultimap, который Вы могли использовать.

И если Вы не хотите использовать их платформа..., они идут с исходным кодом.

26
ответ дан 2 revs, 2 users 72% 24 February 2018 в 14:48
поделиться

регистрация моей версии ответа

List<Map.Entry<String, Integer>> list = new ArrayList<>(map.entrySet());
    Collections.sort(list, (obj1, obj2) -> obj2.getValue().compareTo(obj1.getValue()));
    Map<String, Integer> resultMap = new LinkedHashMap<>();
    list.forEach(arg0 -> {
        resultMap.put(arg0.getKey(), arg0.getValue());
    });
    System.out.println(resultMap);
0
ответ дан Praveen Kumar Mekala 28 July 2019 в 15:51
поделиться

Важное примечание:

Этот код можно взломать несколькими способами. Если вы собираетесь использовать предоставленный код, обязательно прочтите комментарии, чтобы знать о последствиях. Например, значения больше нельзя получить по их ключу. ( get всегда возвращает null .)


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

public class Testing {
    public static void main(String[] args) {
        HashMap<String, Double> map = new HashMap<String, Double>();
        ValueComparator bvc = new ValueComparator(map);
        TreeMap<String, Double> sorted_map = new TreeMap<String, Double>(bvc);

        map.put("A", 99.5);
        map.put("B", 67.4);
        map.put("C", 67.4);
        map.put("D", 67.3);

        System.out.println("unsorted map: " + map);
        sorted_map.putAll(map);
        System.out.println("results: " + sorted_map);
    }
}

class ValueComparator implements Comparator<String> {
    Map<String, Double> base;

    public ValueComparator(Map<String, Double> base) {
        this.base = base;
    }

    // Note: this comparator imposes orderings that are inconsistent with
    // equals.
    public int compare(String a, String b) {
        if (base.get(a) >= base.get(b)) {
            return -1;
        } else {
            return 1;
        } // returning 0 would merge keys
    }
}

Вывод:

unsorted map: {D=67.3, A=99.5, B=67.4, C=67.4}
results: {D=67.3, B=67.4, C=67.4, A=99.5}
411
ответ дан 22 November 2019 в 20:13
поделиться

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

Вот решение, которое я думаю, лучше подходит к лучшему:

public static <K, V extends Comparable<V>> Map<K, V> sortByValues(final Map<K, V> map) {
    Comparator<K> valueComparator =  new Comparator<K>() {
        public int compare(K k1, K k2) {
            int compare = map.get(k2).compareTo(map.get(k1));
            if (compare == 0) return 1;
            else return compare;
        }
    };
    Map<K, V> sortedByValues = new TreeMap<K, V>(valueComparator);
    sortedByValues.putAll(map);
    return sortedByValues;
}

Обратите внимание, что карта отсортирована от наибольшего значения до самой низкой.

25
ответ дан 22 November 2019 в 20:13
поделиться

Вот общая версия:

public class MapUtil {
    public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
        List<Entry<K, V>> list = new ArrayList<>(map.entrySet());
        list.sort(Entry.comparingByValue());

        Map<K, V> result = new LinkedHashMap<>();
        for (Entry<K, V> entry : list) {
            result.put(entry.getKey(), entry.getValue());
        }

        return result;
    }
}
869
ответ дан 22 November 2019 в 20:13
поделиться

Три однострочных ответа ...

Я бы использовал Google Collections Guava для этого - если ваши значения Comparable ], то вы можете использовать

valueComparator = Ordering.natural().onResultOf(Functions.forMap(map))

, который создаст функцию (объект) для карты [которая принимает любой из ключей в качестве входных данных, возвращая соответствующее значение], а затем применяет естественный (сопоставимый) порядок к ним [значениям].

Если они не сопоставимы, вам нужно сделать что-то вроде

valueComparator = Ordering.from(comparator).onResultOf(Functions.forMap(map)) 

. Их можно применить к TreeMap (поскольку Упорядочивание расширяет Comparator ) , или LinkedHashMap после некоторой сортировки

NB : если вы собираетесь использовать TreeMap, помните, что если сравнение == 0, то элемент уже находится в списке (что произойдет, если вы имеют несколько значений, которые сравниваются с одинаковыми).Чтобы облегчить это, вы можете добавить свой ключ к компаратору следующим образом (при условии, что ваши ключи и значения Comparable ):

valueComparator = Ordering.natural().onResultOf(Functions.forMap(map)).compound(Ordering.natural())

= Применить естественный порядок к значению, отображаемому ключом, и составить это с естественным порядком ключей

. Обратите внимание, что это все равно не будет работать, если ваши ключи сравниваются с 0, но этого должно быть достаточно для большинства сопоставимых элементов (как hashCode , равно и compareTo часто синхронизируются ...)

См. Ordering.onResultOf () и Functions.forMap () .

Реализация

Итак, теперь, когда у нас есть компаратор, который делает то, что мы хотим, нам нужно получить от него результат.

map = ImmutableSortedMap.copyOf(myOriginalMap, valueComparator);

Теперь это, скорее всего, сработает, но:

  1. необходимо выполнить с учетом полностью готовой карты
  2. Не пытайтесь использовать приведенные выше компараторы на TreeMap ; нет смысла пытаться сравнить вставленный ключ, если он не имеет значения до тех пор, пока не будет помещен, т.е., он сломается очень быстро

Пункт 1 для меня немного мешает; Коллекции google невероятно ленивы (что хорошо: вы можете выполнять практически все операции в одно мгновение; настоящая работа выполняется, когда вы начинаете использовать результат), и для этого требуется скопировать всю карту !

«Полный» ответ / Живая карта с сортировкой по значениям

Не волнуйтесь; Если бы вы были достаточно одержимы такой сортировкой «живой» карты, вы могли бы решить не одну, а обе (!) из вышеуказанных проблем с помощью чего-то безумного, например следующего:

Примечание: это значительно изменилось в июне 2012 года. - предыдущий код никогда не мог работать: требуется внутренний HashMap для поиска значений без создания бесконечного цикла между TreeMap.get () -> compare () и compare () -> get ()

import static org.junit.Assert.assertEquals;

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

import com.google.common.base.Functions;
import com.google.common.collect.Ordering;

class ValueComparableMap<K extends Comparable<K>,V> extends TreeMap<K,V> {
    //A map for doing lookups on the keys for comparison so we don't get infinite loops
    private final Map<K, V> valueMap;

    ValueComparableMap(final Ordering<? super V> partialValueOrdering) {
        this(partialValueOrdering, new HashMap<K,V>());
    }

    private ValueComparableMap(Ordering<? super V> partialValueOrdering,
            HashMap<K, V> valueMap) {
        super(partialValueOrdering //Apply the value ordering
                .onResultOf(Functions.forMap(valueMap)) //On the result of getting the value for the key from the map
                .compound(Ordering.natural())); //as well as ensuring that the keys don't get clobbered
        this.valueMap = valueMap;
    }

    public V put(K k, V v) {
        if (valueMap.containsKey(k)){
            //remove the key in the sorted set before adding the key again
            remove(k);
        }
        valueMap.put(k,v); //To get "real" unsorted values for the comparator
        return super.put(k, v); //Put it in value order
    }

    public static void main(String[] args){
        TreeMap<String, Integer> map = new ValueComparableMap<String, Integer>(Ordering.natural());
        map.put("a", 5);
        map.put("b", 1);
        map.put("c", 3);
        assertEquals("b",map.firstKey());
        assertEquals("a",map.lastKey());
        map.put("d",0);
        assertEquals("d",map.firstKey());
        //ensure it's still a map (by overwriting a key, but with a new value) 
        map.put("d", 2);
        assertEquals("b", map.firstKey());
        //Ensure multiple values do not clobber keys
        map.put("e", 2);
        assertEquals(5, map.size());
        assertEquals(2, (int) map.get("e"));
        assertEquals(2, (int) map.get("d"));
    }
 }

Когда мы помещаем, мы гарантируем, что хеш-карта имеет значение для компаратора, а затем помещаем в TreeSet для сортировки. Но перед этим мы проверяем хеш-карту, чтобы убедиться, что ключ на самом деле не дубликат. Кроме того, созданный нами компаратор также будет включать ключ, чтобы повторяющиеся значения не удаляли неповторяющиеся ключи (из-за == сравнения). Эти 2 элемента жизненно важны для обеспечения сохранения контракта карты; если вы думаете, что этого не хотите, то вы почти готовы полностью перевернуть карту (к Map ).

Конструктор необходимо вызвать как

 new ValueComparableMap(Ordering.natural());
 //or
 new ValueComparableMap(Ordering.from(comparator));
210
ответ дан 22 November 2019 в 20:13
поделиться

Конечно, это действительно зависит от того, где вы хотите улучшить. Например, если вы хотите заняться системным программированием, вам следует. Однако, если вы хотите развиваться в области веб-приложений, не беспокойтесь. Подробнее об этом см .: Какой сектор индустрии программного обеспечения использует c ++

Первое, что нужно запомнить, когда вы начинаете изучать, однако: Нет такого языка, как C / C ++.

/**
 * Sort a map by it's keys in ascending order. 
 *  
 * @return new instance of {@link LinkedHashMap} contained sorted entries of supplied map.
 * @author Maxim Veksler
 */
public static <K, V> LinkedHashMap<K, V> sortMapByKey(final Map<K, V> map) {
    return sortMapByKey(map, SortingOrder.ASCENDING);
}

/**
 * Sort a map by it's values in ascending order.
 *  
 * @return new instance of {@link LinkedHashMap} contained sorted entries of supplied map.
 * @author Maxim Veksler
 */
public static <K, V> LinkedHashMap<K, V> sortMapByValue(final Map<K, V> map) {
    return sortMapByValue(map, SortingOrder.ASCENDING);
}

/**
 * Sort a map by it's keys.
 *  
 * @param sortingOrder {@link SortingOrder} enum specifying requested sorting order. 
 * @return new instance of {@link LinkedHashMap} contained sorted entries of supplied map.
 * @author Maxim Veksler
 */
public static <K, V> LinkedHashMap<K, V> sortMapByKey(final Map<K, V> map, final SortingOrder sortingOrder) {
    Comparator<Map.Entry<K, V>> comparator = new Comparator<Entry<K,V>>() {
        public int compare(Entry<K, V> o1, Entry<K, V> o2) {
            return comparableCompare(o1.getKey(), o2.getKey(), sortingOrder);
        }
    };

    return sortMap(map, comparator);
}

/**
 * Sort a map by it's values.
 *  
 * @param sortingOrder {@link SortingOrder} enum specifying requested sorting order. 
 * @return new instance of {@link LinkedHashMap} contained sorted entries of supplied map.
 * @author Maxim Veksler
 */
public static <K, V> LinkedHashMap<K, V> sortMapByValue(final Map<K, V> map, final SortingOrder sortingOrder) {
    Comparator<Map.Entry<K, V>> comparator = new Comparator<Entry<K,V>>() {
        public int compare(Entry<K, V> o1, Entry<K, V> o2) {
            return comparableCompare(o1.getValue(), o2.getValue(), sortingOrder);
        }
    };

    return sortMap(map, comparator);
}

@SuppressWarnings("unchecked")
private static <T> int comparableCompare(T o1, T o2, SortingOrder sortingOrder) {
    int compare = ((Comparable<T>)o1).compareTo(o2);

    switch (sortingOrder) {
    case ASCENDING:
        return compare;
    case DESCENDING:
        return (-1) * compare;
    }

    return 0;
}

/**
 * Sort a map by supplied comparator logic.
 *  
 * @return new instance of {@link LinkedHashMap} contained sorted entries of supplied map.
 * @author Maxim Veksler
 */
public static <K, V> LinkedHashMap<K, V> sortMap(final Map<K, V> map, final Comparator<Map.Entry<K, V>> comparator) {
    // Convert the map into a list of key,value pairs.
    List<Map.Entry<K, V>> mapEntries = new LinkedList<Map.Entry<K, V>>(map.entrySet());

    // Sort the converted list according to supplied comparator.
    Collections.sort(mapEntries, comparator);

    // Build a new ordered map, containing the same entries as the old map.  
    LinkedHashMap<K, V> result = new LinkedHashMap<K, V>(map.size() + (map.size() / 20));
    for(Map.Entry<K, V> entry : mapEntries) {
        // We iterate on the mapEntries list which is sorted by the comparator putting new entries into 
        // the targeted result which is a sorted map. 
        result.put(entry.getKey(), entry.getValue());
    }

    return result;
}

/**
 * Sorting order enum, specifying request result sort behavior.
 * @author Maxim Veksler
 *
 */
public static enum SortingOrder {
    /**
     * Resulting sort will be from smaller to biggest.
     */
    ASCENDING,
    /**
     * Resulting sort will be from biggest to smallest.
     */
    DESCENDING
}
4
ответ дан 22 November 2019 в 20:13
поделиться

Это просто слишком сложно. Карты не должны были выполнять такую работу, как сортировка по значению. Самый простой способ - создать свой собственный класс, чтобы он соответствовал вашим требованиям.

В примере ниже вы должны добавить TreeMap компаратор в том месте, где находится *. Но API java предоставляет компаратору только ключи, а не значения. Все приведенные здесь примеры основаны на двух картах. Одна Hash и одна Tree. Что странно.

Пример:

Map<Driver driver, Float time> map = new TreeMap<Driver driver, Float time>(*);

Поэтому измените карту на множество таким образом:

ResultComparator rc = new ResultComparator();
Set<Results> set = new TreeSet<Results>(rc);

Вы создадите класс Results,

public class Results {
    private Driver driver;
    private Float time;

    public Results(Driver driver, Float time) {
        this.driver = driver;
        this.time = time;
    }

    public Float getTime() {
        return time;
    }

    public void setTime(Float time) {
        this.time = time;
    }

    public Driver getDriver() {
        return driver;
    }

    public void setDriver (Driver driver) {
        this.driver = driver;
    }
}

и класс Comparator:

public class ResultsComparator implements Comparator<Results> {
    public int compare(Results t, Results t1) {
        if (t.getTime() < t1.getTime()) {
            return 1;
        } else if (t.getTime() == t1.getTime()) {
            return 0;
        } else {
            return -1;
        }
    }
}

Таким образом, вы сможете легко добавить больше зависимостей.

И в качестве последней точки я добавлю простой итератор:

Iterator it = set.iterator();
while (it.hasNext()) {
    Results r = (Results)it.next();
    System.out.println( r.getDriver().toString
        //or whatever that is related to Driver class -getName() getSurname()
        + " "
        + r.getTime()
        );
}
5
ответ дан 22 November 2019 в 20:13
поделиться

создает список записей для каждого значения, где значения отсортированы
, требует Java 8 или выше

Map<Double,List<Entry<String,Double>>> sorted =
map.entrySet().stream().collect( Collectors.groupingBy( Entry::getValue, TreeMap::new,
    Collectors.mapping( Function.identity(), Collectors.toList() ) ) );

, использование карты {[A=99.5], [B=67.4], [C=67.4], [D=67.3]}
добирается {67.3=[D=67.3], 67.4=[B=67.4, C=67.4], 99.5=[A=99.5]}


†¦ и как получить доступ к каждой записи один за другим:

sorted.entrySet().forEach( e -> e.getValue().forEach( l -> System.out.println( l ) ) );

D=67.3 B=67.4 C=67.4 A=99.5

0
ответ дан 22 November 2019 в 20:13
поделиться

Пользование библиотекой Guava:

public static <K,V extends Comparable<V>>SortedMap<K,V> sortByValue(Map<K,V> original){
    var comparator = Ordering.natural()
            .reverse() // highest first
            .nullsLast()
            .onResultOf(Functions.forMap(original, null))
            .compound(Ordering.usingToString());
    return ImmutableSortedMap.copyOf(original, comparator);
}
0
ответ дан 22 November 2019 в 20:13
поделиться

Данный Карту

   Map<String, Integer> wordCounts = new HashMap<>();
    wordCounts.put("USA", 100);
    wordCounts.put("jobs", 200);
    wordCounts.put("software", 50);
    wordCounts.put("technology", 70);
    wordCounts.put("opportunity", 200);

Сортируют карту на основе значения в порядке возрастания

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

, Сортируют карту на основе значения в убывающем порядке

Map<String,Integer>  sortedMapReverseOrder =  wordCounts.entrySet().
            stream().
            sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).
            collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
    System.out.println(sortedMapReverseOrder);

Вывод:

{software=50, technology=70, USA=100, jobs=200, opportunity=200}

{jobs=200, opportunity=200, USA=100, technology=70, software=50}

0
ответ дан 22 November 2019 в 20:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: