Получить ключи с наибольшими значениями из хэш-карты?
У меня есть HashMap
, как это...
HashMap<String,Integer> uniqueNames = new HashMap<String,Integer>();
Сохраняет имя и имя этого имени. Например...
uniqueNames.put("lastname",42);
Как я могу получить имя с наивысшим результатом?
Для получения дополнительной информации я работаю с деревом двоичного поиска "people", сохраняя уникальные имена и частоты в HashMap
. Я хочу, чтобы напечатать наиболее распространенные имена, и кто-то сказал мне использовать HashMap
, поскольку я хотел сохранить String
вместе с Integer
. Может быть, я должен использовать класс для хранения имени и частоты вместо этого? Не могли бы вы предложить некоторые предложения.
Ответы
Ответ 1
Если вам нужно использовать HashMap, то самый простой способ - это просто перебрать карту в поисках максимального
Entry<String,Integer> maxEntry = null;
for(Entry<String,Integer> entry : uniqueNames.entrySet()) {
if (maxEntry == null || entry.getValue() > maxEntry.getValue()) {
maxEntry = entry;
}
}
// maxEntry should now contain the maximum,
Ответ 2
Наиболее очевидно, что теперь можно использовать несколько с наибольшим значением вхождения:
Integer largestVal = null;
List<Entry<String, Integer>> largestList = new ArrayList<Entry<String, Integer>>();
for (Entry<String, Integer> i : uniqueNames.entrySet()){
if (largestVal == null || largestVal < i.getValue()){
largestVal = i.getValue();
largestList .clear();
largestList .add(i);
}else if (largestVal == i.getValue()){
largestList .add(i);
}
}
Другой вариант - использовать Guava BiMap.
BiMap<String, Integer> uniqueNames = ...;
List<Integer> values = Lists.newArrayList(uniqueNames.values());
Collections.sort(values);
String name = uniqueNames.inverse().get(values.get(0));
Ответ 3
Есть два способа обойти это.
Если вы собираетесь делать это часто, я бы предпочел бы сохранить сопоставление в обратном порядке, где ключ - это количество раз, когда имя появилось, а значение - список имен, появившихся много раз. Я бы также использовал HashMap для выполнения поиска в другом направлении.
TreeMap <Integer, ArrayList <String>> sortedOccurrenceMap =
new TreeMap <Integer, ArrayList <String>> ();
HashMap <String, Integer> lastNames = new HashMap <String, Integer> ();
boolean insertIntoMap(String key) {
if (lastNames.containsKey(key)) {
int count = lastNames.get(key);
lastNames.put(key, count + 1);
//definitely in the other map
ArrayList <String> names = sortedOccurrenceMap.get(count);
names.remove(key);
if(!sortedOccurrenceMap.contains(count+1))
sortedOccurrenceMap.put(count+1, new ArrayList<String>());
sortedOccurrenceMap.get(count+1).add(key);
}
else {
lastNames.put(key, 1);
if(!sortedOccurrenceMap.contains(1))
sortedOccurrenceMap.put(1, new ArrayList<String>());
sortedOccurrenceMap.get(1).add(key);
}
}
Нечто похожее на удаление...
И, наконец, для вашего поиска:
ArrayList <String> maxOccurrences() {
return sortedOccurrenceMap.pollLastEntry().getValue();
}
Возвращает список имен с максимальными вхождениями.
Если вы сделаете это так, поиск может быть выполнен в O (log n), но требования к пространству увеличиваются (только по постоянному коэффициенту).
Если пробел является проблемой или производительность не является проблемой, просто перейдите через uniqueNames.keySet и отслеживайте максимальный размер.
Ответ 4
Похоже, вы хотите что-то немного похожее на SortedMap
, но одно сортируется по значению, а не по ключу. Я не думаю, что такая вещь существует в стандартном API.
Возможно, лучше создать класс Frequency и сохранить экземпляры в SortedSet
.
import java.util.Set;
import java.util.TreeSet;
public class Frequency implements Comparable<Frequency> {
private String name;
private int freq;
public Frequency(String name, int freq) {
this.name = name;
this.freq = freq;
}
public static void main(String[] args) {
Set<Frequency> set = new TreeSet<Frequency>();
set.add(new Frequency("fred", 1));
set.add(new Frequency("bob", 5));
set.add(new Frequency("jim", 10));
set.add(new Frequency("bert", 4));
set.add(new Frequency("art", 3));
set.add(new Frequency("homer", 5));
for (Frequency f : set) {
System.out.println(f);
}
}
@Override
public boolean equals(Object o) {
if (o == null) return false;
if (o.getClass().isAssignableFrom(Frequency.class)) {
Frequency other = (Frequency)o;
return other.freq == this.freq && other.name.equals(this.name);
} else {
return false;
}
}
@Override
public int compareTo(Frequency other) {
if (freq == other.freq) {
return name.compareTo(other.name);
} else {
return freq - other.freq;
}
}
@Override
public String toString() {
return name + ":" + freq;
}
}
Вывод:
Фред: 1
искусство: 3
Берт: 4
боб: 5
Гомер: 5
jim: 10
Ответ 5
List<String> list= new ArrayList<String>();
HashMap<String, Integer> map=new HashMap<String,Integer>();
for(String string: list)
{
if(map.containsKey(string))
{
map.put(string, map.get(string)+1);
}
else {
map.put(string, 1);
}
}
Entry<String,Integer> maxEntry = null;
for(Entry<String,Integer> entry : map.entrySet()) {
if (maxEntry == null || entry.getValue() > maxEntry.getValue()) {
maxEntry = entry;
}
}
Ответ 6
Если вам нужно только значение, которое вы можете использовать для этого. В этом примере мне пришлось получить
максимальная частота числа среди массива "n" чисел
{
int n = sc.nextInt();
int arr[] = new int[n];
int freq = 1;
int i;
Map<Integer,Integer> myMap = new HashMap<Integer,Integer>();
for(i=0;i<n;i++){
arr[i] = sc.nextInt();
if(!myMap.containsKey(arr[i])){
myMap.put(arr[i],freq);
}
else
{
myMap.put(arr[i],(myMap.get(arr[i])+1));
}
}
int max = 0;
for(i=0;i<n;i++){
if(myMap.get(arr[i])>max)
max = myMap.get(arr[i]);
}
System.out.println(max);
}
Ответ 7
Это мой подход.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class FindWordCounter {
public static void main(String[] args) {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
try {
System.out.println("Enter the sentence: ");
String sentence = bufferedReader.readLine();
FindWordCounter.countWord(sentence);
} catch (IOException e) {
System.out.println(e);
}
}
public static void countWord(String sentence) {
Map<String, Integer> hashMap = new HashMap<String, Integer>();
String[] word = sentence.toLowerCase().split(" ");
for (int i=0; i<word.length; i++) {
if (hashMap.containsKey(word[i])) {
int count = hashMap.get(word[i]);
hashMap.put(word[i], count + 1);
}
else {
hashMap.put(word[i], 1);
}
}
Entry<String,Integer> maxCount = null;
for(Entry<String,Integer> entry : hashMap.entrySet()) {
if (maxCount == null || entry.getValue() > maxCount.getValue()) {
maxCount = entry;
}
}
System.out.println("The word with maximum occurence is: " + maxCount.getKey()
+ " and the number of occurence is: " + maxCount.getValue());
}
}
Ответ 8
1. Попробуйте это может помочь.
static <K, V> List<K> getAllKeysForValue(Map<K, V> mapOfWords, V value)
{
List<K> listOfKeys = null;
//Check if Map contains the given value
if(mapOfWords.containsValue(value))
{
// Create an Empty List
listOfKeys = new ArrayList<>();
// Iterate over each entry of map using entrySet
for (Map.Entry<K, V> entry : mapOfWords.entrySet())
{
// Check if value matches with given value
if (entry.getValue().equals(value))
{
// Store the key from entry to the list
listOfKeys.add(entry.getKey());
}
}
}
// Return the list of keys whose value matches with given value.
return listOfKeys;
}