Мне нужно объединить два String
массива в Java.
void f(String[] first, String[] second) {
String[] both = ???
}
Какой самый простой способ сделать это?
java
arrays
concatenation
add
Antti Kissaniemi
источник
источник
array1 + array2
конкатенации.Ответы:
Я нашел однострочное решение из старой доброй библиотеки Apache Commons Lang.
ArrayUtils.addAll(T[], T...)
Код:
источник
Вот простой метод, который объединит два массива и вернет результат:
Обратите внимание, что он не будет работать с примитивными типами данных, только с типами объектов.
Следующая немного более сложная версия работает как с объектными, так и с примитивными массивами. Это делается с использованием
T
вместо типаT[]
аргумента.Это также позволяет объединять массивы двух разных типов, выбирая наиболее общий тип в качестве типа компонента результата.
Вот пример:
источник
Array.newInstance(a.getClass().getComponentType(), aLen + bLen);
. Я удивительно никогда не видел этого раньше. @beaudet Я думаю, что аннотация здесь хорошо, учитывая, почему она подавляется.Можно написать полностью универсальную версию, которая может быть расширена для объединения любого числа массивов. Эти версии требуют Java 6, так как они используют
Arrays.copyOf()
Обе версии избегают создания каких-либо промежуточных
List
объектов и используютSystem.arraycopy()
для обеспечения максимально быстрого копирования больших массивов.Для двух массивов это выглядит так:
А для произвольного числа массивов (> = 1) это выглядит так:
источник
T
наbyte
(и потеряйте<T>
).ByteBuffer buffer = ByteBuffer.allocate(array1.length + array2.length); buffer.put(array1); buffer.put(array2); return buffer.array();
concat(ai, ad)
, гдеai
естьInteger[]
иad
естьDouble[]
. (В этом случае параметр типа<T>
разрешается<? extends Number>
компилятором.) Созданный массивArrays.copyOf
будет иметь тип компонента первого массива, т.е.Integer
в этом примере. Когда функция собирается скопировать второй массив,ArrayStoreException
будет сгенерировано. Решение состоит в том, чтобы иметь дополнительныйClass<T> type
параметр.Использование
Stream
в Java 8:Или вот так, используя
flatMap
:Чтобы сделать это для универсального типа, вы должны использовать отражение:
источник
.boxed()
такими, чтобы они имели тип,Stream
а не, например,IntStream
которые нельзя было бы передать в качестве параметраStream.concat
.a
иb
естьint[]
, используйтеint[] both = IntStream.concat(Arrays.stream(a), Arrays.stream(b)).toArray();
System.arrayCopy
. Но не особенно медленно. Возможно, вам придется делать это очень много раз с огромными массивами в действительно чувствительных к производительности контекстах, чтобы разница во времени выполнения имела значение.Или с любимой гуавы :
Также есть версии для примитивных массивов:
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)
источник
Вы можете добавить два массива в две строки кода.
Это быстрое и эффективное решение, которое будет работать для примитивных типов, так как оба метода перегружены.
Вам следует избегать решений, включающих ArrayLists, потоки и т. Д., Так как они должны будут выделять временную память без какой-либо полезной цели.
Вы должны избегать
for
циклов для больших массивов, так как они не эффективны. Встроенные методы используют функции блочного копирования, которые чрезвычайно быстры.источник
Использование Java API:
источник
both.toArray(new String[0])
будет быстрееboth.toArray(new String[both.size()])
, даже если это противоречит нашей наивной интуиции. Вот почему так важно измерять реальную производительность при оптимизации. Или просто используйте более простую конструкцию, когда преимущество более сложного варианта не может быть доказано.Решение 100% старого Java и без
System.arraycopy
(недоступно, например, в клиенте GWT):источник
null
чеки. И, возможно, установите некоторые из ваших переменных вfinal
.null
Проверки @TrippKinetics будут скрывать NPE, а не показывать их, и использование final для локальных переменных не имеет никакой пользы (пока).Я недавно боролся с проблемами с чрезмерным вращением памяти. Если известно, что a и / или b обычно пусты, вот еще одна адаптация кода silvertab (также обобщенная):
Редактировать: Предыдущая версия этого поста утверждала, что повторное использование массива должно быть четко задокументировано. Как указывает Мартен в комментариях, в целом было бы лучше просто удалить операторы if, что исключает необходимость иметь документацию. Но опять же, эти операторы if были главной целью этой конкретной оптимизации. Я оставлю этот ответ здесь, но будьте осторожны!
источник
System.arraycopy
копирует содержимое массива?if
исключение двух утверждений было бы самым простым решением.Функциональная Java библиотека имеет класс - оболочки массива, экипирование массивов с удобными методами , как конкатенация.
...а потом
Чтобы вернуть развернутый массив, вызовите
источник
источник
both.toArray(new String[both.size()])
)Еще один способ с Java8 с использованием Stream
источник
Вот адаптация решения silvertab с модифицированными дженериками:
ПРИМЕЧАНИЕ. См . Ответ Joachim для решения Java 6. Это не только устраняет предупреждение; это также короче, более эффективно и легче читать!
источник
Если вы используете этот способ, вам не нужно импортировать какие-либо сторонние классы.
Если вы хотите объединить
String
Пример кода для конкатенации двух String Array
Если вы хотите объединить
Int
Пример кода для конкатенации двух целочисленных массивов
Вот основной метод
Мы можем использовать этот способ также.
источник
Пожалуйста, прости меня за добавление еще одной версии в этот уже длинный список. Я посмотрел на каждый ответ и решил, что мне действительно нужна версия с одним параметром в подписи. Я также добавил некоторую проверку аргументов, чтобы извлечь выгоду из раннего сбоя с разумной информацией в случае неожиданного ввода.
источник
Вы можете попробовать преобразовать его в Arraylist и использовать метод addAll, а затем преобразовать обратно в массив.
источник
Используя потоки Java 8+, вы можете написать следующую функцию:
источник
Здесь возможна реализация в рабочем коде решения псевдокода, написанного silvertab.
Спасибо silvertab!
Далее следует интерфейс строителя.
Примечание: сборщик необходим, потому что в Java это невозможно сделать
new T[size]
из-за стирания универсального типа:
Вот конкретный конструктор, реализующий интерфейс, строящий
Integer
массив:И, наконец, приложение / тест:
источник
Это должно быть однострочно.
источник
Вот Это Да! Здесь много сложных ответов, в том числе простых, которые зависят от внешних зависимостей. как насчет этого:
источник
Это работает, но вам нужно вставить свою собственную проверку ошибок.
Это, вероятно, не самый эффективный, но он не зависит ни от чего, кроме собственного API Java.
источник
for
цикл на это:for(int j = 0; j < arr2.length; j++){arrBoth[arr1.length+j] = arr2[j];}
String[] arrBoth = java.util.Arrays.copyOf(arr1, arr1.length + arr2.length)
чтобы пропустить первыйfor
цикл. Экономит время, пропорциональное размеруarr1
.Это преобразованная функция для массива String:
источник
Как насчет просто
И просто делай
Array.concat(arr1, arr2)
. Покаarr1
иarr2
одного типа, это даст вам другой массив того же типа, содержащий оба массива.источник
Универсальная статическая версия, которая использует высокопроизводительную System.arraycopy, не требуя аннотации @SuppressWarnings:
источник
источник
Вот моя слегка улучшенная версия concatAll Йоахима Зауэра. Он может работать на Java 5 или 6, используя Java 6 System.arraycopy, если он доступен во время выполнения. Этот метод (IMHO) идеально подходит для Android, так как он работает на Android <9 (у которого нет System.arraycopy), но будет по возможности использовать более быстрый метод.
источник
Еще один способ задуматься над вопросом. Чтобы объединить два или более массивов, нужно составить список всех элементов каждого массива и затем создать новый массив. Это звучит как создать,
List<T>
а затем призываетtoArray
его. Некоторые другие ответы используетArrayList
, и это нормально. Но как насчет реализации нашего? Это не сложноЯ считаю, что вышеупомянутое эквивалентно решениям, которые используют
System.arraycopy
. Однако я думаю, что у этого есть своя собственная красота.источник
Как насчет :
источник
Простой вариант, позволяющий объединять более одного массива:
источник
Используя только собственный API Javas:
Теперь этот код не самый эффективный, но он опирается только на стандартные классы Java и прост для понимания. Это работает для любого числа String [] (даже нулевых массивов).
источник