ජාවා හි අරා දෙකක් සංයුක්ත කරන්නේ කෙසේද?


1384

මට Stringජාවාහි අරා දෙකක් සංයුක්ත කිරීමට අවශ්‍යයි .

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

මෙය කිරීමට පහසුම ක්‍රමය කුමක්ද?


3
ගුවා සිට බයිට්ස්කොන්කැට්
බෙන් පිටුව

1
මම මෙහි බොහෝ ප්‍රතිචාර දකින නමුත් ප්‍රශ්නය කොතරම් වචන වලින් ('පහසුම ක්‍රමය'?) එය හොඳම පිළිතුර දැක්වීමට ඉඩ නොදේ ...
අර්තූර් ඔපලින්ස්කි

2
මෙහි පිළිතුරු දුසිම් ගණනක් නව අරාවකට දත්ත පිටපත් කරයි, මන්ද එය ඉල්ලා ඇත්තේ එයයි - නමුත් දැඩි ලෙස අවශ්‍ය නොවන විට දත්ත පිටපත් කිරීම විශේෂයෙන් ජාවාහි කිරීම නරක දෙයකි. ඒ වෙනුවට, දර්ශක ගැන සෝදිසියෙන් සිටිමින් අරා දෙක සම්බන්ධ වී ඇති ආකාරයට භාවිතා කරන්න. තාක්‍ෂණය නිරූපණය කරන විසඳුමක් මම එකතු කර ඇත්තෙමි.
ඩග්ලස්

17
මේ වගේ ප්‍රශ්නයකට දැනට වෙනස් පිළිතුරු 50 ක් තිබීම නිසා ජාවා කිසි විටෙකත් සරල array1 + array2සංක්ෂිප්තයක් ලබා නොගත්තේ මන්දැයි මට සිතේ .
ජොලි ජෝකර්

2
සම්මත ජාවා පේළි දෙකකින් ඔබට එය හොඳින් හා ඉතා කාර්යක්ෂමව කළ හැකිය (මගේ පිළිතුර බලන්න), එබැවින් එය කිරීමට තනි ක්‍රමයක් තිබීමෙන් ලබා ගත හැකි භයානක දේ නොමැත. මේ සියලු අමුතු හා අපූරු විසඳුම් කාලය නාස්ති කිරීමකි.
rghome

Answers:


1109

හොඳ පැරණි අපාචේ කොමන්ස් ලැන්ග් පුස්තකාලයෙන් මට එක පේළියේ විසඳුමක් හමු විය.
ArrayUtils.addAll(T[], T...)

කේතය:

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

176
එය ප්‍රශ්නයට පිළිතුරු සපයන්නේ නම් එය "වංචා" කරන්නේ කෙසේද? නිසැකවම, අමතර යැපීමක් තිබීම මෙම විශේෂිත තත්වය සඳහා අධික ලෙස මරණයට පත් විය හැකි නමුත්, එය පවතින බව හ calling නඟා සිටීමෙන් කිසිදු හානියක් සිදු නොවේ.
රොබ්

34
මම එකඟ වෙමි, මෙය ඇත්ත වශයෙන්ම ප්‍රශ්නයට පිළිතුරු සපයන්නේ නැත. ඉහළ මට්ටමේ පුස්තකාල විශිෂ්ට විය හැකි නමුත් ඔබට එය කිරීමට කාර්යක්ෂම ක්‍රමයක් ඉගෙන ගැනීමට අවශ්‍ය නම්, පුස්තකාල ක්‍රමය භාවිතා කරන කේතය දෙස බැලීමට ඔබට අවශ්‍යය. එසේම, බොහෝ අවස්ථාවන්හිදී, ඔබට පියාසර කරන නිෂ්පාදනයේ වෙනත් පුස්තකාලයක් හරහා යා නොහැක.
AdamC

77
මම හිතන්නේ මේක හොඳ පිළිතුරක්. POJO විසඳුම් ද සපයා ඇත, නමුත් OP දැනටමත් ඔවුන්ගේ වැඩසටහන තුළ Apache Commons භාවිතා කරන්නේ නම් (එහි ජනප්‍රියතාවය සැලකිල්ලට ගෙන හැකි නම්) ඔහු තවමත් මෙම විසඳුම නොදැන සිටිය හැකිය. එවිට ඔහු "මෙම එක් ක්‍රමයක් සඳහා යැපීමක් එකතු නොකරනු ඇත", නමුත් දැනට පවතින පුස්තකාලයක් වඩා හොඳින් භාවිතා කරයි.
ඇඩම්

14
තනි ක්‍රමයක් සඳහා පුස්තකාලයක් එක් නොකිරීම ගැන ඔබ සැමවිටම කනස්සල්ලට පත්ව සිටී නම්, නව පුස්තකාල කිසිවක් එකතු නොවේ. අපාචේ කොමන්ස් හි ඇති විශිෂ්ට උපයෝගීතා සැලකිල්ලට ගෙන, පළමු භාවිත අවස්ථාව පැමිණි විට එය එක් කිරීමට මම තරයේ නිර්දේශ කරමි.
හින්ඩෝල්

6
අපාචේ කොමන්ස් භාවිතා කිරීම කිසි විටෙකත් 'වංචා කිරීමක්' ලෙස හැඳින්විය යුතු නැත.
ජෙරිල් කුක්

768

අරා දෙකක් සමපාත කර ප්‍රති result ලය ලබා දෙන සරල ක්‍රමයක් මෙන්න:

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[].

ප්‍රති .ලයේ සං type ටක වර්ගය ලෙස වඩාත් සාමාන්‍ය වර්ගය තෝරා ගැනීමෙන් විවිධ වර්ග දෙකක අරා සංයුක්ත කිරීමට ද එය සමත් වේ.

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
මම මෙම යෝජනාවට කැමතියි එය නවතම ජාවා අනුවාදයන් මත රඳා නොපවතින බැවින්. මගේ ව්‍යාපෘති වලදී මම බොහෝ විට පැරණි ජාවා හෝ සීඑල්ඩීසී පැතිකඩ භාවිතා කරමින් හිර වී සිටිමි. ඇන්ටි සඳහන් කළ පහසුකම් වැනි සමහර පහසුකම් නොමැත.
kvn

4
පහත දැක්වෙන රේඛාව සාමාන්‍ය කොටස බිඳ දමනු ඇත: සමෝච්ඡය (නව
නූල්

upSppressWarnings විවරණිකාව භාවිතා නොකිරීම සතුටක් - මම ඒ සඳහා විසඳුමක් පහතින් පළ කරමි.
beaudet

සඳහා +1 Array.newInstance(a.getClass().getComponentType(), aLen + bLen);. මම පුදුමයට කරුණක් නම් මීට පෙර කවදාවත් දැක නැත. @beaudet මම හිතන්නේ මෙහි විවරණය හොඳයි, එය යටපත් කරන්නේ ඇයිද යන්න සලකා බලන්න.
බ්ලේක්

1
ha, මට පාරිශුද්ධවාදියෙකු ලෙස අමතන්න, නමුත් අනතුරු ඇඟවීම් ඉවත් කිරීම සඳහා අනතුරු ඇඟවීම් යටපත් කිරීම අවශ්‍ය නොවන පිරිසිදු කේතයකට මම කැමැත්තෙමි
beaudet

476

ඕනෑම අරා ගණනක් සංයුක්ත කිරීම සඳහා පවා දීර් can කළ හැකි පූර්ණ ජනක අනුවාදයක් ලිවිය හැකිය. මෙම අනුවාදයන් භාවිතා කරන පරිදි ජාවා 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
jdjBO: ප්‍රාථමික-ටයිප් කළ අරා සඳහා ඔබට එක් එක් වර්ගයට අධික බරක් සෑදිය යුතුය: කේතය පිටපත් කර ඒවා වෙනුවට ආදේශ Tකරන්න byte( නැතිනම් නැති කරන්න <T>).
ජෝකිම් සෝවර්

මගේ පන්තියේ <T> ක්‍රියාකරු වර්ගය භාවිතා කරන්නේ කෙසේදැයි මට කියන්න පුළුවන්ද?
ජොනීඩෙප්

6
මම මෙය ආරම්භයට එකතු කරමි. if (first == null) {if (second == null) {ආපසු ශුන්‍යය; second දෙවන ආපසු; } if (දෙවන == ශූන්‍ය) first පළමුව ආපසු යන්න; }
මැරතන්

4
jdjBo: කුමක් ගැනද:ByteBuffer buffer = ByteBuffer.allocate(array1.length + array2.length); buffer.put(array1); buffer.put(array2); return buffer.array();
සෑම් ගෝල්ඩ්බර්ග්

19
ඔබ විවිධ සංරචක වර්ග අරා සමග මෙම කාර්යයන් පතා නම්, උදාහරණයක් ලෙස පැහැදිලි බවට පත් මෙම ප්රවේශය දෝෂයක් තියෙනවා concat(ai, ad), කොහෙද aiවේ Integer[]හා adවන Double[]. (මෙම අවස්ථාවෙහිදී, පරාමිති වර්ගය සම්පාදකයා විසින් <T>විසඳනු <? extends Number>ලැබේ.) විසින් සාදන ලද Arrays.copyOfඅරාවෙහි පළමු අරාවේ සංරචක වර්ගය ඇත, එනම් Integerමෙම උදාහරණයේ. ශ්‍රිතය දෙවන අරාව පිටපත් කිරීමට ආසන්න වන විට, ArrayStoreExceptionවිසි කරනු ලැබේ. විසඳුම වන්නේ අතිරේක Class<T> typeපරාමිතියක් තිබීමයි.
ටී-බුල්

470

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; dr - ධාරාවන් ක්‍රියාකාරී විය හැකිද නැද්ද යන්න, එය රඳා පවතින්නේ ඔබ ඔවුන් සමඟ කරන දේ සහ ගැටලුවේ අවහිරතා මතය (මෙය සැමවිටම පිළිතුර නොවේද? Lol)
ට්‍රෙවර් බ්‍රවුන්

6
මීට අමතරව, a හෝ b යනු ප්‍රාථමික වර්ගවල අරා නම්, ඒවායේ ප්‍රවාහයන් විය යුතු .boxed()බැවින් ඒවා පරාමිතියක් ලෙස සම්මත කළ නොහැකි Streamඋදා . IntStreamStream.concat
විල් හාඩ්වික්-ස්මිත්

19
@Will Hardwick-ස්මිත්: නැහැ, ඔබ පමණක් අයිතිය ධාරාව පන්ති නම් එසවීමට, උදා: ඇති aහා bවේ int[], භාවිතයint[] both = IntStream.concat(Arrays.stream(a), Arrays.stream(b)).toArray();
Holger

3
Up සුපූස්ටාර්: එය එතරම් වේගවත් නොවේ System.arrayCopy. නමුත් විශේෂයෙන් මන්දගාමී නොවේ. ඔබ බොහෝ විට මෙම කරන්න සිදු වී ඉතා සමග බොහෝ වතාවක් විශාල දී පෙලගැස්මක් ඇත්තටම ප්රශ්නයක් කිරීමට කියාත්මක කාලය වෙනසක් සඳහා කාර්ය සාධන සංවේදී සන්දර්භයන්.
ලී

192

හෝ ආදරණීය ගුවා සමඟ :

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

52
වියුක්ත කිරීමේ ගැටලුව කුමක්ද? ඩන්නෝ මෙහි රෝදය ප්‍රතිනිර්මාණය කිරීමේ ගනුදෙනුව කුමක්ද, ඔබට ගැටලුව ඉගෙන ගැනීමට අවශ්‍ය නම් මූලාශ්‍රය පරීක්ෂා කරන්න හෝ එය කියවන්න. වෘත්තීය කේතය ඉහළ මට්ටමේ පුස්තකාල භාවිතා කළ යුතුය, එය ගූගල් තුළ සංවර්ධනය කර ඇත්නම් වඩා හොඳය!
බ්‍රෙනෝ සල්ගාඩෝ

AvRaviWallau ඔබට මෙය කරන පන්තියට සම්බන්ධ විය හැකිද?
සෙබස්තියන් ට්‍රම්ප්

1
@ SébastienTromp මෙම ප්‍රශ්නයට හොඳම විසඳුම එයයි - ArrayUtils.
රවී වල්ලව්

78

ඔබට අරා දෙක කේත පේළි දෙකකින් එකතු කළ හැකිය.

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

මෙය වේගවත් හා කාර්යක්ෂම විසඳුමක් වන අතර එය ප්‍රාථමික වර්ග සඳහා ක්‍රියා කරනු ඇති අතර ඊට සම්බන්ධ ක්‍රම දෙක අධික ලෙස පටවා ඇත.

අරා ලැයිස්තු, ධාරා යනාදිය සම්බන්ධ විසඳුම් වලින් ඔබ වැළකී සිටිය යුතුය.

forමේවා කාර්යක්ෂම නොවන බැවින් විශාල අරා සඳහා ලූප වළක්වා ගත යුතුය . ගොඩනංවන ලද ක්‍රම අතිශයින්ම වේගවත් බ්ලොක්-පිටපත් කාර්යයන් භාවිතා කරයි.


2
මෙය හොඳම විසඳුමකි. 100% සම්මත ජාවා. වේගවත් / කාර්යක්ෂම. වැඩි දියුණුවක් ලබා ගත යුතුය!
ෂෙබ්ලා ට්සා

අනිවාර්යයෙන්ම හොඳම විසඳුම.
alexovits

58

ජාවා API භාවිතා කිරීම:

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

14
සරලවම, නමුත් අකාර්යක්ෂම වන්නේ එය අරේලිස්ට් සඳහා අරාවක් සාදා ඉන්පසු ToArray ක්‍රමය සඳහා තවත් උත්පාදනය කරන බැවිනි. නමුත් කියවීම සරල බැවින් තවමත් වලංගු වේ.
PhoneixS

1
නූල් සහ වස්තූන් සඳහා අදාළ වේ (ප්‍රශ්නයට අවශ්‍ය පරිදි), නමුත් ප්‍රාථමික වර්ග සඳහා අතිරේක ක්‍රමයක් නොමැත (ints ලෙස)
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.
ට්‍රිප් චාලක විද්‍යාව

Ri ට්‍රිප්කිනෙටික්ස් nullචෙක්පත් මගින් එන්පීඊ පෙන්වීමට වඩා ඒවා සඟවනු ඇති අතර දේශීය වර්‍ග සඳහා අවසාන භාවිතා කිරීමෙන් කිසිදු ප්‍රතිලාභයක් නොමැත (තවමත්).
මාර්ටන් බොඩෙව්ස්

1
Ar මාර්ටන් බොඩ්වේස් ජාවා හි අනුවාදයන්හි සුචිගත කළ ලූපයට සමානව සෑම එකක්ම ක්‍රියාත්මක වන බව ඔබ සොයා ගනු ඇතැයි මම සිතමි (ඔබ එය මා සතුව තිබේ නම්). ප්‍රශස්තකරණය එය බලා ගනී.
rghome

33

මම මෑතකදී අධික මතක භ්‍රමණය සමඟ ගැටලු සමඟ සටන් කළෙමි. A සහ / හෝ b සාමාන්‍යයෙන් හිස් බව දන්නා නම්, මෙන්න සිල්වර්ටැබ් කේතයේ තවත් අනුවර්තනයක් (සාමාන්‍යකරණය කරන ලද):

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

සංස්කරණය කරන්න: මෙම ලිපියේ පෙර අනුවාදයක සඳහන් වූයේ මෙවැනි අරා නැවත භාවිතා කිරීම පැහැදිලිව ලේඛනගත කළ යුතු බවයි. මාර්ටන් අදහස් දැක්වීමේදී පෙන්වා දෙන පරිදි, සාමාන්‍යයෙන් නම් ප්‍රකාශ ඉවත් කිරීම වඩා හොඳ වනු ඇත. නමුත් නැවතත්, ප්‍රකාශයන් නම් මෙම විශේෂිත ප්‍රශස්තිකරණයේ මුලික ලක්ෂ්‍යයයි. මම මෙම පිළිතුර මෙහි තබමි, නමුත් ප්‍රවේශම් වන්න!


5
කෙසේ වෙතත් මෙයින් අදහස් කරන්නේ ඔබ එකම අරාව නැවත ලබා දෙන බවත් ආපසු ලබා දුන් අරාවෙහි අගයක් වෙනස් කිරීමෙන් ආදාන අරා ආපසු ලබා දුන් ස්ථානයේම අගය වෙනස් වන බවත් ය.
ලොරෙන්සෝ බොකාචියා

ඔව් - අරාව නැවත භාවිතා කිරීම පිළිබඳව මගේ ලිපියේ අවසානයේ අදහස් බලන්න. මෙම විසඳුම මගින් පනවා ඇති නඩත්තු පොදු කාර්යය අපගේ විශේෂිත අවස්ථාවෙහිදී එය වටී, නමුත් බොහෝ විට ආරක්ෂක පිටපත් කිරීම භාවිතා කළ යුතුය.
වොලි

ලොරෙන්සෝ / වොලී, අරාව නැවත භාවිතා කිරීමට හේතු වන කේතයේ කුමන කොටසද යන්න ඔබට පැහැදිලි කළ හැකිද? මම හිතුවේ System.arraycopyඅරාවෙහි අන්තර්ගතය පිටපත් කරනවාද?
රොස්ඩි කාසිම්

4
අමතන්නා සාමාන්‍යයෙන් කොන්කට් () වෙත ඇමතුමක් අලුතින් වෙන් කරන ලද අරාවක් ආපසු ලබා දෙනු ඇතැයි අපේක්ෂා කරයි. A හෝ b ශුන්‍ය නම්, කොන්කට් () කෙසේ වෙතත් එයට ඇතුළු වූ අරා වලින් එකක් ආපසු ලබා දෙනු ඇත. මෙම නැවත භාවිතය අනපේක්ෂිත විය හැකිය. (ඔව්, අරාකෝපි පිටපත් කිරීම පමණක් සිදු කරයි. නැවත භාවිතා කිරීම ලැබෙන්නේ a හෝ b කෙලින්ම ආපසු යැවීමෙනි.)
වොලි

කේතය හැකි තරම් ස්වයං පැහැදිලි කිරීමක් විය යුතුය. කේතය කියවන පුද්ගලයින්ට එක් විශේෂිත කොන්දේසියක් සඳහා එක් දෙයක් සහ තවත් දෙයක් තවත් දෙයක් කරන බව සොයා ගැනීමට නම් කරන ලද ශ්‍රිතයක ජාවාඩොක් සොයා බැලිය යුතු නැත. කෙටියෙන් කිවහොත්: ඔබට සාමාන්‍යයෙන් අදහස් දැක්වීමක් සමඟ මෙවැනි නිර්මාණ ගැටළු විසඳිය නොහැක. ifප්‍රකාශ දෙකෙන් ඉවත් වීම පහසුම විසඳුම වනු ඇත.
මාර්ටන් බොඩෙව්ස්

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
පිළිතුර විශිෂ්ටයි නමුත් ඉතා සුළු ප්‍රමාණයක් කැඩී ඇත. එය පරිපූර්ණ කිරීම සඳහා ඔබට අවශ්‍ය වර්ගයේ අරා () වෙත යා යුතුය. ඉහත උදාහරණයේ දී, කේතය විය යුත්තේ: දෙකම.ටෝආරේ (නව නූල් [0]) බලන්න: stackoverflow.com/questions/4042434/…
රොනන් රබිනොවිචි

මෙම පිළිතුර ඉහළ අගයක් නොගන්නේ මන්දැයි නොදනී ... එයට @RonenRabinovici විසින් යෝජනා කරන ලද වෙනසක් අවශ්‍ය බව පෙනේ
drmrbrewer

4
හෝ වඩා හොඳ, අනවශ්‍ය ලෙස ශුන්‍ය දිග අරාව වෙන් නොකර both.toArray(new String[both.size()])
:;


හායි on හොන්සා, ප්‍රාථමික පූර්ණ සංඛ්‍යා පෙළක් පේළි 3 කින් ආපසු ලබා දීම සඳහා එයම කළ හැකිද?
පැනීම_මොන්කි

18

ධාරාව භාවිතා කරමින් ජාවා 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); 
  }

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 () භාවිතා කරන්නේ නම් පරීක්ෂා නොකළ අනතුරු ඇඟවීම ඉවත් කළ හැකිය. ක්‍රියාත්මක කිරීම සඳහා මගේ පිළිතුර බලන්න.
ජෝකිම් සෝවර්

UppSuppressWarnings ("සලකුණු නොකළ")
මාර්ක් රෙනූෆ්

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

        }
    }  

අපට මේ ආකාරයෙන්ද භාවිතා කළ හැකිය.


12

ඔබට එය අරා ලැයිස්තුවක් බවට පරිවර්තනය කර addAll ක්‍රමය භාවිතා කර නැවත අරාවකට පරිවර්තනය කළ හැකිය.

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

හොඳ විසඳුමක් - අරා ලැයිස්තු වලට වාසිදායක ලෙස අරා මඟ හැරීම සඳහා කේතය නැවත සකස් කර ඇත්නම් වඩා හොඳ වනු ඇත, නමුත් එය "පිළිතුර" පාලනයෙන් පිටත සහ ප්‍රශ්න කරන්නා දක්වා වේ.
බිල් කේ

වැඩ කිරීමට අමතර තාවකාලික වස්තු 4 ක් අවශ්‍ය බව මම ගණන් කරමි.
rghome

ghrghome, අවම වශයෙන් එවැනි සරල කාර්යයක් ක්‍රියාත්මක කිරීමට අමතර පුස්තකාලයක් අවශ්‍ය නොවේ
ෆරීඩ්

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 ක් සහ (...) පරාමිතියක් ගත හැකි වන අතර එමඟින් ඔහු එය ක්‍රියාත්මක කර දෝෂය දැකීමට පෙර අවම වශයෙන් අරා දෙකකින්වත් සමත් විය යුතු බව අමතන්නා දනී, නමුත් එය ලූප කේතය සංකීර්ණ කරයි ....
බිල් කේ

9

ජාවා 8+ ධාරාවන් භාවිතා කිරීමෙන් ඔබට පහත ශ්‍රිතය ලිවිය හැකිය:

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

7

සිල්වර්ටැබ් විසින් ලියන ලද ව්‍යාජ කේත විසඳුමේ ක්‍රියාකාරී කේතයේ ක්‍රියාත්මක කිරීමක් මෙහි දැක්වේ.

ස්තූතියි සිල්වර්ටැබ්!

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];}
බැන්සර්

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පවතින තාක් කල් , මෙය ඔබට අරා දෙකම අඩංගු එකම වර්ගයේ තවත් පෙළක් ලබා දෙනු ඇත.


කාර්ය සාධන හේතූන් මත, මම අරේලිස්ට් හි අවසාන ප්‍රමාණය කලින් ගණනය කරමි, මන්ද අරේලිස්ට්, අර්ථ දැක්වීම අනුව, නව අරාවක් වෙන් කර වත්මන් අරාව පිරී ඇති සෑම අවස්ථාවකම එහි අංග පිටපත් කරයි. එසේ නොමැතිනම් එවැනි ගැටළුවකට මුහුණ නොදෙන LinkedList වෙත මම කෙලින්ම යන්නෙමි
usr-local-ΕΨΗΕΛΩΝ

5

UppSuppressWarnings විවරණයකින් තොරව ඉහළ ක්‍රියාකාරී 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

මෙන්න මගේ තරමක් වැඩිදියුණු කළ ජොකිම් සෝවර්ගේ කොන්කාට් ඇල්. එය ජාවා 5 හෝ 6 මත වැඩ කළ හැකි අතර, ජාවා 6 හි System.arraycopy භාවිතා කර එය ක්‍රියාත්මක වේලාවේ තිබේ නම්. මෙම ක්‍රමය (IMHO) ඇන්ඩ්‍රොයිඩ් සඳහා පරිපූර්ණයි, එය ඇන්ඩ්‍රොයිඩ් <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
හොඳ පොදු අදහසක්, නමුත් ක්‍රියාත්මක කරන ඕනෑම කෙනෙකුට: මම කැමතියි පරාවර්තනය වන ආකාරයෙන්ම කරන පිටපත් වලට වඩා පිටපත් සහ පිටපත් නොවන අනුවාද වලට.
rektide

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

ජාවාස්ගේම API පමණක් භාවිතා කිරීම:


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
සියලු අනවශ්‍ය ලැයිස්තු වස්තු නිර්මාණය සඳහා මෙය අඩු කිරීමට සිදු විය.
විරෝධී ක්‍රමලේඛකයා
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.