如何获取哈希图中的两个最高值<整数,字符串>,进行排名



我有以下代码:

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" 只携带一个字符串和一个整数,则集合大小仅为 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>接口,使其作为真正的集合工作。

相关内容

最新更新