学习目标
1.掌握Map集合体系常用类 2.Collections工具类一、Map接口 1.1 Map接口概述
Map与Collection并列存在。用于保存具有映射关系的数据:key-value ;Map 中的 key 和 value 都可以是任何引用类型的数据
Map 中的 key 用Set来存放,不允许重复,即同一个 Map 对象所对应的类,须重写hashCode()和equals()方法 ,常用String类作为Map的“键”
key 和 value 之间存在单向一对一关系,即通过指定的 key 总能找到唯一的、确定的 value
Map接口的常用实现类:HashMap、TreeMap、LinkedHashMap和 Properties。其中,HashMap是 Map 接口使用频率最高的实现类
map底层设计结构如下:
Map中的key:无序的、不可重复的,使用Set存储所有的key —> key所在的类要重写equals()和hashCode() (以HashMap为例);Map中的value:无序的、可重复的,使用Collection存储所有的value —>value所在的类要重写equals();一个键值对:key-value构成了一个Entry对象。Map中的entry:无序的、不可重复的,使用Set存储所有的entry
1.2 map接口常用方法map接口常用方法如下:
- 添加、删除、修改操作:
- Object put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中
- void putAll(Map m):将m中的所有key-value对存放到当前map中
- Object remove(Object key):移除指定key的key-value对,并返回value
- void clear():清空当前map中的所有数据
- 元素查询的操作:
- Object get(Object key):获取指定key对应的value
- boolean containsKey(Object key):是否包含指定的key
- boolean containsValue(Object value):是否包含指定的value
- int size():返回map中key-value对的个数
- boolean isEmpty():判断当前map是否为空
- 元视图操作的方法:
- Set keySet():返回所有key构成的Set集合
- Collection values():返回所有value构成的Collection集合
- Set entrySet():返回所有key-value对构成的Set集合
Map(接口):双列数据,存储key-value对的数据 。他的实现类区别如下:
- HashMap:作为Map的主要实现类;线程不安全的,效率高;存储null的key和value
- LinkedHashMap:作为HashMap的子类保证在遍历map元素时,可以按照添加的顺序实现遍历。原因:在原有的 HashMap 底层结构基础上,添加了一对指针,指向前一个和后一个元素。对于频繁的遍历操作,此类执行效率高于 HashMap。
- TreeMap:保证按照添加的key-value对进行排序,实现排序遍历。此时考虑key的自然排序或定制排序底层使用红黑树
- Hashtable:作为古老的实现类;线程安全的,效率低;不能存储null的key和value,底层原理和 HashMap 几乎一样。
- Properties:常用来处理配置文件。key和value都是String类型
jdk7种的HashMap底层原理:
当我们创建hashMap对象时 Map map = new HashMap():
- 在实例化以后,底层创建了长度是16的一维数组Entry[] table。
- map.put(key1,value1):首先,调用key1所在类的hashCode()计算key1哈希值,此哈希值经过某种算法计算以后,得到在Entry数组中的存放位置。如果此位置上的数据为空,此时的key1-value1添加成功。 ----情况1
- 如果此位置上的数据不为空,(意味着此位置上存在一个或多个数据(以链表形式存在)),比较key1和已经存在的一个或多个数据的哈希值:如果key1的哈希值与已经存在的数据的哈希值都不相同,此时key1-value1添加成功。----情况2
- 如果key1的哈希值和已经存在的某一个数据(key2-value2)的哈希值相同,继续比较:调用key1所在类的equals(key2)方法,比较:如果equals()返回false:此时key1-value1添加成功。----情况3
- 如果equals()返回true:使用value1替换value2。情况四
- 补充:关于情况2和情况3:此时key1-value1和原来的数据以单向链表的方式存储。
- 在不断的添加过程中,会涉及到扩容问题,当超出临界值(且要存放的位置非空)时,扩容。默认的扩容方式:扩容为原来容量的2倍,并将原有的数据复制过来。
jdk8中的hashMap底层原理如下
1.5 LinkedHashMap 详细讲解LinkedHashMap 是 HashMap 的子类
在HashMap存储结构的基础上,使用了一对双向链表来记录添加 元素的顺序
与LinkedHashSet类似,LinkedHashMap 可以维护 Map 的迭代 顺序:迭代顺序与 Key-Value 对的插入顺序一致
1.6 Hashtable详细讲解Hashtable是个古老的 Map 实现类,JDK1.0就提供了。不同于HashMap, Hashtable是线程安全的。
Hashtable实现原理和HashMap相同,功能相同。底层都使用哈希表结构,查询速度快,很多情况下可以互用。
与HashMap不同,Hashtable不允许使用 null 作为 key 和 value
与HashMap一样,Hashtable也不能保证其中 Key-Value 对的顺序
Hashtable判断两个key相等、两个value相等的标准,与HashMap一致。
1.7 TreeMap 详细讲解TreeMap存储 Key-Value 对时,需要根据 key-value 对进行排序。 TreeMap 可以保证所有的 Key-Value 对处于有序状态。
TreeSet底层使用红黑树结构存储数据
TreeMap 的 Key 的排序:
- 自然排序:TreeMap 的所有的 Key 必须实现 Comparable 接口,而且所有 的 Key 应该是同一个类的对象,否则将会抛出 ClasssCastException
- 定制排序:创建 TreeMap 时,传入一个 Comparator 对象,该对象负责对TreeMap 中的所有 key 进行排序。此时不需要 Map 的 Key 实现 Comparable 接口
TreeMap判断两个key相等的标准:两个key通过compareTo()方法或 者compare()方法返回0
1.8 Properties 详细讲解Properties 类是 Hashtable 的子类,该对象用于处理属性文件
由于属性文件里的 key、value 都是字符串类型,所以 Properties 里的 key 和 value 都是字符串类型
存取数据时,建议使用 setProperty(String key,String value) 方法和 getProperty(String key) 方法
@Test
public void test1() throws IOException {
//1.创建对象
Properties properties = new Properties();
//2.加载文件 涉及IO流内容以后会讲这里先强行照抄即可。
properties.load(new FileReader("src/db.properties"));
//3.获取属性
String username = properties.getProperty("username");
System.out.println(username);
String password = properties.getProperty("password");
System.out.println(password);
//4.设置属性 设置的是对象中的属性
properties.setProperty("username", "张飞");
properties.setProperty("password", "7654321");
System.out.println(properties);
}
二、Collections工具类
Collections 是一个操作 Set、List 和 Map 等集合的工具类
Collections 中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作, 还提供了对集合对象设置不可变、对集合对象实现同步控制等方法 ;常用方法如下:
- 排序操作:
- reverse(List):反转 List 中元素的顺序
- shuffle(List):对 List 集合元素进行随机排序
- sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序
- sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
- swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换
- 查找、替换
- Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
- Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素
- Object min(Collection)
- Object min(Collection,Comparator)
- int frequency(Collection,Object):返回指定集合中指定元素的出现次数
- void copy(List dest,List src):将src中的内容复制到dest中
- boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值
示例:Collections工具类应用
@Test
public void test1() {
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
list.add(6);
//1.反转list集合元素
Collections.reverse(list);
System.out.println(list);
//2.集合元素随机排序
Collections.shuffle(list);
System.out.println(list);
//3.排序
Collections.sort(list);
System.out.println(list);
Collections.swap(list, 0, 1);
System.out.println(list);
}
@Test
public void test2() {
Collection c1 = new ArrayList();
c1.add(1);
c1.add(2);
c1.add(6);
c1.add(3);
c1.add(4);
c1.add(5);
c1.add(5);
c1.add(5);
c1.add(5);
Object max = Collections.max(c1);
System.out.println(max);
System.out.println(Collections.frequency(c1, 5));
//1.复制集合
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
List list2 = new ArrayList();
for(int i=0;i
list2.add(null);
}
Collections.copy(list2, list);
System.out.println(list2);
Collections.replaceAll(list, 3, 3333);
System.out.println(list);
}
三、面试题
简述Map实现类 HashMap LinkedHashMap Hashtable TreeMap底层原理
1.HashMap底层采用数组结构,通过hash方法计算存放数据Key得到哈希值,通过这个哈希值获得底层数组存放下标位置,如果该下标没有值,直接存储;如果该下标有值,比较该下标内所有值得hash值,如果hash值不同,直接添加;如果相同比较equals方法 返回false直接添加,返回true修改当前位置值。同一下标存放多个值采用单向链表结构;jdk8在此链表结构中又添加红黑树结构。HashMap可以存放null值,线程是不同步的。
2.Hashtable 底层原理和HashMap几乎一致,不同的是,不可以存放null值,线程是同步的。
3.LinkedHashMap 底层原理和HashMap几乎是一样的,不同的是每个元素之间采用双向链表结构链接,使得LinkedHashMap存放数据看起来像有序的。也可以存放null,线程也是不同步的。
4.TreeMap 底层采用红黑树存储结构,可以实现定制排序和自然排序功能;底层通过comporaTo方法去重复,返回0代表相同。



