Question

Je suis mise en œuvre d'une interface qui a une fonctionnalité similaire à une table qui peut contenir un type d'objets. L'interface spécifie la fonction suivante:

double[] getDoubles(int columnIndex);

Là où je suis déconcerté est que dans ma mise en œuvre, je stocker les données de la table dans un tableau de Object de 2D (Object[][] data). Quand je dois retourner les valeurs, je veux faire ce qui suit (on suppose que getDoubles() ne sera appelée sur une colonne qui contient double, donc il n'y aura pas ClassCastExceptions):

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

Mais - Java ne permet pas Object[] d'être jeté à double[]. Coulée à Double[] est ok parce que Double est un objet et non une primitive, mais mon interface précise que les données seront retournées comme double[].

J'ai donc deux questions:

  1. Est-il possible que je peux obtenir les données de la colonne de la table Object[][] et retourne le tableau de primitives?
  2. Si je changer l'interface pour revenir Double[], y aura-t-il un impact sur le rendement?
Était-ce utile?

La solution

Malheureusement, vous devrez parcourir toute la liste et unbox le Double si vous voulez le convertir en un double[].

En ce qui concerne la performance va, il y a un certain temps associée à des primitives de boxe et unboxing en Java. Si l'ensemble est assez petit, vous ne verrez pas les problèmes de performance.

Autres conseils

Si vous ne me dérange pas utiliser une bibliothèque 3ème partie, commons-lang a 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. Il y aura un temps supplémentaire à faire, mais à moins que le tableau est vraiment grand ne vous inquiétez pas à ce sujet. Testez-le d'abord pour voir si elle est un problème avant refactoring.

La mise en œuvre de la méthode que vous aviez effectivement demandé donnerait quelque chose comme ça.

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

En Java 8, ceci est une doublure:

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

Notez que cette itère encore sur le tableau original et crée un nouveau.

Vous pouvez utiliser une pour chaque boucle pour construire un tableau de température de la même taille puis jeter chaque élément individuel pour doubler et mais dans le tableau.

SO

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 me corriger si je suis mort ne va pas ici.

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

Cela peut être une bonne décision d'architecture. Tout d'abord, il ne fait pas beaucoup de sens de jeter un coup Object[] à un Double[]; ce n'est pas vraiment un tableau de Double parce qu'il pourrait y avoir dans Objects aussi. En second lieu, si vous retournez le tableau directement, le code utilisateur peut modifier et modifier la structure interne de votre objet.

Le principal impact sur les performances serait en retour un tableau de double[], en raison de unboxing et le coût de l'allocation.

Je n'ai rien à ajouter à la vraie question au-delà de ce que jjnguy et Eric dit Koslow.

Mais une note de côté: Vous mentionnez jetant un tableau d'objets à 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 transtypage 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 doubles, de sorte que le casting est invalide.

Vous pouvez utiliser les ArrayUtils pour convertir

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

Pas besoin de boucle l'ensemble des données.

Je deuxième les ArrayUtils répondre et d'ajouter que 1,5 autoboxing documentation ( via ) peu révèle qu'il n'y a aucun moyen builtin:

  

Il n'y a pas de conversion autorisée de type tableau SC [] type de tableau TC [] s'il n'y a pas permis   conversion autre qu'une conversion de chaîne de SC à TC

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top