0

Consider a List which have 60 or more elements. I want to break it into 6 List and add those to List. I am doing that because i want to send data to jsp in tabular format. Anyway, i am doing that but wanted to know if the way in which i am doing is good or not, cause i believe something better exist. Below is my code.

List<String> rollsAll = // from db
        List<List<String>> rolls = new ArrayList<List<String>>();
        int i=0;
        for(String roll:rollsAll){
            if(i<10)
            {
                if(i==0)
                {
                    rolls.add(new ArrayList());
                }
                rolls.get(0).add(roll);
                i++;
                continue;
            }
            else if(i<20)
            {
                if(i==10)
                {
                    rolls.add(new ArrayList());
                }
                rolls.get(1).add(roll);
                i++;
                continue;
            }
            else if(i<30)
            {
                if(i==20)
                {
                    rolls.add(new ArrayList());
                }
                rolls.get(2).add(roll);
                i++;
                continue;
            }else if(i<40)
            {
                if(i==30)
                {
                    rolls.add(new ArrayList());
                }
                rolls.get(3).add(roll);
                i++;
                continue;
            }else if(i<50)
            {
                if(i==40)
                {
                    rolls.add(new ArrayList());
                }
                rolls.get(4).add(roll);
                i++;
                continue;
            }else if(i<60)
            {
                if(i==50)
                {
                    rolls.add(new ArrayList());
                }
                rolls.get(5).add(roll);
                i++;
                continue;
            }else if(i<70)
            {
                if(i==60)
                {
                    rolls.add(new ArrayList());
                }
                rolls.get(6).add(roll);
                i++;
                continue;
            }else if(i<80)
            {
                if(i==70)
                {
                    rolls.add(new ArrayList());
                }
                rolls.get(7).add(roll);
                i++;
                continue;
            }else if(i<90)
            {
                if(i==80)
                {
                    rolls.add(new ArrayList());
                }
                rolls.get(8).add(roll);
                i++;
                continue;
            }else if(i<100)
            {
                if(i==90)
                {
                    rolls.add(new ArrayList());
                }
                rolls.get(9).add(roll);
                i++;
                continue;
            }else if(i<110)
            {
                if(i==100)
                {
                    rolls.add(new ArrayList());
                }
                rolls.get(10).add(roll);
                i++;
                continue;
            }else if(i<120)
            {
                if(i==110)
                {
                    rolls.add(new ArrayList());
                }
                rolls.get(11).add(roll);
                i++;
                continue;
            }
        }

Thanks and Regards

2
  • 2
    Why don't you use another for loop instead of writing 12 times the same snippet? Commented Jun 5, 2013 at 17:55
  • 1
    You could use subList(int fromIndex, int toIndex) ... docs.oracle.com/javase/6/docs/api/java/util/…, int) Commented Jun 5, 2013 at 17:56

8 Answers 8

3

Just walk the list 10 items at a time and use List.subList to grab the chunk that you need.

The below code does this and defensively copies the sub list.

int nPerSublist = 10;

List<String> rollsAll = // from db
List<List<String>> rolls = new ArrayList<List<String>>(
    (rollsAll.size() + nPerSublist - 1) / nPerSublist);

for (int i = 0, n = rollsAll.size(); i < n; i += nPerSublist) {
  rolls.add(new ArrayList<String>(rollsAll.subList(i, Math.min(i + nPerSublist, n))));
}
Sign up to request clarification or add additional context in comments.

Comments

2

Using List.subList will produce an elegant way to achieve what you want:

Suppose I got a List of 1000 numbers and I want to split them into groups of 70:

List<Integer> numbers = new ArrayList<Integer>();
for (int i = 1; i <= 1000; i++) {
    numbers.add(Integer.valueOf(i));
}

int totalItems = numbers.size();
int itemPerGroup = 70;
int totalGroup = (totalItems / itemPerGroup) + 1;
List<List<Integer>> groups = new ArrayList<List<Integer>>();
for (int groupCount = 1; groupCount <= totalGroup; groupCount++) {
    int groupStartIndex = (groupCount - 1) * itemPerGroup;
    int groupEndIndex = Math.min(numbers.size(), groupCount * itemPerGroup);
    groups.add(numbers.subList(groupStartIndex, groupEndIndex));
}

1 Comment

One important note is that the List returned by subList actually shared the same backing array of the original List. Therefore, any modification on the sub lists will affect the original `List. See <docs.oracle.com/javase/6/docs/api/java/util/…, int)>
1

I found this implementation on the web that you can use to store your data into a 2dArrayList, add this as a class to your project and you can use the methods there:

import java.util.ArrayList;

public class ArrayList2d<Type>
{
ArrayList<ArrayList<Type>>  array;

public ArrayList2d()
{
    array = new ArrayList<ArrayList<Type>>();
}

/**
 * ensures a minimum capacity of num rows. Note that this does not guarantee
 * that there are that many rows.
 * 
 * @param num
 */
public void ensureCapacity(int num)
{
    array.ensureCapacity(num);
}

/**
 * Ensures that the given row has at least the given capacity. Note that
 * this method will also ensure that getNumRows() >= row
 * 
 * @param row
 * @param num
 */
public void ensureCapacity(int row, int num)
{
    ensureCapacity(row);
    while (row < getNumRows())
    {
        array.add(new ArrayList<Type>());
    }
    array.get(row).ensureCapacity(num);
}

/**
 * Adds an item at the end of the specified row. This will guarantee that at least row rows exist.
 */
public void Add(Type data, int row)
{
    ensureCapacity(row);
    while(row >= getNumRows())
    {
        array.add(new ArrayList<Type>());
    }
    array.get(row).add(data);
}

public Type get(int row, int col)
{
    return array.get(row).get(col);
}

public void set(int row, int col, Type data)
{
    array.get(row).set(col,data);
}

public void remove(int row, int col)
{
    array.get(row).remove(col);
}

public boolean contains(Type data)
{
    for (int i = 0; i < array.size(); i++)
    {
        if (array.get(i).contains(data))
        {
            return true;
        }
    }
    return false;
}

public int getNumRows()
{
    return array.size();
}

public int getNumCols(int row)
{
    return array.get(row).size();
}
}

2 Comments

How does this address the question?
this gives him an implementation of a 2dArrayList that will allow him to store his data in the tabular form using the methods provided. The algorithm will stay the same as you provided it. This gives him an implementation to store it.
1

You can use that:

private static final int SIZE = 10; // size of an inner list

public List<List<String>> partition(final List<String> rolls)
{
    final List<List<String>> ret = new ArrayList<List<String>>();

    List<String> list;

    int i = 0;

    for (final String roll: rolls) {
        if (i % SIZE == 0) {
            list = new ArrayList<String>();
            ret.add(list);
        }
        list.add(roll);
        i++;
    }

    return ret;
}

Comments

1

Something like

List<String> rollsAll = // from db
List<List<String>> rolls = new ArrayList<List<String>>();
int size = rollsAll.size();
for (int i = 0; i < size / 10; i++) {
    rolls.add(new ArrayList<String>(rollsAll.subList(10*i, 10*(i+1)));
}
// handle last part if size not divisible by 10
if (size % 10 > 0) {
    rolls.add(new ArrayList<String>(rollsAll.subList(10 * (size / 10), size)));
}

Comments

1
List<List<String>> rolls = new ArrayList<List<String>>();
int i=0;
int currentArrayIndex = 0;
List<String> currentArray = null; 
for(String roll:rollsAll){        
    if( (currentArrayIndex = i %10 ) ==0)
    rolls.add(currentArray = new ArrayList());
    currentArray.add(roll); i++;
}

Comments

1

Your approach is ok and other solutions are really good, but you're actually hardcoding the intervals to create the sublists. Instead, a simple counter and a elementsPerList variable could reduce your code to something more versatile:

public List<List<String>> splitList(List<String> original, int elementsPerList) {
    List<List<String>> result = new ArrayList<List<String>>();
    List<String> current = new ArrayList<String>();
    result.add(current);
    for(int i = 0; i < original.size(); i++) {
        if(i < result.size() * elementsPerList) {
            current.add(original.get(0));
        } else {
            current = new ArrayList<String>();
            result.add(current);
            current.add(original.get(0));
        }
    }
    return result;
}

You just need to invoke this method with your current list and 10 as the amount of desired elements per list. Should you ever need to vary the amount of elements to split, you just need to pass the new amount to this method.

Comments

0

Use subList(fromIndex, toIndex)

List oldList = new LinkedList<String>();
// Add your elements in oldList
List newList1 = oldList.subList(0, 5);
List newList2 = oldList.subList(6, 10);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.