Collection学习(一)
2016-12-23 13:59
288 查看
一、概述
Collection位于java.util包下。此接口继承Iterable接口。package java.lang; import java.util.Iterator; /** * * @since 1.5 */ public interface Iterable<T> { /** * Returns an iterator over a set of elements of type T. * * @return an Iterator. */ Iterator<T> iterator(); }
public interface Collection<E> extends Iterable<E> { // Query Operations int size(); boolean isEmpty(); boolean contains(Object o); Iterator<E> iterator(); Object[] toArray(); <T> T[] toArray(T[] a); boolean add(E e); boolean remove(Object o); boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); boolean removeAll(Collection<?> c); boolean retainAll(Collection<?> c); void clear(); boolean equals(Object o); int hashCode(); }
Collection下面的所有实现:
下面主要说明List和Set
List图解
ArrayList的源码分析:
1.底层使用数组
/**
/** * Default initial capacity. */ private static final int DEFAULT_CAPACITY = 10;
* Shared empty array instance used for empty instances. */ private static final Object[] EMPTY_ELEMENTDATA = {}; /** * The array buffer into which the elements of the ArrayList are stored. * The capacity of the ArrayList is the length of this array buffer. Any * empty ArrayList with elementData == EMPTY_ELEMENTDATA will be expanded to * DEFAULT_CAPACITY when the first element is added. */ private transient Object[] elementData;
2.构造方法
public ArrayList() { super(); this.elementData = EMPTY_ELEMENTDATA; }
public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; }
public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); size = elementData.length; // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); }
3.存储方式
ArrayList提供了set(int index, E element)、add(E e)、add(int index, E element)、addAll(Collection<? extends E> c)、addAll(int index,Collection<extends E> c)
set方法:用指定的元素替代此列表中指定位置上的元素,并返回以前位于该位置上的元素。 public E set(int index, E element) { rangeCheck(index); E oldValue = elementData(index); elementData[index] = element; return oldValue; } /** * Checks if the given index is in range. If not, throws an appropriate * runtime exception. This method does *not* check if the index is * negative: It is always used immediately prior to an array access, * which throws an ArrayIndexOutOfBoundsException if index is negative. */ private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }
add方法: //将指定的元素添加到列表的尾部 public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } // 将指定的元素插入此列表中的指定位置。 // 如果当前位置有元素,则向右移动当前位于该位置的元素以及所有后续元素(将其索引加1)。 public void add(int index, E element) { rangeCheckForAdd(index); ensureCapacityInternal(size + 1); // Increments modCount!! // 将 elementData中从Index位置开始、长度为size-index的元素, // 拷贝到从下标为index+1位置开始的新的elementData数组中。 // 即将当前位于该位置的元素以及所有后续元素右移一个位置。 System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; } /** * A version of rangeCheck used by add and addAll. */ private void rangeCheckForAdd(int index) { if (index > size || index < 0) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }
addAll方法: //按照指定collection的迭代器所返回的元素顺序,将该collection中的所有元素添加到此列表的尾部。 public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size + numNew); // Increments modCount System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; } //从指定的位置将指定集合中的所有元素插入此列表。 //变化的元素位置和任何后续元素向右移动(增加他们的指标)。 //新元素的顺序将出现在列表中,指定返回的集合的迭代器。 public boolean addAll(int index, Collection<? extends E> c){ rangeCheckForAdd(index); Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size + numNew); // Increments modCount int numMoved = size - index; if (numMoved > 0) System.arraycopy(elementData, index, elementData, index + numNew, numMoved); System.arraycopy(a, 0, elementData, index, numNew); size += numNew; return numNew != 0; }
remove方法: //通过角标移除元素 public E remove(int index) { rangeCheck(index); //判断角标是否越界 modCount++; E oldValue = elementData(index); int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work return oldValue; } private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } //如果list中存在该元素,就删除该元素。如果列表不包含该元素,list是不变的。 public boolean remove(Object o) { if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); return true; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; } /* * Private remove method that skips bounds checking and does not * return the value removed. */ private void fastRemove(int index) { modCount++; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work }
get方法:获取指定位置的元素 public E get(int index) { rangeCheck(index); return elementData(index); }
/** * Increases the capacity to ensure that it can hold at least the * number of elements specified by the minimum capacity argument. * * @param minCapacity the desired minimum capacity * 数组的扩容 */ private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; //右移一位,等于oldCapacity/2,由此看出新数组最少是原来的1.5倍 int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); }
相关文章推荐
- 通过uri去拿到bitmap
- Java服务端程序简化
- ORACLE 单一分区在频率直方图下的筛选最大边界值时的基数
- 关于SOA之问与答 基础篇
- cocoapods:常见错误总结
- 浅谈Flexbox布局
- ios https 请求
- Centos中设置静态ip
- 【转】史上最全最强SpringMVC详细示例实战教程
- poj1002
- Http协议:彻底弄懂 Http 缓存机制 - 基于缓存策略三要素分解法
- gcc和gdb的使用
- 使用FFMPEG和FFSERVER来搭建流媒体服务器
- hybird apk打包出现的问题
- Mapping - Field datatypes
- 字符串、数值型与字节之间的转换
- 汇编语言编译器发展简史
- 【java】String s = new String("xyz")创建了几个对象
- opencv不能读取MP4格式文件
- js省市二级联动