[英]How can I concatenate two arrays in Java?
我需要在 Java 中連接兩個String
arrays。
void f(String[] first, String[] second) {
String[] both = ???
}
哪種方法最簡單?
我從古老的 Apache Commons Lang 庫中找到了一個單行解決方案。
ArrayUtils.addAll(T[], T...)
代碼:
String[] both = ArrayUtils.addAll(first, second);
這是一個連接兩個數組並返回結果的簡單方法:
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;
}
請注意,它不適用於原始數據類型,只能用於對象類型。
以下稍微復雜的版本適用於對象和原始數組。 它通過使用T
而不是T[]
作為參數類型來做到這一點。
它還可以通過選擇最通用的類型作為結果的組件類型來連接兩種不同類型的數組。
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;
}
下面是一個例子:
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 }));
在 Java 8 中使用Stream
:
String[] both = Stream.concat(Arrays.stream(a), Arrays.stream(b))
.toArray(String[]::new);
或者像這樣,使用flatMap
:
String[] both = Stream.of(a, b).flatMap(Stream::of)
.toArray(String[]::new);
要對泛型類型執行此操作,您必須使用反射:
@SuppressWarnings("unchecked")
T[] both = Stream.concat(Arrays.stream(a), Arrays.stream(b)).toArray(
size -> (T[]) Array.newInstance(a.getClass().getComponentType(), size));
可以編寫一個完全通用的版本,甚至可以擴展它以連接任意數量的數組。 此版本需要 Java 6,因為它們使用Arrays.copyOf()
兩個版本都避免創建任何中間List
對象並使用System.arraycopy()
來確保盡可能快地復制大型數組。
對於兩個數組,它看起來像這樣:
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;
}
對於任意數量的數組 (>= 1),它看起來像這樣:
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;
}
或與心愛的番石榴:
String[] both = ObjectArrays.concat(first, second, String.class);
此外,還有原始數組的版本:
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)
您可以在兩行代碼中附加這兩個數組。
String[] both = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, both, first.length, second.length);
這是一個快速有效的解決方案,適用於原始類型以及所涉及的兩個方法被重載。
您應該避免涉及 ArrayLists、streams 等的解決方案,因為這些將需要分配臨時內存而沒有任何用處。
您應該避免大型數組的for
循環,因為它們效率不高。 內置方法使用非常快的塊復制功能。
使用 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()]);
}
一個解決方案100% 舊 java並且沒有System.arraycopy
(例如在 GWT 客戶端中不可用):
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;
}
我最近解決了過度內存輪換的問題。 如果已知 a 和/或 b 通常為空,則這里是 Silvertab 代碼的另一種改編(也已生成):
private static <T> T[] concatOrReturnSame(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;
}
編輯:這篇文章的前一個版本指出,像這樣的數組重用應該被清楚地記錄下來。 正如 Maarten 在評論中指出的那樣,通常最好只刪除 if 語句,從而無需擁有文檔。 但話又說回來,那些 if 語句首先是這個特定優化的重點。 我會在這里留下這個答案,但要小心!
ArrayList<String> both = new ArrayList(Arrays.asList(first));
both.addAll(Arrays.asList(second));
both.toArray(new String[0]);
Functional Java庫有一個數組包裝類,它為數組配備了一些方便的方法,比如連接。
import static fj.data.Array.array;
...進而
Array<String> both = array(first).append(array(second));
要取回未包裝的數組,請調用
String[] s = both.array();
Java8 使用 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);
}
這是 Silvertab 解決方案的改編版,對泛型進行了改造:
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;
}
注意:有關 Java 6 解決方案,請參閱Joachim 的回答。 它不僅消除了警告; 它也更短、更高效、更容易閱讀!
您可以嘗試將其轉換為 Arraylist 並使用 addAll 方法,然后再轉換回數組。
List list = new ArrayList(Arrays.asList(first));
list.addAll(Arrays.asList(second));
String[] both = list.toArray();
如果您使用這種方式,則無需導入任何第三方類。
如果你想連接String
連接兩個字符串數組的示例代碼
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;
}
如果你想連接Int
連接兩個整數數組的示例代碼
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;
}
這是主要方法
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));
}
}
我們也可以使用這種方式。
請原諒我在這個已經很長的列表中添加了另一個版本。 我查看了每個答案,並決定我真的想要一個簽名中只有一個參數的版本。 我還添加了一些參數檢查,以便在出現意外輸入的情況下通過合理的信息從早期失敗中受益。
@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;
}
使用 Java 8+ 流,您可以編寫以下函數:
private static String[] concatArrays(final String[]... arrays) {
return Arrays.stream(arrays)
.flatMap(Arrays::stream)
.toArray(String[]::new);
}
這應該是單行的。
public String [] concatenate (final String array1[], final String array2[])
{
return Stream.concat(Stream.of(array1), Stream.of(array2)).toArray(String[]::new);
}
這是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;
}
}
接下來是構建器界面。
注意:構建器是必需的,因為在 Java 中這是不可能的
new T[size]
由於泛型類型擦除:
public interface ArrayBuilderI<T> {
public T[] build(int size);
}
這是一個實現接口的具體構建器,構建一個Integer
數組:
public class IntegerArrayBuilder implements ArrayBuilderI<Integer> {
@Override
public Integer[] build(int size) {
return new Integer[size];
}
}
最后是應用程序/測試:
@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]);
}
}
哇! 這里有很多復雜的答案,包括一些依賴於外部依賴的簡單答案。 這樣做怎么樣:
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]);
這有效,但您需要插入自己的錯誤檢查。
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();
}
}
它可能不是最有效的,但它不依賴於 Java 自己的 API 以外的任何東西。
一種允許連接多個數組的簡單變體:
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()]);
}
使用高性能 System.arraycopy 而不需要 @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;
}
這是字符串數組的轉換函數:
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;
}
簡單的怎么樣
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());
}
}
只需執行Array.concat(arr1, arr2)
。 只要arr1
和arr2
的類型相同,這將為您提供另一個包含兩個數組的相同類型的數組。
思考這個問題的另一種方式。 要連接兩個或多個數組,必須列出每個數組的所有元素,然后構建一個新數組。 這聽起來像是創建一個List<T>
然后在其上調用toArray
。 其他一些答案使用ArrayList
,這很好。 但是如何實現我們自己的呢? 這並不難:
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);
}
我相信以上相當於使用System.arraycopy
解決方案。 不過我覺得這個有它自己的美。
怎么樣 :
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()]);
}
我需要在Java中串聯兩個String
數組。
void f(String[] first, String[] second) {
String[] both = ???
}
最簡單的方法是什么?
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;
}
這是我對 Joachim Sauer 的 concatAll 稍加改進的版本。 它可以在 Java 5 或 6 上運行,如果它在運行時可用,則使用 Java 6 的 System.arraycopy。 這種方法(恕我直言)非常適合 Android,因為它適用於 Android <9(沒有 System.arraycopy),但如果可能,將使用更快的方法。
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;
}
僅使用 Java 自己的 API:
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]);
}
現在,這段代碼不是最有效的,但它只依賴於標准的 java 類並且很容易理解。 它適用於任意數量的 String[](甚至零數組)。
類型無關的變體(更新 - 感謝 Volley 實例化 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()));
}
我發現我必須處理數組可以為空的情況......
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;
}
String [] both = new ArrayList<String>(){{addAll(Arrays.asList(first)); addAll(Arrays.asList(second));}}.toArray(new String[0]);
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()]);
}
每個答案都是復制數據並創建一個新數組。 這不是絕對必要的,如果您的數組相當大,這絕對不是您想要做的。 Java 創建者已經知道數組副本是浪費的,這就是為什么他們為我們提供 System.arrayCopy() 以在我們需要時在 Java 之外執行這些操作。
與其復制您的數據,不如考慮將其留在原處並從它所在的位置提取。 僅僅因為程序員想要組織它們而復制數據位置並不總是明智的。
// 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
}
這可能是唯一的通用和類型安全的方法:
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;
}
}
用法非常簡潔:
Integer[] array1 = { 1, 2, 3 };
Double[] array2 = { 4.0, 5.0, 6.0 };
Number[] array = concat(Number[]::new).apply(array1, array2);
(需要靜態導入)
無效的數組類型被拒絕:
concat(String[]::new).apply(array1, array2); // error
concat(Integer[]::new).apply(array1, array2); // error
一種簡單但效率低下的方法(不包括泛型):
ArrayList baseArray = new ArrayList(Arrays.asList(array1));
baseArray.addAll(Arrays.asList(array2));
String concatenated[] = (String []) baseArray.toArray(new String[baseArray.size()]);
如果你想在解決方案中使用 ArrayLists,你可以試試這個:
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()]);
}
我認為泛型的最佳解決方案是:
/* 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;
}
另一個基於 SilverTab 的建議,但支持 x 個參數並且不需要 Java 6。它也不是通用的,但我確信它可以成為通用的。
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;
}
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
你可以用你喜歡的類型/類替換字符串
我確定這可以做得更短更好,但它有效,我懶得進一步整理它......
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;
}
非 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;
}
/**
* With Java Streams
* @param first First Array
* @param second Second Array
* @return Merged Array
*/
String[] mergeArrayOfStrings(String[] first, String[] second) {
return Stream.concat(Arrays.stream(first), Arrays.stream(second)).toArray(String[]::new);
}
這個只適用於 int 但這個想法是通用的
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];
}
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 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;
用法:
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));
結果:
[a, b, c, d, e, f, g, h, i]
您可以嘗試這種連接多個數組的方法:
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;
}
在 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));
}
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];
使用 lambda 連接一系列緊湊、快速且類型安全的數組
@SafeVarargs
public static <T> T[] concat( T[]... arrays ) {
return( Stream.of( arrays ).reduce( ( arr1, arr2 ) -> {
T[] rslt = Arrays.copyOf( arr1, arr1.length + arr2.length );
System.arraycopy( arr2, 0, rslt, arr1.length, arr2.length );
return( rslt );
} ).orElse( null ) );
};
不帶參數調用時返回null
例如。 具有 3 個數組的示例:
String[] a = new String[] { "a", "b", "c", "d" };
String[] b = new String[] { "e", "f", "g", "h" };
String[] c = new String[] { "i", "j", "k", "l" };
concat( a, b, c ); // [a, b, c, d, e, f, g, h, i, j, k, l]
“......可能是唯一的通用和類型安全的方式” ——改編:
Number[] array1 = { 1, 2, 3 };
Number[] array2 = { 4.0, 5.0, 6.0 };
Number[] array = concat( array1, array2 ); // [1, 2, 3, 4.0, 5.0, 6.0]
只是想補充一下,您也可以使用System.arraycopy
:
import static java.lang.System.out;
import static java.lang.System.arraycopy;
import java.lang.reflect.Array;
class Playground {
@SuppressWarnings("unchecked")
public static <T>T[] combineArrays(T[] a1, T[] a2) {
T[] result = (T[]) Array.newInstance(a1.getClass().getComponentType(), a1.length+a2.length);
arraycopy(a1,0,result,0,a1.length);
arraycopy(a2,0,result,a1.length,a2.length);
return result;
}
public static void main(String[ ] args) {
String monthsString = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
String[] months = monthsString.split("(?<=\\G.{3})");
String daysString = "SUNMONTUEWEDTHUFRISAT";
String[] days = daysString.split("(?<=\\G.{3})");
for (String m : months) {
out.println(m);
}
out.println("===");
for (String d : days) {
out.println(d);
}
out.println("===");
String[] results = combineArrays(months, days);
for (String r : results) {
out.println(r);
}
out.println("===");
}
}
我能找到的最簡單的方法如下:
List allFiltersList = Arrays.asList(regularFilters);
allFiltersList.addAll(Arrays.asList(preFiltersArray));
Filter[] mergedFilterArray = (Filter[]) allFiltersList.toArray();
我使用 next 方法使用 java 8 連接任意數量的相同類型的數組:
public static <G> G[] concatenate(IntFunction<G[]> generator, G[] ... arrays) {
int len = arrays.length;
if (len == 0) {
return generator.apply(0);
} else if (len == 1) {
return arrays[0];
}
int pos = 0;
Stream<G> result = Stream.concat(Arrays.stream(arrays[pos]), Arrays.stream(arrays[++pos]));
while (pos < len - 1) {
result = Stream.concat(result, Arrays.stream(arrays[++pos]));
}
return result.toArray(generator);
}
用法:
concatenate(String[]::new, new String[]{"one"}, new String[]{"two"}, new String[]{"three"})
或者
concatenate(Integer[]::new, new Integer[]{1}, new Integer[]{2}, new Integer[]{3})
剛剛發現這個問題,抱歉很晚了,看到很多答案太離譜了,使用某些庫,使用將數據從數組轉換為流再轉換回數組的功能等等。 但是,我們可以只使用一個簡單的循環,問題就解決了
public String[] concat(String[] firstArr,String[] secondArr){
//if both is empty just return
if(firstArr.length==0 && secondArr.length==0)return new String[0];
String[] res = new String[firstArr.length+secondArr.length];
int idxFromFirst=0;
//loop over firstArr, idxFromFirst will be used as starting offset for secondArr
for(int i=0;i<firstArr.length;i++){
res[i] = firstArr[i];
idxFromFirst++;
}
//loop over secondArr, with starting offset idxFromFirst (the offset track from first array)
for(int i=0;i<secondArr.length;i++){
res[idxFromFirst+i]=secondArr[i];
}
return res;
}
僅此而已,對嗎? 他沒有說他關心訂單或任何事情。 這應該是最簡單的方法了。
你可以試試這個
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;
}
你可以輸入你的數組!!!
使用 Java Collections
好吧,Java 沒有提供連接 arrays 的輔助方法。但是,自 Java 5 以來,Collections 實用程序 class 引入了一個 addAll(Collection<? super T> 8811284.T65588 元素) 方法
我們可以創建一個List object,然后兩次調用這個方法將兩個arrays添加到列表中。 最后,我們將結果列表轉換回數組:
static <T> T[] concatWithCollection(T[] array1, T[] array2) {
List<T> resultList = new ArrayList<>(array1.length + array2.length);
Collections.addAll(resultList, array1);
Collections.addAll(resultList, array2);
@SuppressWarnings("unchecked")
//the type cast is safe as the array1 has the type T[]
T[] resultArray = (T[]) Array.newInstance(array1.getClass().getComponentType(), 0);
return resultList.toArray(resultArray);
}
測試
@Test
public void givenTwoStringArrays_whenConcatWithList_thenGetExpectedResult() {
String[] result = ArrayConcatUtil.concatWithCollection(strArray1, strArray2);
assertThat(result).isEqualTo(expectedStringArray);
}
我測試了下面的代碼並且工作正常
我也在使用庫: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]);
}
}
}
問候
我看到許多帶有簽名的通用答案,例如 public static T[] concat(T[] a, T[] b) {},但據我所知,這些答案僅適用於 Object arrays,不適用於原始 arrays。 下面的代碼適用於 Object 和原始 arrays,使其更通用......
public static <T> T concat(T a, T b) {
//Handles both arrays of Objects and primitives! E.g., int[] out = concat(new int[]{6,7,8}, new int[]{9,10});
//You get a compile error if argument(s) not same type as output. (int[] in example above)
//You get a runtime error if output type is not an array, i.e., when you do something like: int out = concat(6,7);
if (a == null && b == null) return null;
if (a == null) return b;
if (b == null) return a;
final int aLen = Array.getLength(a);
final int bLen = Array.getLength(b);
if (aLen == 0) return b;
if (bLen == 0) return a;
//From here on we really need to concatenate!
Class componentType = a.getClass().getComponentType();
final T result = (T)Array.newInstance(componentType, aLen + bLen);
System.arraycopy(a, 0, result, 0, aLen);
System.arraycopy(b, 0, result, aLen, bLen);
return result;
}
public static void main(String[] args) {
String[] out1 = concat(new String[]{"aap", "monkey"}, new String[]{"rat"});
int[] out2 = concat(new int[]{6,7,8}, new int[]{9,10});
}
看看這個優雅的解決方案(如果您需要除 char 以外的其他類型,請更改它):
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;
}
}
您可以連接每個數組計數。
應該做的伎倆。 這是假設 String[] 第一個和 String[] 第二個
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()]);
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];
}
這個可以在不了解任何其他類/庫等的情況下工作。它適用於任何數據類型。 只需將String
替換為int
、 double
或char
。 它的工作效率很高。
我有一個簡單的方法。 您不想浪費時間研究復雜的 java 函數或庫。 但是返回類型應該是String。
String[] f(String[] first, String[] second) {
// Variable declaration part
int len1 = first.length;
int len2 = second.length;
int lenNew = len1 + len2;
String[] both = new String[len1+len2];
// For loop to fill the array "both"
for (int i=0 ; i<lenNew ; i++){
if (i<len1) {
both[i] = first[i];
} else {
both[i] = second[i-len1];
}
}
return both;
}
很簡單...
在 Haskell 中,您可以執行類似[a, b, c] ++ [d, e]
來獲得[a, b, c, d, e]
。 這些是串聯的 Haskell 列表,但很高興在 Java 中看到類似的數組運算符。 你不這么認為嗎? 這是優雅、簡單、通用的,而且實現起來並不難。
如果你願意,我建議你看看 Alexander Hristov 在他的Hacking the OpenJDK compiler 中的工作。 他解釋了如何修改 javac 源代碼以創建新的運算符。 他的例子包括定義一個 '**' 運算符,其中i ** j = Math.pow(i, j)
。 人們可以用這個例子來實現一個連接兩個相同類型數組的運算符。
一旦你這樣做了,你就綁定到你定制的 javac 來編譯你的代碼,但生成的字節碼將被任何 JVM 理解。
當然,您可以在源代碼級別實現自己的數組連接方法,在其他答案中有很多關於如何執行此操作的示例!
有很多有用的運算符可以添加,這就是其中之一。
這是對我有用的:
String[] data=null;
String[] data2=null;
ArrayList<String> data1 = new ArrayList<String>();
for(int i=0; i<2;i++) {
data2 = input.readLine().split(",");
data1.addAll(Arrays.asList(data2));
data= data1.toArray(new String[data1.size()]);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.