簡體   English   中英

如何在HashMap中獲取兩個最高值 <Integer,String> ,排名

[英]How to get the two highest values in a HashMap<Integer,String>, making a ranking

我有以下代碼:

public class Tester {

    public static void main(String[] args) {
        HashMap<Integer,String> map = new HashMap<Integer,String>();

        map.put(1, "one");
        map.put(2, "twp");
        map.put(2, "two2");

        int highest = Integer.MIN_VALUE;
        String highestString = null;
        int secondHighest = Integer.MIN_VALUE;
        String secondHighestString = null;

        if (highest == Integer.MIN_VALUE){
            highest = Collections.max(map.keySet() );
            highestString = map.get(highest);
            map.remove(highest);
        }
        if (secondHighest == Integer.MIN_VALUE ){
            secondHighest = Collections.max(map.keySet() );
            secondHighestString = map.get(secondHighest);
            map.remove(secondHighest);
        }

        System.out.println(highest + highestString);
        System.out.println(secondHighest + secondHighestString);


    }

}

我嘗試不能返回兩個最高值,因為似乎不可能只刪除一個具有相同鍵的值,我也嘗試交換它們(使HashMap也不是最佳選擇)。 我應該嘗試使用任何其他類型的收藏嗎?

我也嘗試過:

TreeSet<Tete> set = new TreeSet<Tete>();

    set.add(new Tete("name1", 1));
    set.add(new Tete("name2",4));
    set.add(new Tete("name3",4));
    set.add(new Tete("name4",12));

    System.out.println(set.size());

假設類“Tete”只攜帶一個String和一個Integer,則設置大小僅為3,而不是4,如預期的那樣。 如果我打印每個數字,“name3”將不會打印,所以我不能返回3個最大值,例如,只會出現“name4”,“name2”和“name1”,但“name3”大於“name1” “

任何Map (包括HashMap )只能為任何鍵存儲一個值。 因此,在三次map.put調用之后,地圖中只有兩個元素: [1,"Um"][2,"dois2"] 地圖中將不再存在值"dois"

如果確實需要為每個鍵存儲多個值,那么使用Java運行時執行此操作的方法是將每個鍵映射到值列表。

HashMap<Integer,ArrayList<String>> map = new HashMap<Integer,ArrayList<String>>();

這確實意味着向地圖添加值以及刪除值的代碼更復雜。 要添加值,需要這樣的代碼:

ArrayList<String> list = map.get(key);
if (list == null) {
    list = new ArrayList<String>();
    map.put(key, list);
}
list.add(newValue);

刪除值類似:您需要獲取列表,然后從ArrayList刪除值,並僅在ArrayList的大小為0時從映射中刪除鍵。

替代方案:第三方庫中有“多地圖”集合,例如Apache Commons( javadoc )。 或者,如@Keenle建議,您可以使用一組,其中的關鍵是同時包含整數和字符串的對象。 你必須為這個對象編寫類,但它會非常簡單。

為了解決排名問題,我會編寫一個自定義類,如下所示:

public class TopsCollection<D> {

    private final TreeMap<Integer, List<D>> map 
        = new TreeMap<>((lhv, rhv) -> rhv.compareTo(lhv));

    public TopsCollection() {}

    public void add(Integer score, D name) {
        List<D> vals = map.get(score);
        if (vals == null) {
            vals = new ArrayList<>();
            map.put(score, vals);
        }
        vals.add(name);
    }

    public List<D> getTops(int n) {
        return map.
            values().
            stream().
            limit(n).
            reduce(new ArrayList<D>(), (lhv, rhv) -> {
                lhv.addAll(rhv);
                return lhv;
            });
    }
}

用法:

TopsCollection<String> tc = new TopsCollection<>();
tc.add(12, "nome4");
tc.add(1, "nome1");
tc.add(4, "nome3");
tc.add(4, "nome2");

List<String> tops = tc.getTops(2); // contains 3 elements: nome4, nome3, nome2

備注:

該特定實現可以返回任意數量的最高等級相關條目。

還應注意add(...)方法需要時間與log(n)成比例,因為TopsCollection由TreeMap類支持。

如果需要TopCollection可以實現Collection<T>接口,使其作為真正的集合。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM