Java: split a List into two sub-Lists?

后端 未结 14 1516
执笔经年
执笔经年 2020-12-08 02:29

What\'s the simplest, most standard, and/or most efficient way to split a List into two sub-Lists in Java? It\'s OK to mutate the original List, so no copying should be nece

相关标签:
14条回答
  • 2020-12-08 02:58
    import java.util.Collection;
    
    public class CollectionUtils {
    
      /**
       * Will split the passed collection so that the size of the new collections
       * is not greater than maxSize
       * @param t
       * @param maxSize
       * @return a List containing splitted collections
       */
    
      @SuppressWarnings("unchecked")
      public static <T> List<Collection<T>>split(Collection<T> t, int maxSize) {
        int counter = 0;
        List<Collection<T>> ret = new LinkedList<Collection<T>>();
        Iterator<T>itr = t.iterator();
        try {
          Collection<T> tmp = t.getClass().newInstance();
          ret.add(tmp);
          while(itr.hasNext()) {
            tmp.add(itr.next());
            counter++;
            if(counter>=maxSize && itr.hasNext()) {
              tmp = t.getClass().newInstance();
              ret.add(tmp);
              counter=0;
            }
          }
        } catch(Throwable e) {
          Logger.getLogger(CollectionUtils.class).error("There was an error spliting "+t.getClass(),e);
        }
        return ret;
      }
    
    }
    
    // JUnit test cases
    
    import java.util.ArrayList;
    
    /**
     *
     * $Change$
     * @version $Revision$
     * Last modified date & time $DateTime$
     */
    public class CollectionUtilsTest {
    
      @Test
      public void testSplitList() {
        List<Integer>test = new ArrayList<Integer>(100);
        for (int i=1;i<101;i++) {
          test.add(i);
        }
        List<Collection<Integer>> tests = CollectionUtils.split(test, 10);
        Assert.assertEquals("Size mismatch", 10,tests.size());
    
        TreeSet<Integer> tmp = new TreeSet<Integer>();
        for(Collection<Integer> cs:tests) {
          for(Integer i:cs) {
            Assert.assertFalse("Duplicated item found "+i,tmp.contains(i));
            tmp.add(i);
          }
          System.out.println(cs);
        }
        int why = 1;
        for(Integer i:tmp) {
          Assert.assertEquals("Not all items are in the collection ",why,i.intValue());
          why++;
        }
      }
      @Test
      public void testSplitSet() {
        TreeSet<Integer>test = new TreeSet<Integer>();
        for (int i=1;i<112;i++) {
          test.add(i);
        }
        List<Collection<Integer>> tests = CollectionUtils.split(test, 10);
        Assert.assertEquals("Size mismatch", 12,tests.size());
    
        TreeSet<Integer> tmp = new TreeSet<Integer>();
        int cI = 0;
        for(Collection<Integer> cs:tests) {
          for(Integer i:cs) {
            Assert.assertFalse("Duplicated item found "+i,tmp.contains(i));
            tmp.add(i);
          }
    //      if(cI>10) {
            System.out.println(cs);
    //      }
          cI++;
        }
        int why = 1;
        for(Integer i:tmp) {
    
          Assert.assertEquals("Not all items are in the collection ",why,i.intValue());
          why++;
        }
      }
    }
    
    0 讨论(0)
  • 2020-12-08 03:04

    Riffing on Marc's solution, this solution uses a for loop that saves some calls to list.size():

    <T> List<T> split(List<T> list, int i) {
        List<T> x = new ArrayList<T>(list.subList(i, list.size()));
        // Remove items from end of original list
        for (int j=list.size()-1; j>i; --j)
            list.remove(j);
        return x;
    }
    
    0 讨论(0)
  • 2020-12-08 03:04

    I use the "Apache Commons Collections 4" library. It has a partition method in the ListUtils class:

    ...
    int targetSize = 100;
    List<Integer> largeList = ...
    List<List<Integer>> output = ListUtils.partition(largeList, targetSize);
    

    This method is adapted from http://code.google.com/p/guava-libraries/

    0 讨论(0)
  • 2020-12-08 03:04
    //Here is my list
        ArrayList<T> items=new ArrayList<T>();
        Integer startIndex = 0;
                int j = 0;
                for (; j < items.size() - 1; j++) {//always start with next index not again 0
                    for (int i = 0; i < 4; i++) { // divide into equal part with 4 item
                        startIndex = startIndex + 1;
                        j = startIndex;
                    }
                }
    
    0 讨论(0)
  • 2020-12-08 03:10

    Getting the returned array is pretty easy using the subList method, but there's no easy way that I know of to remove a range of items from a List.

    Here's what I have:

    <T> List<T> split(List<T> list, int i) {
        List<T> x = new ArrayList<T>(list.subList(i, list.size()));
        // Remove items from end of original list
        while (list.size() > i) {
            list.remove(list.size() - 1);
        }
        return x;
    }
    
    0 讨论(0)
  • 2020-12-08 03:10
    <T> List<T> split(List<T> list, int i) {
       List<T> secondPart = list.sublist(i, list.size());
       List<T> returnValue = new ArrayList<T>(secondPart());
       secondPart.clear(),
       return returnValue;
    }
    
    0 讨论(0)
提交回复
热议问题