मैं जावा में दो सरणियों को कैसे व्यवस्थित कर सकता हूं?


1366

मुझे Stringजावा में दो सरणियों को संक्षिप्त करने की आवश्यकता है ।

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

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


3
गुवा से बाइट्स.कॉन्कट
बेन पेज

1
मैं यहाँ बहुत सारी प्रतिक्रियाएँ देख रहा हूँ लेकिन यह प्रश्न इतना शब्दबद्ध है ('सबसे आसान तरीका'?) कि यह सर्वोत्तम उत्तर को इंगित करने की अनुमति नहीं देता है ...
आर्टुर ओपलिंस्की

2
दर्जनों उत्तर यहां डेटा को एक नए एरे में कॉपी कर रहे हैं क्योंकि उससे जो पूछा गया था - लेकिन जब सख्ती से जरूरी नहीं हो तो डेटा की नकल करना विशेष रूप से जावा में एक बुरी बात है। इसके बजाय, अनुक्रमणिकाओं का ट्रैक रखें और दो सरणियों का उपयोग करें जैसे कि वे शामिल हो गए थे। मैंने तकनीक को दर्शाते हुए एक समाधान जोड़ा है।
डगलस हेल्ड

12
तथ्य यह है कि इस तरह के एक प्रश्न के वर्तमान में 50 अलग-अलग उत्तर हैं, मुझे आश्चर्य होता है कि जावा को कभी भी एक सरल array1 + array2निष्कर्ष क्यों नहीं मिला ।
जॉली जोकर

2
आप इसे मानक जावा की दो पंक्तियों में पूरी तरह से अच्छी तरह से और बहुत कुशलता से कर सकते हैं (मेरा उत्तर देखें), इसलिए इसे करने के लिए एक एकल विधि होने से प्राप्त करने के लिए एक बहुत कुछ नहीं है। इन सभी अजीब-अद्भुत समाधान समय की बर्बादी का एक सा है।
रगोम

जवाबों:


1093

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

कोड:

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

175
यदि यह प्रश्न का उत्तर देता है तो यह "धोखा" कैसे है? निश्चित रूप से, इस विशिष्ट स्थिति के लिए एक अतिरिक्त निर्भरता होना संभव है, लेकिन यह पुकारने में कोई बुराई नहीं है कि यह मौजूद है, खासकर क्योंकि अपाचे कॉमन्स में कार्यक्षमता के इतने उत्कृष्ट बिट्स हैं।
रॉब

33
मैं सहमत हूं, यह वास्तव में सवाल का जवाब नहीं दे रहा है। उच्च स्तर के पुस्तकालय महान हो सकते हैं, लेकिन यदि आप इसे करने के लिए एक कुशल तरीका सीखना चाहते हैं, तो आप उस कोड को देखना चाहते हैं जिसे लाइब्रेरी विधि उपयोग कर रही है। इसके अलावा, कई स्थितियों में, आप मक्खी पर उत्पाद में किसी अन्य पुस्तकालय के माध्यम से नहीं कर सकते।
एडम

76
मुझे लगता है कि यह एक अच्छा जवाब है। पीओजेओ समाधान भी प्रदान किए गए हैं, लेकिन अगर ओपी अपने कार्यक्रम में पहले से ही अपाचे कॉमन्स का उपयोग कर रहा है (पूरी तरह से इसकी लोकप्रियता को देखते हुए) वह अभी भी इस समाधान को नहीं जान सकता है। तब वह "इस एक विधि के लिए एक निर्भरता को जोड़ने" नहीं होगा, लेकिन एक मौजूदा पुस्तकालय का बेहतर उपयोग करेगा।
एडम

14
यदि आप हमेशा एकल विधि के लिए पुस्तकालय नहीं जोड़ने के बारे में चिंतित हैं, तो कोई भी नया पुस्तकालय कभी नहीं जोड़ा जाएगा। Apache Commons में मौजूद उत्कृष्ट उपयोगिताओं को देखते हुए, मैं बहुत पहले उपयोग के मामले के आने पर इसे जोड़ने की सलाह देता हूं।
हिंडोल

6
अपाचे कॉमन्स का उपयोग कभी भी 'धोखा' नहीं कहा जाना चाहिए, मैं डेवलपर्स की पवित्रता पर सवाल उठाता हूं जो इसकी अनावश्यक निर्भरता की बात करते हैं।
जेरिल कुक

768

यहां एक सरल विधि दी गई है जो दो सरणियों को सम्‍मिलित करेगी और परिणाम लौटाएगी:

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

1
मुझे यह सुझाव पसंद है क्योंकि यह नवीनतम जावा संस्करणों पर कम निर्भर है। मेरी परियोजनाओं में मैं अक्सर जावा या सीएलडीसी प्रोफाइल के पुराने संस्करणों का उपयोग करते हुए फंस जाता हूं, जहां एंटिटी द्वारा बताई गई कुछ सुविधाएं उपलब्ध नहीं हैं।
15:

4
निम्न पंक्ति सामान्य भाग को तोड़ देगी: समवर्ती (नया स्ट्रिंग [] {"1"}, नई वस्तु [] {नई वस्तु ()})
ड्रैगन66

अच्छा होगा कि @SuppressWarnings एनोटेशन का उपयोग न करें - मैं इसके लिए एक समाधान पोस्ट करूंगा।
22

के लिए +1 Array.newInstance(a.getClass().getComponentType(), aLen + bLen);। मैंने आश्चर्यजनक रूप से पहले कभी नहीं देखा है। @beaudet मुझे लगता है कि एनोटेशन यहाँ ठीक है, यह देखते हुए कि इसे क्यों दबाया जा रहा है।
ब्लेक

1
हा, मुझे एक शुद्धतावादी फोन, लेकिन मैं साफ कोड इसी क्रम में चेतावनी के दमन की आवश्यकता नहीं है चेतावनियों को दूर करने के लिए पसंद
ब्यूडेट

475

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

10
@djBO: आदिम-टाइप किए गए सरणियों के लिए आपको प्रत्येक प्रकार के लिए एक अधिभार बनाना होगा: बस कोड को कॉपी करें और प्रत्येक Tको प्रतिस्थापित करें byte(और खोएं <T>)।
जोकिम सॉर

क्या आप मुझे बता सकते हैं कि अपनी कक्षा में <T> ऑपरेटर प्रकार का उपयोग कैसे करें?
जॉनीडेप

6
मैं इसे शुरुआत में जोड़ूंगा, सिर्फ रक्षात्मक होने के लिए। if (पहला == null) {if (दूसरा == null) {वापसी null; } दूसरा लौटा; } अगर (दूसरा == अशक्त) {पहले वापस; }
मैराथन

4
@djBo: किस बारे में:ByteBuffer buffer = ByteBuffer.allocate(array1.length + array2.length); buffer.put(array1); buffer.put(array2); return buffer.array();
सैम गोल्डबर्ग

18
इस दृष्टिकोण है जो स्पष्ट हो जाता है अगर आप उदाहरण के लिए विभिन्न प्रकार के घटक सरणियों के साथ इन कार्यों को लागू, में एक बग है concat(ai, ad), जहां aiहै Integer[]और adहै Double[]। (इस मामले में, प्रकार पैरामीटर कंपाइलर द्वारा <T>हल किया <? extends Number>जाता है।) द्वारा बनाई गई Arrays.copyOfसरणी Integerमें इस उदाहरण में पहले प्रकार का घटक प्रकार होगा । जब फ़ंक्शन दूसरे सरणी की प्रतिलिपि बनाने वाला होता है, तो एक ArrayStoreExceptionको फेंक दिया जाएगा। समाधान के लिए एक अतिरिक्त Class<T> typeपैरामीटर है।
टी-बुल

457

Streamजावा 8 में उपयोग करना :

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

या इस तरह, का उपयोग कर flatMap:

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

सामान्य प्रकार के लिए ऐसा करने के लिए आपको प्रतिबिंब का उपयोग करना होगा:

@SuppressWarnings("unchecked")
T[] both = Stream.concat(Arrays.stream(a), Arrays.stream(b)).toArray(
    size -> (T[]) Array.newInstance(a.getClass().getComponentType(), size));

28
यह कितना कारगर है?
सुपरस्टार

8
वर्थ ए रीड: jaxenter.com/… tl; ड्र - स्ट्रीम्स परफ़ॉर्मेंट हो सकती हैं या नहीं, यह इस बात पर निर्भर करता है कि आप उनके साथ क्या कर रहे हैं और समस्या की अड़चनें हैं (क्या यह हमेशा जवाब नहीं है? Lol)
ट्रेवर ब्राउन

6
इसके अतिरिक्त, यदि a या b आदिम प्रकार के सरणियाँ हैं, तो उनकी धाराओं को होने की आवश्यकता होगी, .boxed()इसलिए वे Streamउदाहरण के बजाय टाइप के होते हैं, IntStreamजिन्हें पैरामीटर के रूप में पारित नहीं किया जा सकता है Stream.concat
विल हार्डविक-स्मिथ

17
@Will हार्डविक-स्मिथ: नहीं, आपको केवल सही स्ट्रीम क्लास चुननी है, जैसे अगर aऔर bहैं int[], तो उपयोग करेंint[] both = IntStream.concat(Arrays.stream(a), Arrays.stream(b)).toArray();
Holger

3
@Supuhstar: यह शायद उतना तेज़ नहीं है System.arrayCopy। लेकिन विशेष रूप से धीमा भी नहीं है। संभवतः आपको निष्पादन के समय अंतर के मामले में वास्तव में संवेदनशील संदर्भों में विशाल सरणियों के साथ ऐसा बहुत बार करना पड़ता है।
Lii

191

या प्रिय अमरूद के साथ :

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)

जितना मैं अमरूद से प्यार करता हूं, अपाचे कॉमन्स की विधि नल ​​से बेहतर है।
रवि वालेउ

7
जबकि पुस्तकालयों का उपयोग करना अच्छा है, यह दुर्भाग्यपूर्ण है कि समस्या को दूर कर दिया गया है। इसलिए अंतर्निहित समाधान मायावी रहता है।
user924272

51
अमूर्तता के साथ समस्या क्या है? डननो यहां पहिया को फिर से मजबूत करने के साथ क्या सौदा है, यदि आप समस्या को स्रोत की जांच करना चाहते हैं या उस पर पढ़ना चाहते हैं। पेशेवर कोड उच्च स्तरीय पुस्तकालयों का उपयोग करना चाहिए, अगर यह Google के अंदर विकसित हो तो बेहतर है!
ब्रेनो सालगाडो

@ रविविलाऊ क्या आप उस वर्ग से जुड़ सकते हैं जो ऐसा करता है?
सेबास्टियन ट्रम्प

1
@ SébastienTromp यह इस प्रश्न के लिए शीर्ष समाधान है - ArrayUtils।
रवि वालौ

70

आप दो सरणियों को कोड की दो पंक्तियों में जोड़ सकते हैं।

String[] both = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, both, first.length, second.length);

यह एक तेज़ और कुशल समाधान है और यह आदिम प्रकारों के लिए काम करेगा और साथ ही इसमें शामिल दो तरीके अतिभारित होंगे।

आपको ArrayLists, स्ट्रीम इत्यादि से जुड़े समाधानों से बचना चाहिए क्योंकि ये बिना किसी उपयोगी उद्देश्य के लिए अस्थायी मेमोरी आवंटित करने की आवश्यकता होगी।

आपको forबड़े सरणियों के लिए छोरों से बचना चाहिए क्योंकि ये कुशल नहीं हैं। बिल्ट-इन फ़ंक्शन का उपयोग ब्लॉक-कॉपी फ़ंक्शन का उपयोग करता है जो बहुत तेज़ हैं।


1
यह सबसे अच्छे समाधानों में से एक है। 100% मानक जावा। फास्ट / कुशल। अधिक उत्थान प्राप्त करना चाहिए!
शबला तस्मा

58

जावा एपीआई का उपयोग करना:

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

13
बस, लेकिन अकुशल के रूप में यह एक सरणी बनाता है और फिर ऐरे विधि के लिए एक और उत्पन्न करता है। लेकिन फिर भी मान्य है क्योंकि यह पढ़ने में सरल है।
फोनिक्स

1
स्ट्रिंग्स और ऑब्जेक्ट्स के लिए लागू (जैसा प्रश्न चाहता है), लेकिन प्राथमिक प्रकारों के लिए कोई अतिरिक्त विधि नहीं है (asts)
joro

जैसा कि इस लेख में बताया गया है , इसका उपयोग करने both.toArray(new String[0])से भी तेज होगा both.toArray(new String[both.size()]), भले ही यह हमारे भोले अंतर्ज्ञान का विरोध करता हो। इसलिए अनुकूलन करते समय वास्तविक प्रदर्शन को मापना इतना महत्वपूर्ण है। या बस सरल निर्माण का उपयोग करें, जब अधिक जटिल संस्करण का लाभ सिद्ध नहीं किया जा सकता है।
होल्गर

42

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

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

फ़ाइल [] के लिए खान में काम किया, लेकिन यह वही है। आपके समाधान के लिए धन्यवाद
ShadowFlame

5
हालांकि काफी अक्षम है।
जोनासकज -

आप nullचेक जोड़ना चाह सकते हैं । और शायद अपने कुछ चर सेट करें final
ट्रिप कैनेटिक्स

@TrippKinetics nullचेक्स उन्हें दिखाने के बजाय NPE को छुपाता था और स्थानीय वर्जन के लिए फाइनल का उपयोग करने से कोई लाभ (अभी तक) नहीं होता है।
मार्टन बोदवेस

1
@Maarten Bodewes मुझे लगता है कि आप पाएंगे (यदि आप इसे बेंचमार्क करते हैं, जो मेरे पास है) कि जावा के देर से संस्करणों पर अनुक्रमित लूप के समान ही प्रत्येक के लिए चलता है। आशावादी इसका ख्याल रखता है।
रगोम

33

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

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

संपादित करें: इस पोस्ट के पिछले संस्करण में कहा गया है कि इस तरह से पुनः उपयोग स्पष्ट रूप से प्रलेखित किया जाएगा। के रूप में Maarten टिप्पणियों में बताते हैं कि यह सामान्य रूप से बेहतर होगा कि वे केवल बयानों को हटा दें, इस प्रकार दस्तावेज़ीकरण की आवश्यकता को शून्य कर दें। लेकिन फिर, अगर वे बयान पहली जगह में इस विशेष अनुकूलन के पूरे बिंदु थे। मैं इस जवाब को यहाँ छोड़ दूँगा, लेकिन सावधान रहना!


5
हालांकि इसका मतलब यह है कि आप उसी सरणी को वापस कर रहे हैं और लौटे हुए सरणी पर मान बदलकर इनपुट सरणी की उसी स्थिति में मान बदल देता है।
लोरेंजो बोकासीया

हाँ - सरणी पुन: उपयोग के संबंध में मेरी पोस्ट के अंत में टिप्पणी देखें। इस समाधान द्वारा लगाए गए रखरखाव ओवरहेड हमारे विशेष मामले में इसके लायक थे, लेकिन रक्षात्मक प्रतिलिपि का उपयोग संभवतः अधिकांश मामलों में किया जाना चाहिए।
वॉली

लोरेंजो / वॉली, क्या आप बता सकते हैं कि कोड में कौन सा हिस्सा सरणी पुन: उपयोग का कारण बनता है? मुझे लगा System.arraycopyकि सरणी की सामग्री को कॉपी करता है?
रोजी कासिम

4
एक कॉल करने वाला व्यक्ति सामान्य रूप से एक आबंटित एरे को वापस करने के लिए कॉनकट () को कॉल करने की उम्मीद करेगा। यदि या तो एक बी या अशक्त है, तो कॉनैट () हालांकि इसमें पारित किए गए सरणियों में से एक को वापस कर देगा। यह फिर से उपयोग अप्रत्याशित हो सकता है। (हाँ, एरेस्कोपी केवल नकल करता है। पुन: उपयोग या तो सीधे या बी सीधे वापस आने से होता है।)
वॉली

कोड जितना संभव हो उतना आत्म व्याख्यात्मक होना चाहिए। कोड को पढ़ने वाले लोगों को यह जानने के लिए किसी फ़ंक्शन के JavaDoc को नहीं देखना चाहिए कि यह एक विशेष स्थिति के लिए एक चीज़ करता है और दूसरे के लिए कुछ और। संक्षेप में: आप आम तौर पर एक टिप्पणी के साथ इन जैसी डिजाइन समस्याओं को ठीक नहीं कर सकते। बस दो ifबयानों को छोड़ना सबसे आसान तय होगा।
Maarten Bodewes

27

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

import static fj.data.Array.array;

...और फिर

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

अलिखित सरणी वापस लाने के लिए, कॉल करें

String[] s = both.array();

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

both.toArray(new String[0]);

3
जवाब बहुत अच्छा है लेकिन एक छोटा सा टूटा हुआ है। इसे सही बनाने के लिए आपको ऐरा () प्रकार की एक सरणी को पास करना चाहिए जो आपको चाहिए। उपरोक्त उदाहरण में, कोड होना चाहिए: दोनों .toArray (नया स्ट्रिंग [0]) देखें: stackoverflow.com/questions/4042434/…
Ronen Rabinovici

पता नहीं क्यों इस उत्तर को उच्च दर्जा नहीं दिया गया है ... हालांकि यह @RonenRabinovici द्वारा सुझाए गए बदलाव की आवश्यकता प्रतीत होती है
drmrbrewer

4
या बेहतर, शून्य-लंबाई सरणी के अनावश्यक आवंटन के बिना both.toArray(new String[both.size()]);)
माननीय


हाय @ हॉनज़ा, 3 लाइनों में एक आदिम पूर्णांक सरणी को वापस करने के लिए समान करना संभव है?
जंपिंग_मनकी

18

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

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

17

यहाँ जेनेरिक रेट्रोफ़िटेड के साथ सिल्वरटैब के घोल का रूपांतरण है:

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 समाधान के लिए जोआचिम का उत्तर देखें । न केवल यह चेतावनी को समाप्त करता है; यह छोटा, अधिक कुशल और पढ़ने में आसान है!


आप इस विधि के लिए चेतावनी को दबा सकते हैं, लेकिन इसके अलावा अन्य बहुत कुछ नहीं है जो आप कर सकते हैं। ऐरे और जेनरिक वास्तव में मिश्रण नहीं करते हैं।
दान डायर

3
यदि आप Arrays.copyOf () का उपयोग करते हैं तो अनियंत्रित चेतावनी को समाप्त किया जा सकता है। कार्यान्वयन के लिए मेरा उत्तर देखें।
जोआचिम सॉउर

@SuppressWarnings ("अनियंत्रित")
मार्क

13

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

अगर आप कॉन्कैटनेट चाहते हैं 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));

        }
    }  

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


11

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

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

मैं एक ही लूप में लंबाई समेटूँगा जहाँ आप अपनी अशक्त जाँच कर रहे हैं - लेकिन यह यहाँ के अन्य उत्तरों का बहुत अच्छा सारांश है। मेरा मानना ​​है कि यह इंटर्जेन्सिक प्रकार जैसे "इंट" को भी बिना इंटर्जर ऑब्जेक्ट्स में बदले जो वास्तव में केवल एरेलेस्ट्स के लिए सब कुछ बदलने के बजाय सरणियों के रूप में उनसे निपटने का एकमात्र कारण है, को संभालता है। इसके अलावा आपकी विधि 2 सरणियाँ और (...) पैरामीटर ले सकती है ताकि फोन करने वाले को पता हो कि उसे चलाने से पहले उसे कम से कम दो सरणियों में पास करने की आवश्यकता है और त्रुटि को देखता है, लेकिन यह लूपिंग कोड को जटिल करता है ....
बिल के

11

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

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

अच्छा समाधान - बेहतर होगा यदि कोड को ArrayLists के पक्ष में सरणियों से बचने के लिए फिर से शुरू किया गया था, लेकिन यह "उत्तर" और प्रश्नकर्ता के नियंत्रण से बाहर है।
बिल के

मैं गिनता हूं कि इसे काम करने के लिए 4 अतिरिक्त अस्थायी वस्तुओं की आवश्यकता है।
रगोम जूल

@ सरल, कम से कम इस तरह के सरल कार्य को लागू करने के लिए अतिरिक्त पुस्तकालय की आवश्यकता नहीं है
फरीद

9

जावा 8+ स्ट्रीम का उपयोग करके आप निम्नलिखित फ़ंक्शन लिख सकते हैं:

private static String[] concatArrays(final String[]... arrays) {
    return Arrays.stream(arrays)
         .flatMap(Arrays::stream)
         .toArray(String[]::new);
}

7

यहाँ सिल्वेतब द्वारा लिखित छद्म कोड समाधान के कामकाज कोड में एक संभावित कार्यान्वयन है।

धन्यवाद 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]);
   }
}

7

यह वन-लाइनर होना चाहिए।

public String [] concatenate (final String array1[], final String array2[])
{
    return Stream.concat(Stream.of(array1), Stream.of(array2)).toArray(String[]::new);
}

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

1
..लेकिन अक्षम और धीमा।
जोनासकज -

6

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

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

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


2
+1। दूसरे forलूप को उस के साथ बदलना बेहतर होगा :for(int j = 0; j < arr2.length; j++){arrBoth[arr1.length+j] = arr2[j];}
21

String[] arrBoth = java.util.Arrays.copyOf(arr1, arr1.length + arr2.length)पहला forलूप स्किप करने के लिए उपयोग करें । के आकार के लिए आनुपातिक समय बचाता है arr1
जॉन मेयर

5

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

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

5

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

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


प्रदर्शन कारणों से, मैं ArrayList के अंतिम आकार की पूर्व-गणना करूंगा क्योंकि ArrayList, परिभाषा के अनुसार, एक नया सरणी आवंटित करता है और हर बार वर्तमान सरणी पूर्ण होने पर इसके तत्वों की प्रतिलिपि बनाता है। नहीं तो मैं सीधे
लिंक्डलिस्ट के लिए जाऊंगा

5

एक सामान्य स्थैतिक संस्करण जो @SuppressWarnings एनोटेशन की आवश्यकता के बिना उच्च प्रदर्शन System.arraycopy का उपयोग करता है:

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

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

4

यहाँ जोछिम सॉर के कॉनसैट का मेरा थोड़ा बेहतर संस्करण है। यदि यह रनटाइम पर उपलब्ध है, तो यह जावा 6 के System.arraycopy का उपयोग करके जावा 5 या 6 पर काम कर सकता है। यह विधि (IMHO) Android के लिए एकदम सही है, क्योंकि यह Android <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;
  }

1
अच्छा सामान्य विचार है, लेकिन किसी को भी लागू करने के लिए: मैं एक copyOf और गैर- copyOf संस्करणों को एक से अधिक पसंद करूंगा जो प्रतिबिंब के माध्यम से दोनों करता है।
पुनर्मिलन

4

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



4

एक से अधिक सरणी में शामिल होने की अनुमति देने वाला एक साधारण बदलाव:

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

3

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


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

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


15
सभी अनावश्यक सूची ऑब्जेक्ट निर्माण के लिए इसे नीचे करना पड़ा।
आउटलाव प्रोग्रामर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.