Javaで2つのString
配列を連結する必要があります。
void f(String[] first, String[] second) {
String[] both = ???
}
これを行う最も簡単な方法は何ですか?
私は古き良きApache Commons Langライブラリーから1行の解決策を見つけました。
ArrayUtils.addAll(T[], T...)
コード:
String[] both = (String[])ArrayUtils.addAll(first, second);
これは2つの配列を連結して結果を返す簡単な方法です。
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
を使用します。
結果のコンポーネント型として最も一般的な型を選ぶことによって、2つの異なる型の配列を連結することも可能になります。
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 6が必要です。 Arrays.copyOf()
を使用するためです。
どちらのバージョンも中間のList
オブジェクトを作成することを避け、System.arraycopy()
を使用して大規模な配列のコピーをできるだけ速くします。
2つの配列では、このようになります。
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;
}
Java 8のワンライナー:
String[] both = Stream.concat(Arrays.stream(a), Arrays.stream(b))
.toArray(String[]::new);
または
String[] both = Stream.of(a, b).flatMap(Stream::of)
.toArray(String[]::new);
または最愛の人と/ グアバ :
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)
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;
}
2行のコードに2つの配列を追加することができます。
String[] both = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, both, first.length, second.length);
これは速くて効率的な解決策であり、関係する2つのメソッドがオーバーロードされているのと同様に、プリミティブ型のために働くでしょう。
ArrayLists、ストリームなどを含むソリューションは、有用な目的のために一時メモリを割り当てる必要があるため、避けるべきです。
大きな配列は効率的ではないので、for
ループは避けるべきです。組み込みメソッドは、非常に高速なブロックコピー機能を使用します。
私は最近、過度のメモリローテーションの問題を解決しました。 aまたはb、あるいはその両方が一般的に空であることがわかっている場合は、これもsilvertabのコードの別の応用です(一般化されています)。
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;
}
(どちらの場合も、配列の再利用動作は明確にJavaDocedになります。)
Functional Java ライブラリには、配列に連結のような便利なメソッドを装備する配列ラッパークラスがあります。
import static fj.data.Array.array;
...その後
Array<String> both = array(first).append(array(second));
ラップされていない配列を元に戻すには、次のように呼び出します。
String[] s = both.array();
ArrayList<String> both = new ArrayList(Arrays.asList(first));
both.addAll(Arrays.asList(second));
both.toArray(new String[0]);
ストリームを使用してJava 8で別の方法
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の答え を参照してください。それは警告を排除するだけではありません。また、短く、効率的で読みやすくなります。
あなたがこの方法を使うのであれば、サードパーティのクラスをインポートする必要はありません。
String
を連結したい場合
連結2文字列配列のサンプルコード
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
を連結したい場合
連結2整数配列のサンプルコード
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));
}
}
このようにも使えます。
この長いリストにさらに別のバージョンを追加してください。私はすべての答えを見て、シグネチャに1つのパラメータしか含まないバージョンが本当に欲しいと判断しました。また、予期しない入力があった場合に適切な情報を使用して、初期の失敗から利益を得るための引数チェックを追加しました。
@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メソッドを使ってから配列に戻すことができます。
List list = new ArrayList(Arrays.asList(first));
list.addAll(Arrays.asList(second));
String[] both = list.toArray();
ここで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 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
が同じ型である限り、これは両方の配列を含む同じ型の別の配列になります。
複数の配列を結合できるようにする単純な変形
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()]);
}
これがJoachim SauerのconcatAllを少し改良したものです。実行時に利用可能な場合は、Java 6のSystem.arraycopyを使用して、Java 5または6で動作します。このメソッド(IMHO)は、Android <9(System.arraycopyがありません)で機能するため、Androidに最適ですが、可能であればより高速のメソッドを使用します。
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;
}
これはワンライナーであるべきです。
public String [] concatenate (final String array1[], final String array2[])
{
return Stream.concat(Stream.of(array1), Stream.of(array2)).toArray(String[]::new);
}
質問について考えるもう一つの方法。 2つ以上の配列を連結するには、各配列のすべての要素をリストしてから新しい配列を作成する必要があります。これは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()]);
}
これを行うための簡単ではあるが非効率的な方法
ArrayList baseArray = new ArrayList(Arrays.asList(array1));
baseArray.addAll(Arrays.asList(array2));
String concatenated[] = (String []) baseArray.toArray(new String[baseArray.size()]);
Javas独自の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 [](ゼロ配列でも)に対して機能します。
Java 8+ストリームを使用すると、次の関数を書くことができます。
private static String[] concatArrays(final String[]... arrays) {
return Arrays.stream(arrays)
.flatMap(Arrays::stream)
.toArray(String[]::new);
}
型に依存しないバリエーション(UPDATED - Tをインスタンス化してくれたVolleyに感謝):
@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]);
すべての答えは、データをコピーして新しい配列を作成することです。これは厳密には必要ではなく、配列がそれほど大きくない場合は絶対にしたくないことです。 Javaの作成者は、配列のコピーが無駄であることをすでに知っていたので、必要なときにJavaの外部でそれらを実行するためにSystem.arrayCopy()を提供していました。
あなたのデータをコピーする代わりに、それを所定の位置に残して、それがあるところからそれから引き出すことを検討してください。プログラマがそれらを整理したいという理由だけでデータの場所をコピーすることは、常に賢明ではありません。
// 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
}
ソリューションで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()]);
}
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()]);
}
配列がnullになる可能性がある場合に対処する必要があることがわかりました.
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
あなたはあなたの好みのType/ClassでStringを置き換えることができます
これをもっと短く、より良くできることを確信してください、しかしそれはうまくいって、さらにそれを整理するために怠惰に...
@SuppressWarningsアノテーションを必要とせずに高性能のSystem.arraycopyを使用する汎用静的バージョン。
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;
}
私はジェネリック医薬品との最善の解決策があると思う
/* 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;
}
複数の配列を連結するこの方法を試すことができます。
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;
}
あなたはこれを試すことができます
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はあなたの配列を型キャストできます!
これは 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"]
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));
}
私が見つけることができる最も簡単な方法は次のとおりです。
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];
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;
}
これにはArrayListコレクションを使用できます。その実装は非常に理解しやすいです、最初はArrayListの引数で提供される両方のString配列を格納しなければなりません、そしてそれからtoArray()メソッドでそのArrayListをString配列に変換するだけです。
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());
}
Haskellでは、[a, b, c] ++ [d, e]
を取得するために[a, b, c, d, e]
のようなことができます。これらは連結されたHaskellのリストですが、配列のためにJavaで似たような演算子を見るのはとてもうれしいことです。そう思いませんか?それはエレガントで、シンプルで、一般的なもので、実装するのはそれほど難しくありません。
あなたがそうしたいのなら、Alexander Hristovの彼の OpenJDKコンパイラのハッキング を見てください。彼はjavacのソースを変更して新しい演算子を作成する方法を説明します。彼の例はi ** j = Math.pow(i, j)
のところに '**'演算子を定義することにあります。その例を挙げれば、同じ型の2つの配列を連結する演算子を実装できます。
これを実行すると、コードをコンパイルするためにカスタマイズされたjavacにバインドされますが、生成されたバイトコードはどのJVMでも認識されます。
もちろん、あなたはあなたのソースレベルであなた自身の配列連結メソッドを実装することができます、他の答えでそれをする方法に関する多くの例があります!
追加できる有用な演算子は非常に多くあります。これはそのうちの1つです。
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 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;
}
これはおそらく唯一の一般的でタイプセーフな方法です:
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
これは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];
}
このエレガントな解決策を見てください(あなたが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;
}
}
あなたはすべての数の配列を連結することができます。
これはおそらく唯一の一般的でタイプセーフな方法です:
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
アルゴリズム愛好家のためのもう一つの答え:
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]
トリックをするべきです。これは最初に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()]);
私はコードの下でテストし、うまくいった
また、私はライブラリを使用しています: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]);
}
}
}
よろしく