Java Map按值排序 [英] Java Map sort by value

查看:148
本文介绍了Java Map按值排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找按值排序 Map< String,Integer> 的方法。我找到了这篇文章,其中解决了我的排序问题,但不完全。根据这篇文章,我写了下面的代码:

  import java.util。*; 

public class Sort {

static class ValueComparator implements Comparator< String> {

地图< String,Integer>基础;

ValueComparator(Map< String,Integer> base){
this.base = base;

$ b @Override
public int compare(String a,String b){
if(base.get(a)> = base.get(b )){
return 1;
} else {
return -1;



$ b public static void main(String [] args){
HashMap< String,Integer> map = new HashMap< String,Integer>();
ValueComparator vc = new ValueComparator(map);
TreeMap< String,Integer> sorted = new TreeMap< String,Integer>(vc);
map.put(A,1);
map.put(B,2);
sorted.putAll(map);
for(String key:sorted.keySet()){
System.out.println(key +:+ sorted.get(key)); //为什么这里有空值?
}
System.out.println(sorted.values()); //但我们在这里有非空值!


$ / code $ / pre
$ b $输出:

  A:null 
B:null
[1,2]
建立成功(总时间:0秒)

从输出中可以看到, get 方法总是返回 null 。原因是我的 ValueComparator.compare()方法永远不会返回 0 ,我已经通过这篇文章



有人在该文章中建议解决 null 值问题:

  public int compare(String a,String b){
if(base.get(a)> base.get(b)){
return 1;
} else if(base.get(a)== base.get(b)){
return 0;
}
返回-1;
}

我测试过这段代码,它引入了一个关键的合并问题。换句话说,当这些值相等时,它们的对应键被合并。



我也尝试了以下方法:

  public int compare(String a,String b){
if(a.equals(b))return 0;
if(base.get(a)> = base.get(b)){
return 1;
} else返回-1;
}

它也不起作用。其中一些值仍然是 null 。此外,这种解决方法可能存在逻辑问题。



任何人都可以为我的问题提出完全有效的解决方案?我希望按值函数进行排序,同时 get 方法同时工作。

解决方案

在比较函数中,当值相等时,您应该比较键。这将确保具有相同值的不同键不会被合并,因为它消除了否则将比较相等的条目。



例如:

  @Override 
public int compare(String a,String b){
Integer x = base.get(a);
整数y = base.get(b);
if(x.equals(y)){
return a.compareTo(b);
}
return x.compareTo(y);

$ / code>

(您需要修改上面的代码以匹配您的策略为null值)

请注意,您对值进行排序的方法非常脆弱。您的排序地图不会支持添加新条目,这可能会让人感到困惑。

I was looking for ways of sorting Map<String, Integer> by values. I found this post, which solved my sorting problem, but not exactly. According to the post, I wrote the following code:

import java.util.*;

public class Sort {

    static class ValueComparator implements Comparator<String> {

        Map<String, Integer> base;

        ValueComparator(Map<String, Integer> base) {
            this.base = base;
        }

        @Override
        public int compare(String a, String b) {
            if (base.get(a) >= base.get(b)) {
                return 1;
            } else {
                return -1;
            }
        }
    }

    public static void main(String[] args) {
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        ValueComparator vc = new ValueComparator(map);
        TreeMap<String, Integer> sorted = new TreeMap<String, Integer>(vc);
        map.put("A", 1);
        map.put("B", 2);
        sorted.putAll(map);
        for (String key : sorted.keySet()) {
            System.out.println(key + " : " + sorted.get(key)); // why null values here?
        }
        System.out.println(sorted.values()); // But we do have non-null values here!
    }
}

Output:

A : null
B : null
[1, 2]
BUILD SUCCESSFUL (total time: 0 seconds)

As you can see from the output, the get method always returns null. The reason is my ValueComparator.compare() method never returns 0, which I've figured out by making this post.

Someone suggested in that post the following to solve the null value problem:

        public int compare(String a, String b) {
            if (base.get(a) > base.get(b)) {
                return 1;
            }else if(base.get(a) ==  base.get(b)){
                return 0;
            }
            return -1;  
        }

I've tested this piece of code and it introduces a key merging problem. In other words, when the values are equal their corresponding keys are merged.

I've also tried the following:

            public int compare(String a, String b) {
                if (a.equals(b)) return 0;
                if (base.get(a) >= base.get(b)) {
                    return 1;
                } else return -1;
            }

It does not work either. Some of the values are still null. Besides, this workaround might potentially have logical problems.

Anyone can propose a fully working solution to my problem? I'd like the sort by value function to work and the get method to work at the same time.

解决方案

In your compare function, when the values are equal, you should then compare the keys. This will ensure that different keys having the same value will not be "merged", because it disambiguates entries that would otherwise compare equal.

For example:

    @Override
    public int compare(String a, String b) {
        Integer x = base.get(a);
        Integer y = base.get(b);
        if (x.equals(y)) {
            return a.compareTo(b);
        }
        return x.compareTo(y);
    }

(you'll need to modify the code above to match your policy for null values)

Note that your approach of sorting on values is pretty fragile, though. Your "sorted" map will not support addition of new entries, which could be pretty confusing.

这篇关于Java Map按值排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆