Domanda

sto implementando un'interfaccia che ha una funzionalità simile a una tabella che può contenere un tipo di oggetti. L'interfaccia specifica la seguente funzione:

double[] getDoubles(int columnIndex);

Dove Sono perplesso è che nella mia realizzazione, sto memorizzare i dati della tabella in un array Object 2D (Object[][] data). Quando ho bisogno di restituire i valori, voglio fare il seguente (si presume che getDoubles() sarà chiamato solo su una colonna che contiene doppie, quindi non ci sarà alcun ClassCastExceptions):

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

Ma - Java non permette Object[] per essere lanciato a double[]. Casting a Double[] è ok perché Double è un oggetto e non un primitivo, ma la mia interfaccia specifica che i dati verranno restituiti come double[].

Così ho due domande:

  1. C'è un modo posso ottenere i dati della colonna fuori dal tavolo Object[][] e restituire la matrice di primitive?
  2. Se faccio cambiare l'interfaccia di tornare Double[], ci sarà impatto sulle prestazioni?
È stato utile?

Soluzione

Purtroppo è necessario scorrere l'intera lista e unboxing del Double se si vuole convertirlo in un double[].

Per quanto riguarda le prestazioni va, c'è un po 'di tempo associata con la boxe e unboxing primitive in Java. Se l'apparecchio è abbastanza piccolo, non si vede alcun problemi di prestazioni.

Altri suggerimenti

Se non ti dispiace utilizzando una libreria di terze parti, commons-lang ha le ArrayUtils tipo con vari metodi per la manipolazione.

Double[] doubles;
...
double[] d = ArrayUtils.toPrimitive(doubles);

C'è anche il metodo complementare

doubles = ArrayUtils.toObject(d);

Modifica: Per rispondere al resto della domanda. Ci sarà un certo overhead a fare questo, ma a meno che la matrice è davvero grande, non si dovrebbe preoccupare. Provatelo prima di vedere se si tratta di un problema prima di refactoring.

L'implementazione del metodo si aveva in realtà chiesto darebbe qualcosa di simile.

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

In Java 8, questo è uno-liner:

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

Si noti che questo itera ancora oltre la matrice originale e ne crea uno nuovo.

Si potrebbe utilizzare una per ogni ciclo per costruire una matrice temporanea delle stesse dimensioni poi gettato ogni singolo elemento a raddoppiare e ma nella matrice.

SO:

double[] tempArray = new double[data[columnIndex].length];
int i = 0;
for(Double d : (Double) data[columnIndex]) {
  tempArray[i] = (double) d;
  i++;
}

Si prega di correggermi se sono morto sbagliato qui.

Se si voleva restituire un double[], si avrebbe bisogno di creare un new double[], popolarla, e restituire questo.

Questo può essere una buona decisione architettura. In primo luogo, non fa un sacco di senso per lanciare un Object[] ad un Double[]; non è davvero una serie di Double perché ci potrebbero essere Objects in esso troppo. In secondo luogo, se si torna direttamente l'array, il codice utente può modificare e alterare la struttura interna del vostro oggetto.

L'impatto principale prestazioni sarebbe in restituendo un array di double[], a causa unboxing e il costo di assegnazione.

Non ho nulla da aggiungere alla reale domanda di là di quanto jjnguy ed Eric Koslow detto.

Ma solo un lato nota: Lei parla di colata una matrice Object a un array doppio. Quanto segue non funziona:

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;

L'ultima riga sarà un'eccezione calco. Anche se ogni elemento della matrice è infatti un doppio, l'array è stato creato come un array di oggetti, non una serie di doppi, quindi il cast non è valido.

È possibile utilizzare le ArrayUtils per convertire

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

Non c'è bisogno di loop dell'intero dati.

Vorrei secondo le ArrayUtils rispondere e aggiungere che la documentazione autoboxing 1.5 ( via ) un pò rivela che non c'è modo integrato:

  

Non v'è alcuna conversione consentita dal tipo di matrice SC [] per tipo di matrice TC [] se non v'è permesso   conversione diversa da una conversione stringa dal SC al TC

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top