2014-11-03 4 views
-2

У меня есть HashMap<String, Integer>, содержащий слова вместе с их частотами. Мне нужно сейчас преобразовать это HashMap в ArrayList только слова, отбрасывая частоты, но я также хочу, чтобы ArrayList был отсортированным по убыванию слов по частоте.Преобразование HashMap в Sorted ArrayList

Кто-нибудь знает эффективный способ сделать это?

+4

это довольно стандартный запрос, вы должны легко можно найти материал в Интернете. Вы еще что-нибудь пробовали? Например, – Michael

+0

можно создать класс 'Word', который содержит' String' и частоту и реализует интерфейс 'Comparable', сравнивающий объекты' Word' по их частоте. Затем заполнить 'ArrayList ' из 'HashMap', а затем вызвать' Collections.sort (yourArrayList) ' – nem035

+0

. Недавно у меня было точное назначение. Я не знаю, является ли это лучшим решением, но вместо 'Map ' Я использовал 'ArrayList ', где' MyClass' содержит 'String word' и' int/double frequency' , Затем вы можете использовать 'Collections.sort (yourList, новый Comparator () {@Override public int compare (MyClass mc1, MyClass mc2) {...}});' для сортировки –

ответ

3

HashMap имеет удобный способ под названием entrySet(), который позволяет получить доступ к наборам пар ключ-значение. Вы можете использовать его для построения List<Map.Entry<String,Integer>>.

Теперь у вас есть что-то, что вы можете сортировать. Используйте метод сортировки с пользовательским компаратором, который заказывает записи с более высокими частотами в начало списка.

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

List<Map.Entry<String,Integer>> entries = new ArrayList<Map.Entry<String,Integer>>(
    freqMap.entrySet() 
); 
Collections.sort(
    entries 
, new Comparator<Map.Entry<String,Integer>>() { 
     public int compare(Map.Entry<String,Integer> a, Map.Entry<String,Integer> b) { 
      return Integer.compare(b.getValue(), a.getValue()); 
     } 
    } 
); 
for (Map.Entry<String,Integer> e : entries) { 
    // This loop prints entries. You can use the same loop 
    // to get the keys from entries, and add it to your target list. 
    System.out.println(e.getKey()+":"+e.getValue()); 
} 

Demo.

0

Вы можете:

  • Положите вашу карту в SortedMap определения собственного компаратора.
  • Преобразование набора ключей в отсортированную карту в список.
2

При использовании Java 8 вы можете сделать использование Stream API нравится следующим образом:

final Map<String, Integer> wordStats = new HashMap<>(); 
// some dummy data: 
wordStats.put("twice", 2); 
wordStats.put("thrice", 3); 
wordStats.put("once", 1); 

final List<String> sortedStats = wordStats.entrySet().stream() 
    .sorted((e1, e2) -> e2.getValue().compareTo(e1.getValue())) 
    .map(Map.Entry::getKey) 
    .collect(Collectors.toList()); 
    // or to specify the list implementation: 
    //.collect(ArrayList::new, ArrayList::add, ArrayList::addAll); 

// Output 
sortedStats.forEach(System.out::println); 

Выход:

thrice 
twice 
once 
0

В Java 8 вы также можете сделать это более короткий вариант, что был дан ответ

По возрастанию

ArrayList<Map.Entry<String, Integer>> sorted = newArrayList<>(frequencies.entrySet()); 
sorted.sort(Comparator.comparingInt(Map.Entry::getValue)); 

По убыванию

ArrayList<Map.Entry<String, Integer>> sorted = new ArrayList<>(frequencies.entrySet()); 
sorted.sort(Collections.reverseOrder(Comparator.comparingInt(Map.Entry::getValue))); 
Смежные вопросы