java - मैं जावा में दो सरणी कैसे जोड़ सकता हूं?




arrays concatenation (20)

मुझे जावा में दो स्ट्रिंग एरे को जोड़ना होगा।

void f(String[] first, String[] second) {
    String[] both = ???
}

ऐसा करने का सबसे आसान तरीका क्या है?


Joachim सॉर के concatAll के मेरे थोड़ा बेहतर संस्करण यहाँ है। यह Java 6 की System.arraycopy का उपयोग कर जावा 5 या 6 पर काम कर सकता है अगर यह रनटाइम पर उपलब्ध है। यह विधि (आईएमएचओ) एंड्रॉइड के लिए बिल्कुल सही है, क्योंकि यह एंड्रॉइड <9 (जिसमें System.arraycopy नहीं है) पर काम करता है लेकिन यदि संभव हो तो तेज विधि का उपयोग करेगा।

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

आप इसे एक ऐरेलिस्ट में परिवर्तित करने का प्रयास कर सकते हैं और addAll विधि का उपयोग कर फिर किसी सरणी में कनवर्ट कर सकते हैं।

List list = new ArrayList(Arrays.asList(first));
  list.addAll(Arrays.asList(second));
  String[] both = list.toArray();

एक प्रकार का स्वतंत्र भिन्नता (अद्यतन - तत्काल टी के लिए वॉली के लिए धन्यवाद):

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

एक समाधान 100% पुराना जावा और बिना System.arraycopy (उदाहरण के लिए जीडब्ल्यूटी क्लाइंट में उपलब्ध नहीं है):

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

ऐसा करने के लिए एक आसान, लेकिन अक्षम, तरीका (जेनेरिक शामिल नहीं है):

ArrayList baseArray = new ArrayList(Arrays.asList(array1));
baseArray.addAll(Arrays.asList(array2));
String concatenated[] = (String []) baseArray.toArray(new String[baseArray.size()]);

कृपया मुझे पहले से ही लंबी सूची में एक और संस्करण जोड़ने के लिए क्षमा करें। मैंने हर जवाब को देखा और फैसला किया कि मैं वास्तव में हस्ताक्षर में केवल एक पैरामीटर वाला संस्करण चाहता हूं। मैंने अप्रत्याशित इनपुट के मामले में समझदार जानकारी के साथ प्रारंभिक विफलता से लाभ उठाने के लिए कुछ तर्क जांच भी शामिल की।

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

जावा 8 में एक लाइनर:

String[] both = Stream.concat(Arrays.stream(a), Arrays.stream(b))
                      .toArray(String[]::new);

या:

String[] both = Stream.of(a, b).flatMap(Stream::of)
                      .toArray(String[]::new);

प्रश्न के बारे में सोचने का एक और तरीका। दो या दो से अधिक सरणी को संयोजित करने के लिए, प्रत्येक को प्रत्येक सरणी के सभी तत्वों को सूचीबद्ध करना है, और फिर एक नई सरणी बनाना है। यह एक List<T> बनाने की तरह लगता है और फिर उस पर toArray को कॉल करता है। कुछ अन्य उत्तर ArrayList का उपयोग करते हैं, और यह ठीक है। लेकिन कैसे अपना खुद का कार्यान्वयन करने के बारे में? यह मुश्किल नहीं है:

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

मेरा मानना ​​है कि उपर्युक्त समाधानों के बराबर है जो System.arraycopy का उपयोग करता है। हालांकि मुझे लगता है कि इसकी अपनी सुंदरता है।


बस के बारे में कैसे

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 एक ही प्रकार के होते हैं, तो यह आपको एक ही प्रकार की एक और सरणी देगा जिसमें दोनों सरणी होंगी।


मैंने हाल ही में अत्यधिक स्मृति रोटेशन के साथ समस्याओं का सामना किया है। यदि ए और / या बी को सामान्य रूप से खाली माना जाता है, तो यहां सिल्वरब के कोड का एक और अनुकूलन है (जेनरेटेड भी):

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

(किसी भी मामले में, सरणी पुन: उपयोग व्यवहार स्पष्ट रूप से जावाडॉक्ड होगा!)


यदि आप इस तरह से उपयोग करते हैं तो आपको किसी भी तृतीय पक्ष वर्ग को आयात करने की आवश्यकता नहीं है।

यदि आप समेकित 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;
    }

यहां मुख्य विधि है

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

        }
    }  

हम इस तरह से भी उपयोग कर सकते हैं।


यह काम करता है, लेकिन आपको अपनी खुद की त्रुटि जांच डालने की आवश्यकता है।

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

यह शायद सबसे कुशल नहीं है, लेकिन यह जावा के अपने एपीआई के अलावा किसी अन्य चीज़ पर भरोसा नहीं करता है।


यह स्ट्रिंग सरणी के लिए एक परिवर्तित फ़ंक्शन है:

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

यहां एक सरल विधि है जो दो सरणी को जोड़ती है और परिणाम लौटाती है:

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

यहां जेनरिक रीट्रोफिट के साथ, सिल्वरब के समाधान का एक अनुकूलन है:

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

नोट: जावा 6 समाधान के लिए जोआचिम का जवाब देखें। न केवल चेतावनी को खत्म करता है; यह भी कम, अधिक कुशल और पढ़ने के लिए आसान है!


वाह! यहां कुछ जटिल उत्तर शामिल हैं जिनमें कुछ सरलताएं शामिल हैं जो बाहरी निर्भरताओं पर निर्भर करती हैं। इस तरह ऐसा करने के बारे में:

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

स्ट्रीम का उपयोग कर जावा 8 के साथ एक और तरीका

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

ArrayList<String> both = new ArrayList(Arrays.asList(first));
both.addAll(Arrays.asList(second));

both.toArray(new String[0]);

String [] both = new ArrayList<String>(){{addAll(Arrays.asList(first)); addAll(Arrays.asList(second));}}.toArray(new String[0]);





add