
创建ArrayList
| List<String> list = new ArrayList<>(); |
调用无参构造方法,创建一个初始容量为10的空列表
| private static final int DEFAULT_CAPACITY = 10; |
| |
| private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; |
| |
| public ArrayList() { |
| this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; |
| } |
- 指定初始大小,避免在添加新的元素时进行不必要的扩容
| List<String> list = new ArrayList<>(20); |
添加元素
| public boolean add(E e) { |
| |
| ensureCapacityInternal(size + 1); |
| |
| elementData[size++] = e; |
| return true; |
| } |
| |
| private void ensureCapacityInternal(int minCapacity) { |
| |
| ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); |
| } |
| |
| private static final int DEFAULT_CAPACITY = 10; |
| |
| private static int calculateCapacity(Object[] elementData, int minCapacity) { |
| if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { |
| |
| return Math.max(DEFAULT_CAPACITY, minCapacity); |
| } |
| return minCapacity; |
| } |
| |
| private void ensureExplicitCapacity(int minCapacity) { |
| modCount++; |
| |
| |
| |
| if (minCapacity - elementData.length > 0) |
| grow(minCapacity); |
| } |
| private void grow(int minCapacity) { |
| |
| |
| int oldCapacity = elementData.length; |
| |
| int newCapacity = oldCapacity + (oldCapacity >> 1); |
| |
| if (newCapacity - minCapacity < 0) |
| newCapacity = minCapacity; |
| |
| if (newCapacity - MAX_ARRAY_SIZE > 0) |
| newCapacity = hugeCapacity(minCapacity); |
| |
| |
| elementData = Arrays.copyOf(elementData, newCapacity); |
| } |
| |
| private static int hugeCapacity(int minCapacity) { |
| if (minCapacity < 0) |
| throw new OutOfMemoryError(); |
| return (minCapacity > MAX_ARRAY_SIZE) ? |
| Integer.MAX_VALUE : |
| MAX_ARRAY_SIZE; |
| } |
- ArrayList在第一次执行add后会扩容为10,在添加第11个元素的时候会第二次扩容
向指定位置添加元素
| public void add(int index, E element) { |
| |
| rangeCheckForAdd(index); |
| |
| |
| ensureCapacityInternal(size + 1); |
| |
| System.arraycopy(elementData, index, elementData, index + 1, |
| size - index); |
| |
| elementData[index] = element; |
| |
| size++; |
| } |
| |
| private void rangeCheckForAdd(int index) { |
| if (index > size || index < 0) |
| throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); |
| } |
更新元素
| public E set(int index, E element) { |
| |
| rangeCheck(index); |
| |
| E oldValue = elementData(index); |
| elementData[index] = element; |
| return oldValue; |
| } |
删除元素
| 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; |
| |
| return oldValue; |
| } |
| 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 void fastRemove(int index) { |
| modCount++; |
| |
| int numMoved = size - index - 1; |
| if (numMoved > 0) |
| System.arraycopy(elementData, index+1, elementData, index, |
| numMoved); |
| |
| elementData[--size] = null; |
| } |
查找元素
| list.indexOf("haha"); |
| list.lastIndexOf("haha"); |
| public int indexOf(Object o) { |
| if (o == null) { |
| for (int i = 0; i < size; i++) |
| if (elementData[i]==null) |
| return i; |
| } else { |
| for (int i = 0; i < size; i++) |
| if (o.equals(elementData[i])) |
| return i; |
| } |
| return -1; |
| } |
| public int lastIndexOf(Object o) { |
| if (o == null) { |
| for (int i = size-1; i >= 0; i--) |
| if (elementData[i]==null) |
| return i; |
| } else { |
| for (int i = size-1; i >= 0; i--) |
| if (o.equals(elementData[i])) |
| return i; |
| } |
| return -1; |
| } |
| |
| public boolean contains(Object o) { |
| return indexOf(o) >= 0; |
| } |
二分查找
| public static void main(String[] args) { |
| List<String> list = new ArrayList<>(); |
| list.add("c"); |
| list.add("e"); |
| list.add("d"); |
| |
| |
| Collections.sort(list); |
| |
| System.out.println(list); |
| |
| System.out.println(Collections.binarySearch(list, "e")); |
| } |
时间复杂度
操作 |
最好 |
最坏 |
查询 |
O(1) |
O(1) |
插入 |
O(1) |
O(n)需要将插入位置之后的元素全部向后移动一位 |
删除 |
O(1) |
O(n)需要将删除位置之后的元素全部向前移动一位 |
修改 |
O(1) |
O(1) |
拷贝
| |
| |
| |
| |
| public Object clone() { |
| try { |
| |
| ArrayList<?> v = (ArrayList<?>) super.clone(); |
| |
| v.elementData = Arrays.copyOf(elementData, size); |
| v.modCount = 0; |
| return v; |
| } catch (CloneNotSupportedException e) { |
| |
| throw new InternalError(e); |
| } |
| } |
序列化
- 使用了 ArrayList 的实际大小 size 而不是数组的长度(
elementData.length
)来作为元素的上限进行序列化
| private void writeObject(java.io.ObjectOutputStream s) |
| throws java.io.IOException{ |
| |
| int expectedModCount = modCount; |
| |
| s.defaultWriteObject(); |
| |
| |
| |
| s.writeInt(size); |
| |
| |
| for (int i=0; i<size; i++) { |
| |
| s.writeObject(elementData[i]); |
| } |
| |
| if (modCount != expectedModCount) { |
| throw new ConcurrentModificationException(); |
| } |
| } |
| private void readObject(java.io.ObjectInputStream s) |
| throws java.io.IOException, ClassNotFoundException { |
| elementData = EMPTY_ELEMENTDATA; |
| |
| |
| |
| s.defaultReadObject(); |
| |
| |
| |
| s.readInt(); |
| |
| if (size > 0) { |
| |
| |
| int capacity = calculateCapacity(elementData, size); |
| SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, capacity); |
| ensureCapacityInternal(size); |
| |
| Object[] a = elementData; |
| |
| |
| for (int i=0; i<size; i++) { |
| |
| a[i] = s.readObject(); |
| } |
| } |
| } |
本文作者:n1ce2cv
本文链接:https://www.cnblogs.com/sprinining/p/18300956
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步