Java 在地图中合并条目

Java 在地图中合并条目,java,dictionary,duplicates,Java,Dictionary,Duplicates,我有类ID和值,以及从ID到值的映射 public class IDs { public TreeSet<Integer> ids; public HashSet<IDs> neighbors; public static HashSet<IDs> idSet = new HashSet<>(); private boolean hash; private int hashcode; publi

我有类ID和值,以及从ID到值的映射

public class IDs {

    public TreeSet<Integer> ids;
    public HashSet<IDs> neighbors;
    public static HashSet<IDs> idSet = new HashSet<>();

    private boolean hash;
    private int hashcode;

    public IDs(int id,HashSet<IDs> neighbors) {
        this.ids = new TreeSet<>();
        this.ids.add(id);
        this.neighbors = neighbors;
        idSet.add(this);

        this.hash = false;
        this.hashcode = 0;
    }

    public void addNeighbor(IDs neighbor) {
        this.neighbors.add(neighbor);
        neighbor.neighbors.add(this);
    }

    public static boolean cluster(IDs id1,IDs id2) {
        if (id1.equals(id2))
            return false;
        id1.ids.addAll(id2.ids);
        id2.ids.addAll(id1.ids);
        id2.neighbors.remove(id1);
        id1.neighbors.remove(id2);
        id1.neighbors.addAll(id2.neighbors);
        id2.neighbors.addAll(id1.neighbors);

        id1.hash = false;

        return true;
    }

    @Override
    public String toString() {
        String name = "{";
        for (Integer i:ids)
            name += "Cell " + i + ", ";
        name += "}";
        return name;
    }

    @Override
    public boolean equals(Object obj) {
        IDs o = (IDs) obj;
        return this.ids.containsAll(o.ids) && o.ids.containsAll(this.ids);
    }

    @Override
    public int hashCode() {
        if (this.hash)
            return this.hashcode;
        TreeSet temp = (TreeSet) this.ids.clone();
        int first,hash = 0;
        while (!temp.isEmpty()) {
            first = (int) temp.first();
            temp.remove(temp.first());
            hash = CantorPair(hash,first);
        }
        this.hash = true;
        this.hashcode = hash;
        return hash;
    }

    private int CantorPair(int k1,int k2) {
        return (k1 + k2) * (k1 + k2 + 1) / 2 + k2;
    }

}


class Value{
    Integer value;
}
Map<ID,Value> map = new Map<>();
公共类ID{
公共树集ID;
公共哈希集邻居;
public static HashSet idSet=new HashSet();
私有布尔散列;
私有整数哈希码;
公共id(整数id、哈希集邻居){
this.ids=新树集();
this.ids.add(id);
这个。邻居=邻居;
idSet.add(这个);
this.hash=false;
this.hashcode=0;
}
公共无效添加邻居(IDs邻居){
this.neighbors.add(neighbor);
邻居。邻居。添加(此);
}
公共静态布尔集群(IDs id1、IDs id2){
if(id1.等于(id2))
返回false;
id1.ids.addAll(id2.ids);
id2.ids.addAll(id1.ids);
id2.邻居。移除(id1);
id1.邻居。移除(id2);
id1.neights.addAll(id2.neights);
id2.neights.addAll(id1.neights);
id1.hash=false;
返回true;
}
@凌驾
公共字符串toString(){
字符串名称=“{”;
for(整数i:id)
名称+=“单元”+i+“,”;
名称+=“}”;
返回名称;
}
@凌驾
公共布尔等于(对象obj){
IDs o=(IDs)obj;
返回this.ids.containsAll(o.ids)和&o.ids.containsAll(this.ids);
}
@凌驾
公共int hashCode(){
if(this.hash)
返回此.hashcode;
TreeSet temp=(TreeSet)this.ids.clone();
int-first,hash=0;
而(!temp.isEmpty()){
first=(int)temp.first();
临时移除(临时优先());
哈希=CantorPair(哈希,第一);
}
this.hash=true;
this.hashcode=hash;
返回散列;
}
私人内部康托帕尔(内部k1,内部k2){
返回(k1+k2)*(k1+k2+1)/2+k2;
}
}
阶级价值{
整数值;
}
Map Map=newmap();
现在我想将条目合并在一起,新值是旧值的总和,但我创建的是具有重复键和旧值的条目。有人知道怎么解决这个问题吗

EDIT1:我已经重写了
equals()
hashCode()
了,很抱歉没有在这里显示它,映射仍然有重复的键条目


EDIT2:我已经上传了我的类的完整代码,当
hashCode()
equals(Object o)
方法没有被您的键类(
ID
)覆盖时,Java只使用内存中对象的实际引用(指针地址)来计算值(即检查它是否是类的同一个实例化)这就是为什么会得到重复的键(Java“认为”所有结果都是唯一的)

要解决这个问题,您需要重写这两个方法,
equals()
hashCode()


上面的代码应该可以帮助您使用自定义类(ID)作为集合密钥。但我发现您的问题中还有一个问题:

现在我想合并条目,新值是旧值的总和

请先尝试自己解决问题(如果没有成功),然后(如果没有成功)在此处发布一个显示您的努力的问题。您当前编写的问题没有显示您尝试过的内容。

hashCode()
equals(Object o)
方法未被您的键类(
ID
)覆盖时,Java只使用对内存中对象的实际引用(指针地址)来计算值(即检查它是否是类的同一实例化)。这就是为什么会得到重复的键(Java“认为”所有结果都是唯一的)

要解决这个问题,您需要重写这两个方法,
equals()
hashCode()


上面的代码应该可以帮助您使用自定义类(ID)作为集合密钥。但我发现您的问题中还有一个问题:

现在我想合并条目,新值是旧值的总和


请先尝试自己解决(如果没有成功)在此处发布一个显示您所做努力的问题。您当前编写的问题没有显示您所做的尝试。

用作
映射的键的类需要以一致的方式重写
hashCode
equals
方法。(简而言之,这意味着如果两个实例按照
equals
方法相等,那么它们的
hashCode
方法必须返回相同的值)

您在
ID
类中既没有覆盖
equals
也没有覆盖
hashCode
,因此每当您将其用作映射的键时,都会得到意外的结果

根据值的合并,在
映射
中有一个方法,这绝对是您要查找的。如果您在
类中有一个即
求和
方法,您可以按如下方式执行:

class Value {
    Integer value;

    Value sum(Value another) {
        value += another.value;
        return this;
    }
}

Map<ID, Value> map = new HashMap<>(); // Map is an interface, 
                                      // you need an actual implementation

map.merge(someId, someValue, Value::sum);
类值{
整数值;
值和(另一个值){
value+=另一个.value;
归还这个;
}
}
Map Map=new HashMap();//Map是一个接口,
//您需要一个实际的实现
merge(someId,someValue,Value::sum);

用作
映射的键的类需要以一致的方式重写
hashCode
equals
方法(简而言之,这意味着如果根据
equals
方法两个实例相等,那么它们的
hashCode
方法必须返回相同的值)

您在
ID
类中既没有覆盖
equals
也没有覆盖
hashCode
,因此每当您将其用作映射的键时,都会得到意外的结果

根据值的合并,在
Map
中有一个方法,这绝对是您要寻找的。如果您在
Value
类中有一个即
sum
方法,您可以
class Value {
    Integer value;

    Value sum(Value another) {
        value += another.value;
        return this;
    }
}

Map<ID, Value> map = new HashMap<>(); // Map is an interface, 
                                      // you need an actual implementation

map.merge(someId, someValue, Value::sum);