2013-11-24 4 views
1

Как я могу получить значение, которое больше всего встречается в HashMap выше, в данном случае это будет «Школа». Я был бы признателен за наиболее эффективный и понятный метод подхода.Как узнать, какое значение имеет наибольшее значение в HashMap?

+1

Не могли бы вы показать нам, что вы пробовали до сих пор? Как выглядит ваш код и какая конкретная деталь дает вам проблемы? – Pshemo

ответ

3

Простым решением является просто посмотреть на значения.

public static <E> E mostFrequentElement(Iterable<E> iterable) { 
    Map<E, Integer> freqMap = new HashMap<>(); 
    E mostFreq = null; 
    int mostFreqCount = -1; 
    for (E e : iterable) { 
     Integer count = freqMap.get(e); 
     freqMap.put(e, count = (count == null ? 1 : count+1)); 
     // maintain the most frequent in a single pass. 
     if (count > mostFreqCount) { 
      mostFreq = e; 
      mostFreqCount = count; 
     } 
    } 
    return mostFreq; 
} 

и на карте вы можете сделать

V v = mostFrequentElement(map.values()); 
+0

Спасибо, Питер, это подходит для моего использования. Я также (пытаюсь) сделать способ для возврата freqMap. – user2803086

3

Одно из решений:

  • Построить новый HashMap, который имеет строкуkey и значение int.
  • Для каждого value вашего текущего HashMap:
    • Добавить значение как key в новом HashMap и значение как 1, если это первый раз, когда вы вставив его.
    • В противном случае добавьте value к одному для текущего key.
  • Теперь итерация на вновь созданный карты и получить ключ, который имеет максимальное значение .

Для текущей карты:

votes.put("Henk","School"); 
votes.put("Elise","School"); 
votes.put("Jan","Work"); 
votes.put("Mert","Party"); 

Вы первый вставить School в качестве ключа со значением 1. Затем вы сталкиваетесь School снова, так что вы увеличить значениена 1 , имея счет 2. Теперь вы вставляете Work с значение 1 и Party со значением 1.

После повторения на карте вы получите School с наивысшим значением . И это то, чего ты хочешь!

+0

Хорошо, я разработал ваше решение, но я не уверен, что это лучший способ. http://pastebin.com/zJFBsRiJ – user2803086

+0

@ user2803086 Вы можете сделать это за один проход. См. Мое решение. –

0

Я считаю, что это будет делать то, что вы хотите -

/** 
* Get the most frequent value present in a map. 
* 
* @param map 
*   The map to search. 
* @return The most frequent value in the map (or null). 
*/ 
public static <K, V> V getMostFrequentValue(
    Map<K, V> map) { 
    // Make sure we have an entry. 
    if (map != null && map.size() > 0) { 
    // the entryset from our input. 
    Set<Entry<K, V>> entries = map.entrySet(); 

    // we need a map to hold the count. 
    Map<V, Integer> countMap = new HashMap<V, Integer>(); 
    // iterate the entries. 
    for (Entry<K, V> entry : entries) { 
     // get the value. 
     V value = entry.getValue(); 

     if (countMap.containsKey(value)) { 
     // if we've seen it before increment the previous 
     // value. 
     countMap.put(value, countMap.get(value) + 1); 
     } else { 
     // otherwise, store 1. 
     countMap.put(value, 1); 
     } 
    } 
    // A holder for the maximum. 
    V maxV = null; 
    for (Entry<V, Integer> count : countMap.entrySet()) { 
     if (maxV == null) { 
     maxV = count.getKey(); 
     continue; 
     } 
     if (count.getValue() > countMap.get(maxV)) { 
     maxV = count.getKey(); 
     } 
    } 
    return maxV; 
    } 
    return null; 
} 
+0

Я бы перебрал через entrySet(), поэтому вам не нужно искать ключ. –

+0

@PeterLawrey Я отредактировал, чтобы включить это предложение. –

0

Вот реализация Маруной псевдокоде. Попробуйте,

Map<String, String> votes = new HashMap<String, String>(); 
    votes.put("Henk", "School"); 
    votes.put("Elise", "School"); 
    votes.put("Jan", "Work"); 
    votes.put("Mert", "Party"); 
    //Define a countMap with String as value, Integer for count 
    Map<String, Integer> countMap = new HashMap<>(); 

    for (Map.Entry<String, String> entry : votes.entrySet()) { 
     if (countMap.containsKey(entry.getValue())) { 
      countMap.put(entry.getValue(), countMap.get(entry.getValue()) + 1); 
     } else { 
      countMap.put(entry.getValue(), 1); 
     } 
    } 
    // Got the number of maximum occuarance 
    Integer maxNum = Collections.max(countMap.values()); 

    String result = ""; 
    // Iterate to search the result. 
    for (Map.Entry<String, Integer> entry : countMap.entrySet()) { 
     if(maxNum==entry.getValue()){ 
      result=entry.getKey(); 
     } 

    } 
    System.out.println(result); 
2

Просто с помощью API:

 Map<String,String> votes = new HashMap<String,String>(); 
     votes.put("Henk","School"); 
     votes.put("Elise","School"); 
     votes.put("Jan","Work"); 
     votes.put("Mert","Party"); 

     Collection<String> c = votes.values(); 
     List<String> l = new ArrayList<>(c); 

     Set<String> set = new HashSet<>(c); 
     Iterator<String> i = set.iterator(); 
     String valueMax = ""; 
     int max = 0; 
     while(i.hasNext()){ 
      String s = i.next(); 
      int frequence = Collections.frequency(l, s); 
      if(frequence > max){ 
       max = frequence; 
       valueMax = s; 
      } 
     } 

     System.out.println(valueMax+": "+max); 

Выход:

School: 2 
0

Вы можете переопределять значение put() и remove() класса HashMap и создайте свой собственный, который также контролирует количество добавленных объектов. Как так:

public class MyHashMap<K, V> extends HashMap<K, V> { 

private HashMap<String, Integer> countMap = new HashMap<String, Integer>(); 

@Override 
public V put(K key, V value) { 
    Integer count = countMap.get(value); 
    if (count != null) { 
     countMap.put((String) value, ++count); 
    } else { 
     countMap.put((String) value, new Integer(1)); 
    } 


    return super.put(key, value); 
} 

@Override 
public V remove(Object key) { 
    String countKey = (String) get(key); 
    Integer count = countMap.get(countKey); 
    if (count != null) { 
     countMap.put(countKey, --count); 
    } 

    return super.remove(key); 
} 

public Integer getCount(Object value) { 
    return countMap.get((String)value); 
} 

} 

Таким образом, вы не должны цикла по элементам вашего HashMap сосчитать их. Вместо этого, после того, как вы добавите их:

Map<String,String> votes = new MyHashMap<String,String> 
votes.put("Henk","School"); 
votes.put("Elise","School"); 
votes.put("Jan","Work"); 
votes.put("Mert","Party"); 

Вы можете просто получить счетчик для каждого, как:

Integer schoolCount = votes.getCount("School"); 
Смежные вопросы