J'ai deux classes, J'ai pensé à utiliser un hashmap, avec des touches de paire: P> classa code> et
classb code>, ainsi que "nombre de nombreux" code "
associationClass code>. Je veux une structure qui détient les associations entre A et B afin que je puisse trouver la contrepartie pour chaque instance de A ou B.
Hasmap<Pair<ClassA, ClassB>, AssociationClass> associations;
7 Réponses :
Utilisation de votre associationClass, vous pouvez simplement avoir CLASSA et Classb contiennent les deux une référence à AssociationClass:
private List<ClassA> classAList;
Oui, mais je devrais les garder synchronisés d'une manière ou d'une autre. Je pense que je préfère avoir un titulaire de l'association indépendant qui fait le travail séparément.
Il serait facile de les garder synchronisés. Vous pouvez écrire dans cette logique sur vos propriétés de setter.
Peut-être le multimap ou le bimap à partir du bibliothèque Google Collections peut faire ce que vous avez besoin. p>
Je l'ai regardé. Cela ne vous aidera pas dans ce cas, mais je garde cela dans mon préféré. Je ne connaissais pas cette bibliothèque. Cela pourrait être utile. Merci.
Ceci ressemble à un problème dans lequel vous avez des données sur lesquelles vous souhaitez utiliser plusieurs clés. Vous voulez rechercher par classe et par Classb. Cela conduit généralement à plusieurs cartes au-dessus des données afin que chaque carte conserve une clé de recherche dans les données sous-jacentes. Peut-être quelque chose comme ça fonctionnerait: insertion va comme ceci: p> Obtenir les données que vous pouvez interroger chacune des cartes pour obtenir ce que tu veux. Vous pouvez même avoir votre classe Le problème avec cette approche est que si les données sous-jacentes changent beaucoup Vous devez vous assurer que toutes les cartes sont synchronisées. S'il s'agit principalement d'un problème lisonly, vous créez les cartes, puis interrogeez celui-ci avec votre clé dans les données. P> p> code> comme un autre index dans les données: p>
Oui, j'ai certainement besoin de plusieurs cartes. Mais je pense avoir besoin de deux cartes des cartes.
Rmarimon est juste qu'elle nécessite deux cartes, mais je pense que vous voulez que vous souhaitez AB, pas une donnée et des données B. p> Vous avez donc simplement besoin de deux cartes: P>
Hashmap bByA = new HashMap(); Hashmap aByB = new HashMap();
Pourquoi ne pas mettre une carte dans chaque classe?
Merci pour vos suggestions.
J'ai finalement réinventé la roue ... J'ai écrit une classe générique pour la tenue d'associations. J'utilise deux cartes des cartes, synchronisée. P>
Le titulaire des associations fournit les méthodes suivantes p> Voici le code: p> 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);
}
}
Voici mon implémentation basée sur GUAVA MULTIMAP:
public class ImmutableBiMultimap<K, V> { private final ImmutableSetMultimap<K, V> kToV; private final ImmutableSetMultimap<V, K> vToK; public ImmutableBiMultimap (SetMultimap<K, V> keyToValueMap) { kToV = ImmutableSetMultimap.copyOf(keyToValueMap); SetMultimap<V, K> valueToKeyMap = HashMultimap.create(); for (Entry<K, V> entry : kToV.entries()) { valueToKeyMap.put(entry.getValue(), entry.getKey()); } vToK = ImmutableSetMultimap.copyOf(valueToKeyMap); } public ImmutableSet<V> getValuesForKey(K key) { return kToV.get(key); } public ImmutableSet<K> getKeysForValue(V value) { return vToK.get(value); } }
Les cas particuliers de la classe et de la classe B peuvent-ils avoir de nombreuses classes d'association qui les communiquent?
C'est une bonne question: Non. Dans mon cas, il y a au plus une association pour chaque couple.
@Cperkins. Oui c'est le cas. Pour deux instance 'A' et 'B', il pourrait y avoir 0 ou 1 association. A peut également être associé à B, B1, B2, B3 et B pourrait être associé à A, A1, A2, A3.