集合框架体系讲解

                                                                集合框架体系讲解

集合的框架体系主要是①:接口 ②:实现类 ③:算法

集合框架体系讲解_第1张图片

1:从图中可以看出Connection是顶层接口,含有Set接口**(无序,不重复)和list接口(有序可以重复)**
①其中Set接口有两个常用的实现类:HashSet实现类(无序的)和TreeSet实现类(有序的),因为TreeSet实现的是Set的一个子接口SortSet接口,这个子接口中有Comparator排序方法; HashSet是无序的,因为hashSet本质上是对hashMap(无序)的操作,里面就是HashMap的构造函数,线程是不安全的。
②List接口有三个常用的实现类:ArrayList(动态数组) ,LinkedList (双向链表),Vector(数组,线程安全)
ArrayList允许任何符合规则的元素插入甚至包括null。每一个ArrayList都有一个初始容量(10)查询快,增删慢 底层数据是数组数据结构。
Linkedlist是一个双向链表,由于实现的方式不同,LinkedList不能随机访问,它所有的操作都是要按照双重链表的需要执行。在列表中索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端)。这样做的好处就是可以通过较低的代价在List中进行插入和删除操作。和ArrayList一样都是非同步的,想要实现访问同步,加关键字synchronized。
Vector的操作和ArrayList几乎一样,但它是同步的,是线程安全的动态数组。
2:Map接口:Map与List、Set接口不同,它是由一系列键值对组成的集合,提供了key到Value的映射。同时它也没有继承Collection。在Map中它保证了key与value之间的一一对应关系。也就是说一个key对应一个value,所以它不能存在相同的key值,当然value值可以相同
①:Map接口常用的实现类为HashMap ,TreeMap ,HashTable;
其中HashMap–>是散列表(哈希表)—>是数组–>每个元素里面是链表, 他是支持null键和null值的,当我们往HashMap中put元素的时候,会先根据它的key值计算出hash值,根据hash值得到这个元素在数组中的位置(即下标),那么这个位置上的元素将以链表的形式存放,新加入的放在链头,后加入的放在链尾,如果数组该位置上没有元素,就直接将该元素放在此数组中的该位置上。(addEntry(hash, key, value, i)方法根据计算出的hash值)
HashTable是线程同步的并且安全的,但是效率没有HashMap高,(可以网上查询一下哈希表的存储过程即可知道);而 HashTable在遇到null时,会抛出NullPointerException异常。这并不是因为HashTable有什么特殊的实现层面的原因导致不能支持null键和null值,这仅仅是因为HashMap在实现时对null做了特殊处理,将null的hashCode值定为了0,从而将其存放在哈希表的第0个bucket中。
②: 可以说map和set是无序的,但是不能说TreeSet和TreeMap是无序的,因为它实现了各自的sortedMap和sortedSet方法,由图可以看出sortedMap是Map的一个子接口。
3:arrayList的扩容机制:
(1)无参构造方法默认长度10;
集合框架体系讲解_第2张图片
(2)通过ensureCapacityInternal()方法判断现有元素的个数和容量进行比较,如果需要扩容则进行扩容。ensureCapacityInternal方法名的英文大致是“确保内部容量”,size表示的是执行添加之前的元素个数,并非ArrayList的容量,容量应该是数组elementData的长度。
集合框架体系讲解_第3张图片
(3)假设 ArrayList stu=new ArrayList<>;那么该集合的初始长度为0,往里面添加一个元素后会变为10;但是如果直接定义该集合的初始长度0,即 ArrayList stu=new ArrayList<>(0);那么在前四次往里面添加数据的时候,该集合的容量会逐渐加1,直到第五次添加数据的时候集合的容量才会按照1.5倍的量进行添加。
(4)查看arraylist容量的方法

public static int getArrayListCapacity(ArrayList arrayList) {
        Class arrayListClass = ArrayList.class;
        try {
            Field field = arrayListClass.getDeclaredField("elementData");
            field.setAccessible(true);
            Object[] objects = (Object[])field.get(arrayList);
           return objects.length;
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
            return -1;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return -1;
        }
    }

(4)当扩容量(newCapacity)大于ArrayList数组定义的最大值后会调用hugeCapacity来进行判断。如果minCapacity已经大于Integer的最大值(溢出为负数)那么抛出OutOfMemoryError(内存溢出)否则的话根据与MAX_ARRAY_SIZE的比较情况确定是返回Integer最大值还是MAX_ARRAY_SIZE。这边也可以看到ArrayList允许的最大容量就是Integer的最大值(-2的31次方~2的31次方减1)。

你可能感兴趣的:(面向对象知识)