Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当两个以上的值具有相同的排序属性时,按值排序Java树映射不起作用_Java_Sorting_Treemap - Fatal编程技术网

当两个以上的值具有相同的排序属性时,按值排序Java树映射不起作用

当两个以上的值具有相同的排序属性时,按值排序Java树映射不起作用,java,sorting,treemap,Java,Sorting,Treemap,我想根据一些值属性对Java树映射进行排序。具体来说,我想根据哈希集的大小对树映射进行排序。为了实现这一目标,我做了以下工作: 比较类: private static class ValueComparer implements Comparator<Integer> { private Map<Integer, HashSet<Integer>> map = null; public ValueComparer (Map<Intege

我想根据一些值属性对Java树映射进行排序。具体来说,我想根据
哈希集的大小对
树映射进行排序。为了实现这一目标,我做了以下工作:

比较类:

private static class ValueComparer implements Comparator<Integer> {
    private Map<Integer, HashSet<Integer>>  map = null;
    public ValueComparer (Map<Integer, HashSet<Integer>> map){
        super();
        this.map = map;
    }

@Override
    public int compare(Integer o1, Integer o2) {
        HashSet<Integer> h1 = map.get(o1);
        HashSet<Integer> h2 = map.get(o2);

        int compare = h2.size().compareTo(h1.size());

        if (compare == 0 && o1!=o2){
            return -1;
        }
        else {
            return compare;
        }
    }
}
TreeMap<Integer, HashSet<Integer>> originalMap = new TreeMap<Integer, HashSet<Integer>>();

//load keys and values into map

ValueComparer comp = new ValueComparer(originalMap);
TreeMap<Integer, HashSet<Integer>> sortedMap = new TreeMap<Integer, HashSet<Integer>>(comp);
sortedMap.putAll(originalMap);
私有静态类ValueComparer实现Comparator{
私有映射=null;
公共价值比较器(地图){
超级();
this.map=map;
}
@凌驾
公共整数比较(整数o1,整数o2){
HashSet h1=map.get(o1);
HashSet h2=map.get(o2);
int compare=h2.size().compareTo(h1.size());
如果(比较==0&&o1!=o2){
返回-1;
}
否则{
返回比较;
}
}
}
用法示例:

private static class ValueComparer implements Comparator<Integer> {
    private Map<Integer, HashSet<Integer>>  map = null;
    public ValueComparer (Map<Integer, HashSet<Integer>> map){
        super();
        this.map = map;
    }

@Override
    public int compare(Integer o1, Integer o2) {
        HashSet<Integer> h1 = map.get(o1);
        HashSet<Integer> h2 = map.get(o2);

        int compare = h2.size().compareTo(h1.size());

        if (compare == 0 && o1!=o2){
            return -1;
        }
        else {
            return compare;
        }
    }
}
TreeMap<Integer, HashSet<Integer>> originalMap = new TreeMap<Integer, HashSet<Integer>>();

//load keys and values into map

ValueComparer comp = new ValueComparer(originalMap);
TreeMap<Integer, HashSet<Integer>> sortedMap = new TreeMap<Integer, HashSet<Integer>>(comp);
sortedMap.putAll(originalMap);
TreeMap originalMap=newtreemap();
//将键和值加载到映射中
ValueComparer comp=新的ValueComparer(原始映射);
TreeMap sortedMap=新的TreeMap(comp);
分类地图putAll(原始地图);
问题:

private static class ValueComparer implements Comparator<Integer> {
    private Map<Integer, HashSet<Integer>>  map = null;
    public ValueComparer (Map<Integer, HashSet<Integer>> map){
        super();
        this.map = map;
    }

@Override
    public int compare(Integer o1, Integer o2) {
        HashSet<Integer> h1 = map.get(o1);
        HashSet<Integer> h2 = map.get(o2);

        int compare = h2.size().compareTo(h1.size());

        if (compare == 0 && o1!=o2){
            return -1;
        }
        else {
            return compare;
        }
    }
}
TreeMap<Integer, HashSet<Integer>> originalMap = new TreeMap<Integer, HashSet<Integer>>();

//load keys and values into map

ValueComparer comp = new ValueComparer(originalMap);
TreeMap<Integer, HashSet<Integer>> sortedMap = new TreeMap<Integer, HashSet<Integer>>(comp);
sortedMap.putAll(originalMap);
originalMap
包含两个以上相同大小的值时,这不起作用。对于其他情况,它可以正常工作。当映射中有两个以上的值大小相同时,新排序映射中的第三个值为null,并在我尝试访问它时抛出NullPointerException

我想不出是什么问题。如果有人能指出,那就太好了

更新: 下面是一个示例,当两个值具有相同的大小时,该示例有效:
在上面的示例中,如果您取消注释第52-54行,此代码将失败-这就是我的问题所在。

更新:您不能从
ValueComparator
返回
-1
,因为您希望避免重复的键不被删除。检查合同


当您将
比较器
传递到
树映射
时,您将计算一个(“新”)位置来放置条目无(计算)键在
树状图中可以存在多次


如果要按值的大小对
orginalMap
进行排序,可以执行以下操作:

public static void main(String[] args) throws Exception {

    TreeMap<Integer, HashSet<Integer>> originalMap = 
        new TreeMap<Integer, HashSet<Integer>>();

    originalMap.put(0, new HashSet<Integer>() {{ add(6); add(7); }});
    originalMap.put(1, new HashSet<Integer>() {{ add(6); }});
    originalMap.put(2, new HashSet<Integer>() {{ add(9); add(8); }});


    ArrayList<Map.Entry<Integer, HashSet<Integer>>> list = 
        new ArrayList<Map.Entry<Integer, HashSet<Integer>>>();
    list.addAll(originalMap.entrySet());

    Collections.sort(list, new Comparator<Map.Entry<Integer,HashSet<Integer>>>(){
        public int compare(Map.Entry<Integer, HashSet<Integer>> o1,
                           Map.Entry<Integer, HashSet<Integer>> o2) {

            Integer size1 = (Integer) o1.getValue().size();
            Integer size2 = (Integer) o2.getValue().size();
            return size2.compareTo(size1);
        }
    });

    System.out.println(list);
}
publicstaticvoidmain(字符串[]args)引发异常{
树映射原始映射=
新树映射();
originalMap.put(0,新HashSet(){{add(6);add(7);}});
originalMap.put(1,新HashSet(){{add(6);}});
originalMap.put(2,新HashSet(){{add(9);add(8);}});
ArrayList列表=
新的ArrayList();
list.addAll(originalMap.entrySet());
Collections.sort(list,newcomparator(){
公共整数比较(Map.Entry o1,
地图入口(o2){
整数size1=(整数)o1.getValue().size();
整数size2=(整数)o2.getValue().size();
返回size2.compareTo(size1);
}
});
系统输出打印项次(列表);
}

您的比较器不遵守比较器合同:如果
比较(o1,o2)<0
,那么
比较(o2,o1)
应该是
>0
。当两个大小相同且整数不相同时,必须找到一种确定的方法来比较元素。在本例中,您可能可以使用整数的
System.identityHashCode()
来比较它们

也就是说,我真的想知道你能用这样的映射做什么:你不能创建新的整数并用它们从映射中获取值,你也不能修改它所包含的集合

旁注:比较器代码示例使用
映射
数据
引用同一个映射。

比较器逻辑(我不确定为什么会返回-1,如果设置的大小相等,但键不同)不应该影响调用
get(key)
时映射本身返回的内容


您确定没有在初始映射中插入空值吗?这段代码是什么样子的?

假设您不能使用返回0的比较器与集合,这可能会起作用:将
originalMap.entrySet()
中的所有元素添加到
ArrayList
中,然后使用
ValueComparer
ArrayList
进行排序,必要时将其更改为
return 0


然后将排序后的
数组列表中的所有条目添加到
链接映射中

您可以仅按键对树映射进行排序。无法创建按值排序的树映射,因为您将得到StackOverflowException

想想看。要从树中获取元素,需要执行比较,但要执行比较,需要获取元素


您必须在其他集合中对其进行排序或使用Tree,您还必须将整数(来自输入值)封装到输入键中,并使用从键中获取的整数定义comparator。

我遇到了与原始海报类似的问题。我有一个树映射,我想根据一个值进行排序。但是,当我制作一个比较器来查看值时,我遇到了一些问题,因为JB提到的比较器被破坏了。我能够使用我的定制比较仪,但仍然遵守合同。当我看到的价值相等时,我又开始比较钥匙。如果值相等,我不关心顺序

    public int compare(String a, String b) {
    if(base.get(a)[0] == base.get(b)[0]){ //need to handle when they are equal
        return a.compareTo(b);
    }else if (base.get(a)[0] < base.get(b)[0]) {
        return -1;
    } else {
        return 1;
    } // returning 0 would merge keys
public int比较(字符串a、字符串b){
if(base.get(a)[0]==base.get(b)[0]){//当它们相等时需要处理
返回a.compareTo(b);
}else if(base.get(a)[0]
我们需要知道当两个或多个值的大小相同时(据我所知,这是新映射中的键),您期望得到什么。您是否知道映射的属性,即键必须是唯一的?是的,我知道。对键不做任何操作-当小于3个值具有相同的大小时,它们保持唯一,并且上述操作非常有效。我对