Это не отвечает на ваш вопрос напрямую, но я хотел бросить пару вещей:
Обычно я считаю контрпродуктивным отдельный сгенерированный код. Мне всегда нравится, как правило, следовать правилу «один класс за файл», но здесь я делаю исключение, потому что часто имею дело с очень большими схемами. Даже в своем собственном каталоге, я не хочу, чтобы разделить десятки (до сотен) файлов, когда я создаю новую версию кода. Мне очень удобно иметь весь сгенерированный код, который может быть размытым в одном файле.
Теперь, чтобы предложить возможное решение - Resharper имеет возможность вытащить все классы из файл и поместить их в свои собственные файлы. Если вы щелкните правой кнопкой мыши файл в проводнике решений, вы можете сказать Refactor → Переместить типы в соответствующие файлы ... . Конечно, это не так удобно, как просто генерировать его таким образом, но я не знаю инструмента, который это сделает.
Я нашел однострочное решение из старой доброй библиотеки Apache Commons Lang.
ArrayUtils.addAll(T[], T...)
Код:
String[] both = ArrayUtils.addAll(first, second);
Если вы хотите работать с 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()]);
}
Еще один, основанный на предложении 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;
}
Вы можете попробовать этот метод, который объединяет несколько массивов:
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;
}
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;
}
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 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 можете набрать свой массив !!!
String [] both = new ArrayList<String>(){{addAll(Arrays.asList(first)); addAll(Arrays.asList(second));}}.toArray(new String[0]);
Если вы используете этот способ, вам не нужно импортировать какие-либо сторонние классы.
Если вы хотите объединить 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));
}
}
Мы также можем использовать этот способ.
Или с любимой гуавой :
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);
Это быстрое и эффективное решение, которое будет работать для примитивных типов, так как оба метода перегружены.
Вам следует избегать решений, включающих ArrayLists, потоки и т. Д., Так как они должны будут выделять временную память без какой-либо полезной цели.
Вы должны избегать циклов for
для больших массивов, так как они неэффективны. Встроенные методы используют функции блочного копирования, которые чрезвычайно быстры.
В 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));
}
Я недавно боролся с проблемами с чрезмерным вращением памяти. Если известно, что a и / или 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;
}
Редактирование: в предыдущей версии этого поста говорилось, что повторное использование массива выглядит следующим образом должны быть четко документированы. Как указывает Мартен в комментариях, в целом было бы лучше просто удалить операторы if, что исключает необходимость иметь документацию. Но опять же, эти операторы if были главной целью этой конкретной оптимизации. Я оставлю этот ответ здесь, но будьте осторожны!
Библиотека 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]);
Вот адаптация решения 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. Это не только устраняет предупреждение; это также короче, более эффективно и легче читать!
Пожалуйста, прости меня за добавление еще одной версии в этот и без того длинный список. Я посмотрел на каждый ответ и решил, что мне действительно нужна версия с одним параметром в подписи. Я также добавил некоторую проверку аргументов, чтобы извлечь выгоду из раннего сбоя с разумной информацией в случае неожиданного ввода.
@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;
}
Вот простой метод, который объединит два массива и вернет результат:
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 }));
Я протестировал приведенный ниже код и работал нормально
Также я использую библиотеку: 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]);
}
}
}
С уважением
Используя API Java:
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()]);
}
Здесь возможна реализация в рабочем коде решения псевдокода, написанного silvertab.
Спасибо 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]);
Должен сделать свое дело. Предполагается, что String [] first и String [] second
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()]);
Я обнаружил, что имел дело со случаем, когда массивы могут быть нулевыми ...
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;
}
Вы можете использовать коллекцию ArrayList для этого. его реализация очень проста для понимания, сначала вы должны хранить оба массива String, которые представлены в аргументах в ArrayList, а после этого просто конвертировать этот ArrayList в массив String с помощью метода toArray (), вот реализация:
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());
}
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;
}
Это, вероятно, единственный общий и безопасный для типов способ:
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 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
относятся к одному типу, это даст вам другой массив того же типа, содержащий оба массива.