Eu tenho uma matriz de primitivas, por exemplo, para int, int [] foo. Pode ser de tamanho pequeno ou não.
int foo[] = {1,2,3,4,5,6,7,8,9,0};
Qual é a melhor maneira de criar um a Iterable<Integer>
partir dele?
Iterable<Integer> fooBar = convert(foo);
Notas:
Por favor, não responda usando loops (a menos que você possa dar uma boa explicação sobre como o compilador faz algo inteligente sobre eles?)
Observe também que
int a[] = {1,2,3};
List<Integer> l = Arrays.asList(a);
Não vai nem compilar
Type mismatch: cannot convert from List<int[]> to List<Integer>
Verifique também Por que uma matriz não é atribuível à Iterable? antes de responder.
Além disso, se você usa alguma biblioteca (por exemplo, Goiaba), explique por que esse é o melhor. (Como é do Google não é uma resposta completa: P)
Por fim, como parece haver um dever de casa sobre isso, evite postar código de dever de casa.
Respostas:
Embora você precise usar uma
Integer
matriz (não umaint
matriz) para que isso funcione.Para primitivos, você pode usar goiaba:
Para Java8: (da resposta de Jin Kwon)
fonte
int
, nãoInteger
2)List
já é,Iterable
portanto, a terceira linha é inútil.apenas meus 2 centavos:
fonte
Iterator<Character>
de aString
. Implementar o seu próprioIterator
parece ser a única maneira de evitar iterações desnecessárias através de todos os valores para converter do tipo de objeto para o tipo primitivo (via Guava's,Ints.asList()
por exemplo), apenas para obter um resultadoIterator
doList
que foi criado.Com o Java 8, você pode fazer isso.
fonte
A goiaba fornece o adaptador que você deseja como Int.asList () . Existe um equivalente para cada tipo primitivo na classe associada, por exemplo,
Booleans
paraboolean
, etc.As sugestões acima a serem usadas
Arrays.asList
não funcionarão, mesmo que elas sejam compiladas porque você recebe umIterator<int[]>
e nãoIterator<Integer>
. O que acontece é que, em vez de criar uma lista apoiada por sua matriz, você criou uma lista de matrizes com 1 elemento, contendo sua matriz.fonte
Eu tive o mesmo problema e resolvi-o assim:
O iterador em si é um preguiçoso,
UnmodifiableIterator
mas é exatamente isso que eu precisava.fonte
No Java 8 ou posterior,
Iterable
é retornada uma interface funcionalIterator
. Então você pode fazer isso.fonte
Antes de tudo, só posso concordar que essa
Arrays.asList(T...)
é claramente a melhor solução para tipos ou matrizes de wrapper com tipos de dados não primitivos. Esse método chama um construtor de umaAbstractList
implementação estática privada simples naArrays
classe que basicamente salva a referência da matriz especificada como campo e simula uma lista substituindo os métodos necessários.Se você pode escolher entre um tipo primitivo ou um tipo de invólucro para sua matriz, eu usaria o tipo de invólucro para essas situações, mas é claro que nem sempre é útil ou necessário. Existem apenas duas possibilidades que você pode fazer:
1) Você pode criar uma classe com um método estático para cada matriz de tipo de dados primitiva (
boolean, byte, short, int, long, char, float, double
retornando umIterable<
WrapperType>
. Esses métodos usariam classes anônimas deIterator
(além deIterable
) que têm permissão para conter a referência do argumento do método compreensivo (por exemplo, umint[]
) como campo para implementar os métodos.-> Essa abordagem é de bom desempenho e economiza memória (exceto para a memória dos métodos recém-criados, embora o uso
Arrays.asList()
levaria memória da mesma maneira)2) Como as matrizes não têm métodos (como lidas na lateral) você vinculou) eles também não podem fornecer uma
Iterator
instância. Se você realmente tem preguiça de escrever novas classes, deve usar uma instância de uma classe já existente que implementeIterable
porque não há outra maneira de instanciarIterable
ou um subtipo.A ÚNICA maneira de criar um derivado de coleção existente implementando
Iterable
é usar um loop (exceto se você usar classes anônimas como descrito acima) ou instanciar umaIterable
classe de implementação cujo construtor permita uma matriz de tipos primitivos (porqueObject[]
não permite matrizes com elementos de tipos primitivos), mas até onde eu sei, a API Java não apresenta uma classe como essa.O motivo do loop pode ser explicado facilmente:
para cada coleção, você precisa de objetos e tipos de dados primitivos não são objetos. Os objetos são muito maiores que os tipos primitivos, de modo que requerem dados adicionais que devem ser gerados para cada elemento da matriz de tipos primitivos. Isso significa que, se duas maneiras de três (usar
Arrays.asList(T...)
ou usar uma coleção existente) exigirem um agregado de objetos, você precisará criar para cada valor primitivo do seuint[]
matriz o objeto wrapper. A terceira maneira usaria a matriz como está e a utilizaria em uma classe anônima, pois acho que é preferível devido ao desempenho rápido.Há também uma terceira estratégia usando um
Object
argumento as para o método em que você deseja usar a matriz ouIterable
e isso exigiria verificações de tipo para descobrir qual o tipo de argumento, no entanto, eu não o recomendaria, pois você geralmente precisa considere que o objeto nem sempre tem o tipo necessário e que você precisa de código separado para determinados casos.Concluindo, a culpa é do sistema problemático de tipo genérico do Java, que não permite usar tipos primitivos como tipo genérico, o que economizaria muito código usando simplesmente
Arrays.asList(T...)
. Portanto, você precisa programar para cada matriz de tipos primitivos, um método desse tipo (que basicamente não faz diferença para a memória usada por um programa C ++ que criaria para cada argumento de tipo usado um método separado.fonte
Você pode usar
IterableOf
do Cactoos :Em seguida, você pode transformá-lo em uma lista usando
ListOf
:Ou simplesmente isso:
fonte
Embora uma resposta semelhante já tenha sido publicada, acho que o motivo para usar o novo PrimitiveIterator.OfInt não estava claro. Uma boa solução é usar o Java 8 PrimitiveIterator, pois é especializado em tipos int primitivos (e evita a penalidade extra de boxe / unboxing):
Ref: https://doc.bccnsoft.com/docs/jdk8u12-docs/api/java/util/PrimitiveIterator.OfInt.html
fonte
No java8, o fluxo do IntSteam pode ser encaixotado no fluxo de inteiros.
Eu acho que o desempenho é importante com base no tamanho da matriz.
fonte