文章目录
- 一、集合框架概述
- 🔥两大体系
- 👌Collection接口继承树
- 👌Map接口继承树
- 二、Collection接口
- 三、Iterator迭代器
- 🔥Iterator接口方法
- 🔥迭代器执行原理
- 🔥foreach遍历集合
- 四、List接口
- 🔥List接口方法
- 👌List实现类之一:ArrayList
- 👌List实现类之二:LinkedList
- 👌List实现类之三:Vector
- 五、Set接口
- 👌Set实现类之一:HashSet
- 👌Set实现类之二:LinkedHashSet
- 👌Set实现类之三:TreeSet
- 🚩自然排序
- 🚩定制排序
- 🔥Set和List的区别
- 六、Map接口
- 👌Map实现类之一:HashMap
- 🚩HashMap存储结构
- 🚩HashMap的扩容
- 👌Map实现类之二:LinkedHashMap
- 👌Map实现类之三:TreeMap
- 👌Map实现类之四:Hashtable
- 👌Map实现类之五:Properties
- 七、Collections工具类
- 🔥Collections常用方法
一、集合框架概述
●面向对象语言对事物的体现都是以对象
的形式,为了方便对多个对象的操作,就要对对象进行存储
●使用Array存储对象方面具有一些弊端,而 Java集合就像一种容器,可以动态地把多个对象的引用放入容器中
●Java 集合类可以用于存储数量不等的多个对象,还可用于保存具有映射关系的关联数组
🔥两大体系
- Collection接口:单列数据,定义了存取一组对象的方法的集合
- Map接口:双列数据,保存具有映射关系“key-value对”的集合
👌Collection接口继承树
👌Map接口继承树
二、Collection接口
三、Iterator迭代器
Iterator对象称为迭代器(设计模式的一种),主要用于遍历 Collection 集合中的元素Iterator 仅用于遍历集合
🔥Iterator接口方法
Collection接口继承了java.lang.Iterable接口,该接口有一个iterator()方法,那么所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象
🎁注:如果还未调用next()或在上一次调用 next 方法之后已经调用了 remove 方法,再调用remove都会报IllegalStateException
🔥迭代器执行原理
//hasNext():判断是否还有下一个元素
while(iterator.hasNext()){
//next():①指针下移 ②将下移以后集合位置上的元素返回
System.out.println(iterator.next());
}
🔥foreach遍历集合
四、List接口
Collection子接口之一:List接口
🔥List接口方法
除从Collection继承方法外,List 里添加了一些根据索引来操作集合元素的方法
:
👌List实现类之一:ArrayList
ArrayList 是 List 接口的典型实现类、主要实现类
- ArrayList的JDK1.8之前与之后的实现区别?
●JDK1.7:ArrayList像饿汉式,直接创建一个初始容量为10的数组
●JDK1.8:ArrayList像懒汉式,开始创建一个长度为0的数组,当添加第一个元素时再创建一个始容量为10的数组 - Arrays.asList(…) 方法返回的 List 集合是一个固定长度的 List 集合
👌List实现类之二:LinkedList
LinkedList类对于频繁的插入或删除元素的操作,效率较高
- 双向链表,内部没有声明数组,而是定义了Node类型的first和last,用于记录首末元素。同时,定义内部类Node,作为LinkedList中保存数据的基本结构;
Node除了保存数据,还定义了两个变量:
●prev变量记录前一个元素的位置
●next变量记录下一个元素的位置 - 源码:
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
- 方法:
👌List实现类之三:Vector
Vector 是一个古老的集合,是线程安全的,故是三者中最慢,尽量避免使用
- 方法:
五、Set接口
Collection子接口之二:Set接口
👌Set实现类之一:HashSet
HashSet 是 Set 接口的典型实现
- HashSet 具有以下特点:
●不能保证元素的排列顺序
●HashSet 不是线程安全的
●集合元素可以是 null - HashSet 集合判断两个元素相等的标准:
两个对象通过 hashCode() 方法比较相等,并且两个对象的 equals() 方法返回值也相等 - 对于存放在Set容器中的对象,对应的类一定要重写equals()和hashCode(Object obj)方法,以实现对象相等规则,即:“相等的对象必须具有相等的散列码”
👌Set实现类之二:LinkedHashSet
LinkedHashSet 是 HashSet 的子类
- LinkedHashSet插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能
- LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置,但它同时使用双向链表维护元素的次序,这使得元素看起来是以插入顺序保存的
LinkedHashSet 不允许集合元素重复
👌Set实现类之三:TreeSet
TreeSet 是 SortedSet 接口的实现类,TreeSet 可以确保集合元素处于排序状态
- TreeSet底层使用红黑树结构存储数据
- 方法:
- TreeSet 两种排序方法:
自然排序
和定制排序
默认情况下,TreeSet 采用自然排序
🚩自然排序
TreeSet 会调用集合元素的compareTo(Object obj)
方法来比较元素之间的大小关系,然后将集合元素按升序(默认情况)排列
- Comparable 的典型实现
- 对于 TreeSet 集合而言,它判断两个对象是否相等的唯一标准是:
两个对象通过 compareTo(Object obj) 方法比较返回值
🚩定制排序
TreeSet的自然排序要求元素所属的类实现Comparable接口,如果元素所属的类没有实现Comparable接口,或不希望按照升序(默认情况)的方式排列元素或希望按照其它属性大小进行排序,则考虑使用定制排序。定制排序,通过Comparator接口来实现。需要重写compare(T o1,T o2)方法
- 使用定制排序判断两个元素相等的标准是:通过Comparator比较两个元素返回了0
🔥Set和List的区别
- Set 接口实例存储的是无序的,不重复的数据;List 接口实例存储的是有序的,可以重复的元素
- Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变
<实现类有HashSet,TreeSet> - List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector>
六、Map接口
常用方法:
Map map = new HashMap();
//map.put(..,..)省略
System.out.println("map的所有key:");
Set keys = map.keySet();// HashSet
for (Object key : keys) {
System.out.println(key + "->" + map.get(key));
}
System.out.println("map的所有的value:");
Collection values = map.values();
Iterator iter = values.iterator();
while (iter.hasNext()) {
System.out.println(iter.next());
}
System.out.println("map所有的映射关系:");
// 映射关系的类型是Map.Entry类型,它是Map接口的内部接口
Set mappings = map.entrySet();
for (Object mapping : mappings) {
Map.Entry entry = (Map.Entry) mapping;
System.out.println("key是:" + entry.getKey() + ",value是:" + entry.getValue());
}
👌Map实现类之一:HashMap
HashMap是 Map 接口使用频率最高的实现类
- key所在的类要重写:equals()和hashCode()
value所在的类要重写:equals() - 一个key-value构成一个entry
- HashMap 判断
两个 key
相等标准是:两个 key 通过 equals() 方法返回 true,hashCode 值相等
HashMap 判断两个 value
相等标准是:两个 value 通过 equals() 方法返回 true
🚩HashMap存储结构
JDK 7及以前版本:HashMap是数组+链表结构(即为链地址法)
JDK 8版本发布以后:HashMap是数组+链表+红黑树实现
- JDK7:
- JDK8:
- HashMap的内部存储结构其实是数组和链表的结合
数组+链表+树的结合 -
添加元素的过程
向HashMap中添加entry1(key,value),首先计算entry1中key的哈希值(hashCode()计算得到),此哈希值经处理以后,得到在底层Entry[]数组中要存储的位置i,如果位置i上没有元素,则entry1直接添加成功。如果位置i上已经存在entry2(或链表还存在entry3…),则需要通过循环的方法,依次比较entry1中key和其他的entry。如果hash值不同,则直接添加成功,如果hash值不同,继续比较二者是否equals如果返回值为true,则使用entry1的value去替换equals为true的entry的value。如果遍历一遍以后,发现所有的equals返回都为false,则entry1仍可添加成功,entry1指向原有的entry元素
🚩HashMap的扩容
当HashMap中的元素越来越多的时候,hash冲突的几率也就越来越高,因数组的长度是固定的,所以为了提高查询的效率,就要对HashMap的数组进行扩容,而在HashMap数组扩容之后,最消耗性能的点就是原数组中的数据必须重新计算其在新数组中的位置,并放进去,这就是resize,如果我们已经预知HashMap中元素的个数,那么预设元素的个数能够有效的提高HashMap的性能
👌Map实现类之二:LinkedHashMap
LinkedHashMap 是 HashMap 的子类
- 与LinkedHashSet类似,LinkedHashMap 可以维护 Map 的迭代顺序:迭代顺序与 Key-Value 对的插入顺序一致
- HashMap中的内部类:Node
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
Node<K,V> next;
}
- LinkedHashMap中的内部类:Entry
static class Entry<K,V> extends HashMap.Node<K,V> {
Entry<K,V> before, after;
Entry(int hash, K key, V value, Node<K,V> next) {
super(hash, key, value, next);
}
}
👌Map实现类之三:TreeMap
TreeSet底层使用红黑树结构存储数据
- TreeMap 的 Key 的排序:
●自然排序:TreeMap 的所有的 Key 必须实现 Comparable 接口,而且所有的 Key 应该是同一个类的对象,否则将会抛出 ClasssCastException
●定制排序:创建 TreeMap 时,传入一个 Comparator 对象,该对象负责对TreeMap 中的所有 key 进行排序。此时不需要 Map 的 Key 实现Comparable 接口 - TreeMap判断两个key相等的标准:两个key通过compareTo()方法或者compare()方法返回0
👌Map实现类之四:Hashtable
古老的 Map 实现类
Hashtable是线程安全的
- Hashtable实现原理和HashMap相同,功能相同。底层都使用哈希表结构,查询速度快,很多情况下可以互用
👌Map实现类之五:Properties
- Properties 类是 Hashtable 的子类,该对象用于处理属性文件*,由于属性文件里的 key、value 都是字符串类型,所以 Properties 里的 key和 value 都是字符串类型*
- 存取数据方法:
setProperty(String key,String value)
getProperty(String key)
Properties pros = new Properties();
pros.load(new FileInputStream("jdbc.properties"));
String user = pros.getProperty("user");
System.out.println(user);
七、Collections工具类
操作数组的工具类:Arrays
- Collections 是一个操作 Set、List 和 Map 等集合的工具类
🔥Collections常用方法