Java多对多关联图
问题内容:
我有两堂课,ClassA
和一堂课,ClassB
“一对多”
AssociationClass
。我想要一个结构,其中包含A和B之间的关联,以便我可以找到A或B的每个实例的对应对象。
我想到了使用带对键的Hashmap:
Hasmap<Pair<ClassA, ClassB>, AssociationClass> associations;
这样一来,我可以添加和删除的两个实例之间的关联ClassA
和ClassB
,我可以查询两个给定的情况下的关系。
但是,我错过了为ClassA
或给定实例定义所有关联的功能ClassB
。
我可以通过蛮力做到这一点,并在地图的所有键上循环以搜索给定实例之间的关联,但这效率低下而且不够优雅。
您是否知道任何启用此功能的数据结构/免费库?我不想重新发明轮子。
注意 :这不是“数据库”问题。这些对象是用于实时计算的纯POJO,我不需要持久性东西。
问题答案:
感谢您的建议。
我终于重新发明了轮子……我编写了一个用于持有关联的通用类。我使用两张同步的地图。
协会持有人提供以下方法
void setAssociation(LeftClass left, RightClass right, AssociationClass assoc);
AssociationClass getAssociation(LeftClass left, RightClass right);
Map<RightClass, AssociationClass> getAssocationsLeft(LeftClass left);
Map<LeftClass, AssociationClass> getAssocationsRight(RightClass right);
void removeAssociation(LeftClass left, RightClass right);
这是代码:
import java.util.HashMap;
/** This class holds many to many associations between two classes. */
public class AssociationHolder<LeftClass, RightClass, AssociationClass> {
// -------------------------------------------------------
// Attributes
// -------------------------------------------------------
private HashMap<LeftClass, HashMap<RightClass, AssociationClass>> associationsLeft =
new HashMap<LeftClass, HashMap<RightClass,AssociationClass>>();
private HashMap<RightClass, HashMap<LeftClass, AssociationClass>> associationsRight =
new HashMap<RightClass, HashMap<LeftClass,AssociationClass>>();
// -------------------------------------------------------
// Methods
// -------------------------------------------------------
/**
* Set an association between two instance.
* Any prior association is overwritten.
*/
public void setAssociation(LeftClass left, RightClass right, AssociationClass association) {
// Get the map for the left
HashMap<RightClass, AssociationClass> leftMap = this.associationsLeft.get(left);
// No association defined yet for this left key ? => Create new map
if (leftMap == null) {
leftMap = new HashMap<RightClass, AssociationClass>();
this.associationsLeft.put(left, leftMap);
}
// Get the map for the right
HashMap<LeftClass, AssociationClass> rightMap = this.associationsRight.get(right);
// No association defined yet for this right key ? => Create new map
if (rightMap == null) {
rightMap = new HashMap<LeftClass, AssociationClass>();
this.associationsRight.put(right, rightMap);
}
// Set the assoication on both maps
leftMap.put(right, association);
rightMap.put(left, association);
}
/** @return null if no association found. */
public AssociationClass getAssociation(LeftClass left, RightClass right) {
// Use left maps (could have used the right one as well)
HashMap<RightClass, AssociationClass> leftMap = this.associationsLeft.get(left);
if (leftMap == null) return null;
return leftMap.get(right);
}
/** Get all associations defined for a given Left instance. */
public HashMap<RightClass, AssociationClass> getAssociationsLeft(LeftClass left) {
HashMap<RightClass, AssociationClass> leftMap = this.associationsLeft.get(left);
// No map defined ? return empty one instead of null
if (leftMap == null) {
return new HashMap<RightClass, AssociationClass>();
} else {
return leftMap;
}
}
/** Get all associations defined for a given Right instance. */
public HashMap<LeftClass, AssociationClass> getAssociationsRight(RightClass right) {
HashMap<LeftClass, AssociationClass> rightMap = this.associationsRight.get(right);
// No map defined ? return empty one instead of null
if (rightMap == null) {
return new HashMap<LeftClass, AssociationClass>();
} else {
return rightMap;
}
}
/**
* Remove an association between two instances.
*/
public void removeAssociation(LeftClass left, RightClass right) {
HashMap<RightClass, AssociationClass> leftMap = this.getAssociationsLeft(left);
HashMap<LeftClass, AssociationClass> rightMap = this.getAssociationsRight(right);
leftMap.remove(right);
rightMap.remove(left);
}
}
我希望这可以在将来对某人有所帮助。