版权声明:本文为博主原创文章,未经博主允许不得转载。 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 指定集合容量大小的构造方法