Lists

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mingyundezuoan/article/details/81106699

Lists


概述

  • com.google.common.collect

partition()

  • 方法功能:将传入的集合按照指定的大小进行分组
  • 源码分析:
    // partition 实现
    // @param list
    // @param size 指定的分片大小 
    public static <T> List<List<T>> partition(List<T> list, int size) {
        Preconditions.checkNotNull(list);
        Preconditions.checkArgument(size > 0);
        return (List)(list instanceof RandomAccess ? new Lists.RandomAccessPartition(list, size) : new Lists.Partition(list, size));
    }

    // RandomAccessPartition 方法源码,继承 Partition
    private static class RandomAccessPartition<T> extends Lists.Partition<T> implements RandomAccess {
        RandomAccessPartition(List<T> list, int size) {
            super(list, size);
        }
    }

    // Lists 中的 私有静态内部类 Partition 
    // 继承 AbstractList ,而 AbstractList 实现 List ,所以 Partition 的对象可以转为 List 
    private static class Partition<T> extends AbstractList<List<T>> {
        final List<T> list;
        final int size;

        Partition(List<T> list, int size) {
            this.list = list;
            this.size = size;
        }

        public List<T> get(int index) {
            Preconditions.checkElementIndex(index, this.size());
            int start = index * this.size;
            int end = Math.min(start + this.size, this.list.size());
            return this.list.subList(start, end);
        }

        public int size() {
            return IntMath.divide(this.list.size(), this.size, RoundingMode.CEILING);
        }
    }
  • 使用示例
    public static void main(String[] args) {
        Integer [] arr = new Integer[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
        List<Integer> arrList = Arrays.asList(arr);
        List<List<Integer>> partition = Lists.partition(arrList, 4);
        // 1.遍历 Iterator()
        Iterator<List<Integer>> iterator = partition.iterator();
        while(iterator.hasNext()){
            iterator.next();
        }
        // 2.for 循环:实际运行与 Iterator 一致
        for(List<Integer> intl : partition){
            System.out.println(intl.toString());
        }
    }
  • 示例分析
    // 获取迭代器
    Iterator<List<Integer>> iterator = partition.iterator();

    // 源码分析调用 List 中的 iterator() 方法
    // java.util.List
   /**
     * Returns an iterator over the elements in this list in proper sequence.
     *
     * @return an iterator over the elements in this list in proper sequence
     */
    Iterator<E> iterator();

    // java.util.AbstractList implements List 具体实现在 AbstractList 类中
    public Iterator<E> iterator() {
        return new Itr(); // List 中的内部类
    }    

    private class Itr implements Iterator<E> {
        /**
         * Index of element to be returned by subsequent call to next.
         */
        int cursor = 0;

        /**
         * Index of element returned by most recent call to next or
         * previous.  Reset to -1 if this element is deleted by a call
         * to remove.
         */
        int lastRet = -1;

        /**
         * The modCount value that the iterator believes that the backing
         * List should have.  If this expectation is violated, the iterator
         * has detected concurrent modification.
         */
        int expectedModCount = modCount;

        public boolean hasNext() { // 集合中是否有下一个元素
            return cursor != size();
        }

        public E next() { // 获取集合中的下一个元素
            checkForComodification();
            try {
                int i = cursor;
                E next = get(i);
                lastRet = i;
                cursor = i + 1;
                return next;
            } catch (IndexOutOfBoundsException e) {
                checkForComodification();
                throw new NoSuchElementException();
            }
        }
    }

    // 集合中是否有下一个元素,需要调用 size() 方法
    // 获取集合中的下一个元素,需要调用 get(i) 方法
    // 两个方法都是  AbstractList    抽象方法,具体实现由子类完成
    abstract public E get(int index);

    // Lists 类中 Partition 继承 AbstractList 实现具体的方法
    private static class Partition<T> extends AbstractList<List<T>> {
        final List<T> list;
        final int size;

        Partition(List<T> list, int size) {
            this.list = list;
            this.size = size;
        }

        public List<T> get(int index) {
            Preconditions.checkElementIndex(index, this.size());
            int start = index * this.size;
            int end = Math.min(start + this.size, this.list.size());
            return this.list.subList(start, end);
        }

        public int size() {
            return IntMath.divide(this.list.size(), this.size, RoundingMode.CEILING);
        }

        public boolean isEmpty() {
            return this.list.isEmpty();
        }
    } 
- 从源码实现上Partition并没有对List<T>进行分组分片的操作,而是等遍历使用集合的时,通过Iterator 循环时每次调用  Partition 类内部的 size 方法确认分组后的集合的大小,调用 get 方法通过定位每个分组内元素的起始、截止位置调用 subList 进行截取
- for 循环调用等价于 Iterator 调用

newArrayList()

  • 方法功能:实例化,无需关注泛型T
  • 源码分析:
    // 返回调用泛型的数组集合
    public static <E> ArrayList<E> newArrayList() {
        return new ArrayList();
    }
  • 方法缺点:
  • 底层实现实质是调用java.util.ArrayList而没有指定集合的大小,使用时难免会出现扩容,应避免使用,直接调用 java.util.ArrayList 指定集合容量大小的构造方法

猜你喜欢

转载自blog.csdn.net/mingyundezuoan/article/details/81106699