Je suis en train de parcourir les tableaux Java et en plus, je suis à la recherche de génériques. Voici les deux méthodes d'initialisation d'un tableau
outcome = {7, "Tie" , 9.0};
Mais lorsque j'utilise des génériques, j'ai un mélange de types de données par exemple,
String[] outcome = {"0 wins", "Tie" , "X wins"};
Le tableau ci-dessus a un seul type de données String. Et si dans un tableau j'avais quelque chose comme ci-dessous
int[] data = {1,2,3,4,5,6,7,8,9}; // or int[] data; data = new int[] {1,2,3,4,5,6,7,8,9};
maintenant j'ai un mélange de types de données dans un tableau. Comment puis-je l'écrire ou s'il est possible de le faire avec des génériques? Puis-je le faire avec ArrayList?
Merci
6 Réponses :
Une façon de gérer cela est de créer un tableau d ' Object
, qui peut accueillir tous les types de données
if(outcome[0] instanceof Integer){ Integer i = (Integer) outcome[0]; }
Et plus tard, vous pouvez accéder à des objets tels que:
Object[] outcome = {7, "Tie" , 9.0};
et vice versa ..
Donc, pour chaque type de données différent, je dois écrire la condition ci-dessus?
si vous êtes sûr du type de données, vous n'avez pas à les écrire, mais si vous n'êtes pas sûr, vous devrez
Oui. Il n'y a pas d'autre moyen si vous utilisez le type d'objet. Si vous voulez mettre des limites, utilisez des génériques.
Object[] outcome = {7, "Tie" , 9.0};
Comme mentionné précédemment, vous pouvez utiliser un tableau Object. Vous pouvez également utiliser une classe générique. Voici un exemple:
public class Queue<E> { private ArrayList<E> queue; /**Unparametrized constructor**/ public Queue() { queue = new ArrayList<E>(); } /**Enqueues an element into the queue.**/ public void enqueue(E val) { queue.add(val); } /**Dequeues an element from the queue.**/ public E dequeue() { E output = queue.get(0); queue.remove(0); return output; } /**Gets the current size of the queue.**/ public int size() { return queue.size(); } }
Vous allez devoir créer un tableau d'objets, puisque tous les objets en java étend Object
:
List<Object> listObjects = new ArrayList<Objects>();
Et pour trouver si l'objet à l'index x est (par exemple) un Integer
alors vous allez devoir utiliser un cast:
int x = (Integer)arr[x]; //x could be 0 or 1 or 2
Vous pouvez également le faire avec un ArrayList
:
Object[] arr = new Object[3]; //to add objects to it: arr[0]=new String("element at index 0"); arr[1]=new Integer(1); arr[2]=new Character('2');
Je voudrais corriger ceci:
Mais lorsque j'utilise des génériques, j'ai un mélange de types de données
Les génériques nécessitent des types de données homogènes . Par exemple, une List
est une liste qui ne peut contenir qu'un Integer
, et une List extend Number>
ne peut contenir que des Number
s, qui couvrent d'autres types de nombres tels que Long
, Short
, Double < / code>, etc ... mais sont référencés par le simple type
Number
.
Quoi qu'il en soit, ce que vous recherchez est un sac - une collection qui peut contenir n'importe quel objet arbitraire. Vous pouvez l'implémenter avec un Object []
ou une List
, et vous allez devoir vérifier le type de chacun élément que vous retirez lorsque vous voulez l'utiliser, car il n'y a aucun moyen en Java d'avoir un type de données hétérogène, ce que vous recherchez.
Si l'OP est intéressé par une petite refonte, il y a une très bonne description d'une collection hétérogène dans Effective Java 2nd Edition.
tl; dr: À mon avis, les tableaux ne conviennent pas au problème, vous devriez plutôt utiliser des objets.
Ce n'est pas une réponse directe à votre question, mais une réponse sous la forme de une refonte.
Tout d'abord, abordons votre déclaration sur les génériques et les tableaux. Les tableaux sont covariants et conservés, tandis que les génériques sont invariants et effacés.
B étend A
, vous pouvez écrire A [] aArray = new B [someSize];
. Invariant signifie que ce n'est pas possible: ArrayList aList = new ArrayList ();
entraînera une erreur de compilation. Le mélange de covaraint et conservé contre invariant et effacé a un bon potentiel pour vous causer des ennuis. C'est la raison pour laquelle ArrayList
utilise un Object []
au lieu d'un T []
comme structure de données de sauvegarde .
Passons maintenant à la question réelle. Comme d'autres l'ont déjà dit, nous pourrions aller sur la route et créer un Object []
. Je déconseillerais fortement cela car nous perdons toutes les informations de type. Le seul moyen de récupérer ces informations est une vérification instanceof
, qui rend votre code rigide. Imaginez que vous modifiez le type d'une entrée. Dans ce cas, l ' instanceof
renverra false
, conduisant éventuellement à un comportement indésirable et (dans le meilleur des cas) un test devenant rouge ou (dans le pire des cas) nous pourrions ne pas le remarquer.
Maintenant, comment contourner cela? Nous créons une classe représentant (ce que j'en déduis) des résultats de match:
public class MatchResult { private final int firstTeamScore; private final int secondTeamScore; public MatchResult(final int firstTeamScore, final int secondTeamScore) { this.firstTeamScore = firstTeamScore; this.secondTeamScore = secondTeamScore; } public int getFirstTeamScore() { return firstTeamScore; } public int getSecondTeamScore() { return secondTeamScore; } public String getResultForFirstTeam() { if (firstTeamScore > secondTeamScore) { return "Win"; // In an actual implementation, I would replace this with an enum } else if(firstTeamScore = secondTeamScore) { return "Tie"; } else { return "Lose"; } } // You can add a method public String getResultForSecondTeam(), I omitted it for brevity }
Qu'avons-nous gagné? Nous avons des types. Les scores sont toujours des int
, les résultats toujours des String
. Si nous devions, par exemple, changer le type de getReultforFirstTeam ()
de String
à, par exemple, un Enum
, nous aurions des erreurs de compilation pour tous les emplacements où le type ne correspond plus. Ainsi, nous perfectionnons la conception fail-fast et sommes obligés de modifier le code si nécessaire . Et ainsi, nous n'avons même pas la chance d'avoir le comportement sournois et indésirable que nous avions auparavant.
Ne mélangez pas le tableau et les génériques. Le fait que les tableaux soient covariants et conservés, alors que les génériques sont invariants et effacés, vous causera forcément des ennuis. --- Au lieu de mélanger différents types dans un tableau, créez une classe qui représente votre résultat.