Comment convertir Double [] en double[]?
J'implémente une interface qui a des fonctionnalités similaires à une table qui peut contenir un type d'objets. L'interface spécifie la fonction suivante:
double[] getDoubles(int columnIndex);
Où je suis perplexe, c'est que dans mon implémentation, je stocke les données de la table dans un tableau 2D Object
(Object[][] data
). Quand j'ai besoin de retourner les valeurs, je veux faire ce qui suit (il est supposé que getDoubles()
ne sera appelé que sur une colonne qui contient des doubles, donc il n'y aura pas ClassCastExceptions
):
double[] getDoubles(int columnIndex) {
return (double[]) data[columnIndex];
}
Mais-Java ne permet pas à Object[]
d'être converti en double[]
. Moulage Double[]
est ok parce que Double
est un objet et non primitive, mais mon interface spécifie que les données seront retournées comme un double[]
.
J'ai Donc deux questions:
- est-il possible d'obtenir les données de colonne de la table
Object[][]
et de retourner le tableau de primitives? - Si je change l'interface pour retourner
Double[]
, y aura-t-il un impact sur les performances?
8 réponses
Malheureusement, vous devrez parcourir toute la liste et déballer le Double
si vous voulez le convertir en double[]
.
En ce qui concerne la performance, il y a un certain temps associé aux primitives de boxe et de déballage en Java. Si l'ensemble est assez petit, vous ne verrez aucun problème de performance.
Si cela ne vous dérange pas d'utiliser une bibliothèque tierce, commons-lang a le type ArrayUtils avec diverses méthodes de manipulation.
Double[] doubles;
...
double[] d = ArrayUtils.toPrimitive(doubles);
Il y a aussi la méthode complémentaire
doubles = ArrayUtils.toObject(d);
Edit: pour répondre au reste de la question. Il y aura des frais généraux à faire cela, mais à moins que le tableau ne soit vraiment grand, vous ne devriez pas vous en inquiéter. Testez-le d'abord pour voir si c'est un problème avant de refactorer.
Mettre en œuvre la méthode que vous aviez réellement posée donnerait quelque chose pareil.
double[] getDoubles(int columnIndex) {
return ArrayUtils.toPrimitive(data[columnIndex]);
}
Dans Java 8, c'est un liner:
Double[] boxed = new Double[] { 1.0, 2.0, 3.0 };
double[] unboxed = Stream.of(boxed).mapToDouble(Double::doubleValue).toArray();
Notez que cela itère toujours sur le tableau d'origine et en crée un nouveau.
Vous pouvez utiliser un for chaque boucle pour construire un tableau temporaire de la même taille, puis lancer chaque élément individuel pour le doubler et le dans le tableau.
Donc:
double[] tempArray = new double[data[columnIndex].length];
int i = 0;
for(Double d : (Double) data[columnIndex]) {
tempArray[i] = (double) d;
i++;
}
S'il vous Plaît corrigez-moi si j'ai tort ici.
Si vous vouliez retourner un double[]
, vous devez créer un new double[]
, le remplir, et de retour que.
Cela peut être une bonne décision d'architecture. Tout d'abord, cela n'a pas beaucoup de sens de lancer un Object[]
à un Double[]
; ce n'est pas vraiment un tableau de Double
car il pourrait y avoir des Object
s dedans aussi. Deuxièmement, si vous renvoyez le tableau directement, le code utilisateur peut le modifier et modifier la structure interne de votre objet.
L'impact principal sur les performances serait de renvoyer un tableau de double[]
, en raison de déballage et le coût de l'allocation.
Je n'ai rien à ajouter à la vraie question au-delà de ce que jjnguy et Eric Koslow ont dit.
Mais juste une note de côté: vous mentionnez la conversion D'un tableau D'objets en un tableau Double. Ce qui suit ne fonctionnera pas:
Object[] oa=new Object[3];
oa[0]=new Double("1.0");
oa[1]=new Double("2.0");
oa[2]=new Double("3.0");
Double[] da=(Double[])oa;
La dernière ligne lancera une exception de cast de classe. Même si chaque élément du tableau est en effet un Double, le tableau a été créé comme un tableau d'Objets, pas un tableau de Double, si le casting n'est pas valide.
Je seconderais la réponse ArrayUtils et ajouterais que la documentation 1.5 autoboxing(via ) révèle un peu qu'il n'y a pas de moyen intégré:
Il N'y a pas de conversion autorisée du type de tableau SC[] en type de tableau TC[] s'il n'y a pas de conversion autorisée conversion autre qu'une conversion de chaîne de SC À TC
Vous pouvez utiliser les ArrayUtils pour convertir
Double[] d; // initialise
double[] array = ArrayUtils.toPrimitive(d);
Pas besoin de boucler les données entières.