您的位置:首页 > 编程语言 > Java开发

JDK源码——java.util

2016-11-29 10:14 190 查看
看了Collection与AbstractCollection

先说说AbstractCollection虚类,里面大部分方法都很简单没什么好说的,说个我最重要的收获:数组每次扩容时,增加的容量为当前容量的二分之一,代码如下



扩展一点>>、<<这两者都是位移操作意思是先把当前值转成二进制然后向右或向左移动位,举个例子 3 >> 1 = 1;左移一位相当于在二进制上乘10,二进制的10等于十进制2,因此左移一位相当于乘2,但效率更高;同理左移两位相当于乘4,左移三位相当于乘8

再说一个Collection与Collections的区别

Collection:是所有集合类的父接口

Collections:是集合类的一个工具类,提供各种集合操作方法.

首先说个简单的ArrayList这个是最常用的线性表,没什么可说的,我写了个小demo用来说下需要注意的地方

public class TestArrayList {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList(10);
Object o = new Object();
arrayList.add(new Object());
arrayList.add(new Object());
arrayList.add(new Object());
arrayList.add(o);
System.out.println(arrayList.size());
arrayList.trimToSize();//没看到效果
System.out.println(arrayList.size());
arrayList.ensureCapacity(20);//没看到效果
System.out.println(arrayList.size());
System.out.println(arrayList.contains(o));
ArrayList list = (ArrayList) arrayList.clone();//重新创建了一个对象,深复制
System.out.println(list.size());
arrayList.add(new Object());
System.out.println(arrayList.size());
System.out.println(list.size());
arrayList.add(5,new Object());//如果不连续,比如index=6就会报错,所以不如用add
for (Object o1 : arrayList) {
System.out.println(o1);
}
//        for (int i = 0; i < arrayList.size(); i++) {
//            arrayList.remove(2);//在for循环中删除可能得到错误的结果,因此最好使用iterator做删除
//        }
//        System.out.println(arrayList.size());
//        for (Object o1 : arrayList) {
//            System.out.println(o1);
//        }

List list1 = arrayList.subList(1, 3);
for (Object o1 : list1) {
System.out.println(o1);
}
arrayList.add(new Object());//对原表的修改,会导致子表遍历、增加、删除均报异常
for (Object o1 : list1) {
System.out.println(o1);
}
}
}


Arrays,数组的工具类,提供一系列操作数组的方法,其中另我比较差异的是,里面的很多方法除了数组类型不一样,代码都是一样的,后来一想这大概是应为数组不支持泛型所致,于是搜索了一下为什么数组不支持泛型,其实也没有看特别明白,大概意思是因为泛型在编译时会进行类型擦除,可能会引发异常

HashMap

这个是用的最多的map集合,其结构是个数组加链表的结构,数组的每个index上都是一个链表;其中数组是用来存储key放在哪个位置的,具体算法是先获取key的hash值,然后通过hash值对数组的size进行取模,即可获得key存放的位置;这样肯定会有多个key用都在同一个index上,相同index上的值就组成一个链表

其有两个关键的属性初始容量(数组长度)、加载因子(链表长度)

咱们看几个比较关键的方法

先看put方法



看看addEntry方法



这个方法很简单呢没什么说的,继续看createEntry方法



这里能看到是创建了一个Entry对象,让后把这个对象放到table[i]的位置,这个Entry的next指向原来table[i]的值;因此能知道新插入的对象其实是在链表的最前端

remove()方法也很简单,这里我就不列出来了,咱们一起来看看resize()方法,也就是当链表过长,效率不高时,需要使数组变长来重新计算位置使链表变短,效率变高



这里看看transfer这个方法



原来总觉得hashmap的结构理解不了,现在想来自己是真的成长了不少

HashSet

HashSet的内部实现其实就是一个HashMap





在新增元素时,就是往hashMap中插入一个key为传入元素,value为new Object的过程

HashTable

一个通过在方法前加synchronized来达到线程安全目的的Map,但这样效率比较低



其他基本与HashMap一致

IdentifyHashMap

key可重复的Map。一般的map如HashMap在比较key是否相等时使用如下办法



即使用equals判断,而IdentifyHashMap则使用==



因此key可以存在重复;其他均与HashMap类似

Vector

线程安全的List,通过在方法前用synchorized实现

这里面挑重点看了这些类,其它的浏览了一下,如果以后有空再详细研究那再补上,不过估计是没机会了(逃
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: