etc./StackOverFlow

Java에서 두 개의 배열을 어떻게 연결할 수 있습니까?

청렴결백한 만능 재주꾼 2022. 2. 24. 22:02
반응형

질문자 :Community Wiki


Java에서 String 배열을 연결해야 합니다.

 void f(String[] first, String[] second) { String[] both = ??? }

이 작업을 수행하는 가장 쉬운 방법은 무엇입니까?



좋은 오래된 Apache Commons Lang 라이브러리에서 한 줄 솔루션을 찾았습니다.
ArrayUtils.addAll(T[], T...)

암호:

 String[] both = ArrayUtils.addAll(first, second);

Community Wiki

다음은 두 개의 배열을 연결하고 결과를 반환하는 간단한 방법입니다.

 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 }));

Community Wiki

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));

Community Wiki

모든 배열을 연결하도록 확장할 수 있는 완전히 일반적인 버전을 작성하는 것이 가능합니다. Arrays.copyOf() 를 사용하므로 Java 6이 필요합니다.

두 버전 모두 중간 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; }

Community Wiki

또는 사랑하는 구아바 와 함께:

 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)

Community Wiki

두 줄의 코드에 두 개의 배열을 추가할 수 있습니다.

 String[] both = Arrays.copyOf(first, first.length + second.length); System.arraycopy(second, 0, both, first.length, second.length);

이것은 빠르고 효율적인 솔루션이며 기본 유형과 관련된 두 가지 방법이 오버로드된 경우에도 작동합니다.

ArrayList, 스트림 등과 관련된 솔루션은 유용한 목적 없이 임시 메모리를 할당해야 하므로 피해야 합니다.

큰 배열에 대해서는 효율적이지 않으므로 for 루프를 피해야 합니다. 내장 메소드는 매우 빠른 블록 복사 기능을 사용합니다.


Community Wiki

자바 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()]); }

Community Wiki

System.arraycopy 없는 100% 오래된 Java 솔루션(예: 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; }

Community Wiki

나는 최근에 과도한 메모리 회전 문제와 싸웠습니다. 및/또는 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 문은 처음에 이 특정 최적화의 요점이었습니다. 이 답변을 여기에 남길 것이지만 조심하십시오!


Community Wiki

Functional Java 라이브러리에는 배열에 연결과 같은 편리한 방법을 제공하는 배열 래퍼 클래스가 있습니다.

 import static fj.data.Array.array;

...그리고

 Array<String> both = array(first).append(array(second));

래핑되지 않은 배열을 다시 꺼내려면 다음을 호출하십시오.

 String[] s = both.array();

Community Wiki

ArrayList<String> both = new ArrayList(Arrays.asList(first)); both.addAll(Arrays.asList(second)); both.toArray(new String[0]);

Community Wiki

Stream을 사용하는 Java8의 또 다른 방법

 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); }

Community Wiki

다음은 제네릭을 개조한 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의 답변을 참조하십시오. 경고를 제거할 뿐만 아니라; 또한 더 짧고 효율적이며 읽기 쉽습니다!


Community Wiki

Arraylist로 변환하고 addAll 메서드를 사용한 다음 다시 배열로 변환할 수 있습니다.

 List list = new ArrayList(Arrays.asList(first)); list.addAll(Arrays.asList(second)); String[] both = list.toArray();

Community Wiki

이 방법을 사용하면 타사 클래스를 가져올 필요가 없습니다.

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; }

다음은 Main 메서드입니다.

 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)); } }

우리도 이 방법을 사용할 수 있습니다.


Community Wiki

이미 긴 목록에 다른 버전을 추가한 것을 용서해 주십시오. 모든 답변을 살펴보고 서명에 매개변수가 하나만 있는 버전을 원한다고 결정했습니다. 또한 예상치 못한 입력의 경우에 합리적인 정보로 조기 실패의 이점을 얻기 위해 몇 가지 인수 검사를 추가했습니다.

 @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; }

Community Wiki

Java 8+ 스트림을 사용하여 다음 함수를 작성할 수 있습니다.

 private static String[] concatArrays(final String[]... arrays) { return Arrays.stream(arrays) .flatMap(Arrays::stream) .toArray(String[]::new); }

Community Wiki

다음은 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; } }

다음은 빌더 인터페이스입니다.

참고: 자바에서는 할 수 없기 때문에 빌더가 필요합니다.

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]); } }

Community Wiki

이것은 한 줄로 되어 있어야 합니다.

 public String [] concatenate (final String array1[], final String array2[]) { return Stream.concat(Stream.of(array1), Stream.of(array2)).toArray(String[]::new); }

Community Wiki

우와! 여기에는 외부 종속성에 의존하는 몇 가지 간단한 답변을 포함하여 복잡한 답변이 많이 있습니다. 다음과 같이 하면 어떻습니까?

 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]);

Community Wiki

이것은 작동하지만 고유한 오류 검사를 삽입해야 합니다.

 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 이외의 다른 것에 의존하지 않습니다.


Community Wiki

이것은 String 배열에 대한 변환된 함수입니다:

 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; }

Community Wiki

간단히 어떻습니까

 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) 하세요. arr1arr2 가 같은 유형이면 두 배열을 모두 포함하는 동일한 유형의 다른 배열이 제공됩니다.


Community Wiki

둘 이상의 배열을 결합할 수 있는 간단한 변형:

 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()]); }

Community Wiki

@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; }

Community Wiki

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[](심지어 0개의 배열도 포함)에 대해 작동합니다.


Community Wiki

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; }

Community Wiki

다음은 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; }

Community Wiki

질문에 대해 생각하는 또 다른 방법입니다. 두 개 이상의 배열을 연결하려면 각 배열의 모든 요소를 나열한 다음 새 배열을 작성해야 합니다. 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 를 사용하는 솔루션과 동일하다고 생각합니다. 하지만 이것도 나름의 아름다움이 있는 것 같아요.


Community Wiki

어때요:

 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()]); }

Community Wiki

출처 : http:www.stackoverflow.com/questions/80476/how-can-i-concatenate-two-arrays-in-java

반응형