2021.2.3随笔

2021.2.3随笔

// 底层结构 --> 扩容机制/初始容量 --> null,重复,有序 --> 线程安全 --> 横向对比

(记住这个顺序,要有逻辑的描述出来)

逻辑:线性表/树/图/集合
物理:数组/链表
数组:初始容量/扩容

ArrayList 的特点(重点)

ArrayList 是 List 的一个具体实现类( List 是 Collection 的线性表子接口)
ArrayList 是 List 的一个数组实现( ArrayList 里面必定维护了一个数组)
ArrayList 允许重复,允许 null ,有序( List:线性表:除了头尾元素之外,这个序列每个元素都有唯一的前驱和后继 --> 有序 --> 有下标)
ArrayList 线程不安全

扩容机制:扩为原来的 1.5 倍
默认的数组的初始容量是 10

注意:默认的构造方法,并不能直接给我们创建一个长度为 10 的数字
ArrayList源码分析1
 ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("zs");

class ArrayList<E> {
    
    // ArrayList底层所维护的数组
    transient Object[] elementData;
    
    // 空数组
      private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    
     // 记录这个容器存储多少个元素
    // size = 0
    int size;
    
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    
    
    public boolean add(E e) {
        // 参数检查/扩容
        // 1; 一般在初始情况, 创建默认为10的数组
        // 2; 如果数组满了, 扩容
        ensureCapacityInternal(size + 1);  
        
        // 初始情况下, 必定创建一个长度为10的数组
        
        
        elementData[size] = e;
        size++;
        
        return true;
    }
    
    private static final int DEFAULT_CAPACITY = 10;
    
    // minCapacity = 1
     private void ensureCapacityInternal(int minCapacity) {
         
         // elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA: 真
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            
            //                            10               1
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
            // minCapacity = 10
        }

         //                     minCapacity = 10
        ensureExplicitCapacity(minCapacity);
    }
    
    //  minCapacity = 10
    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;// 记录这个对象(ArrayList)被修改的次数

        // 10    -         0  > 0 真
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);// 扩容方法
    }
    
        private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    
   //  minCapacity = 10
    private void grow(int minCapacity) {
        // oldCapacity = 0 // 空数组的长度 --->旧长度 0
        int oldCapacity = elementData.length;
        // newCapacity = 1.5 oldCapacity  ---> 扩容机制: 扩为原来的1.5倍
        // newCapacity = 0
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        
        //  0   - 10 < 0  真
        if (newCapacity - minCapacity < 0)
            // newCapacity = 10
            newCapacity = minCapacity;
        
        //  10 -  假
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        
        
        // Arrays.copyOf 复制方法 ; 复制的来源elementData, 复制多长newCapacity 10 
        // 产生了一个长度为10的数组, 赋值给elementData
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

    
}
ArrayLisi 源码分析2
public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {
        // 如果给定长度大于0,那么直接创建一个数组
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}
ArrayList<String> list = new ArrayList<>();
// ArrayList(Collection<? extends E> c)

// 要求 当作参数传进来的集合类里面存储的参数类型
// 应该是,当前集合类对象存储参数类型的相同或者子类
ArrayList<Object> list1 = new ArrayList<>(list);
public ArrayList(Collection<? extends E> c) {
    // c.toArray();// 把c这个Collection集合类转化为数组
    // 用这个经过转化的数组,来充当,此时创建对象的底层数组
    elementData = c.toArray();
    
    // size = elementData.length // 同步集合类存储数据的个数
    
    if ((size = elementData.length) != 0) {
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        // 如果 c.toArray();返回的不是一个Object类型的数组,那么就转化为一个 Object 类型的数组。
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    } else {
        // replace with empty array.
        // 置空
        this.elementData = EMPTY_ELEMENTDATA;
    }
}
public void ensureCapacity(int minCapacity) {
    
    //				100
    int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
        // any size if not default element table
        ? 0
        // larger than default for default empty table. It's already
        // supposed to be at default size.
        : DEFAULT_CAPACITY;
	
    // 100 > 0 ?
    if (minCapacity > minExpand) {
        ensureExplicitCapacity(minCapacity);
    }
}
//									100
private void ensureExplicitCapacity(int minCapacity) {
        modCount++;
		
        // overflow-conscious code
    //		100 -          10 > 0 真
        if (minCapacity - elementData.length > 0)
            // 扩容(100)
            grow(minCapacity);
    }



private void grow(int minCapacity) {
        // oldCapaCity = 10
        int oldCapacity = elementData.length;
    	// oldCapaCity = 15
        int newCapacity = oldCapacity + (oldCapacity >> 1);
    	// 15 - 100 < 0
        if (newCapacity - minCapacity < 0)
            //newCapaCity = 100
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // 
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
API
 boolean add(E e) 
          将指定的元素添加到此列表的尾部。 
 void add(int index, E element) 
          将指定的元素插入此列表中的指定位置。 
 boolean addAll(Collection<? extends E> c) 
          按照指定 collection 的迭代器所返回的元素顺序,将该 collection 中的所有元素添加到此列表的尾部。 
 boolean addAll(int index, Collection<? extends E> c) 
          从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。 
 void clear() 
          移除此列表中的所有元素。 
 boolean contains(Object o) 
          如果此列表中包含指定的元素,则返回 trueint indexOf(Object o) 
          返回此列表中首次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1boolean isEmpty() 
          如果此列表中没有元素,则返回 true 
 int lastIndexOf(Object o) 
          返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含索引,则返回 -1。 
 E remove(int index) 
          移除此列表中指定位置上的元素。 
 boolean remove(Object o) 
          移除此列表中首次出现的指定元素(如果存在)。 
protected  void removeRange(int fromIndex, int toIndex) 
          移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。 

 int size() 
          返回此列表中的元素数。 
 Object[] toArray() 
          按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组。 
<T> T[] 
 toArray(T[] a) 
          按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。 
// 浅拷贝 
Object clone() 
          返回此 ArrayList 实例的浅表副本。 
     
 E get(int index) 
          返回此列表中指定位置上的元素。 
  E set(int index, E element) 
          用指定的元素替代此列表中指定位置上的元素。 

// 手动控制容量 >= 给定minCapacity  //没啥用
 void ensureCapacity(int minCapacity) 
          如有必要,增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数。 
    
    
// 就是把底层数组的长度,调整为size长度。
void trimToSize()
	将此 ArrayList 实例的容量调整为列表的当前大小。  

iterator()
listiterator()
    
ArrayList 源码分析3
ArrayList<String> list = new ArrayList<>();
list.add("zs");
list.add("ls");
list.add("ww");
list.add("zl");

// 0 1 2 3
// zs ls wu zl

Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}
public Iterator<E> iterator() {
    return new Itr();
}

//				zs			ls			wu			zl
//lastRet	cursor
//				i
private class Itr implements Iterator<E> {
        int cursor;       // 初始值 0 : 指向下一个要遍历的位置
        int lastRet = -1; // 初始值 -1 :上一次遍历的元素
    
    
    // modCount 源集合类对象的修改次数
    // 把迭代器的expectedModeCount 和源集合类同步
        int expectedModCount = modCount; 

        Itr() {}

        public boolean hasNext() {
            return cursor != size;
        }

    
    
        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }
		
    // 删除:上一次刚遍历过的元素
    // 未遍历之前不能删除
    // 不能连续删除
    
        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                
                // 相当于调用源集合类的删除方法,删除下标为lastRet位置的元素
                ArrayList.this.remove(lastRet);
                // cursor前移
                cursor = lastRet;
                lastRet = -1;
                
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

    
    
        @Override
        @SuppressWarnings("unchecked")
        public void forEachRemaining(Consumer<? super E> consumer) {
            Objects.requireNonNull(consumer);
            final int size = ArrayList.this.size;
            int i = cursor;
            if (i >= size) {
                return;
            }
            final Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length) {
                throw new ConcurrentModificationException();
            }
            while (i != size && modCount == expectedModCount) {
                consumer.accept((E) elementData[i++]);
            }
            // update once at end of iteration to reduce heap write traffic
            cursor = i;
            lastRet = i - 1;
            checkForComodification();
        }

        final void checkForComodification() {
            // 检查迭代器记录的修改次数和源集合类修改次数是否还一样
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }
ArrayList源码分析4
public ListIterator<E> listIterator() {
    return new ListItr(0);
}
// zs ls ww wl

private class ListItr extends Itr implements ListIterator<E> {
        int cursor;       // 标记要遍历的元素
        int lastRet = -1; // 上一个遍历的元素
        int expectedModCount = modCount;// 同步修改次数
    
    
    	ListItr(int index) {
            super();
            cursor = index;
        }

        public boolean hasPrevious() {
            return cursor != 0;
        }

        public int nextIndex() {
            return cursor;
        }

        public int previousIndex() {
            return cursor - 1;
        }
		
    
    	// 向前遍历
        @SuppressWarnings("unchecked")
        public E previous() {
            checkForComodification();// 检查并发修改异常
            int i = cursor - 1;
            if (i < 0)
                throw new NoSuchElementException();
            
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            // cursor 前移
            cursor = i;
            return (E) elementData[lastRet = i];
        }
		
        // 修改  : 修改的是刚刚遍历过的“位置” --> 可以连续修改,没遍历之前是不可以修改的
        public void set(E e) {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                // 直接调用源集合类的修改方面,并且把需要修改的位置,传递过去
                ArrayList.this.set(lastRet, e);
                // 修改不需要同步modCount
                
                
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
		
    
    // 添加的位置,光标所在的位置
    // 添加元素之后,可以删除吗?不可以,因为lastRet=-1。
    // 添加元素之后,可以修改吗?不可以,
    // 可以添加吗?可以
        public void add(E e) {
            checkForComodification();

            try {
                int i = cursor;
                ArrayList.this.add(i, e);
                cursor = i + 1;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
    
    
    
    	Itr() {}

        public boolean hasNext() {
            return cursor != size;
        }
    	public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
    }

ArrayList 源码分析5
   ArrayList<String> list = new ArrayList<>();
        list.add("zs");
        list.add("ls");
        list.add("ww");
        list.add("zl");

        System.out.println(list);
public String toString() {
    // 相当于
        Iterator<E> it = iterator();
        if (! it.hasNext())
            return "[]";

        StringBuilder sb = new StringBuilder();
        sb.append('[');
        for (;;) {
            E e = it.next();
            // 遍历到没有元素,null是有元素的
            sb.append(e == this ? "(this Collection)" : e);
            if (! it.hasNext())
                return sb.append(']').toString();
            sb.append(',').append(' ');
        }
    }

补充:

ArrayList 的 toString 方法,是继承来的,里面实现的逻辑实际上是一个iterrator迭代

Vector 概述

Vector:向量,矢量:有大小有方向

底层结构是数组

默认初始容量(10),扩容机制(默认机制扩为原来的2倍)

Null,重复,有序

线程安全

扩容:“增量”,我们可以控制 Vector 每次扩容的大小

Vector 源码分析1

Vector<String> vector = new Vector<>();

vector.add("zs");
elementData // 集合类数组

public Vector() {
    this(10);
}

public Vector(int initialCapacity) {
        this(initialCapacity, 0);
}

public Vector(int initialCapacity, int capacityIncrement) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
        this.capacityIncrement = capacityIncrement;
}

private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

​ 总结:摸鱼的一天,LeeCode每日都没刷过去,今天就干了一件事,复制粘贴源码。。希望大家别学我

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值