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

StringJava에서 두 개의 배열 을 연결해야합니다 .

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


답변

StreamJava 8에서 사용 :

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


답변

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

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

이 방법은 빠르고 효율적인 솔루션이며 기본 유형과 관련된 두 가지 방법이 모두 오버로드 될 수 있습니다.

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

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