Eu sou novo em Java e muito confuso.
Eu tenho um grande conjunto de dados de comprimento 4 int[]
e quero contar o número de vezes que cada combinação específica de 4 números inteiros ocorre. Isso é muito semelhante à contagem de frequências de palavras em um documento.
Eu quero criar um Map<int[], double>
que mapeie cada int [] para uma contagem em execução, pois a lista é repetida, mas o Map não aceita tipos primitivos.
então eu fiz Map<Integer[], Double>
meus dados são armazenados como um ArrayList<int[]>
modo meu loop deve ser algo como
ArrayList<int[]> data = ... // load a dataset`
Map<Integer[], Double> frequencies = new HashMap<Integer[], Double>();
for(int[] q : data) {
// **DO SOMETHING TO convert q from int[] to Integer[] so I can put it in the map
if(frequencies.containsKey(q)) {
frequencies.put(q, tfs.get(q) + p);
} else {
frequencies.put(q, p);
}
}
Não tenho certeza do código necessário no comentário para fazer esse trabalho converter um int[]
para um Integer[]
. Ou talvez eu esteja fundamentalmente confuso sobre a maneira correta de fazer isso.
java
arrays
generics
collections
Jonik
fonte
fonte
Respostas:
Java 8 nativo (uma linha)
Com o Java 8,
int[]
pode ser convertido paraInteger[]
facilmente:Como outros afirmaram,
Integer[]
geralmente não é uma boa chave do mapa. Mas no que diz respeito à conversão, agora temos um código relativamente limpo e nativo.fonte
List<Integer> list = IntStream.of(q).boxed().collect(Collectors.toList());
Integer[]
eu realmente sugerir o uso seguinte sintaxe:Integer[] boxed = IntStream.of(unboxed).boxed().toArray();
Na forma semelhante como @NwDxIntStream.of
ligaArrays.stream
mesmo assim. Acho que tudo se resume à preferência pessoal - prefiro uma função substituída, alguns adoram usar classes mais explícitas.the "new" method (constructor) of the Integer[] class
.Se você deseja converter um
int[]
para umInteger[]
, não há uma maneira automatizada de fazer isso no JDK. No entanto, você pode fazer algo assim:Se você tiver acesso ao biblioteca Apache lang , poderá usar o
ArrayUtils.toObject(int[])
método como este:fonte
value
enquanto a variável de indexaçãoi
estiver lá.for (int i...)
loop tradicional seria mais eficiente aqui.Presumivelmente, você deseja que a chave do mapa corresponda ao valor dos elementos em vez da identidade da matriz. Nesse caso, você deseja algum tipo de objeto que define
equals
ehashCode
como seria de esperar. O mais fácil é converter para umList<Integer>
, umArrayList
uso ou melhorArrays.asList
. Melhor que isso, você pode introduzir uma classe que represente os dados (semelhante a,java.awt.Rectangle
mas eu recomendo tornar as variáveis privadas como finais e também a classe).fonte
Usando loop for regular sem bibliotecas externas:
Converter int [] em Inteiro []:
Converta Inteiro [] para int []:
fonte
Eu estava errado em uma resposta anterior. A solução adequada é usar essa classe como uma chave no mapa, envolvendo a int real [].
e altere seu código assim:
fonte
Converter int [] em Inteiro []
Converter Inteiro [] em int []
fonte
newArray[i] = ids[i];
e na segunda umnewArray[i] = WrapperArray[i]
:)Em vez de escrever seu próprio código, você pode usar um IntBuffer para agrupar o int [] existente sem precisar copiar os dados em uma matriz Inteira
O IntBuffer implementa comparáveis para que você possa usar o código que você já escreveu. Os mapas formalmente comparam chaves de modo que a.equals (b) seja usado para dizer que duas chaves são iguais, portanto, dois IntBuffers com matriz 1,2,3 - mesmo que as matrizes estejam em locais diferentes de memória - sejam iguais e assim será trabalhe para o seu código de frequência.
}
espero que ajude
fonte
Não sei por que você precisa de um duplo no seu mapa. Em termos do que você está tentando fazer, você tem um int [] e deseja apenas contar quantas vezes cada sequência ocorre? Por que isso exigia um Double de qualquer maneira?
O que eu faria é criar um wrapper para a matriz int com os métodos .equals e .hashCode adequados para levar em conta o fato de que o objeto int [] em si não considera os dados em sua versão desses métodos.
E, em seguida, use o multiset do google goiaba, que se destina exatamente ao objetivo de contar as ocorrências, desde que o tipo de elemento inserido tenha os métodos .equals e .hashCode adequados.
Em seguida, para obter a contagem para qualquer combinação específica:
fonte
IntArrayWrapper
Definitivamente, essa é a abordagem correta para o uso de umaint[]
matriz como chave de hash, mas deve-se mencionar que esse tipo já existe ... Você pode usá-lo para agrupar uma matriz e não apenas a possuihashCode
eequals
é até comparável.Atualização: Embora o abaixo seja compilado, ele lança um
ArrayStoreException
em tempo de execução. Que pena. Vou deixar para referência futura.Convertendo um
int[]
, para umInteger[]
:Devo admitir que fiquei um pouco surpreso que isso compila, dado
System.arraycopy
ser de nível baixo e tudo mais, mas faz. Pelo menos em java7.Você pode converter para o outro lado com a mesma facilidade.
fonte
Isso funcionou como um encanto!
fonte
Converter int [] em Inteiro []:
fonte
você não precisa.
int[]
é um objeto e pode ser usado como uma chave dentro de um mapa.é a definição adequada do mapa de frequências.
Isso estava errado :-). A solução adequada também é publicada :-).
fonte
frequencies.containsKey(q)
que sempre seria falso, mesmo que eu tenhaput
a mesma matriz duas vezes - há alguma falha aqui envolvendo a definição de igualdade de java com int [] 's?Basta usar:
fonte