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




arrays concatenation add (25)

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

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

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


Answers

मुझे अच्छे पुराने अपाचे कॉमन्स लैंग लाइब्रेरी से एक-लाइन समाधान मिला।
ArrayUtils.addAll(T[], T...)

कोड:

String[] both = (String[])ArrayUtils.addAll(first, second);

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

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


एक समाधान 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;
}

जावा 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);

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

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

एक पूर्ण जेनेरिक संस्करण लिखना संभव है जिसे किसी भी प्रकार के सरणी को संयोजित करने के लिए भी बढ़ाया जा सकता है। इस संस्करण को जावा 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;
}

स्ट्रीम का उपयोग कर जावा 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); 
  }

यदि आप समाधान में 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[] 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()]);
}

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

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

कार्यात्मक जावा लाइब्रेरी में एक सरणी रैपर वर्ग है जो संयोजक जैसे आसान तरीकों के साथ सरणी को लैस करता है।

import static fj.data.Array.array;

...और फिर

Array<String> both = array(first).append(array(second));

अनचाहे सरणी को वापस पाने के लिए, कॉल करें

String[] s = both.array();

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

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

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

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

both.toArray(new String[0]);

केवल जावा स्वयं का एपीआई का उपयोग करना:


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

अब, यह कोड सबसे कुशल नहीं है, लेकिन यह केवल मानक जावा वर्गों पर निर्भर करता है और समझने में आसान है। यह स्ट्रिंग [] (यहां तक ​​कि शून्य सरणी) की किसी भी संख्या के लिए काम करता है।


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

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

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

        }
    }  

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


यहां 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;
   }
}

अगले के बाद निर्माता इंटरफ़ेस है।

नोट: एक निर्माता आवश्यक है क्योंकि जावा में ऐसा करना संभव नहीं है

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

प्रश्न के बारे में सोचने का एक और तरीका। दो या दो से अधिक सरणी को संयोजित करने के लिए, प्रत्येक को प्रत्येक सरणी के सभी तत्वों को सूचीबद्ध करना है, और फिर एक नई सरणी बनाना है। यह एक 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 <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 }));

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

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

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


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

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

मैंने एक्सेलिप बनाम नेटबीन्स 8.0.2 पर परीक्षण किया, दोनों जावा संस्करण 1.8 के साथ; मैंने माप के लिए System.nanoTime() उपयोग किया।

ग्रहण:

मुझे दोनों मामलों में एक ही समय मिला - लगभग 1.564 सेकंड

NetBeans:

  • "#" का प्रयोग करना: 1.536 सेकेंड
  • "बी" का प्रयोग: 44.164 सेकेंड

तो, ऐसा लगता है कि नेटबीन के प्रिंट पर कंसोल पर खराब प्रदर्शन है।

अधिक शोध के बाद मुझे एहसास हुआ कि समस्या Netbeans के अधिकतम बफर की line-wrapping है (यह System.out.println कमांड तक सीमित नहीं है), इस कोड द्वारा प्रदर्शित:

for (int i = 0; i < 1000; i++) {
    long t1 = System.nanoTime();
    System.out.print("BBB......BBB"); \\<-contain 1000 "B"
    long t2 = System.nanoTime();
    System.out.println(t2-t1);
    System.out.println("");
}

समय के परिणाम हर पांचवें पुनरावृत्ति को छोड़कर प्रत्येक पुनरावृत्ति के बाद 1 मिलीसेकंड कम होते हैं, जब समय का परिणाम लगभग 225 मिलीसेकंड होता है। कुछ ऐसा (नैनोसेकंड में):

BBB...31744
BBB...31744
BBB...31744
BBB...31744
BBB...226365807
BBB...31744
BBB...31744
BBB...31744
BBB...31744
BBB...226365807
.
.
.

और इसी तरह..

सारांश:

  1. ग्रहण पूरी तरह से "बी" के साथ काम करता है
  2. नेटबीन्स में एक लाइन-रैपिंग समस्या होती है जिसे हल किया जा सकता है (क्योंकि समस्या ग्रहण में नहीं होती है) (बी ("बी") के बाद जगह जोड़ने के बिना)।




java arrays concatenation add