更多java知识,点击了解:https://how2j.cn/k/collection/collection-arraylist/363.html
集合
层次一:针对不同特点的数据,能够选择对应接口的主要的类进行实例化和方法的调用
层次二:熟悉接口的不同的实现类的区别、特点
层次三:相关接口实现类的底层实现:存储结构
若要深刻了解,还是自己去剖析源码,看明白了,就真的懂了,个人也在努力中。
集合框架结构
|-----Collection:存储一个一个的数据
|-----List:存储有序的、可以重复的数据 : 替换数组,"动态数组" |-----ArrayList/LinkedList/Vector |-----Set:存储无序的、不可重复的数据: 高中的集合 |-----HashSet/LinkedHashSet/TreeSet |-----Map:存储一对一对的数据(key-value):高中的函数。 y = f(x) (x1,y1),(x2,y2) |-----HashMap/LinkedHashMap/TreeMap/Hashtable/Properties
Collection包含List和Set两个子接口;
其中List存放 有序、可重复数据 ----à动态数组
List是Collection的子接口,Collection中声明的方法,在List的实现类中都可以使用。
ArrayList:Collection collection = new ArrayList();
List list = Arrays.aslist();//将数组转化为list,一般是初始化时使用。且不支持add()和remove(),也就是说在不改变长度的情况下,可以使用。
ArrayList list = new ArrayList();
List list = new ArrayList();//多态性;
Collection中的常用方法
功能:增,删,改,查,插,长度,遍历
//1. add(Object obj):添加元素obj到当前集合中,可以自动装箱
//2.size():获取集合中元素的个数
//3.addAll(Collection coll):将coll集合中的元素添加到当前集合中。
//4.isEmpty():判断当前集合是否为空。
//5.clear():清空当前集合
//6.contains(Object obj):判断当前集合中是否包含obj元素
//7.containsAll(Collection coll):判断当前集合中是否包含coll集合中的所有元素
//8.remove(Object obj):删除当前集合中首次出现的obj元素
//9.removeAll(Collection coll):差集:从当前集合中移除其与coll集合共有的元素
//10.retainAll(Collection coll):交集:获取当期集合与coll集合共有的元素
//11. equals(Object obj):判断当前集合与obj元素是否相等
//12.hashCode():返回当前集合对象的哈希值
//13.toArray():将集合转换为数组
ArrayList:线程不安全,效率高,相对于其他List是主要实现类,适用于大量的查找工作,底层是Object[]数组,有序可重复。
Integer[] arr2 = new Integer[]{1,2,3};
int[] arr3 = new int[]{1,2,3}; List list2 = Arrays.asList(arr2); List list3 = Arrays.asList(arr3);//存放的时地址值 List list4 = Arrays.asList(1,2,3); System.out.println(list2.size());//3 System.out.println(list3.size());//1 System.out.println(list4.size());//3 System.out.println(list3);//[[I@4459eb14]
LinkedList:LinkedList list = new LinkedList();
线程不安全;底层使用双向链表存储数据,对于频繁的插入、删除操作,使用此类效率高。
Vector:Vector v = new Vector();
List的古老实现类,线程安全,效率低,底层使用Object[]存储
Set:其中Set存放 无序、不可重复数据 ----à类似初中概念集合
HashSet:HashSet set = new HashSet(); Set set = new HashSet();
主要实现类,线程不安全,可以存放null值,底层也是使用数组+链表+红黑树存储的。
无序性:不等于随机性,元素在底层存储的位置不是像数组一样是依次紧密排列的,而是参考其hashCode值决定的存储位置,理解为无序性。
不可重复性:跟据对象的equals()进行判断。如果返回true,则添加失败。保证了不可重复性。
所以,必须要重写hashCode()和equals()方法,并且保持两方法的一致性,相等的对象必须具有相等的散列码。
LinkedHashSet:
LinkedHashSet set = new LinkedHashSet();
Set set = new LinkedHashSet();
是HashSet的子类,在添加数据之外,还通过一对指针记录先后添加的顺序,使得遍历Set元素时,较HashSet效率更高。
TreeSet:TreeSet set = new TreeSet();
可以按照添加的元素的指定的属性的大小进行遍历,排列的方式有自然排序和定制排序,底层使用的红黑树。
特别注意:向TreeSet中添加的元素必须是同一个类型的对象,TreeSet中不能存放相同的元素,判断的标准不是hashCode()和equals()方法,而是按照自然排序或定制排序中重写的compareTo()或compare()方法进行比较。
Map接口,存放一对一对的数据,键值对(key-value),map中一个key-value构成了一个Entry,Map接口类似函数。
HashMap:HashMap map = new HashMap();//底层创建长度为16的Entry数组table
Map中的key彼此不可重复、无序,添加元素方法put();且添加遵循七上八下(jdk7中添加元素放在首端,jdk8中添加元素放在末尾);
Map中的常用方法:Object put(Object key,Object value); void putAll(Map m); Object remove(Object key); void clear(); Object get(Object key); boolean containKey(Object key); boolean containsValue(Object value); int size(); boolean isEmpty; boolean equals(Object obj); Set keyset(); Collection values(); Set entrySet();
总结:
增:put(Object key,Object value) 删:remove(Object key) 改:put(Object key,Object value) 查:get(Object key) 长度:size() 遍历:keySet();values();entrySet() LinkedHashMap: TreeMap:TreeMap map = new TreeMap(); 向TreeMap中添加key-value,要求所有的key必须是同一个类的对象,针对于key,实现自然排序或定制排序。 Hashtable: Properties:Hashtable的子类,其中key-value都是String类型,常用来处理属性文件。
HashMap的源码解析(底层实现原理)
HashMap使用的存储结构:jdk8:数组+链表+红黑树 jdk7:数组+链表 (链表结构七上八下) 加了红黑树以后,提高数据的查找、对比的效率 链表:“七上八下” 初始化的问题:new HashMap(); jdk8:没有初始化底层数组(懒汉式)
jdk7:实例化时就初始化了底层数组(饿汉式)
jdk8:底层的数组Node[] (class HashMap.Node implements Map.entry)
jdk7:底层的数组Entry[] (class HashMap.Entry implements Map.entry)
class Node/Entry<K,V>{ int hash; K key; V value; Node/Entry next; } 添加数据的过程: 在jdk8中,首次调用put(),底层会创建长度为16的数组,然后添加数据 在jdk7中,首次调用put(),直接添加数据 扩容机制 临界值threshold,当添加的元素超过临界值时,要考虑扩容,默认扩容为原来的2倍 默认情况下等于
DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY.即为12
加载因子:默认时0.75 添加操作之外的,get(),remove()也参考put(key,value)
增强for循环(for-each循环)
格式:
for(集合元素类型 变量名 : 待编列的集合对象的引用){
}
例子:
for( Object obj : collection){
System.out.println(obj);
}
迭代器Iterator
Iterator的对象成为迭代器,主要用于遍历Collection集合中的元素
Collection c = new ArrayList();
c.add(1);//自动装箱
c.add(2);
c.add(3);
Iterator iterator = c.iterator();
While(iterator.hasNext()){
Object obj = iterator.next(); System.out.println(obj); System.out.println(iterator.next());//可以,但是不推荐
}