Como faço para converter duas vezes em [] para duplicar []?
-
12-09-2019 - |
Pergunta
Estou implementando uma interface que tem funcionalidade semelhante a uma tabela que pode conter uma tipos de objetos. Os especifica de interface a seguinte função:
double[] getDoubles(int columnIndex);
Onde estou perplexo é que na minha aplicação, eu estou armazenando os dados da tabela em uma matriz Object
2D (Object[][] data
). Quando eu preciso para retornar os valores, eu quero fazer o seguinte (presume-se que getDoubles()
só vai ser chamado em uma coluna que contém duplos, então não haverá ClassCastExceptions
):
double[] getDoubles(int columnIndex) {
return (double[]) data[columnIndex];
}
Mas - Java não permitem Object[]
para ser convertido para double[]
. Lançando-a Double[]
é ok porque Double
é um objeto e não um primitivo, mas meus especifica de interface que os dados serão retornados como um double[]
.
Então, eu tenho duas perguntas:
- Existe alguma maneira eu posso obter os dados da coluna para fora da mesa de
Object[][]
e retornar a matriz de primitivos? - Se eu fizer mudar a interface para
Double[]
retorno, vai haver qualquer impacto no desempenho?
Solução
Infelizmente você terá que percorrer a lista inteira e unbox o Double
se você quiser convertê-lo para um double[]
.
Tanto quanto o desempenho vai, há algum tempo associado com boxing e unboxing primitivos em Java. Se o conjunto é pequeno o suficiente, você não vai ver quaisquer problemas de desempenho.
Outras dicas
Se você não se importa com uma biblioteca parte 3, commons-lang tem o tipo ArrayUtils com vários métodos para a manipulação.
Double[] doubles;
...
double[] d = ArrayUtils.toPrimitive(doubles);
Há também o método complementar
doubles = ArrayUtils.toObject(d);
Edit: Para responder o resto da pergunta. Haverá alguma sobrecarga para fazer isso, mas a menos que a matriz é muito grande você não deve se preocupar com isso. Testá-lo primeiro para ver se é um problema antes de refatoração.
A implementação do método que você tinha realmente perguntado sobre daria algo como isto.
double[] getDoubles(int columnIndex) {
return ArrayUtils.toPrimitive(data[columnIndex]);
}
Em Java 8, esta é uma linha:
Double[] boxed = new Double[] { 1.0, 2.0, 3.0 };
double[] unboxed = Stream.of(boxed).mapToDouble(Double::doubleValue).toArray();
Note que este ainda itera sobre a matriz original e cria um novo.
Pode-se utilizar um para cada circuito para construir uma matriz de temperatura do mesmo tamanho, em seguida, fundido cada elemento individual para o dobro e, mas na matriz.
SO:
double[] tempArray = new double[data[columnIndex].length];
int i = 0;
for(Double d : (Double) data[columnIndex]) {
tempArray[i] = (double) d;
i++;
}
Por favor me corrija se eu estiver errado mortos aqui.
Se você quiser retornar um double[]
, você precisa criar um new double[]
, preenchê-lo e retornar isso.
Isso pode ser uma decisão boa arquitetura. Em primeiro lugar, não faz muito sentido para lançar um Object[]
a um Double[]
; não é realmente uma série de Double
porque pode haver Object
s nele também. Segundo, se você retornar a matriz diretamente, o código do usuário pode modificá-la e alterar a estrutura interna do seu objeto.
O impacto no desempenho principal seria em retornar um array de double[]
, devido ao unboxing e o custo de alocação.
Eu não tenho nada a acrescentar à verdadeira questão para além do que jjnguy e Eric Koslow disse.
Mas apenas uma nota lateral: Você menciona lançando uma matriz de objectos a um conjunto duplo. O seguinte não irá funcionar:
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;
A última linha irá lançar uma exceção de lançamento de classe. Mesmo que cada elemento na matriz é de fato um casal, a matriz foi criado como um array de objetos, não um conjunto de Duplas, assim que o elenco é inválido.
Você pode utilizar os ArrayUtils para converter
Double[] d; // initialise
double[] array = ArrayUtils.toPrimitive(d);
Não há necessidade de looping os dados inteira.
Eu segundo os ArrayUtils responder e acrescentar que o 1.5 documentação autoboxing ( através ) tipo revela que não há nenhuma maneira builtin:
não é permitida a conversão do tipo de matriz SC [] de tipo de matriz TC [] se houver nenhum é permitido conversão diferente de uma conversão de cadeia de SC para TC