Eu preciso concatenar duas String
matrizes em Java.
void f(String[] first, String[] second) {
String[] both = ???
}
Qual é a maneira mais fácil de fazer isso?
java
arrays
concatenation
add
Antti Kissaniemi
fonte
fonte
array1 + array2
concatenação simples .Respostas:
Encontrei uma solução de uma linha na boa e antiga biblioteca Apache Commons Lang.
ArrayUtils.addAll(T[], T...)
Código:
fonte
Aqui está um método simples que concatenará duas matrizes e retornará o resultado:
Observe que ele não funcionará com tipos de dados primitivos, apenas com tipos de objetos.
A seguinte versão um pouco mais complicada funciona com matrizes de objeto e primitivas. Faz isso usando em
T
vez deT[]
como o tipo de argumento.Também possibilita concatenar matrizes de dois tipos diferentes, escolhendo o tipo mais geral como o tipo de componente do resultado.
Aqui está um exemplo:
fonte
Array.newInstance(a.getClass().getComponentType(), aLen + bLen);
. Surpreendentemente, nunca vi isso antes. @ Beaudet Acho que a anotação está bem aqui, considerando por que está sendo suprimida.É possível escrever uma versão totalmente genérica que pode até ser estendida para concatenar qualquer número de matrizes. Essas versões requerem Java 6, pois usam
Arrays.copyOf()
Ambas as versões evitam a criação de
List
objetos intermediários e são usadasSystem.arraycopy()
para garantir que a cópia de matrizes grandes seja o mais rápida possível.Para duas matrizes, fica assim:
E para um número arbitrário de matrizes (> = 1), fica assim:
fonte
T
porbyte
(e perder o<T>
).ByteBuffer buffer = ByteBuffer.allocate(array1.length + array2.length); buffer.put(array1); buffer.put(array2); return buffer.array();
concat(ai, ad)
, ondeai
estáInteger[]
ead
estáDouble[]
. (Nesse caso, o parâmetro type<T>
é resolvido<? extends Number>
pelo compilador.) A matriz criada porArrays.copyOf
terá o tipo de componente da primeira matriz, ou sejaInteger
, neste exemplo. Quando a função está prestes a copiar a segunda matriz, umArrayStoreException
será lançado. A solução é ter umClass<T> type
parâmetro adicional .Usando
Stream
no Java 8:Ou assim, usando
flatMap
:Para fazer isso para um tipo genérico, você precisa usar a reflexão:
fonte
.boxed()
modo que sejam do tipoStream
e não, por exemplo,IntStream
que não possam ser passados como parâmetro paraStream.concat
.a
eb
sãoint[]
, usoint[] both = IntStream.concat(Arrays.stream(a), Arrays.stream(b)).toArray();
System.arrayCopy
. Mas também não é particularmente lento. Você provavelmente tem que fazer isso uma muito muitas vezes com enormes matrizes em realmente contextos sensíveis de desempenho para a diferença de tempo de execução para a matéria.Ou com a amada Goiaba :
Além disso, existem versões para matrizes primitivas:
Booleans.concat(first, second)
Bytes.concat(first, second)
Chars.concat(first, second)
Doubles.concat(first, second)
Shorts.concat(first, second)
Ints.concat(first, second)
Longs.concat(first, second)
Floats.concat(first, second)
fonte
Você pode anexar as duas matrizes em duas linhas de código.
Esta é uma solução rápida e eficiente e funcionará para tipos primitivos, bem como os dois métodos envolvidos estão sobrecarregados.
Você deve evitar soluções que envolvam ArrayLists, fluxos etc., pois elas precisarão alocar memória temporária sem nenhum objetivo útil.
Você deve evitar
for
loops para matrizes grandes, pois elas não são eficientes. Os métodos integrados usam funções de cópia em bloco extremamente rápidas.fonte
Usando a API Java:
fonte
both.toArray(new String[0])
será mais rápido do queboth.toArray(new String[both.size()])
, mesmo que contradiga nossa intuição ingênua. É por isso que é tão importante medir o desempenho real ao otimizar. Ou apenas use a construção mais simples, quando a vantagem da variante mais complicada não puder ser comprovada.Uma solução java 100% antiga e sem
System.arraycopy
(não disponível no cliente GWT, por exemplo):fonte
null
cheques. E talvez defina algumas de suas variáveis parafinal
.null
verificações do @TrippKinetics ocultariam as NPEs , em vez de mostrá-las, e o uso final de vars locais ainda não tem nenhum benefício.Recentemente, lutei contra problemas com rotação excessiva de memória. Se se sabe que a e / ou b geralmente estão vazios, aqui está outra adaptação do código do silvertab (também gerado):
Edit: Uma versão anterior deste post afirmou que a reutilização da matriz como esta deve ser claramente documentada. Como Maarten aponta nos comentários, em geral, seria melhor remover as declarações if, anulando assim a necessidade de ter documentação. Mas, novamente, essas instruções if foram o ponto principal dessa otimização específica em primeiro lugar. Vou deixar essa resposta aqui, mas tenha cuidado!
fonte
System.arraycopy
copia o conteúdo da matriz?if
declarações de fora seria a solução mais fácil.A biblioteca Java Funcional possui uma classe de wrapper de matriz que equipa as matrizes com métodos úteis, como concatenação.
...e depois
Para recuperar a matriz desembrulhada, chame
fonte
fonte
both.toArray(new String[both.size()])
;)Outra maneira com Java8 usando Stream
fonte
Aqui está uma adaptação da solução da silvertab, com os genéricos adaptados:
NOTA: Consulte a resposta de Joachim para obter uma solução Java 6. Não apenas elimina o aviso; também é mais curto, mais eficiente e mais fácil de ler!
fonte
Se você usar dessa maneira, não precisará importar nenhuma classe de terceiros.
Se você quer concatenar
String
Código de exemplo para concate two String Array
Se você quer concatenar
Int
Código de exemplo para concate two Integer Array
Aqui está o método principal
Também podemos usar esse caminho.
fonte
Por favor, perdoe-me por adicionar mais uma versão a esta lista já longa. Olhei para todas as respostas e decidi que realmente queria uma versão com apenas um parâmetro na assinatura. Também adicionei uma verificação de argumento para se beneficiar de falhas precoces com informações sensatas em caso de entrada inesperada.
fonte
Você pode tentar convertê-lo em uma lista de matriz e usar o método addAll e depois converter novamente em uma matriz.
fonte
Utilizando fluxos Java 8+, você pode escrever a seguinte função:
fonte
Aqui está uma possível implementação no código de trabalho da solução de pseudocódigo escrita por silvertab.
Obrigado silvertab!
A seguir, é apresentada a interface do construtor.
Nota: Um construtor é necessário porque em java não é possível fazer
new T[size]
devido ao apagamento de tipo genérico:
Aqui, um construtor de concreto implementando a interface, construindo uma
Integer
matriz:E finalmente a aplicação / teste:
fonte
Isso deve ser one-liner.
fonte
Uau! Muitas respostas complexas aqui, incluindo algumas simples que dependem de dependências externas. Que tal fazer assim:
fonte
Isso funciona, mas você precisa inserir sua própria verificação de erro.
Provavelmente não é o mais eficiente, mas não depende de nada além da própria API do Java.
fonte
for
loop por aquele:for(int j = 0; j < arr2.length; j++){arrBoth[arr1.length+j] = arr2[j];}
String[] arrBoth = java.util.Arrays.copyOf(arr1, arr1.length + arr2.length)
para pular o primeirofor
loop. Economiza tempo proporcional ao tamanho dearr1
.Esta é uma função convertida para uma matriz String:
fonte
Que tal simplesmente
E apenas faça
Array.concat(arr1, arr2)
. Contanto quearr1
earr2
sejam do mesmo tipo, isso fornecerá outra matriz do mesmo tipo contendo as duas matrizes.fonte
Uma versão estática genérica que usa o System.arraycopy de alto desempenho sem exigir uma anotação @SuppressWarnings:
fonte
fonte
Aqui está minha versão ligeiramente melhorada do concatAll de Joachim Sauer. Ele pode funcionar no Java 5 ou 6, usando System.arraycopy do Java 6, se estiver disponível em tempo de execução. Esse método (IMHO) é perfeito para o Android, pois funciona no Android <9 (que não possui System.arraycopy), mas utilizará o método mais rápido, se possível.
fonte
Outra maneira de pensar sobre a questão. Para concatenar duas ou mais matrizes, é necessário listar todos os elementos de cada matriz e criar uma nova matriz. Parece criar um
List<T>
e, em seguida, chamatoArray
. Algumas outras respostas usamArrayList
, e isso é bom. Mas que tal implementar a nossa? Não é difícil:Eu acredito que o acima é equivalente a soluções que usa
System.arraycopy
. No entanto, acho que este tem sua própria beleza.fonte
E se :
fonte
Uma variação simples que permite a junção de mais de uma matriz:
fonte
Usando apenas a API própria do Javas:
Agora, esse código não é o mais eficiente, mas depende apenas de classes java padrão e é fácil de entender. Funciona para qualquer número de String [] (mesmo zero matrizes).
fonte