java - কিভাবে আমি জাভা দুটি অ্যারে concatenate করতে পারেন?




arrays concatenation (20)

অথবা প্রিয় Guava :

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)

আমি জাভা দুটি স্ট্রিং অ্যারে সংহত করতে হবে।

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

এই কাজ করতে সবচেয়ে সহজ পদ্ধিতি হল উপায় কি?


আপনি এটি একটি অ্যারেস্টিস্টে রূপান্তর করার চেষ্টা করতে পারেন এবং addAll পদ্ধতিটি ব্যবহার করুন তারপর একটি অ্যারে রূপান্তর করুন।

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

আমি ভাল পুরাতন অ্যাপাচি কমন্স ল্যাং লাইব্রেরি থেকে এক-লাইন সমাধান খুঁজে পেয়েছি।
ArrayUtils.addAll(T[], T...)

কোড:

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

আমি সম্প্রতি অত্যধিক মেমরি ঘূর্ণন সঙ্গে সমস্যা যুদ্ধ করেছি। যদি একটি এবং / অথবা খ সাধারণভাবে খালি বলে পরিচিত হয়, তবে এখানে সিলভারবের কোডের আরেকটি অভিযোজন রয়েছে (জেনারাইজড):

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

(কোন ক্ষেত্রে, অ্যারে পুনরায় ব্যবহার আচরণ স্পষ্টভাবে জাভাডকড হবে!)


এই ইতিমধ্যে দীর্ঘ তালিকা এখনো আরেকটি সংস্করণ যোগ করার জন্য আমাকে ক্ষমা করুন। আমি প্রতিটি উত্তরের দিকে তাকালাম এবং সিদ্ধান্ত নিলাম যে আমি স্বাক্ষরের মাত্র একটি প্যারামিটারের সাথে একটি সংস্করণ চেয়েছিলাম। আমি অপ্রত্যাশিত ইনপুট ক্ষেত্রে বুদ্ধিমান তথ্য সঙ্গে প্রাথমিক ব্যর্থতা থেকে উপকার করার জন্য কিছু যুক্তি পরীক্ষণ যোগ।

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

এটি সম্ভবত সবচেয়ে কার্যকরী নয়, তবে এটি জাভা এর নিজস্ব API ছাড়া অন্য কোনও উপর নির্ভর করে না।


একটি সমাধান 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;
}

একটি সম্পূর্ণ জেনেরিক সংস্করণ লিখতে পারে যা যেকোনো সংখ্যক অ্যারে সংহত করার জন্য এমনকি বাড়ানো যেতে পারে। এই সংস্করণের জন্য জাভা 6 প্রয়োজন, তারা Arrays.copyOf() ব্যবহার করে

উভয় সংস্করণ কোন মধ্যস্থতাকারী List বস্তু তৈরি করতে এবং System.arraycopy() বড় বড় অ্যারে অনুলিপি যত দ্রুত সম্ভব তা নিশ্চিত করতে 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;
}

একাধিক অ্যারে যোগদান করার অনুমতি দেয় একটি সহজ বৈচিত্র:

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

এখানে আমার সামান্য উন্নত সংস্করণ Joachim Sauer এর concatAll। এটি জাভা 6 এর 6 বা 6 এ কাজ করতে পারে, জাভা 6 এর সিস্টেম.অ্যার্রেকপি ব্যবহার করে এটি রানটাইম এ উপলব্ধ থাকে। এই পদ্ধতিটি (আইএমএইচও) অ্যানড্রইডের জন্য উপযুক্ত, এটি অ্যান্ড্রয়েড <9 (যা সিস্টেমে.অ্যারে কপি নেই) এ কাজ করে তবে সম্ভব হলে দ্রুত পদ্ধতিটি ব্যবহার করবে।

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

এখানে সিলভারব এর সমাধানটির একটি অভিযোজন রয়েছে, জেনারিকগুলি পুনঃপ্রতিষ্ঠিত হয়েছে:

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 এর সমাধান জাভািমের উত্তরটি দেখুন। এটি শুধুমাত্র সতর্কতা নিষ্কাশন না; এটা আরও ছোট, আরও দক্ষ এবং সহজ পড়তে!


এখানে সিলভারব দ্বারা লেখা ছদ্ম কোড সলিউশনটির কাজের কোডে একটি কার্যকর বাস্তবায়ন।

ধন্যবাদ সিলভারব!

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]

জেনেরিক টাইপ erasure কারণে:

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

কিভাবে সহজভাবে সম্পর্কে

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 এবং arr1 একই ধরণের হয়, ততক্ষণ এটি আপনাকে একই ধরণের আরেকটি অ্যারে দেবে যা দুটি অ্যারে রয়েছে।


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

জাভা মধ্যে এক-মাছ ধরার নৌকা 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);

শুধুমাত্র জাভাসমূহের নিজস্ব 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]);
}

এখন, এই কোডটি সবচেয়ে দক্ষ নয়, তবে এটি শুধুমাত্র স্ট্যান্ডার্ড জাভা ক্লাসগুলিতে নির্ভর করে এবং বোঝার পক্ষে সহজ। এটি স্ট্রিং [] (এমনকি শূন্য অ্যারে) এর যেকোনো সংখ্যা জন্য কাজ করে।


স্ট্রিম ব্যবহার করে জাভা 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); 
  }

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

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

both.toArray(new String[0]);





add