String
Java에서 두 개의 배열 을 연결해야합니다 .
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;
}
답변
Stream
Java 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()]);
}