How can I concatenate two arrays in Java?
我需要在Java中连接两个EDCOX1的0个数组。
最简单的方法是什么?
我从优秀的旧ApacheCommonsLang库中找到了一个单行解决方案。
代码:
下面是一个简单的方法,它将连接两个数组并返回结果:
1 2 3 4 5 6 7 8 9 10 11 |
请注意,它将不适用于基本数据类型,只适用于对象类型。
下面稍微复杂一点的版本适用于对象和基元数组。它通过使用
它还可以通过选择最通用的类型作为结果的组件类型来连接两个不同类型的数组。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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; } |
下面是一个例子:
1 2 |
It's possible to write a fully generic version that can even be extended to concatenate any number of arrays. This versions require Java 6, as they use
Both versions avoid creating any intermediary
For two arrays it looks like this:
1 2 3 4 5 |
对于任意数量的数组(>=1),它如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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; } |
Java 8中的一个内衬:
或:
或与心爱的番石榴:
此外,还有用于基本数组的版本:
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)
使用Java API:
1 2 3 4 5 6 | 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()]); } |
你可以添加两个代码阵列线。
1 2 |
这是一个几乎和高效的解决方案的原始类型和想要工作的工作人员参与的是超负荷的方法。
你应该避免的解决方案,包括流arraylists等,为论文所要分配的临时内存的需要没有有用的用途。
你应该避免
一个解决方案100%旧Java和没有EDCOX1×0(例如在GWT客户机中不可用):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
我最近与过度记忆旋转的问题作了斗争。如果A和/或B通常是空的,那么下面是对Silvertab代码的另一种改编(也进行了generified):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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语句首先是这个特定优化的全部要点。我把这个答案留在这里,但要小心!
函数式Java库有一个数组包装器类,它用类似于级联的方便方法对数组进行排列。
1 |
然后……
1 | Array<String> both = array(first).append(array(second)); |
要使展开的数组返回,请调用
1 |
1 2 3 4 |
一个java8单向流
1 2 3 4 5 |
以下是对Silvertab解决方案的改编,对仿制药进行了改装:
1 2 3 4 5 6 7 8 9 | 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解决方案的答案。它不仅消除了警告,而且更短、更高效、更容易阅读!
如果你使用这种方式,所以你不需要任何第三方的进出口等。
如果你想链接
样品码级连的二维字符串数组
1 2 3 4 5 6 7 |
如果你想链接
级连码的二维整数数组示例
1 2 3 4 5 6 7 |
这里是主要的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | public static void main(String[] args) { String [] first = {"a","b","c <p><center>[wp_ad_camp_2]</center></p><hr><P>请原谅我在这个已经很长的列表中添加了另一个版本。我看了每个答案,决定我真的想要一个签名中只有一个参数的版本。我还添加了一些参数检查,以便在意外输入的情况下,使用明智的信息从早期失败中获益。</P>[cc lang="java"]@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; } |
您可以尝试将其转换为arraylist,然后使用addall方法将其转换回数组。
1 2 3 |
这里是SilverTab编写的伪代码解决方案的工作代码中的一个可能实现。
谢谢西尔弗塔布!
1 2 3 4 5 6 7 8 9 |
接下来是构建器接口。
注意:一个建设者是必要的,因为在Java中是不可能的。
由于通用类型擦除:
1 2 3 4 | public interface ArrayBuilderI<T> { public T[] build(int size); } |
这里是一个实现接口的具体构建器,构建一个
1 2 3 4 5 6 7 |
最后是应用程序/测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @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]); } } |
This works, but you need to insert your own error checking.
1 2 3 4 5 6 7 8 9 10 11 12 | 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 <div class="suo-content">[collapse title=""]<ul><li>+ 1。最好把第二个<wyn>for</wyn>环换成:<wyn>for(int j = 0; j < arr2.length; j++){arrBoth[arr1.length+j] = arr2[j];}</wyn>环。</li><li>使用<wyn>String[] arrBoth = java.util.Arrays.copyOf(arr1, arr1.length + arr2.length)</wyn>跳过第一个<wyn>for</wyn>循环。节省与<wyn>arr1</wyn>大小成比例的时间。</li></ul>[/collapse]</div><hr><P>真的!这里有很多复杂的答案,包括一些依赖外部依赖的简单答案。这样做怎么样:</P>[cc lang="java"]String [] arg1 = new String{"a","b","c <div class="suo-content">[collapse title=""]<ul><li>简单实用。</li><li>…但效率低下,速度慢。</li></ul>[/collapse]</div><hr><P>你可以用Java写的8 +流的以下功能:</p>[cc lang="java"]private static String[] concatArrays(final String[]... arrays) { return Arrays.stream(arrays) .flatMap(Arrays::stream) .toArray(String[]::new); } |
这应该是一个衬板。
1 2 3 4 |
简单点怎么样
1 2 3 4 5 6 7 8 9 | 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()); } } |
就这么做。只要
这是字符串数组的转换函数:
1 2 3 4 5 6 7 | 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; } |
这是我对约阿希姆·绍尔的《海螺》的改进版。它可以在Java 5或6上工作,如果运行时可用的话,可以使用Java 6的系统。此方法(imho)非常适合Android,因为它在Android<9(没有system.arraycopy)上工作,但如果可能,将使用更快的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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; } |
允许连接多个数组的简单变体:
1 2 3 4 5 6 7 8 9 10 |
Another way to think about the question. To concatenate two or more arrays, one have to do is to list all elements of each arrays, and then build a new array. This sounds like create a
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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); } |
我相信上述方法相当于使用
怎么样:
1 2 3 4 5 6 |
一种简单但效率低下的方法(不包括仿制药):
1 2 3 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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; } |
仅使用javas自己的API:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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类,并且易于理解。它适用于任意数量的字符串[](甚至是零个数组)。
一个独立于类型的变体(更新了-由于使用了Volley来实例化t):
1 2 3 4 5 6 7 8 9 10 11 12 |
一个通用的静态版本的使用要求不高的表演从指定源suppresswarnings A"标注:
1 2 3 4 5 |
1 |
1 2 3 4 5 6 7 8 9 | Import java.util.*; String array1[] = {"bla","bla <p><center>[wp_ad_camp_4]</center></p><hr><P>如果要在解决方案中使用ArrayList,可以尝试以下操作:</P>[cc lang="java"]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()]); } |
1 2 3 4 5 6 7 |
我发现我必须处理数组可以为空的情况…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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; } |
这是由abacusutil代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 | String[] a = {"a","b","c <hr><P>一个单一的答案复制数据和创建一个新的阵列。这不是严格必要的和是肯定不是你想做的是,如果有大型阵列。Java的创造者已经知道数组的副本是wasteful和这是为什么他们提供从指定源(美国)做的工作时,我们必须使用Java。</p><P>复制你的数据不是在考虑离开它,在它的地方和从它读。复制数据的位置,只是因为他们想组织一个程序员并不总是敏感。</p>[cc lang="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 } |
我认为使用仿制药的最佳解决方案是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | /* 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; } |
另一个是基于SILVALTAB的建议,但是支持X个参数,而不需要Java 6。它也不是通用的,但我相信它可以被做成通用的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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; } |
你可以使用ArrayList集合。它的实现是很容易的,你必须明白,这两个存储阵列提供的参数字符串是在这之后就在ArrayList和转换到一个ArrayList数组拷贝()方法,这是实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
在Java中8
1 2 3 4 5 6 |
You can try this method which concatenates multiple arrays:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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; } |
我测试了以下代码,工作正常
另外,我正在使用库:org.apache.commons.lang.arrayutils
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public void testConcatArrayString(){ String[] a = null; String[] b = null; String[] c = null; a = new String[] {"1","2","3","4","5 <hr>[cc lang="java"]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; } |
You can try this
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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; } |
你可以输入你的数组!!!!
这一个只适用于int,但其思想是通用的
1 2 3 4 5 6 7 8 9 10 11 | 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]; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | object[]obj="hi","there<div class="suo-content">[collapse title=""]<ul><li>请解释一下你的密码-原因如下</li></ul>[/collapse]</div><hr><P>这是唯一的通用和类型安全的方式:</p>[cc lang="java"]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; } } |
和使用是很简明:
1 2 3 |
(需要静态导入)
无效的数组类型是不是:
1 2 |
最简单的方法是:
1 2 3 4 5 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
看看这个优雅的解决方案(如果您需要char以外的其他类型,请更改它):
1 2 3 4 5 6 7 8 | 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; } } |
可以将数组的每个计数连接起来。
应该有技巧。这假定首先使用字符串[],然后使用字符串[]second。
1 2 3 |
1 2 3 4 5 6 7 |
这一类的作品,没有任何其他/知识库等。它为任何数据类型。只是一个什么样
Yet another answer for algorithm lovers:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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; |
用法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | String[] array1str = new String[]{"a","b","c","d <div class="suo-content">[collapse title=""]<ul><li>每一份的if语句不是一个好主意,因为它将有一个巨大的性能冲击。</li><li>@Maartenbodewes学习专注于性能的新方法总是很好的。有什么改进的建议吗?</li><li>好吧,是的,<wyn>arrayCopy</wyn>,但我想在其他一些例子中提到过。对于两个或多个<wyn>for</wyn>循环,也是如此;可以将分支(if语句)从循环中去掉。</li></ul>[/collapse]</div><hr><P>解决方案:非Java 8</p>[cc lang="java"]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; } |
在哈斯克尔,你可以做一些类似于
如果你愿意的话,我建议你看看亚历山大·赫里斯托夫在他开发OpenJDK编译器时所做的工作。他解释了如何修改javac源代码以创建新的操作符。他的例子包括定义一个"**"运算符,其中
一旦这样做了,您将绑定到定制的javac来编译代码,但是生成的字节码将被任何JVM理解。当然,您可以在源代码级别实现自己的数组连接方法,在其他答案中有许多关于如何实现它的示例!有那么多有用的操作符可以添加,这个操作符就是其中之一。