Je dois concaténer deux tableaux String
en Java.
void f(String[] first, String[] second) {
String[] both = ???
}
Quelle est la manière la plus simple de faire ça?
J'ai trouvé une solution d'une ligne dans la bonne vieille bibliothèque Apache Commons Lang.
ArrayUtils.addAll(T[], T...)
Code:
String[] both = (String[])ArrayUtils.addAll(first, second);
Voici une méthode simple qui concaténera deux tableaux et retournera le résultat:
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;
}
Notez que cela ne fonctionnera pas avec les types de données primitifs, mais uniquement avec les types d'objet.
La version légèrement plus compliquée suivante fonctionne avec les tableaux d’objets et primitifs. Pour cela, il utilise T
au lieu de T[]
en tant que type d'argument.
Il permet également de concaténer des tableaux de deux types différents en choisissant le type le plus général en tant que type de composant du résultat.
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;
}
Voici un exemple:
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 }));
Il est possible d'écrire une version entièrement générique pouvant même être étendue pour concaténer un nombre illimité de tableaux. Cette version nécessite Java 6, car elle utilise Arrays.copyOf()
Les deux versions évitent de créer des objets List
intermédiaires et utilisent System.arraycopy()
pour garantir une copie aussi rapide que possible des tableaux de grande taille.
Pour deux tableaux, cela ressemble à ceci:
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;
}
Et pour un nombre arbitraire de tableaux (> = 1), cela ressemble à ceci:
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;
}
One-Liner en Java 8:
String[] both = Stream.concat(Arrays.stream(a), Arrays.stream(b))
.toArray(String[]::new);
Ou:
String[] both = Stream.of(a, b).flatMap(Stream::of)
.toArray(String[]::new);
Ou avec le bien-aimé goyave :
String[] both = ObjectArrays.concat(first, second, String.class);
En outre, il existe des versions pour les tableaux primitifs:
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)
Utilisation de l'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()]);
}
Une solution 100% ancien Java et sans System.arraycopy
(non disponible dans le client GWT par exemple):
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;
}
Vous pouvez ajouter les deux tableaux en deux lignes de code.
String[] both = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, both, first.length, second.length);
Ceci est une solution rapide et efficace et fonctionnera pour les types primitifs ainsi que les deux méthodes impliquées sont surchargées.
Vous devriez éviter les solutions impliquant ArrayLists, les flux, etc.
Vous devez éviter les boucles for
pour les tableaux de grande taille car elles ne sont pas efficaces. Les méthodes intégrées utilisent des fonctions de copie de bloc extrêmement rapides.
J'ai récemment combattu les problèmes de rotation excessive de la mémoire. Si on sait que a et/ou b sont généralement vides, voici une autre adaptation du code de silvertab (aussi générifié):
private static <T> T[] concat(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;
}
(Dans les deux cas, le comportement de réutilisation de tableau doit être clairement JavaDoced!)
La bibliothèque fonctionnelle Java possède une classe wrapper qui donne aux tableaux des méthodes pratiques comme la concaténation.
import static fj.data.Array.array;
...et alors
Array<String> both = array(first).append(array(second));
Pour récupérer le tableau non emballé, appelez
String[] s = both.array();
ArrayList<String> both = new ArrayList(Arrays.asList(first));
both.addAll(Arrays.asList(second));
both.toArray(new String[0]);
Une autre façon avec Java8 en utilisant Stream
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);
}
Voici une adaptation de la solution de silvertab, avec la modification ultérieure des génériques:
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;
}
REMARQUE: Voir Réponse de Joachim pour une solution Java 6. Non seulement cela élimine l'avertissement; c'est aussi plus court, plus efficace et plus facile à lire!
Si vous utilisez cette méthode, vous n'avez pas besoin d'importer de classe tierce.
Si vous voulez concaténer String
Exemple de code pour concate deux String Array
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;
}
Si vous voulez concaténer Int
Exemple de code pour concate deux Integer Array
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;
}
Voici la méthode principale
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));
}
}
Nous pouvons utiliser cette façon aussi.
Veuillez me pardonner d’avoir ajouté une autre version à cette liste déjà longue. J'ai examiné chaque réponse et décidé que je voulais vraiment une version avec un seul paramètre dans la signature. J'ai également ajouté des vérifications d'arguments afin de tirer profit d'un échec précoce avec des informations sensibles en cas de saisie inattendue.
@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;
}
Vous pouvez essayer de le convertir en tableau et d’utiliser la méthode addAll, puis de le reconvertir en tableau.
List list = new ArrayList(Arrays.asList(first));
list.addAll(Arrays.asList(second));
String[] both = list.toArray();
Voici une implémentation possible dans le code de travail de la solution de pseudo-code écrite par silvertab.
Merci 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;
}
}
Ensuite, l'interface du générateur.
Note: Un constructeur est nécessaire car en Java il n’est pas possible de faire
new T[size]
en raison de l'effacement de type générique:
public interface ArrayBuilderI<T> {
public T[] build(int size);
}
Voici un constructeur concret implémentant l'interface, construisant un tableau Integer
:
public class IntegerArrayBuilder implements ArrayBuilderI<Integer> {
@Override
public Integer[] build(int size) {
return new Integer[size];
}
}
Et enfin l'application/test:
@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]);
}
}
Hou la la! Beaucoup de réponses complexes ici, y compris quelques simples qui dépendent de dépendances externes. que diriez-vous de le faire comme ça:
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]);
Cela fonctionne, mais vous devez insérer votre propre vérification d'erreur.
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();
}
}
Ce n'est probablement pas le plus efficace, mais il ne repose que sur la propre API de Java.
Ceci est une fonction convertie pour un tableau 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;
}
Que diriez-vous simplement
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());
}
}
Et juste faire Array.concat(arr1, arr2)
. Tant que arr1
et arr2
sont du même type, cela vous donnera un autre tableau du même type contenant les deux tableaux.
Une variante simple permettant de joindre plusieurs tableaux:
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()]);
}
Voici ma version légèrement améliorée de concatAll de Joachim Sauer. Il peut fonctionner sur Java 5 ou 6, en utilisant System.arraycopy de Java 6 s'il est disponible au moment de l'exécution. Cette méthode (IMHO) est parfaite pour Android, car elle fonctionne sous Android <9 (qui n’a pas System.arraycopy) mais utilisera la méthode plus rapide si possible.
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;
}
Cela devrait être one-liner.
public String [] concatenate (final String array1[], final String array2[])
{
return Stream.concat(Stream.of(array1), Stream.of(array2)).toArray(String[]::new);
}
Une autre façon de réfléchir à la question. Pour concaténer deux tableaux ou plus, il suffit de répertorier tous les éléments de chaque tableau, puis de créer un nouveau tableau. Cela ressemble à créer un List<T>
et ensuite appeler toArray
dessus. Certaines autres réponses utilisent ArrayList
, et c'est bien. Mais que diriez-vous de mettre en œuvre notre propre? Ce n'est pas difficile:
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);
}
Je pense que ce qui précède est équivalent aux solutions qui utilisent System.arraycopy
. Cependant, je pense que celui-ci a sa propre beauté.
Que diriez-vous :
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()]);
}
Une façon simple mais peu efficace de procéder (génériques non inclus):
ArrayList baseArray = new ArrayList(Arrays.asList(array1));
baseArray.addAll(Arrays.asList(array2));
String concatenated[] = (String []) baseArray.toArray(new String[baseArray.size()]);
En utilisant uniquement la propre API de Javas:
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]);
}
Ce code n’est pas le plus efficace, il repose uniquement sur les classes Java standard et est facile à comprendre. Cela fonctionne pour n'importe quel nombre de String [] (même des tableaux de zéro).
En utilisant les flux Java 8+, vous pouvez écrire la fonction suivante:
private static String[] concatArrays(final String[]... arrays) {
return Arrays.stream(arrays)
.flatMap(Arrays::stream)
.toArray(String[]::new);
}
Une variante indépendante du type (MISE À JOUR - grâce à Volley pour l’instanciation de T):
@SuppressWarnings("unchecked")
public static <T> T[] join(T[]...arrays) {
final List<T> output = new ArrayList<T>();
for(T[] array : arrays) {
output.addAll(Arrays.asList(array));
}
return output.toArray((T[])Array.newInstance(
arrays[0].getClass().getComponentType(), output.size()));
}
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;
}
String [] both = new ArrayList<String>(){{addAll(Arrays.asList(first)); addAll(Arrays.asList(second));}}.toArray(new String[0]);
Chaque réponse consiste à copier des données et à créer un nouveau tableau. Ce n'est pas strictement nécessaire et ce n'est certainement pas ce que vous voulez faire si vos baies sont raisonnablement grandes. Les créateurs de Java savaient déjà que les copies de tableau étaient une perte de temps. C'est pourquoi ils nous ont fourni System.arrayCopy () pour effectuer les tâches en dehors de Java lorsque cela est nécessaire.
Au lieu de copier vos données, envisagez de les laisser en place et d’en tirer où elles se trouvent. Copier des emplacements de données simplement parce que le programmeur souhaite les organiser n'est pas toujours judicieux.
// I have arrayA and arrayB; would like to treat them as concatenated
// but leave my damn bytes where they are!
Object accessElement ( int index ) {
if ( index < 0 ) throw new ArrayIndexOutOfBoundsException(...);
// is reading from the head part?
if ( index < arrayA.length )
return arrayA[ index ];
// is reading from the tail part?
if ( index < ( arrayA.length + arrayB.length ) )
return arrayB[ index - arrayA.length ];
throw new ArrayIndexOutOfBoundsException(...); // index too large
}
Si vous souhaitez utiliser ArrayLists dans la solution, vous pouvez essayer ceci:
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()]);
}
J'ai trouvé que je devais traiter avec le cas où les tableaux peuvent être nuls ...
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;
}
Import Java.util.*;
String array1[] = {"bla","bla"};
String array2[] = {"bla","bla"};
ArrayList<String> tempArray = new ArrayList<String>(Arrays.asList(array1));
tempArray.addAll(Arrays.asList(array2));
String array3[] = films.toArray(new String[1]); // size will be overwritten if needed
Vous pouvez remplacer String par un Type/Class de votre choix
Je suis sûr que cela peut être raccourci et amélioré, mais cela fonctionne et je suis trop paresseux pour le régler plus loin ...
Une version statique générique qui utilise la très performante System.arraycopy sans nécessiter d'annotation @SuppressWarnings:
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;
}
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 int[] mergeArrays(int [] a, int [] b) {
int [] merged = new int[a.length + b.length];
int i = 0, k = 0, l = a.length;
int j = a.length > b.length ? a.length : b.length;
while(i < j) {
if(k < a.length) {
merged[k] = a[k];
k++;
}
if((l - a.length) < b.length) {
merged[l] = b[l - a.length];
l++;
}
i++;
}
return merged;
}
Je pense que la meilleure solution avec les génériques serait:
/* This for non primitive types */
public static <T> T[] concatenate (T[]... elements) {
T[] C = null;
for (T[] element: elements) {
if (element==null) continue;
if (C==null) C = (T[]) Array.newInstance(element.getClass().getComponentType(), element.length);
else C = resizeArray(C, C.length+element.length);
System.arraycopy(element, 0, C, C.length-element.length, element.length);
}
return C;
}
/**
* as far as i know, primitive types do not accept generics
* http://stackoverflow.com/questions/2721546/why-dont-Java-generics-support-primitive-types
* for primitive types we could do something like this:
* */
public static int[] concatenate (int[]... elements){
int[] C = null;
for (int[] element: elements) {
if (element==null) continue;
if (C==null) C = new int[element.length];
else C = resizeArray(C, C.length+element.length);
System.arraycopy(element, 0, C, C.length-element.length, element.length);
}
return C;
}
private static <T> T resizeArray (T array, int newSize) {
int oldSize =
Java.lang.reflect.Array.getLength(array);
Class elementType =
array.getClass().getComponentType();
Object newArray =
Java.lang.reflect.Array.newInstance(
elementType, newSize);
int preserveLength = Math.min(oldSize, newSize);
if (preserveLength > 0)
System.arraycopy(array, 0,
newArray, 0, preserveLength);
return (T) newArray;
}
Vous pouvez essayer cette méthode qui concatène plusieurs tableaux:
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;
}
Vous pouvez essayer ceci
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 peut taper cast votre tableau !!!
Voici le code par AbacusUtil .
String[] a = {"a", "b", "c"};
String[] b = {"1", "2", "3"};
String[] c = N.concat(a, b); // c = ["a", "b", "c", "1", "2", "3"]
// N.concat(...) is null-safety.
a = null;
c = N.concat(a, b); // c = ["1", "2", "3"]
En 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));
}
Le moyen le plus simple que je puisse trouver est le suivant:
List allFiltersList = Arrays.asList(regularFilters);
allFiltersList.addAll(Arrays.asList(preFiltersArray));
Filter[] mergedFilterArray = (Filter[]) allFiltersList.toArray();
Object[] obj = {"hi","there"};
Object[] obj2 ={"im","fine","what abt u"};
Object[] obj3 = new Object[obj.length+obj2.length];
for(int i =0;i<obj3.length;i++)
obj3[i] = (i<obj.length)?obj[i]:obj2[i-obj.length];
Un autre basé sur la suggestion de SilverTab, mais conçu pour supporter un nombre x d’arguments et ne nécessite pas Java 6. Il n’est pas non plus générique, mais je suis sûr qu’il pourrait être générique.
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;
}
Vous pouvez utiliser la collection ArrayList pour cela. son implémentation est très facile à comprendre. Vous devez d’abord stocker les tableaux de chaînes String fournis dans les arguments de ArrayList, puis convertir ce tableau en tableau String avec la méthode 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());
}
En Haskell, vous pouvez faire quelque chose comme [a, b, c] ++ [d, e]
pour obtenir [a, b, c, d, e]
. Ce sont des listes Haskell concaténées mais ça aurait été très agréable de voir un opérateur similaire en Java pour les tableaux. Tu ne crois pas? C'est élégant, simple, générique et ce n'est pas si difficile à mettre en œuvre.
Si vous le souhaitez, je vous suggère de jeter un coup d'œil au travail d'Alexander Hristov dans son Piratage du compilateur OpenJDK . Il explique comment modifier le code source javac pour créer un nouvel opérateur. Son exemple consiste à définir un opérateur '**' où i ** j = Math.pow(i, j)
. On pourrait prendre cet exemple pour implémenter un opérateur qui concatène deux tableaux du même type.
Une fois que vous avez fait cela, vous êtes lié à votre javac personnalisé pour compiler votre code, mais le pseudo-code généré sera compris par toute machine virtuelle Java.
Bien sûr, vous pouvez implémenter votre propre méthode de concaténation de tableaux à votre niveau source, il existe de nombreux exemples sur la façon de le faire dans les autres réponses!
Il y a tellement d'opérateurs utiles qui pourraient être ajoutés, celui-ci en serait un.
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];
}
Celui-ci fonctionne sans connaissance d'autres classes/bibliothèques, etc. Il fonctionne pour tout type de données. Il suffit de remplacer String
par un élément comme int
, double
ou char
. Cela fonctionne assez efficacement.
Solution non 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;
}
C'est probablement le seul moyen générique et sûr pour le type:
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;
}
}
Et l'usage est assez concis:
Integer[] array1 = { 1, 2, 3 };
Double[] array2 = { 4.0, 5.0, 6.0 };
Number[] array = concat(Number[]::new).apply(array1, array2);
(nécessite une importation statique)
Les types de tableau non valides sont rejetés:
concat(String[]::new).apply(array1, array2); // error
concat(Integer[]::new).apply(array1, array2); // error
Celui-ci ne fonctionne qu'avec int mais l'idée est générique
public static int[] junta(int[] v, int[] w) {
int[] junta = new int[v.length + w.length];
for (int i = 0; i < v.length; i++) {
junta[i] = v[i];
}
for (int j = v.length; j < junta.length; j++) {
junta[j] = w[j - v.length];
}
Regardez cette solution élégante (si vous avez besoin d'un autre type que char, changez-le):
private static void concatArrays(char[] destination, char[]... sources) {
int currPos = 0;
for (char[] source : sources) {
int length = source.length;
System.arraycopy(source, 0, destination, currPos, length);
currPos += length;
}
}
Vous pouvez concaténer chaque nombre de tableaux.
C'est probablement le seul moyen générique et sûr pour le type:
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;
}
}
Et l'usage est assez concis:
Integer[] array1 = { 1, 2, 3 };
Double[] array2 = { 4.0, 5.0, 6.0 };
Number[] array = concat(Number[]::new).apply(array1, array2);
(nécessite une importation statique)
Les types de tableau non valides sont rejetés:
concat(String[]::new).apply(array1, array2); // error
concat(Integer[]::new).apply(array1, array2); // error
Encore une autre réponse pour les amateurs d’algorithmes:
public static String[] mergeArrays(String[] array1, String[] array2) {
int totalSize = array1.length + array2.length; // Get total size
String[] merged = new String[totalSize]; // Create new array
// Loop over the total size
for (int i = 0; i < totalSize; i++) {
if (i < array1.length) // If the current position is less than the length of the first array, take value from first array
merged[i] = array1[i]; // Position in first array is the current position
else // If current position is equal or greater than the first array, take value from second array.
merged[i] = array2[i - array1.length]; // Position in second array is current position minus length of first array.
}
return merged;
Usage:
String[] array1str = new String[]{"a", "b", "c", "d"};
String[] array2str = new String[]{"e", "f", "g", "h", "i"};
String[] listTotalstr = mergeArrays(array1str, array2str);
System.out.println(Arrays.toString(listTotalstr));
Résultat:
[a, b, c, d, e, f, g, h, i]
Devrait faire l'affaire. Ceci suppose que String [] en premier et String [] en 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()]);
J'ai testé ci-dessous le code et a bien fonctionné
J'utilise aussi la bibliothèque: 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]);
}
}
}
Cordialement