Ich muss zwei String
-Arrays in Java verketten.
void f(String[] first, String[] second) {
String[] both = ???
}
Was ist der einfachste Weg, dies zu tun?
Ich habe eine einzeilige Lösung aus der guten alten Apache Commons Lang-Bibliothek gefunden.
ArrayUtils.addAll(T[], T...)
Code:
String[] both = (String[])ArrayUtils.addAll(first, second);
Hier ist eine einfache Methode, die zwei Arrays verkettet und das Ergebnis zurückgibt:
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;
}
Beachten Sie, dass es nicht mit primitiven Datentypen funktioniert, sondern nur mit Objekttypen.
Die folgende etwas kompliziertere Version funktioniert sowohl mit Objekt- als auch mit primitiven Arrays. Dazu wird T
anstelle von T[]
als Argumenttyp verwendet.
Außerdem können Sie Arrays zweier verschiedener Typen verketten, indem Sie den allgemeinsten Typ als Komponententyp des Ergebnisses auswählen.
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;
}
Hier ist ein Beispiel:
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 }));
Es ist möglich, eine vollständig generische Version zu schreiben, die sogar erweitert werden kann, um eine beliebige Anzahl von Arrays zu verketten. Diese Versionen benötigen Java 6, da sie Arrays.copyOf()
verwenden.
Beide Versionen vermeiden das Erstellen von Zwischenobjekten List
und verwenden System.arraycopy()
, um sicherzustellen, dass das Kopieren großer Arrays so schnell wie möglich ist.
Für zwei Arrays sieht es so aus:
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;
}
Und für eine beliebige Anzahl von Arrays (> = 1) sieht es so aus:
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;
}
Einzeiler in Java 8:
String[] both = Stream.concat(Arrays.stream(a), Arrays.stream(b))
.toArray(String[]::new);
Oder:
String[] both = Stream.of(a, b).flatMap(Stream::of)
.toArray(String[]::new);
Oder mit dem Geliebten Guave :
String[] both = ObjectArrays.concat(first, second, String.class);
Es gibt auch Versionen für primitive Arrays:
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)
Verwendung der Java API:
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()]);
}
Eine Lösung 100% altes Java und ohne System.arraycopy
(beispielsweise nicht im GWT-Client verfügbar):
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;
}
Sie können die zwei Arrays in zwei Codezeilen anhängen.
String[] both = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, both, first.length, second.length);
Dies ist eine schnelle und effiziente Lösung, die für primitive Typen geeignet ist. Außerdem sind beide Methoden überlastet.
Sie sollten Lösungen mit ArrayLists, Streams usw. vermeiden, da diese temporären Speicher für keinen sinnvollen Zweck zuordnen müssen.
Sie sollten for
-Schleifen für große Arrays vermeiden, da diese nicht effizient sind. Die integrierten Methoden verwenden Blockkopierfunktionen, die extrem schnell sind.
Ich habe kürzlich Probleme mit übermäßiger Gedächtnisrotation bekämpft. Wenn bekannt ist, dass a und/oder b allgemein leer sind, folgt hier eine weitere Anpassung des Codes von silvertab (auch generiert):
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 beiden Fällen muss das Verhalten der Array-Wiederverwendung eindeutig JavaDoced sein!)
Die Functional Java - Bibliothek verfügt über eine Array-Wrapper-Klasse, die Arrays mit praktischen Methoden wie Verkettung ausstattet.
import static fj.data.Array.array;
...und dann
Array<String> both = array(first).append(array(second));
Rufen Sie an, um das unverpackte Array wieder herauszuholen
String[] s = both.array();
ArrayList<String> both = new ArrayList(Arrays.asList(first));
both.addAll(Arrays.asList(second));
both.toArray(new String[0]);
Ein anderer Weg mit Java8 mit 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);
}
Hier ist eine Anpassung der Lösung von Silvertab mit nachgerüsteten Generika:
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;
}
HINWEIS: Siehe Joachim's Antwort für eine Java 6-Lösung. Es beseitigt nicht nur die Warnung; es ist auch kürzer, effizienter und lesbarer!
Wenn Sie diese Methode verwenden, müssen Sie keine Fremdklasse importieren.
Wenn Sie verketten möchten, String
Beispielcode für zwei aufeinanderfolgende String-Arrays
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;
}
Wenn Sie verketten möchten, Int
Beispielcode für zwei ganze Integer-Arrays
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;
}
Hier ist Hauptmethode
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));
}
}
Wir können diesen Weg auch verwenden.
Bitte verzeihen Sie mir, dass Sie dieser langen Liste noch eine weitere Version hinzufügen. Ich schaute jede Antwort an und entschied, dass ich wirklich eine Version mit nur einem Parameter in der Signatur wollte. Ich habe auch einige Argumente hinzugefügt, um bei einem unerwarteten Input von einem frühen Ausfall mit sinnvollen Informationen zu profitieren.
@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;
}
Sie können versuchen, es in eine Arrayliste zu konvertieren, die addAll-Methode zu verwenden und dann wieder in ein Array zu konvertieren.
List list = new ArrayList(Arrays.asList(first));
list.addAll(Arrays.asList(second));
String[] both = list.toArray();
Hier eine mögliche Implementierung der Pseudocodelösung von Silvertab in Arbeitscode.
Danke 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;
}
}
Als nächstes folgt die Builder-Schnittstelle.
Hinweis: Ein Builder ist erforderlich, da dies in Java nicht möglich ist
new T[size]
wegen generischer Löschung:
public interface ArrayBuilderI<T> {
public T[] build(int size);
}
Hier ein konkreter Builder, der die Schnittstelle implementiert und ein Integer
-Array erstellt:
public class IntegerArrayBuilder implements ArrayBuilderI<Integer> {
@Override
public Integer[] build(int size) {
return new Integer[size];
}
}
Und zum Schluss noch die Anwendung/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]);
}
}
Beeindruckend! Viele komplexe Antworten, einschließlich einiger einfacher Antworten, die von externen Abhängigkeiten abhängen. wie wäre es damit:
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]);
Dies funktioniert, aber Sie müssen Ihre eigene Fehlerprüfung einfügen.
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();
}
}
Es ist wahrscheinlich nicht das effizienteste, aber es ist nicht auf etwas anderes als Javas eigene API angewiesen.
Dies ist eine konvertierte Funktion für ein String-Array:
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;
}
Wie wäre es einfach?
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());
}
}
Und tun Sie einfach Array.concat(arr1, arr2)
. Solange arr1
und arr2
vom gleichen Typ sind, erhalten Sie ein anderes Array des gleichen Typs, das beide Arrays enthält.
Eine einfache Variante, die das Verbinden mehrerer Arrays ermöglicht:
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()]);
}
Hier ist meine leicht verbesserte Version von Joachim Sauers concatAll. Es kann auf Java 5 oder 6 unter Verwendung von System.arraycopy von Java 6 ausgeführt werden, sofern es zur Laufzeit verfügbar ist. Diese Methode (IMHO) ist perfekt für Android, da sie auf Android <9 (das nicht über System.arraycopy verfügt) funktioniert, jedoch die schnellere Methode verwendet, wenn dies möglich ist.
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;
}
Dies sollte ein Liner sein.
public String [] concatenate (final String array1[], final String array2[])
{
return Stream.concat(Stream.of(array1), Stream.of(array2)).toArray(String[]::new);
}
Eine andere Möglichkeit, über die Frage nachzudenken. Um zwei oder mehr Arrays zu verketten, müssen Sie alle Elemente der einzelnen Arrays auflisten und anschließend ein neues Array erstellen. Das klingt nach einem List<T>
und ruft dann toArray
auf. Einige andere Antworten verwenden ArrayList
, und das ist in Ordnung. Aber wie wäre es mit unserer eigenen? Es ist nicht schwer:
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);
}
Ich glaube, das obige ist gleichwertig zu Lösungen, die System.arraycopy
verwenden. Ich denke jedoch, dass dieser eine eigene Schönheit hat.
Wie wäre es mit :
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()]);
}
Eine einfache, aber ineffiziente Möglichkeit, dies zu tun (Generika nicht enthalten):
ArrayList baseArray = new ArrayList(Arrays.asList(array1));
baseArray.addAll(Arrays.asList(array2));
String concatenated[] = (String []) baseArray.toArray(new String[baseArray.size()]);
Nur Javas eigene API verwenden:
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]);
}
Dieser Code ist jetzt nicht der effizienteste, aber er basiert nur auf Standard-Java-Klassen und ist leicht verständlich. Es funktioniert für eine beliebige Anzahl von String [] (auch Null-Arrays).
Mit Java 8+ Streams können Sie die folgende Funktion schreiben:
private static String[] concatArrays(final String[]... arrays) {
return Arrays.stream(arrays)
.flatMap(Arrays::stream)
.toArray(String[]::new);
}
Eine typunabhängige Variante (AKTUALISIERT - dank Volley für die Instantiierung von 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]);
Bei jeder Antwort werden Daten kopiert und ein neues Array erstellt. Dies ist nicht unbedingt erforderlich und ist definitiv NICHT das, was Sie tun möchten, wenn Ihre Arrays relativ groß sind. Java-Ersteller haben bereits gewusst, dass Array-Kopien verschwenderisch sind. Deshalb haben sie uns System.arrayCopy () zur Verfügung gestellt, um außerhalb von Java zu arbeiten, wenn wir müssen.
Anstatt Ihre Daten um sich herum zu kopieren, sollten Sie sie in Betracht ziehen und daraus ziehen, wo sie liegen. Das Kopieren von Datenorten, nur weil der Programmierer sie organisieren möchte, ist nicht immer sinnvoll.
// 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
}
Wenn Sie mit ArrayLists in der Lösung arbeiten möchten, können Sie Folgendes versuchen:
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()]);
}
Ich fand, dass ich mich mit dem Fall befassen musste, in dem die Arrays null sein können ...
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
Sie können String durch einen Typ/eine Klasse Ihrer Wahl ersetzen
Ich bin sicher, dass dies kürzer und besser gemacht werden kann, aber es funktioniert und ich bin faul, es weiter auszusortieren ...
Eine generische statische Version, die die leistungsstarke System.arraycopy verwendet, ohne dass eine @SuppressWarnings-Anmerkung erforderlich ist:
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;
}
Ich denke, die beste Lösung mit Generika wäre:
/* 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;
}
Sie können diese Methode ausprobieren, die mehrere Arrays verkettet:
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;
}
Du kannst es versuchen
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;
}
Du kannst dein Array eingeben !!!
Hier ist der Code von 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));
}
Der einfachste Weg, den ich finden konnte, ist folgender:
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];
Eine weitere basiert auf dem Vorschlag von SilverTab, wurde jedoch zur Unterstützung der x-Anzahl von Argumenten verwendet und erfordert nicht Java 6. Es ist auch nicht generisch, aber ich bin mir sicher, dass es generisch gemacht werden könnte.
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;
}
Sie können dafür die ArrayList-Auflistung verwenden. Die Implementierung ist sehr einfach zu verstehen. Zunächst müssen Sie sowohl die String-Arrays speichern, die in der ArrayList als Argumente angegeben sind, als auch diese ArrayList mit der toArray () - Methode in ein String-Array konvertieren.
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 können Sie so etwas [a, b, c] ++ [d, e]
tun, um [a, b, c, d, e]
zu erhalten. Dies sind verkettete Haskell-Listen, aber es wäre schön, einen ähnlichen Operator in Java für Arrays zu sehen. Glaubst du nicht? Das ist elegant, einfach, generisch und es ist nicht so schwer zu implementieren.
Wenn Sie möchten, schlage ich vor, Alexander Hristovs Arbeit in seinem Hacking the OpenJDK-Compiler zu betrachten. Er erläutert, wie Sie die Javac-Quelle ändern, um einen neuen Operator zu erstellen. Sein Beispiel besteht in der Definition eines '**' - Operators mit i ** j = Math.pow(i, j)
. Man könnte dieses Beispiel nehmen, um einen Operator zu implementieren, der zwei Arrays desselben Typs verkettet.
Wenn Sie dies getan haben, sind Sie an Ihren benutzerdefinierten Javac gebunden, um Ihren Code zu kompilieren, der generierte Bytecode wird jedoch von jeder JVM verstanden.
Natürlich können Sie Ihre eigene Array-Verkettungsmethode auf der Quellenebene implementieren. In den anderen Antworten finden Sie viele Beispiele dazu.
Es gibt so viele nützliche Operatoren, die hinzugefügt werden könnten, dieser wäre einer von ihnen.
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];
}
Dies funktioniert ohne Kenntnis anderer Klassen/Bibliotheken usw .. Es funktioniert für jeden Datentyp. Ersetzen Sie einfach String
durch irgendetwas wie int
, double
oder char
. Es funktioniert ziemlich effizient.
Nicht Java 8-Lösung:
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;
}
Dies ist wahrscheinlich der einzige generische und typsichere Weg:
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;
}
}
Und die Verwendung ist recht knapp:
Integer[] array1 = { 1, 2, 3 };
Double[] array2 = { 4.0, 5.0, 6.0 };
Number[] array = concat(Number[]::new).apply(array1, array2);
(erfordert statischen Import)
Ungültige Feldtypen werden abgelehnt:
concat(String[]::new).apply(array1, array2); // error
concat(Integer[]::new).apply(array1, array2); // error
Dieser arbeitet nur mit int, aber die Idee ist generisch
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];
}
Sehen Sie sich diese elegante Lösung an (wenn Sie einen anderen Typ als char benötigen, ändern Sie ihn):
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;
}
}
Sie können jede Anzahl von Arrays verketten.
Dies ist wahrscheinlich der einzige generische und typsichere Weg:
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;
}
}
Und die Verwendung ist recht knapp:
Integer[] array1 = { 1, 2, 3 };
Double[] array2 = { 4.0, 5.0, 6.0 };
Number[] array = concat(Number[]::new).apply(array1, array2);
(erfordert statischen Import)
Ungültige Array-Typen werden zurückgewiesen:
concat(String[]::new).apply(array1, array2); // error
concat(Integer[]::new).apply(array1, array2); // error
Noch eine Antwort für Algorithmusliebhaber:
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;
Verwendungszweck:
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));
Ergebnis:
[a, b, c, d, e, f, g, h, i]
Sollte den Trick tun. Dies setzt voraus, dass String [] first und String [] second sind
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()]);
Ich habe den Code getestet und funktionierte gut
Außerdem verwende ich die Bibliothek: 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]);
}
}
}
Grüße