10
votes

Y a-t-il une union dans les génériques Java?

Puis-je contenir deux types différents dans une collection? Par exemple, puis-je avoir la liste ?


2 commentaires

Une contre-question: pourquoi auriez-vous deux types différents types dans une collection ?


@Ballusc - Un cas d'utilisation pour une telle construction que j'ai couru est un objet de modèle. par exemple. Dans une API de repos, cela correspond à l'objet de transfert de données (DTO) représentant un message protobuf avec un champ . Un OneOf est essentiellement un syndicat. Il peut contenir l'un des types de types différents spécifiés. Une valeur de l'un de ces types occupe la même mémoire et un seul type peut être stocké à la fois. Il semble être analogue à l'union dans C.


6 Réponses :


9
votes

réponse courte? Non. Vous pouvez (bien sûr) avoir une liste de objets , mais vous pouvez ensuite mettre rien dedans, pas seulement String ou integer objets.

Vous pouvez créer une liste d'objets de conteneur et cet objet conteneur contiendrait soit un entier ou chaîne (peut-être via des génériques). Un peu plus de tracas. xxx

et implémenter contenait et contenait .

Bien sûr, la question réelle est la raison pour laquelle vous voulez faire cela? Je m'attendrais à ce que la collection contienne des objets du même type, puis je peux parcourir et effectuer des actions sur ces objets sans vous soucier de ce qu'ils sont. Peut-être que votre hiérarchie de l'objet a besoin d'une nouvelle pensée?


0 commentaires

4
votes

Nope. Vous avez quelques alternatives, bien que:

  • Vous pouvez utiliser une liste et cacher tout ce que vous voulez; ou p> li>

  • Vous pouvez utiliser une liste et mettre vos données dans l'un de ces membres de la classe. p> li> ul>

    EDIT: strong> Exemple. P>

    public boolean isItAString() { return (this.stringValue != null }
    


1 commentaires

Pourriez-vous s'il vous plaît expliquer la deuxième option?



0
votes

Non. Pensez-y de cette façon: avec des génériques, toute l'idée est de fournir une sécurité de type. Cela ne serait pas possible si vous pouviez mettre des objets de types différents.

Vous pouvez utiliser le java.util.list non générique code> pour votre but. P>

si Vous voulez vous assurer que seulement chaîne code> ou integer code> Les objets entrent dans la liste, vous pouvez créer votre propre implémentation de la liste, comme vous le souhaitez: P>

public class MySpecialList {
   private List list= new LinkedList();
   ...
   public void add(final String string) {
       list.add(string);
   }

   public void add(final Integer integer) {
       list.add(integer);
   }
   ...
   // add rest of List style methods
}


0 commentaires

2
votes

En plus des belles réponses déjà fournies ...


éventuellement, vous avez les deux types de données dans votre algorithme. Mais vous ne pouvez pas avoir à les mettre dans la même liste ...

Créer deux listes dactylographiques pourrait être plus claire pour votre algorithme, vous garderiez toujours le "Type-Séance "Et porter toutes vos données. Les échantillons de deux code suivent, le second regroupant les deux listes d'un objet myData. xxx


0 commentaires

4
votes

Si vous faites quelque chose comme une programmation fonctionnelle en Java 8 ou plus, vous voudrez peut-être essayer JavaSealeUnions : XXX

Je n'ai pas testé cela, mais je pense que vous avez eu l'idée.


0 commentaires

0
votes

Ce que vous décrivez est le cas d'utilisation parfait pour le modèle de visiteur

  • 100% de type statiquement vérifié li>
  • n'a pas besoin de Java 8 ou plus li> ul>

    Utilisation: p>

    interface UnionType {
        <R> R when(Cases<R> c);
        interface Cases<R> {
            R is(StringContainer stringContainer);
            R is(IntegerContainer integerContainer);
        }
    }
    
    class StringContainer implements UnionType {
    
        private final String value;
        public StringContainer(String value) { this.value = value; }
        public String getValue() { return value; }
    
        @Override
        public <R> R when(Cases<R> cases) {
            return cases.is(this);
        }
    }
    
    class IntegerContainer implements UnionType {
    
        private final Integer value;
        public IntegerContainer(Integer value) { this.value = value; }
        public Integer getValue() { return value; }
    
        @Override
        public <R> R when(Cases<R> cases) {
            return cases.is(this);
        }
    }
    


0 commentaires