12
votes

Java Beaucoup de la carte de l'association

J'ai deux classes, 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.

J'ai pensé à utiliser un hashmap, avec des touches de paire: P>

Hasmap<Pair<ClassA, ClassB>, AssociationClass> associations;


3 commentaires

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.


7 Réponses :


0
votes

Utilisation de votre associationClass, vous pouvez simplement avoir CLASSA et Classb contiennent les deux une référence à AssociationClass:

private List<ClassA> classAList;


2 commentaires

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.



1
votes

Peut-être le multimap ou le bimap à partir du bibliothèque Google Collections peut faire ce que vous avez besoin.


1 commentaires

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.



1
votes

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: xxx

insertion va comme ceci: xxx

Obtenir les données que vous pouvez interroger chacune des cartes pour obtenir ce que tu veux. Vous pouvez même avoir votre classe comme un autre index dans les données: xxx

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.


1 commentaires

Oui, j'ai certainement besoin de plusieurs cartes. Mais je pense avoir besoin de deux cartes des cartes.



0
votes

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();


0 commentaires

0
votes

Pourquoi ne pas mettre une carte dans chaque classe? XXX


0 commentaires

3
votes

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> xxx pré>

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);  
    }
}


0 commentaires

4
votes

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);
    }
}


0 commentaires