Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

divide array into smaller parts

Tags:

java

arrays

I would like to divide a large byte array into smaller chunks (say 64 bytes). Please help me with this.

like image 647
malak Avatar asked Aug 04 '10 11:08

malak


5 Answers

You can use the method Arrays.copyOfRange(original, from, to)

 public static byte[][] divideArray(byte[] source, int chunksize) {


        byte[][] ret = new byte[(int)Math.ceil(source.length / (double)chunksize)][chunksize];

        int start = 0;

        for(int i = 0; i < ret.length; i++) {
            ret[i] = Arrays.copyOfRange(source,start, start + chunksize);
            start += chunksize ;
        }

        return ret;
    }

Or You can use as Max suggested the System.arraycopy

public static byte[][] divideArray(byte[] source, int chunksize) {


        byte[][] ret = new byte[(int)Math.ceil(source.length / (double)chunksize)][chunksize];

        int start = 0;

        for(int i = 0; i < ret.length; i++) {
            if(start + chunksize > source.length) {
                System.arraycopy(source, start, ret[i], 0, source.length - start);
            } else {
                System.arraycopy(source, start, ret[i], 0, chunksize);
            }
            start += chunksize ;
        }


        return ret;
    }
like image 198
Damian Leszczyński - Vash Avatar answered Oct 21 '22 06:10

Damian Leszczyński - Vash


Damian Vash's first method (the one using Arrays.copyOfRange()) adds zeros to the end of the last chunk if the input is not exactly a multiple of chunksize.

You might want to use this instead:

public static List<byte[]> divideArray(byte[] source, int chunksize) {

    List<byte[]> result = new ArrayList<byte[]>();
    int start = 0;
    while (start < source.length) {
        int end = Math.min(source.length, start + chunksize);
        result.add(Arrays.copyOfRange(source, start, end));
        start += chunksize;
    }

    return result;
}

and in case it's useful, the same thing using ArrayList's:

  public static List<List<String>> divideList(List<String> source, int chunksize) {
    List<List<String>> result = new ArrayList<List<String>>();
    int start = 0;
    while (start < source.size()) {
      int end = Math.min(source.size(), start + chunksize);
      result.add(source.subList(start, end));
      start += chunksize;
    }
    return result;
  }
like image 42
Mirko Seifert Avatar answered Oct 21 '22 07:10

Mirko Seifert


If you are looking save some memory, a slight modification to Damian Vash's answer would help (in this case any remaining chunk is not allocated a complete 64 byte block size, as well...)

private byte[][] splitChunks(byte[] source)
{
    byte[][] ret = new byte[(int)Math.ceil(source.length / (double)CHUNK_SIZE)][];
    int start = 0;
    for(int i = 0; i < ret.length; i++) {
        if(start + CHUNK_SIZE > source.length) {
            ret[i] = new byte[source.length-start];
            System.arraycopy(source, start, ret[i], 0, source.length - start);
        } 
        else {
            ret[i] = new byte[CHUNK_SIZE];
            System.arraycopy(source, start, ret[i], 0, CHUNK_SIZE);
        }
        start += CHUNK_SIZE ;
    }
    return ret;
}
like image 30
uLYsseus Avatar answered Oct 21 '22 08:10

uLYsseus


Well, System.arraycopy(src, fromPos, dest, toPos, length) is generally considered faster than Arrays.copyOfRange.

byte[] source = ...read it from somewhere...;
byte[] newArray = new byte[64];
System.arraycopy(source, 0, newArray, 0, 64);
like image 20
bezmax Avatar answered Oct 21 '22 08:10

bezmax


You have two choices:

  • System.arraycopy(...)
  • Array.copyOfRange(...)

both of them work the same way but while first one only manages copy, second one is meant to be used to allocate the new chunk at the same time.

I benchmarked them with a result that System.arraycopy is faster if you manage to allocate chunks all together before splitting your array but slightly slower if you allocate them whle you copy: in this case you should use Array.copyOfRange.

like image 1
Jack Avatar answered Oct 21 '22 08:10

Jack