web-dev-qa-db-fra.com

Comment convertir Double [] en double []?

J'implémente une interface dont les fonctionnalités sont similaires à celles d'une table pouvant contenir plusieurs types d'objets. L'interface spécifie la fonction suivante: 

double[] getDoubles(int columnIndex);

Là 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). Lorsque je dois renvoyer les valeurs, je souhaite procéder comme suit (il est supposé que getDoubles() ne sera appelé que sur une colonne contenant des doubles, il n'y aura donc pas de ClassCastExceptions):

double[] getDoubles(int columnIndex) {
    return (double[]) data[columnIndex];
}

Mais - Java n'autorise pas Object[] à être converti en double[]. Il est correct de le convertir en Double[] car Double est un objet et non une primitive, mais mon interface spécifie que les données seront renvoyées sous la forme d'un double[].

J'ai donc deux questions:

  1. Est-il possible d'extraire les données de colonne de la table Object[][] et de renvoyer le tableau de primitives?
  2. Si je modifie l'interface pour renvoyer Double[], cela aura-t-il un impact sur les performances?
58
Brian

Malheureusement, vous devrez parcourir toute la liste et décompresser la Double si vous voulez la convertir en double[].

En ce qui concerne les performances, il existe un certain temps associé aux primitives de boxing et de unboxing en Java. Si l'ensemble est suffisamment petit, vous ne verrez aucun problème de performances.

33
jjnguy

Si l'utilisation d'une bibliothèque tierce ne vous dérange pas, commons-lang utilise le type ArrayUtils avec différentes 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. Cela occasionnera des frais généraux, 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 la refactorisation.

La mise en œuvre de la méthode que vous aviez réellement demandée donnerait quelque chose comme ceci.

double[] getDoubles(int columnIndex) {
    return ArrayUtils.toPrimitive(data[columnIndex]);
}
83
Rich Seller

En Java 8, il s’agit d’un one-liner:

Double[] boxed = new Double[] { 1.0, 2.0, 3.0 };
double[] unboxed = Stream.of(boxed).mapToDouble(Double::doubleValue).toArray();

Notez que cela parcourt encore le tableau d'origine et en crée un nouveau.

41
Infeligo

Vous pouvez utiliser un pour chaque boucle pour construire un tableau temporaire de la même taille, puis convertir chaque élément individuel en double et le placer dans le tableau.

ALORS:

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 je me trompe complètement ici.

7
Eric Koslow

Si vous voulez renvoyer un double[], vous devez créer un new double[], le remplir et le renvoyer.

Cela peut être une bonne décision d'architecture. Premièrement, il n’a pas beaucoup de sens de convertir un Object[] en un Double[]; ce n'est pas vraiment un tableau de Double car il pourrait aussi y avoir Objects. Deuxièmement, si vous renvoyez le tableau directement, le code utilisateur peut le modifier et modifier la structure interne de votre objet.

Le principal impact sur les performances serait de renvoyer un tableau de double[], en raison de la décompression et du coût d’allocation.

3
John Calsbeek

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 avez mentionné le fait de transformer un tableau Object 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 lève une exception de classe. Même si chaque élément du tableau est bien un double, le tableau a été créé sous la forme d'un tableau d'objets, et non d'un tableau de doublons. La distribution n'est donc pas valide.

1
Jay

J'appuie la réponse ArrayUtils et ajoute que la documentation de 1.5 autoboxing ( via ) révèle un peu qu'il n'y a pas de méthode intégrée:

Il n'y a pas de conversion autorisée du type de matrice SC [] en type de matrice TC [] s'il n'y a pas de permission autorisée Conversion autre qu'une conversion de chaîne de SC en TC

0
svrist

Vous pouvez utiliser ArrayUtils pour convertir

Double[] d; // initialise
double[] array = ArrayUtils.toPrimitive(d);

Pas besoin de boucler la totalité des données.

0
Praveen