简体   繁体   中英

create lists from list in java

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

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

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

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

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

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

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM