Set接口继承Collection并且和其中的方法保持一致。
特点:1.无序、不可重复;无序指set中元素没有索引只能遍历查找;不可重复指不允许加入重复的元素。【新元素若和set中某一元素通过equals()方法比较为true,则不能加入,并且set中只能放一个null不能多个】
1.HashSet()底层实现:
(1)HashSet是采用哈希算法实现,底层实际用HashMap实现(本质是一个简化版的HashMap),因此查询效率和增删效率比较高。
(2)HashSet(value):其中的value值就相当于HashMap中的key值,因为key不能重复所以set中值不能重复,而其中的HashMap中的value是一个固定值(常数)。
(3)每次创建HashSet对象时就是来创建HashMap对象,因此HashSet的底层比较简单完全是调用HashMap的方法类来实现的。
List接口:
List是有序、可重复的容器。
有序:List中国每一个元素都有索引标记。可以根据元素的索引标记(在List中的位置)访问元素,从而精确控制这些元素。
可重复:List允许加入重复的元素。确切讲是List通常允许满足e1.equals(e2)的元素重复加入容器。
List接口常用实现类:ArrayList、LinkedList
ArrayList<E>等三种方法的——索引和顺序:
ArrayList<E>【底层是一个数组实现的,线程不安全】:
方法:1.void add(E element);往集合中添加一个元素。
2.void add(int index,E element);往指定索引处添加一个元素【后边元素自动往后移】
3.void set(int index,E element);替换指定索引处的元素。
4.boolean remove(int index);移除指定索引处的元素。
6.E get(int index);返回指定索引处的元素。
5.int indexOf(Object o);返回从0开始查找第一个出现的元素索引下标。【没有返回-1】
7.int lastIndexOf(Object o);返回从最后开始查找第一个出现的元素索引下标。【没有返回-1】
ArrayList底层实现:
ArrayList底层是用数组实现的存储。特点:查询效率高,增删效率低,线程不安全。
数组长度是有限的,而ArrayList是可以存放任意数量的对象,长度不受限制,是怎么实现的?
原理:进行数组的扩容,默认定义一个指定长度的为10的数组,然后以旧的数组长度右移一位(10/2)的大小进行扩容【newlength =oldlength+oldlength>>1】,在进行数组元素添加(add(E element))的时候先进行数组长度的判断,然后决定是否需要扩容,不需要直接添加,需要时先扩容再添加
LinkedList<E>【底层是一个链表实现的】:
LinkedList底层实现:
LinkedList底层用双向链表实现的存储,特点:查询效率低,增删效率高,线程不安全。
双向链表也叫双链表,是链表的一种,它的每一个数据节点都有两个指针,分别指向前一个节点和后一个节点。所以从双向链表中的任意一个节点开始,都可以很方便地找到所有节点。删除:只要将删除元素的前一个元素的后一个节点指向后一个元素的前一个节点,那么就删除了。
插入:只要将插入位置的前一个元素的后一个节点指向插入元素的前一个节点,插入元素的后一个节点指向后一个元素的前一个节点。
建议:如何使用ArrayList、LinkedList、Vector?
1.需要线程安全时用Vector。
2.不存在线程安全问题时,并且查找较多用ArrayList(一般使用它)
3.不存在线程安全问题时,增加或删除元素较多用LinkedList
Map接口:
是一种成对存储的关系。Map就是用来存储"键(key)-值(value)对"的。Map类中存储的"键值对"通过键来做标识,所以"键对象"不能重复。
Map接口的实现类有HashMap、TreeMap、HashTable、Properties等。
常用方法:1.Object put(Object key,Object value);存放键值对【map中键值对不允许重复,如果重复(是否重复是根据key的equals方法来判断),则新的覆盖旧的】
2.Object get(Object key);通过键对象查找得到值的对象
3.Object remove(Object key);删除键对象对应的键值对。
4.boolean containsKey(Object key);Map容器中是否包含键对象对应的键值对
5.boolean containsValue(Object value);Map容器中是否包含值对象对应的键值对
6.int size();包含键值对的数量。
7.boolean isEmpty();Map是否为空
8.void putAll(Map t);将t的所有键值对存放到本Map对象
9.void clear();清空本map对象所有的键值对
HashMap()底层的实现:
HashMap底层实现采用了哈希表,这是一个非常重要的数据结构。比如:redis数据库的核心技术和HashMap一样
数据结构中有数组和链表来实现对数据的存储,他们各有特点。
1.数组:占用空间连续。寻址容易查询速度快。但是增加和删除效率非常低。
2.链表:占用空间不连续,寻址困难,查询速度慢,但是增加和删除效率高。
所以引入哈希表,哈希表的本质就是“数组+链表”,既查询快,又增删效率高。
核心代码:Node<k,v>[] table(位桶数组);这就是JDK1.8中HashMap中的节点数组。
*每一个Node对象就是一个单向链表结构,由 hash、key、value、next组成。
*HashMap数组的默认长度为16。**