了解与使用Map集合

Map集合

Map集合以键值对的形式存储,如<学生姓名,成绩>,第一个数据称为键,第二个数据称为值
1.在Java中Map集合是接口
2.Map的实现类才是存储数据的具体容器
3.Map接口中定义了一组操作集合的规范
4.Map集合是对实现类的统称

使用HashMap

//Map是一个接口,需要赋值实现类对象
//在创建Map集合时,通过泛型指定键值的数据类型
Map<String, Integer> map = new HashMap<>();
//2) put(key,value)添加数据
//3) 直接打印map, 当前map实际引用的是hashMap对象, 会调用HashMap的toString()方法
//在HashMap集合中,键值对的实际存储顺序与添加顺序可能不一样
/***注意: Map的键不允许重复, 在put添加键值对时,如果键已存在会使用新的value值替换原来的值****/

get(Key)

返回键对应的值
containsKey()

判断键中是否包含
containsValue()

判断值中是否包含
keySet()

返回所有的键
values()

返回所有的值
entrySet()

返回所有的键值对,一个键值对就是一个entry, Entry是Map接口中定义的一个内部接口, 类名.类名的形式就是一种内部类的使用格式
replace(key, newValue)

把map中键是key的值替换为newValue
put(key,value)

本质工作是添加键值对,虽然当键存在时,功能与replace()一样,但是在替换修改键的值时,一般使用replace()
remove()

删除


//1) 可以输入  iter 生成foreach循环代码块, 选择遍历map的哪些内容
//2) 注意keySet(),values()这些方法并没有创建新的集合, 可以对keySet, values集合进行删除操作, 实际删除的是Map的数据,  这些集合不支持add()添加操作

HashMap工作原理


1.HashMap底层是哈希表(哈希表也称为散列表,其实就是数组,数组的每个元素是单向链表)
2.put(key,value)添加键值对时,先根据键的哈希码(hashCode方法返回值)经过hash函数计算哈希值,再根据哈希值计算数组下标,访问数组中这个下标的元素,如果为null则创建一个结点保存在这个位置,如果不为null就遍历这个位置链表的每个结点,如果存在结点的key与当前的键equals相等就用新的value替换结点的value,如果没有匹配的就创建一个新结点插入链表尾部


HashMap如何解决哈希冲突?


采用链表法
哈希冲突也称为哈希碰撞,就是equals不相等的两个键计算出的hash值可能相等,因此在数组中的索引值可能相等


在JDK8中对HashMap作了哪些改进?


1.新增结点插入链表的尾部,之前新增结点插入链表头部
2.当链表结点数量超过8个时,会把单向链表转换为红黑树,当红黑树结点数量小于6个时,再转回单向链表


HashMap的get原理


1.根据键的哈希码经过hash函数计算hash值,根据哈希值计算数组下标
2.访问该下标元素,如果为null就返回null,如果不为null就遍历这个位置链表的每个结点,如果有结点的key与当前的键equals相等就返回该结点的value值,所有结点都不匹配返回null


HashMap与HashTable


底层数据结构是哈希表,但是HashTable是线程安全的,HashMap不是线程安全的
HashTable初始化容量:11,HashMap初始化容量:16
加载因子:0.75,当键值对的数量 > 容量 × 加载因子时扩容(扩容:解决哈希冲突,提升运行效率)
HashMap按2倍大小扩容,HashTable按2倍+1扩容
HashTable的键和值都不能为null,HashMap的键或值可以为null
在创建时都可以指定初始化容量,但是HashMap会把初始化容量自动调整为2的幂次方,为了快速计算数组的下标


Properties


Properties继承了HashTable,键值的数据类型是String字符串,不需要泛型
经常用于读取/设置属性,常用方法getProperty(属性名)、setProperty(属性名,属性值)
 

//1) 创建Properties对象
Properties properties = new Properties();
//2)设置/读取属性
properties.setProperty("username", "user");
System.out.println( properties.getProperty("username"));
//3)读取系统 的属性
String userdir = System.getProperty("user.dir");
//获得所有的系统 属性
properties = System.getProperties();
for (Map.Entry<Object, Object> entry : properties.entrySet()) {
    System.out.println(entry);
}

1) 一般情况下,会把属性保存在配置文件中
2) 一般情况下, 会在src目录中单独创建一个resources资源包, 在该包中添加配置文件
3) 在resources包中 新建resource bundle就是添加配置文件,在弹出的对话框中输入配置文件名, 不需要输入扩展名,系统默认扩展名为.properties
4) 可以使用Properties读取配置文件中的属性

#在配置文件中属性名 与 属性值 一般使用 等号= 或者 冒号:分隔
#注意:不管是属性名还是属性值都不需要引号
#属性名与属性值一般不使用中文, 如果需要中文,需要设置配置文件的编码

//2)在当前程序与配置文件之间建立字节流通道
        //经常使用当前类的字节码的类加载器来建立与配置文件的流通道
	InputStream in = Test02.class.getClassLoader().getResourceAsStream("resources/config.properties");
        //也经常使用 线程的上下文类加载器获得与配置文件的流通道
	InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("resources/config.properties");
//3) properties通过字节流加载配置文件, load(InputStream)方法有受检异常需要预处理, 当前Alt+ enter,选择 Add exception to method signautre 抛出处理, 当程序运行后, 如果配置文件路径不正确,找不到配置文件就会抛出异常
	properties.load(in);
//4) 读取配置文件的属性
	System.out.println(properties.getProperty("username"));
//5)关闭流
	in.close();
//直接使用ResourceBundle读取配置文件的属性
//1) 创建ResourceBundle, 注意: 配置文件路径不需要扩展名, 如果配置文件路径不正确会抛出异常
	ResourceBundle bundle = ResourceBundle.getBundle("resources/config");
//2)读取配置文件属性
	System.out.println( bundle.getString("username"));

TreeMap


TreeMap实现了SortedMap接口,可以根据键进行排序,要求键必须可以比较大小
1.在TreeMap构造方法中指定Comparator比较器
2.没有指定比较器,要求键实现Comparable接口
HashSet底层数据结构是HashMap,TreeSet底层数据结构是TreeMap
TreeMap的键根据红黑树原理排序


firstKey()/lastKey()
firstEntry()/lastEntry()

//第一个/最后一个Entry或者key
pollFirstEntry()

//删除第一个键值对
pollLastEntry()

//删除最后一个键值对


//在URL地址中, 问号后面的是参数, 参数名=参数值,  参数之间使用&连接
//注意: interest参数名可以有多个值,  在定义Map时, 参数名可以定义为String字符串类型, Map的value值存储参数值, 参数值可能有多个时, Map的value可以定义为数组类型,或者List集合类型

Map的键值类型问题


Map的键从语法上可以是任意引用类型,但在实际开发中,通常使用String字符串或Integer整数作为键,很少使用自定义类型作为Map的键,当修改键对象的属性值后,使用get(key)、containsKey(Key)时,查找位置可能与存储位置不同

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值