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:

  1. est-il possible d'obtenir les données de colonne de la table Object[][] et de retourner le tableau de primitives?
  2. Si je change l'interface pour retourner Double[], y aura-t-il un impact sur les performances?
56
demandé sur Lahiru Ashan 2009-07-10 18:46:31

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.

32
répondu jjnguy 2009-07-10 14:52:19

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]);
}
80
répondu Rich Seller 2009-07-10 16:19:03

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.

37
répondu Infeligo 2015-05-08 06:55:13

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.

7
répondu Eric Koslow 2009-07-10 14:54:32

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 Objects 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.

3
répondu John Calsbeek 2009-07-10 14:53:51

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.

1
répondu Jay 2009-07-10 16:56:38

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

0
répondu svrist 2009-07-10 16:33:36

Vous pouvez utiliser les ArrayUtils pour convertir

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

Pas besoin de boucler les données entières.

0
répondu Praveen 2017-02-15 13:28:57