HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaModerate

Split Java ArrayList into equal parts

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
equalintojavasplitarraylistparts

Problem

I have seen this question asked a few times, but I do not entirely understand the solutions provided.
Below is a bit of code I came up with for splitting up an arraylist into five parts. I have tested and changed the array size from 0 to 16 and it works fine.

I am sure there is a "better" way of doing this, so I would like to see what others think.

public static void main(String[] args)
{
    ArrayList arrayList = new ArrayList();
    arrayList.add("A");//1
    arrayList.add("B");//2
    arrayList.add("C");//3
    arrayList.add("D");//4
    arrayList.add("E");//5
    arrayList.add("F");//6
    arrayList.add("G");//7
    arrayList.add("H");//8
    arrayList.add("I");//9
    arrayList.add("J");//10
    arrayList.add("K");//11
    arrayList.add("L");//12
    arrayList.add("M");//13
    arrayList.add("N");//14
    arrayList.add("O");//15
    arrayList.add("P");//16
    arrayList.add("X");//17

    int i1 = (int) Math.ceil(arrayList.size()/5.0);

    List sublist = new ArrayList();
    int x=0;
    for(int p=0; p=(x+5))
        {
            sublist = new ArrayList(arrayList.subList(x, x+5));
            x+=5;
        }
        else
            sublist = new ArrayList(arrayList.subList(x, arrayList.size()));
        for(String slist : sublist)
        {
            System.out.println("i:"+slist);
        }
    }
}

Solution

It seems like you are mixing up the number of segments and the number of elements per segment. In your example, both are the same, so the result is correct, but in other cases it will not be. For instance, i1 is created as the number of elements per segment, with the number of segments being hard-coded as 5.0. Then, in the loop, you treat i1 as the number of segments, while the number of elements per segment is hard-coded as 5. Mistakes like this will be easier to spot if you use properly named variables, like numSegments or segmentSize instead of i1 or integer constants.

Also:

  • no need to wrap the sublists into new ArrayList



  • you can just count by increments according to the number of elements per sublist instead of using two counters, for the current sublist and the offset



  • you could use a ternary ... ? ... : ... instead of that if/else



How about this:

public static void main(String[] args) {
    List arrayList = new ArrayList();
    for (int i = 0; i  sublist = arrayList.subList(start, end);
        System.out.println(sublist);
    }
}


Here, size is the number of elements in each sublist. So instead of counting the segment of the list and increasing a second counter by 5 each time, you can just increase the first counter by five in the third argument of the for loop. Also, you can use the result of subList directly, without passing it to a constructor first. And you can get rid of the if-else by using min to determine the end index.

Output:

[0, 1, 2, 3, 4]
[5, 6, 7, 8, 9]
[10, 11, 12, 13, 14]
[15, 16, 17, 18, 19]
[20, 21, 22]


If instead of sublists with 5 elements you wanted five sublists, then use this (same result for the given example, but different for other list sizes):

int size = (int) Math.ceil(arrayList.size() / 5.0);

Code Snippets

public static void main(String[] args) {
    List<String> arrayList = new ArrayList<String>();
    for (int i = 0; i < 23; i++) {
        arrayList.add(String.valueOf(i));
    }

    int size = 5;
    for (int start = 0; start < arrayList.size(); start += size) {
        int end = Math.min(start + size, arrayList.size());
        List<String> sublist = arrayList.subList(start, end);
        System.out.println(sublist);
    }
}
[0, 1, 2, 3, 4]
[5, 6, 7, 8, 9]
[10, 11, 12, 13, 14]
[15, 16, 17, 18, 19]
[20, 21, 22]
int size = (int) Math.ceil(arrayList.size() / 5.0);

Context

StackExchange Code Review Q#27928, answer score: 10

Revisions (0)

No revisions yet.