集合源码

源码分析

如何看源码:
脉络 解决什么问题,忽略掉不重要的一些细节
构造 add remove
理解代码运行过程
ArrayList
集合1

1、集合框架--Collection

2、ArrayList 和LinkedList

ArrayList:基于数组实现,查询效率高

LinkedList:基于链表实现,增删效率高

size():长度

add():添加

remove():删除

clear():清空

set():修改

3、泛型

限制类型

不用转型

泛型:<>

4、Collections

shuffle:

Collections.reverse(list);反转集合

Collections.checkedList(dogs,Dog.class):对加入数据的类型进行检查

5、HashSet

hashCode:确定桶的
equals:比较是否同一个对象,决定了这个元素是丢是留

LinkedHashSet是在HashSet的基础上新维护了一个双向链表

6、TreeSet

树:二叉树

两种排序:

       用匿名内部类在构造TreeSet的时候放一个Comparator



      用需要排序的类去实现Comparable

7、迭代器

iterator

Collection extends Iterable;

意味着只要是Collection的儿子都有迭代器

//获取迭代器
Iterator<T> itor = 集合.iterator();
//while
while(itor.hasNext()){
   T t = itor.next();
}
注意:迭代器可以在迭代的同事删除当前元素
    
 反向迭代器   

8、Map

8.1 HashMap<K,V>

  put(k,v);

  remove(key)

 get(key)

 keySet():key的集合----Set

 values():Collection

 entrySet():Set<Entry<K,V>>

 containsKey():是否包含这个键

8.2 Hashtable

    线程安全的,效率低,使用少,键值不能为null

     Properties类:

编写配置文件

8.3 LinkedHashMap

public static void main(String[] args) {
		LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();		
		map.put("CN", "CHINA");
		map.put("US", "AMERICA");
		map.put("RU", "RUSSIA");
		map.put("JP", "JAPAN");
		map.put("FR", "FRANCE");
		map.put("UK", "UNITEDKINGDON");
		System.out.println(map);
}

8.4 TreeMap

public static void main(String[] args) {
		TreeMap<Student, String> map = new TreeMap<Student, String>(new Comparator<Student>() {
			public int compare(Student o1, Student o2) {
				return o1.salary-o2.salary;
			}
		});
		map.put(new Student("中国",50,10), "CHINA");
		map.put(new Student("美国",20,21), "AMERICA");
		map.put(new Student("俄国",30,23), "RUSSIA");
		map.put(new Student("日本",40,34), "JAPAN");
		map.put(new Student("法国",60,34), "FRANCE");
		map.put(new Student("英国",100,66), "UNITEDKINGDON");
		System.out.println(map);
	}

9、源码分析

如何看源码:

     脉络---解决什么问题,忽略掉不重要的一些细节

     构造---》add--->remove

9.1 ArrayList

ArrayList<String> list =new ArrayList<String>(20);//1
ArrayList<String> list =new ArrayList<String>();//3
ArrayList<String> list =new ArrayList<String>(0);//1,2,3,4,6,9,13,19,28//9
list.add("111");
这两种方式定义集合,当集合长度达到20时,分别经历了多少次扩容?
    
public ArrayList() {
      //构造一个无参的对象,就把一个空数组赋给elementData,这个数组实际上就是
      //ArrayList的底层数据存储的地方
      this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;//{};
}  
//私有静态常量对象数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//对象数组的属性
transient Object[] elementData;

//添加方法
public boolean add(E e) {
      ensureCapacityInternal(size + 1);  //private int size;---默认为0
      elementData[size++] = e;
      return true;
}


private void ensureCapacityInternal(int minCapacity) {//1
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));//{}-DEFAULTCAPACITY_EMPTY_ELEMENTDATA,1 ---10
}

private static int calculateCapacity(Object[] elementData, int minCapacity) {
      if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//无参构造第一次满足
            return Math.max(DEFAULT_CAPACITY, minCapacity);
          // private static final int DEFAULT_CAPACITY = 10;
      }
     return minCapacity;
}

private void ensureExplicitCapacity(int minCapacity) {//10 
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);//扩容-10
}

 private void grow(int minCapacity) {//10--1
        // overflow-conscious code
        int oldCapacity = elementData.length;//0
        int newCapacity = oldCapacity + (oldCapacity >> 1);//0
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;//10
        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);//扩容
 }

以上是无参构造的执行过程

 public ArrayList(int initialCapacity) {//20
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
}

//modCount--模数    魔数    魔术
这个变量记录的是集合操作的次数---增删


//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;
}

//get    

1、ArrayList在无参构造的时候,设置对象数组为空

2、如果是无参构造出来的空集合,一开始长度为0,第一次执行添加操作的时候,会扩容到10

3、以后ArrayList满了的时候就会按照1.5倍进行扩容

4、如果构造的是带参的,那么直接扩容到参数指定的个数,特例如果参数为0,就从0开始扩容

源码解决ArrayList不可修改的问题

Arrays类里有一个ArrayList的内部类,这个类没有实现add,remove方法发,而是直接抛异常

String[] strs = {"aaa","bbb","ddd"};
List list = Arrays.asList(strs);

这样得到的list集合只能读写,不能增删

9.2 LinkedList

无参构造:
public LinkedList() {
}

public boolean add(E e) {
        linkLast(e);//后面添加元素
        return true;
}
//链表的节点
private static class Node<E> {
        E item;//数据---“aaa”
        Node<E> next;//后继
        Node<E> prev;//前驱

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
}
//添加元素
void linkLast(E e) {
        final Node<E> l = last;//先把最后一个节点缓存起来
        //这个节点是要添加的节点,前驱是上次最后的节点,后继为空
        final Node<E> newNode = new Node<>(l, e, null);
        //成员变量last保存当前要添加的节点为最后节点
        last = newNode;
        if (l == null)
            //第一个节点,first=last=newNode
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
}

//删除指定元素
public boolean remove(Object o) {
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
posted @ 2022-07-15 20:32  yishizhengbianren  阅读(146)  评论(0)    收藏  举报