Ho bisogno di concatenare due array String
in Java.
void f(String[] first, String[] second) {
String[] both = ???
}
Qual è il modo più semplice per farlo?
Ho trovato una soluzione a una riga dalla buona vecchia libreria di Apache Commons Lang.
ArrayUtils.addAll(T[], T...)
Codice:
String[] both = (String[])ArrayUtils.addAll(first, second);
Ecco un semplice metodo che concatenerà due array e restituirà il risultato:
public <T> T[] concatenate(T[] a, T[] b) {
int aLen = a.length;
int bLen = b.length;
@SuppressWarnings("unchecked")
T[] c = (T[]) Array.newInstance(a.getClass().getComponentType(), aLen + bLen);
System.arraycopy(a, 0, c, 0, aLen);
System.arraycopy(b, 0, c, aLen, bLen);
return c;
}
Si noti che non funzionerà con i tipi di dati primitivi, solo con i tipi di oggetto.
La seguente versione leggermente più complicata funziona sia con gli oggetti che con gli array primitivi. Lo fa usando T
invece di T[]
come tipo di argomento.
Consente inoltre di concatenare matrici di due tipi diversi selezionando il tipo più generale come tipo di componente del risultato.
public static <T> T concatenate(T a, T b) {
if (!a.getClass().isArray() || !b.getClass().isArray()) {
throw new IllegalArgumentException();
}
Class<?> resCompType;
Class<?> aCompType = a.getClass().getComponentType();
Class<?> bCompType = b.getClass().getComponentType();
if (aCompType.isAssignableFrom(bCompType)) {
resCompType = aCompType;
} else if (bCompType.isAssignableFrom(aCompType)) {
resCompType = bCompType;
} else {
throw new IllegalArgumentException();
}
int aLen = Array.getLength(a);
int bLen = Array.getLength(b);
@SuppressWarnings("unchecked")
T result = (T) Array.newInstance(resCompType, aLen + bLen);
System.arraycopy(a, 0, result, 0, aLen);
System.arraycopy(b, 0, result, aLen, bLen);
return result;
}
Ecco un esempio:
Assert.assertArrayEquals(new int[] { 1, 2, 3 }, concatenate(new int[] { 1, 2 }, new int[] { 3 }));
Assert.assertArrayEquals(new Number[] { 1, 2, 3f }, concatenate(new Integer[] { 1, 2 }, new Number[] { 3f }));
È possibile scrivere una versione completamente generica che può anche essere estesa per concatenare un numero qualsiasi di array. Queste versioni richiedono Java 6, poiché usano Arrays.copyOf()
Entrambe le versioni evitano di creare oggetti List
intermedi e utilizzano System.arraycopy()
per garantire che la copia di array di grandi dimensioni sia il più veloce possibile.
Per due array sembra questo:
public static <T> T[] concat(T[] first, T[] second) {
T[] result = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, result, first.length, second.length);
return result;
}
E per un numero arbitrario di matrici (> = 1) assomiglia a questo:
public static <T> T[] concatAll(T[] first, T[]... rest) {
int totalLength = first.length;
for (T[] array : rest) {
totalLength += array.length;
}
T[] result = Arrays.copyOf(first, totalLength);
int offset = first.length;
for (T[] array : rest) {
System.arraycopy(array, 0, result, offset, array.length);
offset += array.length;
}
return result;
}
One-liner in Java 8:
String[] both = Stream.concat(Arrays.stream(a), Arrays.stream(b))
.toArray(String[]::new);
O:
String[] both = Stream.of(a, b).flatMap(Stream::of)
.toArray(String[]::new);
O con l'amato Guava :
String[] both = ObjectArrays.concat(first, second, String.class);
Inoltre, ci sono versioni per gli array primitivi:
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)
Utilizzo dell'API Java:
String[] f(String[] first, String[] second) {
List<String> both = new ArrayList<String>(first.length + second.length);
Collections.addAll(both, first);
Collections.addAll(both, second);
return both.toArray(new String[both.size()]);
}
Una soluzione 100% vecchio Java e senza System.arraycopy
(non disponibile nel client GWT per esempio):
static String[] concat(String[]... arrays) {
int length = 0;
for (String[] array : arrays) {
length += array.length;
}
String[] result = new String[length];
int pos = 0;
for (String[] array : arrays) {
for (String element : array) {
result[pos] = element;
pos++;
}
}
return result;
}
È possibile aggiungere i due array in due righe di codice.
String[] both = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, both, first.length, second.length);
Questa è una soluzione rapida ed efficiente e funzionerà per i tipi primitivi così come i due metodi coinvolti sono sovraccarichi.
È necessario evitare soluzioni che coinvolgono ArrayList, flussi, ecc. In quanto questi dovranno allocare memoria temporanea per scopi non utili.
Dovresti evitare cicli for
per array di grandi dimensioni in quanto non sono efficienti. I metodi integrati utilizzano funzioni di copia di blocchi estremamente veloci.
Recentemente ho combattuto problemi con un'eccessiva rotazione della memoria. Se a e/o b sono noti per essere comunemente vuoti, ecco un altro adattamento del codice di silvertab (anch'esso generato):
private static <T> T[] concat(T[] a, T[] b) {
final int alen = a.length;
final int blen = b.length;
if (alen == 0) {
return b;
}
if (blen == 0) {
return a;
}
final T[] result = (T[]) Java.lang.reflect.Array.
newInstance(a.getClass().getComponentType(), alen + blen);
System.arraycopy(a, 0, result, 0, alen);
System.arraycopy(b, 0, result, alen, blen);
return result;
}
(In entrambi i casi, il comportamento di riutilizzo dell'array deve essere chiaramente JavaDoced!)
La libreria Functional Java ha una classe wrapper di array che equipaggia gli array con metodi pratici come la concatenazione.
import static fj.data.Array.array;
...e poi
Array<String> both = array(first).append(array(second));
Per richiamare l'array unwrapped, chiama
String[] s = both.array();
ArrayList<String> both = new ArrayList(Arrays.asList(first));
both.addAll(Arrays.asList(second));
both.toArray(new String[0]);
Un altro modo con Java8 usando Stream
public String[] concatString(String[] a, String[] b){
Stream<String> streamA = Arrays.stream(a);
Stream<String> streamB = Arrays.stream(b);
return Stream.concat(streamA, streamB).toArray(String[]::new);
}
Ecco un adattamento della soluzione di silvertab, con i generici adattati:
static <T> T[] concat(T[] a, T[] b) {
final int alen = a.length;
final int blen = b.length;
final T[] result = (T[]) Java.lang.reflect.Array.
newInstance(a.getClass().getComponentType(), alen + blen);
System.arraycopy(a, 0, result, 0, alen);
System.arraycopy(b, 0, result, alen, blen);
return result;
}
NOTA: vedere La risposta di Joachim per una soluzione Java 6. Non solo elimina l'avvertimento; è anche più breve, più efficiente e più facile da leggere!
Se si utilizza in questo modo, non è necessario importare classi di terze parti.
Se vuoi concatenare String
Esempio di codice per concare due Array di stringhe
public static String[] combineString(String[] first, String[] second){
int length = first.length + second.length;
String[] result = new String[length];
System.arraycopy(first, 0, result, 0, first.length);
System.arraycopy(second, 0, result, first.length, second.length);
return result;
}
Se vuoi concatenare Int
Esempio di codice per conciliare due array Integer
public static int[] combineInt(int[] a, int[] b){
int length = a.length + b.length;
int[] result = new int[length];
System.arraycopy(a, 0, result, 0, a.length);
System.arraycopy(b, 0, result, a.length, b.length);
return result;
}
Ecco il metodo principale
public static void main(String[] args) {
String [] first = {"a", "b", "c"};
String [] second = {"d", "e"};
String [] joined = combineString(first, second);
System.out.println("concatenated String array : " + Arrays.toString(joined));
int[] array1 = {101,102,103,104};
int[] array2 = {105,106,107,108};
int[] concatenateInt = combineInt(array1, array2);
System.out.println("concatenated Int array : " + Arrays.toString(concatenateInt));
}
}
Possiamo usare anche in questo modo.
Per favore perdonami per aver aggiunto ancora un'altra versione a questa già lunga lista. Ho guardato ogni risposta e ho deciso che volevo davvero una versione con un solo parametro nella firma. Ho anche aggiunto alcuni argomenti per trarre vantaggio da un errore precoce con informazioni sensibili in caso di input inattesi.
@SuppressWarnings("unchecked")
public static <T> T[] concat(T[]... inputArrays) {
if(inputArrays.length < 2) {
throw new IllegalArgumentException("inputArrays must contain at least 2 arrays");
}
for(int i = 0; i < inputArrays.length; i++) {
if(inputArrays[i] == null) {
throw new IllegalArgumentException("inputArrays[" + i + "] is null");
}
}
int totalLength = 0;
for(T[] array : inputArrays) {
totalLength += array.length;
}
T[] result = (T[]) Array.newInstance(inputArrays[0].getClass().getComponentType(), totalLength);
int offset = 0;
for(T[] array : inputArrays) {
System.arraycopy(array, 0, result, offset, array.length);
offset += array.length;
}
return result;
}
Potresti provare a convertirlo in un Arraylist e usare il metodo addAll per poi riconvertirlo in un array.
List list = new ArrayList(Arrays.asList(first));
list.addAll(Arrays.asList(second));
String[] both = list.toArray();
Ecco una possibile implementazione nel codice di lavoro della soluzione di pseudo codice scritta da silvertab.
Grazie silvertab!
public class Array {
public static <T> T[] concat(T[] a, T[] b, ArrayBuilderI<T> builder) {
T[] c = builder.build(a.length + b.length);
System.arraycopy(a, 0, c, 0, a.length);
System.arraycopy(b, 0, c, a.length, b.length);
return c;
}
}
Di seguito è l'interfaccia del costruttore.
Nota: un builder è necessario perché in Java non è possibile farlo
new T[size]
a causa della cancellazione di tipo generico:
public interface ArrayBuilderI<T> {
public T[] build(int size);
}
Qui un costruttore concreto che implementa l'interfaccia, costruendo un array Integer
:
public class IntegerArrayBuilder implements ArrayBuilderI<Integer> {
@Override
public Integer[] build(int size) {
return new Integer[size];
}
}
E infine l'applicazione/test:
@Test
public class ArrayTest {
public void array_concatenation() {
Integer a[] = new Integer[]{0,1};
Integer b[] = new Integer[]{2,3};
Integer c[] = Array.concat(a, b, new IntegerArrayBuilder());
assertEquals(4, c.length);
assertEquals(0, (int)c[0]);
assertEquals(1, (int)c[1]);
assertEquals(2, (int)c[2]);
assertEquals(3, (int)c[3]);
}
}
Wow! molte risposte complesse qui incluse alcune semplici che dipendono da dipendenze esterne. che ne dici di farlo in questo modo:
String [] arg1 = new String{"a","b","c"};
String [] arg2 = new String{"x","y","z"};
ArrayList<String> temp = new ArrayList<String>();
temp.addAll(Arrays.asList(arg1));
temp.addAll(Arrays.asList(arg2));
String [] concatedArgs = temp.toArray(new String[arg1.length+arg2.length]);
Funziona, ma è necessario inserire il proprio controllo degli errori.
public class StringConcatenate {
public static void main(String[] args){
// Create two arrays to concatenate and one array to hold both
String[] arr1 = new String[]{"s","t","r","i","n","g"};
String[] arr2 = new String[]{"s","t","r","i","n","g"};
String[] arrBoth = new String[arr1.length+arr2.length];
// Copy elements from first array into first part of new array
for(int i = 0; i < arr1.length; i++){
arrBoth[i] = arr1[i];
}
// Copy elements from second array into last part of new array
for(int j = arr1.length;j < arrBoth.length;j++){
arrBoth[j] = arr2[j-arr1.length];
}
// Print result
for(int k = 0; k < arrBoth.length; k++){
System.out.print(arrBoth[k]);
}
// Additional line to make your terminal look better at completion!
System.out.println();
}
}
Probabilmente non è il più efficiente, ma non si basa su qualcosa di diverso dall'API di Java.
Questa è una funzione convertita per un array di stringhe:
public String[] mergeArrays(String[] mainArray, String[] addArray) {
String[] finalArray = new String[mainArray.length + addArray.length];
System.arraycopy(mainArray, 0, finalArray, 0, mainArray.length);
System.arraycopy(addArray, 0, finalArray, mainArray.length, addArray.length);
return finalArray;
}
Che ne dici di semplicemente
public static class Array {
public static <T> T[] concat(T[]... arrays) {
ArrayList<T> al = new ArrayList<T>();
for (T[] one : arrays)
Collections.addAll(al, one);
return (T[]) al.toArray(arrays[0].clone());
}
}
E fai solo Array.concat(arr1, arr2)
. Finché arr1
e arr2
sono dello stesso tipo, questo ti darà un altro array dello stesso tipo che contiene entrambi gli array.
Una semplice variazione che consente l'unione di più di un array:
public static String[] join(String[]...arrays) {
final List<String> output = new ArrayList<String>();
for(String[] array : arrays) {
output.addAll(Arrays.asList(array));
}
return output.toArray(new String[output.size()]);
}
Ecco la mia versione leggermente migliorata di concatAll di Joachim Sauer. Può funzionare su Java 5 o 6, utilizzando System.arraycopy di Java 6 se è disponibile in fase di runtime. Questo metodo (IMHO) è perfetto per Android, poiché funziona su Android <9 (che non ha System.arraycopy) ma utilizzerà il metodo più veloce se possibile.
public static <T> T[] concatAll(T[] first, T[]... rest) {
int totalLength = first.length;
for (T[] array : rest) {
totalLength += array.length;
}
T[] result;
try {
Method arraysCopyOf = Arrays.class.getMethod("copyOf", Object[].class, int.class);
result = (T[]) arraysCopyOf.invoke(null, first, totalLength);
} catch (Exception e){
//Java 6 / Android >= 9 way didn't work, so use the "traditional" approach
result = (T[]) Java.lang.reflect.Array.newInstance(first.getClass().getComponentType(), totalLength);
System.arraycopy(first, 0, result, 0, first.length);
}
int offset = first.length;
for (T[] array : rest) {
System.arraycopy(array, 0, result, offset, array.length);
offset += array.length;
}
return result;
}
Questo dovrebbe essere one-liner.
public String [] concatenate (final String array1[], final String array2[])
{
return Stream.concat(Stream.of(array1), Stream.of(array2)).toArray(String[]::new);
}
Un altro modo di pensare alla domanda. Per concatenare due o più matrici, è necessario elencare tutti gli elementi di ciascun array e quindi creare un nuovo array. Sembra come creare un List<T>
e quindi chiamare toArray
su di esso. Alcune altre risposte usano ArrayList
, e va bene. Ma come implementare il nostro? Non è difficile:
private static <T> T[] addAll(final T[] f, final T...o){
return new AbstractList<T>(){
@Override
public T get(int i) {
return i>=f.length ? o[i - f.length] : f[i];
}
@Override
public int size() {
return f.length + o.length;
}
}.toArray(f);
}
Credo che quanto sopra sia equivalente alle soluzioni che usa System.arraycopy
. Comunque penso che questo abbia la sua bellezza.
Che ne dite di :
public String[] combineArray (String[] ... strings) {
List<String> tmpList = new ArrayList<String>();
for (int i = 0; i < strings.length; i++)
tmpList.addAll(Arrays.asList(strings[i]));
return tmpList.toArray(new String[tmpList.size()]);
}
Un modo facile, ma inefficiente, per farlo (generici non inclusi):
ArrayList baseArray = new ArrayList(Arrays.asList(array1));
baseArray.addAll(Arrays.asList(array2));
String concatenated[] = (String []) baseArray.toArray(new String[baseArray.size()]);
Utilizzando solo l'API di Javas:
String[] join(String[]... arrays) {
// calculate size of target array
int size = 0;
for (String[] array : arrays) {
size += array.length;
}
// create list of appropriate size
Java.util.List list = new Java.util.ArrayList(size);
// add arrays
for (String[] array : arrays) {
list.addAll(Java.util.Arrays.asList(array));
}
// create and return final array
return list.toArray(new String[size]);
}
Ora, questo codice non è il più efficiente, ma si basa solo su classi Java standard ed è facile da capire. Funziona per qualsiasi numero di String [] (anche zero array).
Utilizzando gli stream Java 8+ è possibile scrivere la seguente funzione:
private static String[] concatArrays(final String[]... arrays) {
return Arrays.stream(arrays)
.flatMap(Arrays::stream)
.toArray(String[]::new);
}
Una variazione di tipo indipendente (AGGIORNATA - grazie a Volley per l'istanziazione di T):
@SuppressWarnings("unchecked")
public static <T> T[] join(T[]...arrays) {
final List<T> output = new ArrayList<T>();
for(T[] array : arrays) {
output.addAll(Arrays.asList(array));
}
return output.toArray((T[])Array.newInstance(
arrays[0].getClass().getComponentType(), output.size()));
}
public String[] concat(String[]... arrays)
{
int length = 0;
for (String[] array : arrays) {
length += array.length;
}
String[] result = new String[length];
int destPos = 0;
for (String[] array : arrays) {
System.arraycopy(array, 0, result, destPos, array.length);
destPos += array.length;
}
return result;
}
String [] both = new ArrayList<String>(){{addAll(Arrays.asList(first)); addAll(Arrays.asList(second));}}.toArray(new String[0]);
Ogni singola risposta è la copia dei dati e la creazione di un nuovo array. Questo non è strettamente necessario e NON è sicuramente quello che vuoi fare se i tuoi array sono abbastanza grandi. I creatori di Java sapevano già che le copie di array erano inutili e per questo motivo ci hanno fornito System.arrayCopy () per farlo al di fuori di Java quando necessario.
Invece di copiare i tuoi dati, prendi in considerazione l'idea di lasciarli al loro posto e di attingere da dove si trova. La copia delle posizioni dei dati solo perché il programmatore vorrebbe organizzarle non è sempre ragionevole.
// I have arrayA and arrayB; would like to treat them as concatenated
// but leave my damn bytes where they are!
Object accessElement ( int index ) {
if ( index < 0 ) throw new ArrayIndexOutOfBoundsException(...);
// is reading from the head part?
if ( index < arrayA.length )
return arrayA[ index ];
// is reading from the tail part?
if ( index < ( arrayA.length + arrayB.length ) )
return arrayB[ index - arrayA.length ];
throw new ArrayIndexOutOfBoundsException(...); // index too large
}
Se desideri lavorare con ArrayLists nella soluzione, puoi provare questo:
public final String [] f(final String [] first, final String [] second) {
// Assuming non-null for brevity.
final ArrayList<String> resultList = new ArrayList<String>(Arrays.asList(first));
resultList.addAll(new ArrayList<String>(Arrays.asList(second)));
return resultList.toArray(new String [resultList.size()]);
}
public static String[] toArray(String[]... object){
List<String> list=new ArrayList<>();
for (String[] i : object) {
list.addAll(Arrays.asList(i));
}
return list.toArray(new String[list.size()]);
}
Ho scoperto che dovevo affrontare il caso in cui gli array possono essere nulli ...
private double[] concat (double[]a,double[]b){
if (a == null) return b;
if (b == null) return a;
double[] r = new double[a.length+b.length];
System.arraycopy(a, 0, r, 0, a.length);
System.arraycopy(b, 0, r, a.length, b.length);
return r;
}
private double[] copyRest (double[]a, int start){
if (a == null) return null;
if (start > a.length)return null;
double[]r = new double[a.length-start];
System.arraycopy(a,start,r,0,a.length-start);
return r;
}
Import Java.util.*;
String array1[] = {"bla","bla"};
String array2[] = {"bla","bla"};
ArrayList<String> tempArray = new ArrayList<String>(Arrays.asList(array1));
tempArray.addAll(Arrays.asList(array2));
String array3[] = films.toArray(new String[1]); // size will be overwritten if needed
Potresti sostituire String con un tipo/classe di tuo gradimento
Sono sicuro che questo può essere reso più breve e migliore, ma funziona e sto a pigro per risolverlo ulteriormente ...
Una versione statica generica che utilizza System.arraycopy ad alte prestazioni senza richiedere un'annotazione @SuppressWarnings:
public static <T> T[] arrayConcat(T[] a, T[] b) {
T[] both = Arrays.copyOf(a, a.length + b.length);
System.arraycopy(b, 0, both, a.length, b.length);
return both;
}
Object[] mixArray(String[] a, String[] b)
String[] s1 = a;
String[] s2 = b;
Object[] result;
List<String> input = new ArrayList<String>();
for (int i = 0; i < s1.length; i++)
{
input.add(s1[i]);
}
for (int i = 0; i < s2.length; i++)
{
input.add(s2[i]);
}
result = input.toArray();
return result;
public int[] mergeArrays(int [] a, int [] b) {
int [] merged = new int[a.length + b.length];
int i = 0, k = 0, l = a.length;
int j = a.length > b.length ? a.length : b.length;
while(i < j) {
if(k < a.length) {
merged[k] = a[k];
k++;
}
if((l - a.length) < b.length) {
merged[l] = b[l - a.length];
l++;
}
i++;
}
return merged;
}
Penso che la soluzione migliore con i generici sarebbe:
/* This for non primitive types */
public static <T> T[] concatenate (T[]... elements) {
T[] C = null;
for (T[] element: elements) {
if (element==null) continue;
if (C==null) C = (T[]) Array.newInstance(element.getClass().getComponentType(), element.length);
else C = resizeArray(C, C.length+element.length);
System.arraycopy(element, 0, C, C.length-element.length, element.length);
}
return C;
}
/**
* as far as i know, primitive types do not accept generics
* http://stackoverflow.com/questions/2721546/why-dont-Java-generics-support-primitive-types
* for primitive types we could do something like this:
* */
public static int[] concatenate (int[]... elements){
int[] C = null;
for (int[] element: elements) {
if (element==null) continue;
if (C==null) C = new int[element.length];
else C = resizeArray(C, C.length+element.length);
System.arraycopy(element, 0, C, C.length-element.length, element.length);
}
return C;
}
private static <T> T resizeArray (T array, int newSize) {
int oldSize =
Java.lang.reflect.Array.getLength(array);
Class elementType =
array.getClass().getComponentType();
Object newArray =
Java.lang.reflect.Array.newInstance(
elementType, newSize);
int preserveLength = Math.min(oldSize, newSize);
if (preserveLength > 0)
System.arraycopy(array, 0,
newArray, 0, preserveLength);
return (T) newArray;
}
Puoi provare questo metodo che concatena più array:
public static <T> T[] concatMultipleArrays(T[]... arrays)
{
int length = 0;
for (T[] array : arrays)
{
length += array.length;
}
T[] result = (T[]) Array.newInstance(arrays.getClass().getComponentType(), length) ;
length = 0;
for (int i = 0; i < arrays.length; i++)
{
System.arraycopy(arrays[i], 0, result, length, arrays[i].length);
length += arrays[i].length;
}
return result;
}
Puoi provare questo
public static Object[] addTwoArray(Object[] objArr1, Object[] objArr2){
int arr1Length = objArr1!=null && objArr1.length>0?objArr1.length:0;
int arr2Length = objArr2!=null && objArr2.length>0?objArr2.length:0;
Object[] resutlentArray = new Object[arr1Length+arr2Length];
for(int i=0,j=0;i<resutlentArray.length;i++){
if(i+1<=arr1Length){
resutlentArray[i]=objArr1[i];
}else{
resutlentArray[i]=objArr2[j];
j++;
}
}
return resutlentArray;
}
U puoi digitare cast il tuo array !!!
Ecco il codice di AbacusUtil .
String[] a = {"a", "b", "c"};
String[] b = {"1", "2", "3"};
String[] c = N.concat(a, b); // c = ["a", "b", "c", "1", "2", "3"]
// N.concat(...) is null-safety.
a = null;
c = N.concat(a, b); // c = ["1", "2", "3"]
In Java 8
public String[] concat(String[] arr1, String[] arr2){
Stream<String> stream1 = Stream.of(arr1);
Stream<String> stream2 = Stream.of(arr2);
Stream<String> stream = Stream.concat(stream1, stream2);
return Arrays.toString(stream.toArray(String[]::new));
}
Il modo più semplice che ho trovato è il seguente:
List allFiltersList = Arrays.asList(regularFilters);
allFiltersList.addAll(Arrays.asList(preFiltersArray));
Filter[] mergedFilterArray = (Filter[]) allFiltersList.toArray();
Object[] obj = {"hi","there"};
Object[] obj2 ={"im","fine","what abt u"};
Object[] obj3 = new Object[obj.length+obj2.length];
for(int i =0;i<obj3.length;i++)
obj3[i] = (i<obj.length)?obj[i]:obj2[i-obj.length];
Un altro basato sul suggerimento di SilverTab, ma realizzato per supportare il numero x di argomenti e non richiede Java 6. Inoltre non è generico, ma sono sicuro che potrebbe essere reso generico.
private byte[] concat(byte[]... args)
{
int fulllength = 0;
for (byte[] arrItem : args)
{
fulllength += arrItem.length;
}
byte[] retArray = new byte[fulllength];
int start = 0;
for (byte[] arrItem : args)
{
System.arraycopy(arrItem, 0, retArray, start, arrItem.length);
start += arrItem.length;
}
return retArray;
}
Puoi usare la collezione ArrayList per questo. la sua implementazione è molto facile da comprendere, inizialmente è necessario memorizzare entrambi gli array di stringhe forniti negli argomenti in ArrayList e dopo averlo convertito in array String con il metodo toArray (), ecco l'implementazione:
public static void f(String[] first, String[] second) {
ArrayList<String> list = new ArrayList<>();
for(String s: first){
list.add(s);
}
for(String s: second){
list.add(s);
}
String[] both = list.toArray(new String[list.size()]);
System.out.println(list.toString());
}
In Haskell puoi fare qualcosa del genere [a, b, c] ++ [d, e]
per ottenere [a, b, c, d, e]
. Queste sono liste Haskell concatenate ma sarebbe molto bello vedere un operatore simile in Java per gli array. Non la pensi così? È elegante, semplice, generico e non è così difficile da implementare.
Se vuoi, ti suggerisco di dare un'occhiata al lavoro di Alexander Hristov nel suo Hacking the OpenJDK compiler . Spiega come modificare javac source per creare un nuovo operatore. Il suo esempio consiste nel definire un operatore '**' in cui i ** j = Math.pow(i, j)
. Si potrebbe prendere quell'esempio per implementare un operatore che concatena due array dello stesso tipo.
Una volta che lo fai, sei legato al tuo javac personalizzato per compilare il tuo codice, ma il codice byte generato sarà compreso da qualsiasi JVM.
Naturalmente, puoi implementare il tuo metodo di concatenazione dell'array a livello sorgente, ci sono molti esempi su come farlo nelle altre risposte!
Ci sono così tanti operatori utili che potrebbero essere aggiunti, questo sarebbe uno di loro.
void f(String[] first, String[] second) {
String[] both = new String[first.length+second.length];
for(int i=0;i<first.length;i++)
both[i] = first[i];
for(int i=0;i<second.length;i++)
both[first.length + i] = second[i];
}
Questo funziona senza conoscenza di altre classi/librerie ecc Funziona con qualsiasi tipo di dati. Basta sostituire String
con qualcosa come int
, double
o char
. Funziona in modo abbastanza efficiente.
Soluzione non Java 8:
public static int[] combineArrays(int[] a, int[] b) {
int[] c = new int[a.length + b.length];
for (int i = 0; i < a.length; i++) {
c[i] = a[i];
}
for (int j = 0, k = a.length; j < b.length; j++, k++) {
c[k] = b[j];
}
return c;
}
Questo è probabilmente l'unico modo generico e sicuro per il tipo:
public class ArrayConcatenator<T> {
private final IntFunction<T[]> generator;
private ArrayConcatenator(IntFunction<T[]> generator) {
this.generator = generator;
}
public static <T> ArrayConcatenator<T> concat(IntFunction<T[]> generator) {
return new ArrayConcatenator<>(generator);
}
public T[] apply(T[] array1, T[] array2) {
T[] array = generator.apply(array1.length + array2.length);
System.arraycopy(array1, 0, array, 0, array1.length);
System.arraycopy(array2, 0, array, array1.length, array2.length);
return array;
}
}
E l'uso è abbastanza conciso:
Integer[] array1 = { 1, 2, 3 };
Double[] array2 = { 4.0, 5.0, 6.0 };
Number[] array = concat(Number[]::new).apply(array1, array2);
(richiede l'importazione statica)
I tipi di array non validi vengono rifiutati:
concat(String[]::new).apply(array1, array2); // error
concat(Integer[]::new).apply(array1, array2); // error
Questo funziona solo con int ma l'idea è generica
public static int[] junta(int[] v, int[] w) {
int[] junta = new int[v.length + w.length];
for (int i = 0; i < v.length; i++) {
junta[i] = v[i];
}
for (int j = v.length; j < junta.length; j++) {
junta[j] = w[j - v.length];
}
Guarda questa soluzione elegante (se hai bisogno di un altro tipo di carattere, cambialo):
private static void concatArrays(char[] destination, char[]... sources) {
int currPos = 0;
for (char[] source : sources) {
int length = source.length;
System.arraycopy(source, 0, destination, currPos, length);
currPos += length;
}
}
È possibile concatenare ogni numero di array.
Questo è probabilmente l'unico modo generico e sicuro per il tipo:
public class ArrayConcatenator<T> {
private final IntFunction<T[]> generator;
private ArrayConcatenator(IntFunction<T[]> generator) {
this.generator = generator;
}
public static <T> ArrayConcatenator<T> concat(IntFunction<T[]> generator) {
return new ArrayConcatenator<>(generator);
}
public T[] apply(T[] array1, T[] array2) {
T[] array = generator.apply(array1.length + array2.length);
System.arraycopy(array1, 0, array, 0, array1.length);
System.arraycopy(array2, 0, array, array1.length, array2.length);
return array;
}
}
E l'uso è abbastanza conciso:
Integer[] array1 = { 1, 2, 3 };
Double[] array2 = { 4.0, 5.0, 6.0 };
Number[] array = concat(Number[]::new).apply(array1, array2);
(richiede l'importazione statica)
I tipi di array non validi vengono rifiutati:
concat(String[]::new).apply(array1, array2); // error
concat(Integer[]::new).apply(array1, array2); // error
Ancora un'altra risposta per gli amanti dell'algoritmo:
public static String[] mergeArrays(String[] array1, String[] array2) {
int totalSize = array1.length + array2.length; // Get total size
String[] merged = new String[totalSize]; // Create new array
// Loop over the total size
for (int i = 0; i < totalSize; i++) {
if (i < array1.length) // If the current position is less than the length of the first array, take value from first array
merged[i] = array1[i]; // Position in first array is the current position
else // If current position is equal or greater than the first array, take value from second array.
merged[i] = array2[i - array1.length]; // Position in second array is current position minus length of first array.
}
return merged;
Uso:
String[] array1str = new String[]{"a", "b", "c", "d"};
String[] array2str = new String[]{"e", "f", "g", "h", "i"};
String[] listTotalstr = mergeArrays(array1str, array2str);
System.out.println(Arrays.toString(listTotalstr));
Risultato:
[a, b, c, d, e, f, g, h, i]
Dovrebbe fare il trucco. Questo presuppone String [] first e String [] second
List<String> myList = new ArrayList<String>(Arrays.asList(first));
myList.addAll(new ArrayList<String>(Arrays.asList(second)));
String[] both = myList.toArray(new String[myList.size()]);
Ho provato sotto il codice e ho funzionato bene
Inoltre sto usando la libreria: org.Apache.commons.lang.ArrayUtils
public void testConcatArrayString(){
String[] a = null;
String[] b = null;
String[] c = null;
a = new String[] {"1","2","3","4","5"};
b = new String[] {"A","B","C","D","E"};
c = (String[]) ArrayUtils.addAll(a, b);
if(c!=null){
for(int i=0; i<c.length; i++){
System.out.println("c[" + (i+1) + "] = " + c[i]);
}
}
}
Saluti