> 文档中心 > Java基础篇集合框架体系---Map

Java基础篇集合框架体系---Map

Map总结目录

  • 1. Map接口
    • 1.1 Map接口概述
    • 1.2 Map存储结构及常用方法
    • 1.3 HashMap底层实现原理
  • 2. Collections工具类的使用
    • 2.1 Collections概述
    • 2.2 Collections常用方法
    • 2.3 Collections的同步机制
  • 3. 集合知识补充
    • 3.1 TreeMap元视图操作
    • 3.2 Properties 概述

1. Map接口

1.1 Map接口概述

Map集合特点

①Map与Collection并列存在。用于保存具有映射关系的数据:key-value
②Map集合中的每一条数据存储的是两个数值,有意义对应的关系
③Map中每一条数据成为一个entry或者Node

Map集合的常用实现类结构

|----Map接口:双列集合,用来存储一对一对(key - value)的数据。
        |----HashMap:作为Map的主要实现类;线程不安全,效率高,存储的key和value可以有null值
            |----LinkedHashMap:保证在遍历map元素时,可以按照添加的顺序进行遍历
在原有的HashMap底层结构基础之上,添加了一对指针,指向前一个和后一个数据,对于频繁的遍历操作,此类的执行效率高于HashMap
       |----TreeMap:保证按照添加的key-value对进行排序,实现排序遍历,此时考虑使用key的自然排序和定制排序
       |----Hashtable:作为古老的实现类(过时);线程安全,效率低,不能存储null的key和value
           |----Properties:常用来处理配置文件,底层使用红黑树

HashMap:底层使用数组+链表+红黑树

1.2 Map存储结构及常用方法

存储特点

(1) Map集合:双列数据,存储key- value对数据
(2) key:无序的、不可重复的 ,底层使用Set存储
(3) value:无序的、可重复的,底层使用Collection存储
(4) entry:无序的、不可重复的 ,底层使用Set存储

图形展示

Java基础篇集合框架体系---Map

常用方法

方法名 说明
put(Object key,Object value) 添加 key-value到(或修改)当前map对象
remove(Object key) 移除指定key的key-value对
get(Object key) 获取指定key对应的value
int size() 返回map中key-value对的个数
Set keySet() 返回所有key构成的Set集合
Collection values() 返回所有value构成的Collection集合
Set entrySet() 返回所有key-value对构成的Set集合

使用方法展示

@Test    public void test2() { Map map = new HashMap<>(); //添加单个Node map.put("AA", 12); map.put("BB", 34); map.put("CC", 56); System.out.println(map); //添加集合 Map map1 = new HashMap<>(); map1.put("DD", 78); map1.put("EE", 90); map.putAll(map1); System.out.println(map); //③ Object remove(Object key):移除指定key的key-value对,并返回value map.remove("EE"); System.out.println(map); //④void clear():清空当前map中的所有数据 map.clear(); System.out.println(map.size());    }

1.3 HashMap底层实现原理

非常重要
JDK7实现原理概述
在这里按照执行步骤对底层实现的原理进行描述
(1)
HashMap map = new HashMap():

在实例化以后,底层创建了长度是16的一维数组Entry[] table.

(2)
map.put(key1,value1)
这里是存放的关键步骤具体实现如下:

首先,调用key1所在类的hashCode()计算key1的哈希值,此哈希值经过某种算法计算以后,得到在Entry(键值对)数组中的存放位置。
      如果此位置上的数据为空,此时的key1-value1添加成功

      如果此位置上的数据不为空时,(意味着此位置上存在一个或者多个数组(一链表的形式存在)),比较key1和已经存在的一个或者多个数据 的哈希值:
            如果key1的哈希值与已经存在的数据的哈希值都不相同时,此时的key1-value1添加成功

            如果key1的哈希值与已经存在的某一个数据(key2-value2)的哈希值相同,继续比较:调用key1所在类的equals(key2)
                  如果equals()返回false:此时的key1-value1添加成功

                  如果equals()返回true:使用value1替换value2

JDK8实现原理修改
1.new HashMap():底层没有创建一个长度为16的数组
2.jdk8底层使用的数组是:Node[],替换了以前的Entry[]
3.首次调用put()方法时,底层创建了长度为16的数组
4.jdk7底层结构只有:数组+链表。jdk8中底层结构:数组+链表+红黑树。
        当数组的某一个索引位置上的元素以来链表的形式存在的数据个数 > 8时,并且数组的长度 > 64 时,此时索引位置上的所有数据改为使用红黑树存储

存储图示:
Java基础篇集合框架体系---Map
LinkedHashMap底层实现原理

     LinkedHashMap底层底层使用的结构和HashMap相同,因为LinkedHashMap是继承于HashMap,区别在于LinkedHashMap内部提供了Entry,替换了HashMap中的Node,保证可LinkedHashMap可以按照添加的顺序去实现遍历

TreeMap实现

     TreeMap,必须添加同一类的数据,对于TreeMap来说,最重要的还是实现自然排序和定制排序。

2. Collections工具类的使用

2.1 Collections概述

了解内容

①Collections 是一个操作 Set、List 和 Map 等集合的工具类
②Collections 中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作,还提供了对集合对象设置不可变、对集合对象实现同步控制等方法。

总的来说Collections就是用来操作Collextion的工具类

2.2 Collections常用方法

方法名 说明
Object max(Collection) 返回给定集合中的最大元素(自然排序)
max(Collection,Comparator) 返回给定集合中的最大元素(定制)
frequency(Collection,Object) 返回指定集合中指定元素的出现次数
copy(List dest,List src) 将src中的内容复制到dest中
replaceAll(List list,Object oldVal,Object newVal) 使用新值替换List 对象的所有旧值

对于copy()这一个方法要特别留意一下:

在进行copy之前,目标集合dest,里面可以没有元素,但是要有申请有空间来存储被复制的数据

使用方法

List list1 = Arrays.asList(new Object[list.size()]); Collections.copy(list1,list); System.out.println(list1);

使用部分方法展示

@Test    public void test1(){ List list = new ArrayList<>(); list.add(123); list.add(45); list.add(56); list.add(0); //反转集合 Collections.reverse(list); //shuffle(List):对 List 集合元素进行随机排序 Collections.shuffle(list); //sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序 Collections.sort(list); //swap(List,int, int) Collections.swap(list,2,3); System.out.println(list); List list1 = Arrays.asList(new Object[list.size()]); Collections.copy(list1,list); System.out.println(list1); //list1即为线程安全的 List list2 = Collections.synchronizedList(list);    }

2.3 Collections的同步机制

同步机制
Collections 类中提供了多个 synchronizedXxx() 方法,该方法可使将指定集
合包装成线程同步的集合,从而可以解决多线程并发访问集合时的线程安全
问题.

使用方法调用即可将集合变为线程安全

//list1即为线程安全的 List list2 = Collections.synchronizedList(list);

3. 集合知识补充

3.1 TreeMap元视图操作

说明
由于TreeMap存储的是键值对,所以在遍历的时候,不能够使用迭代器,只有在调用方法,将key存储在Set集合,Value存储在Collection集合之后才能够实现遍历,将key-value也要存储在Set集合当中

使用的方法

方法名 说明
Set keySet() 返回所有key构成的Set集合
Collection values() 返回所有value构成的Collection集合
Set entrySet() 返回所有key-value对构成的Set集合

转化实现的演示

@Test    public void test4() { Map map = new HashMap<>(); map.put("AA", 12); map.put("BB", 34); map.put("CC", 56); //遍历所有的key Set set = map.keySet(); Iterator iterator = set.iterator(); while (iterator.hasNext()) {     System.out.println(iterator.next()); } //遍历所有的value   使用Collection集合存储 Collection values = map.values(); for (Object obj : values) {     System.out.println(obj); } //遍历所有的键值对 Set entrySet = map.entrySet(); Iterator iterator1 = entrySet.iterator(); while (iterator1.hasNext()) {     //得到的是一个entry(键值对)     Object obj = iterator1.next();     //做一个强制转化     Map.Entry entry = (Map.Entry) obj;     System.out.println(entry.getKey() + "---->" + entry.getValue()); } //实现遍历方式二:得到key集合,然后利用get()得到value Set set1 = map.keySet(); Iterator iterator2 = set1.iterator(); while (iterator2.hasNext()) {     Object key = iterator2.next();     Object value = map.get(key);     System.out.println(key + "--------->" + value); }    }

3.2 Properties 概述

说明:properties常用来处理配置文件,key和value都是String类型的
例如:再进行数据库链接的时候,会有jabc.properties文件,Properties可以对账号以及密码进行读取

简单实用样例:
jabc.properties文件

name=Jerrypassword=123

测试类:

public class PropertiesTest {    public static void main(String[] args) throws Exception { FileInputStream fis = null; try {     //properties常用来处理配置文件,key和value都是String类型的     Properties properties = new Properties();     fis = new FileInputStream("jdbc.properties");     properties.load(fis);//加载流对应的文件     String name = properties.getProperty("name");     String password = properties.getProperty("password");     System.out.println( "name = " + name + ",password = "+ password); } catch (IOException e) {     e.printStackTrace(); }finally {     try {  fis.close();     } catch (IOException e) {  e.printStackTrace();     } }    }}

这便可以读取数据库的账号以及密码