Map接口、HashMap集合、TreeMap集合、Properties类

一、Map接口

1、Map和Collection没有继承关系

2、Map集合以keyvalue的方式存储数据:键值对

keyvalue都是引用数据类型
keyvalue都是存储对象的内存地址
key起主导的地位,valuekey的一个附属品

1、Map接口中的常用方法

V put​(K key, V value) 向Map集合中添加键值对

V get​(Object key)通过可以获取value

void clear()清空Map集合

boolean containsKey(Object key)判断Map中是否包含某个key

boolean containsValue(Object value)判断Map中是否包含某个value

boolean isEmpty()判断Map集合中元素个数是否为0

Set<K> keySet()获取Map集合所有的key(所有的键是一个set集合)

V remove​(Object key) 通过key删除键值对

int size() 获取Map集合中键值对的个数。

Collection<V> values() 获取Map集合中所有的value,返回一个Collection

Set<Map.Entry<K,​V>> entrySet() b 将Map集合转换成Set集合

注意:

Map.Entry和String一样,都是一种类型的名字,只不过:Map.Entry是静态内部类,是Map中的静态类
Map集合通过entrySet()的方法转换成的这个Set集合,Set集合中的元素的类型都是Map.Entry<K,V>

2、遍历Map集合

import java.util.*;

public class MapText {
    public static void main(String[] args) {

        //第一种方式:获取所有Key,通过遍历key。来遍历value
        Map<Integer,String> map = new HashMap<>();
        map.put(1,"zhangsan");
        map.put(2,"lisi");
        map.put(3,"wangwu");
        map.put(4,"zhaoliu");

1、第一种方式:获取所有Key,通过遍历key。来遍历value

   //遍历Map集合
        //获取所有的key,所有的key是一个Set集合
        Set<Integer> keys = map.keySet();
        //遍历key,通过key返回value
        //迭代器也可以
        Iterator<Integer> it = keys.iterator();
        while (it.hasNext()){
            Integer key = it.next();
            String value = map.get(key);
            System.out.println(key + "=" + value);
        }

		 //foreach
        for (Integer key : keys){
            System.out.println(key + "=" + map.get(key));
        }

2、第二种方法:Set<Map.Entry<K,​V>> entrySet() b 将Map集合转换成Set集合,Set集合中元素的类型是:Map.Entry

Map.Entry和String一样,都是一种类型的名字,只不过:Map.Entry是静态内部类,是Map中的静态类
在这里插入图片描述

 Set<Map.Entry<Integer,String>> set = map.entrySet();
        //遍历Set集合,每一次取出一个Node
        //迭代器
        Iterator<Map.Entry<Integer,String>> it = set.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }

或者

        Set<Map.Entry<Integer,String>> set = map.entrySet();
        //遍历Set集合,每一次取出一个Node
        //迭代器
        Iterator<Map.Entry<Integer,String>> it = set.iterator();
        while (it.hasNext()){
            Map.Entry<Integer,String> node = it.next();
            Integer key = node.getKey();
            String value = node.getValue();
            System.out.println(key + "=" + value );
        }

foreach:

  • 这种方式效率比较高,因为获取key和value都是直接从node对象中获取的属性值
  • 这种方式比较适合大数据
		Set<Map.Entry<Integer,String>> set = map.entrySet();
        for (Map.Entry<Integer,String> node: set){
            System.out.println(node.getKey() + "--->" + node.getValue());
        }

二、HashMap集合

HashMap集合底层是哈希表/散列表的数据结构。

在JDK8之后,如果哈希表单向链表中元素超过8个,单向链表这种数据结构会变成红黑树数据结构。当红黑树上的节点数量小于6时,会重新把红黑树变成单向链表数据结构。

这种方式也是为了提高检索效率,二叉树的检索会再次缩小扫描范围。提高效率。

1、哈希表

哈希表是一个怎样的数据结构?
是一个一维数组,这个数组中每一个元素是一个单向链表。(数组和链表的结合体)

哈希表是一个数组和单向链表的结合体

  • 数组:在查询方面效率很高,随机增删效率很低。
  • 单向链表:在随机增删方面效率很高,在查询方面效率很低
  • 哈希表将以上的两种数据结构融合在一起,充分发挥了它们各自的优点。

对于哈希表数据结构来说:

  • 如果o1和o2的hash值相同,一定是放到同一个单向链表上。
  • 当然如果o1和o2的hash值不相同,但由于哈希算法执行结束之后转换的数组下标可能相同,此时会发生“哈希碰撞

2、HashMap集合底层的源代码

public class HashMap{

	//HashMap底层实际上就是一个数组。(一维数组)
	Node<K,V>[] table;
	
	//静态的内部类HashMap.Node
	static class Node<K,V>{
		final int hash;//哈希值(哈希值是key的hashCode()方法的执行结果。hash值通过哈希函数,可以转换成数组的下标)
		final K ley; //存储到Map集合中的那个key
		V value;//存储到Map集合中的那个value
		Node<K,V> next;//下一个节点的内存地址
	}
}

HashMap
在这里插入图片描述
为什么哈希表的随机增删,以及查询效率都很高?

增删是在链表上完成的。
查询也不需要都扫描,只需要部分扫描。

3、HashMap集合的key特点

无序不可重复

  • 为什么无序? 因为不一定挂在哪个单向链表上。
  • 不可重复是怎么保证的? equals()方法来保证HashMap集合的key不可重复。如果key重复了,value会覆盖。

放在HashMap集合key部分的元素其实就是放到HashSet集合中了。

所以HashSet集合中的元素也需要同时重写hashCode()+equals()方法

4、哈希表HashMap使用不当时无法发挥性能

假设将所有的hashCode()方法返回值固定为某个值,那么会导致底层哈希表变成了纯单向链表。这种情况我们称为:散列分布不均匀

什么实际散列分布均匀?

假设有100个元素,10个单向链表,那么每个单向链表上有10个节点,这是最好的,是散列分布均匀的。

假设将所有的hashCode()方法返回值都设定为不一样的值,可以吗?

不可以,因为这样的话导致底层哈希表就变成了一维数组了,没有链表的概念了。也是散列分布不均匀。

5、必须同时重写hashCode和equals方法

放在HashMap集合key部分的元素,以及放在HashSet集合中的元素,需要同时重写hashCode和equals方法

并且 equals() 方法返回如果是true,hasCode() 方法返回的值必须一样

6、HashMap集合容量

HashMap集合的默认初始化容量是16默认加载因子是0.75

这个默认加载因子是当HashMap集合底层数组的容量达到75%的时候,数组开始扩容。

重点:HashMap集合的初始化容量必须是2的倍数,这也是官方推荐的,这是因为达到散列均匀,为了提高HashMap集合的存取效率,所必需的。

7、HashMap集合key允许为null

注意:但是HashMap集合keynull只能有一个

三、HashMap和Hashtable的区别

Hashtable的keyvalue都是不能为null的。
HashMap集合的keyvalue都是可以为null的。

Hashtable集合初始化容量是11集合扩容是:原容量*2+1

四、TreeMap集合

TreeMap集合底层实际上是一个二叉树。

五、Properties类

Properties是一个Map集合继承Hashtable,Properties的keyvalue都是String类型;

Properties被称为属性类对象

Properties是线程安全的。

import java.util.Properties;

public class PropertiesText {
    public static void main(String[] args) {
        //创建一个Properties对象
        Properties pro = new Properties();

        //需要掌握Properties的两个方法,一个存,一个取
        pro.setProperty("url","jdbc:mysql://localhost:3306/bjpowernode");
        pro.setProperty("driver","com.mysql.jdbc.Driver");
        pro.setProperty("username","root");
        pro.setProperty("password","123");

        //通过key获取value
         String url = pro.getProperty("url");
         String driver = pro.getProperty("driver");
         String username = pro.getProperty("username") ;
         String password = pro.getProperty("password");

        System.out.println(url);
        System.out.println(driver);
        System.out.println(username);
        System.out.println(password);
    }
}

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值