Map集合-主要HashMap和Hashtable
JAVA8除了给Map集合新增了方法remove(Object key,Object value)默认方法外
还增加了以下方法
Object replace(Object key,Object value),与put方法不同,他如果发现原来key不存在也不会增加新的key-value
boolean replace(Object key,V Oldvalue,V Newvalue)
Object putIfAbsent(Object key,Object value)自动检测该key对应的VALUE是否为空,如果为空,则用value替换原来的 NULL
Object getOrDefault(Object key,V defaultValue)获得指定的Key的value,如果为空就返回默认值defaultValue
其他方法似乎不常用,用到再补充啦
HashMap与HashTable的关系好像ArrayList与Vetor,HashTable比较老旧,HashMap是改进版本,在存在key冲突时候依然有比较好的性能(HashMap采用链表解决冲突)
他们有以下两个典型的区别、
HashMap是线程不安全的,HashTable是线程安全的,所以HashMap有比较好的性能。但是如果多个线程访问Map集合,HashTable的性能更好(尽量少用HashMap)
HashTable键值对都不能放null作为key,value HashMap可以null为空,不能重复,value可以多个空。
看如下代码:
package Test01;
import java.util.HashMap;
public class TestHashMap {
public static void main(String[] args) {
HashMap m = new HashMap();
m.put(null, null);
m.put(null, null);
m.put("a", "9");
System.out.println(m);
}
}
运行结果可看,不能把两个null放入HashMap
为了成功在HashMap和HashTable中存储对象,作为Key的Object 的对象必须实现hashcode()和equals方法。也就是说作为key的对象,通过equals返回true后,hashcode()值也必须相等。
那么对于value值呢,HashMap和HashTable都有containValue方法,可判断是否包含了指定的value,那如何判断value相等呢?返回equals比较相等即可。
package Test01; import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;
class C{
public int count;
public C(int count) {
this.count =count;
}
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(obj != null && obj.getClass() == C.class) {
C m =(C) obj;
return this.count == m.count;
}
return false;
}
public int hashcode() {
return this.count;
}
public String toString() {
return "试试C[count=" + count + "]";
} }
class B{ @Override
public boolean equals(Object arg0) {
// TODO Cuto-generated method stub
return true;
} }
public class TestMap{
@SuppressWarnings("unchecked")
public static void main(String[] args){
HashMap m =new HashMap();
B b= new B();
m.put(new C(200), "第一次");
m.put(new C(39), "第二次");
m.put(new C(450), "第三次");
m.put(new C(2222), b);
System.out.println(b.equals("erer "));
System.out.println( m.containsValue("测试字符串")); //按理不是返回true,结果返回false
}
}
与HashSet类似,也尽量不要把可变对象作为hashMap和Hashtable作为key,如果非得,也尽量不要在程序里修改他的实例变量。
HashSet有个子类是LinkedHashSet,hashMap也有子类LinkedhashMap子类 LinkedhashMap用一个双向链表维护Key-value顺序。迭代顺序和插入顺序一致。可以维持顺序的同时又避免使用TreeMap增加的成本。
package Test01;
import java.util.LinkedHashMap;
public class D{
public static void main(String[] args) {
LinkedHashMap m =new LinkedHashMap();
m.put("语文", 80);
m.put("数学", 23);
m.put("英语", 123);
m.forEach((key,value) -> System.out.println( key +" -->"+value));
}
}
下面讲解下Properties类,他是Hashtable的子类(Properties类是一个Key,value都是String类的Map),它处理属性文件(windows的Ini文件就是一种属性文件)特别方便。有以下方法
String getProperty(String key)获得指定属性名的属性值
String getProperty(String key,String defaultValue)获得指定属性名的属性值,如果没有,就设置为defaultValue
Object setProperty(String key,String Value)设置属性值,;类似Hashtable的put方法
另外还有两种方法读写属性文件
void load(InputStream inputStream) 从属性文件中(以输入流的形式展示)加载属性值,把加载到的Key-value追加到Properties类里。
void store(OutputStream outputStream,String comments) 把Properties中的Key-value输出到指定的属性文件中,以输出流显示。
package Test01; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties; public class TestProperties {
public static void main(String[] args) throws FileNotFoundException, IOException {
Properties properties =new Properties();
properties.setProperty("a", "今天");
properties.setProperty("b", "天气");
properties.store(new FileOutputStream("a.ini"), "contrm");
System.out.println(properties.getProperty("a"));
Properties prop2 =new Properties();
prop2.setProperty("c", "不错");
prop2.load(new FileInputStream("a.ini"));
System.out.println(prop2);
}
}
hashSet和其子类都是靠hash算法来决定集合元素的存储位置,并控制集合的大小。
对于Hashtable和HashMap和子类来说,采用hash算法决定Map中key的存储,可增加Key集合大小。
hash表里可以存储元素的位置被称为“桶”,单个桶存储一个元素是有最好的性能。
通过hashcode值算出桶的存储位置。接着从桶里取出元素。
但是hash表是open 的,发生hash冲突时单个桶可以存储多个元素,元素以链表形式存储,必须按顺序搜索。
hash表有以下属性:
容量:hash表的桶的数量
初始化容量:创建hash表时桶的数量,在构造器中指定初始化容量。
尺寸:当前hash表记录的数量。
负载因子:为0表示空的hash表,0.5表示半满的。轻负载的hash表表示冲突少,适合插入和查询。
还有个负载极限:决定最大填满程度,达到负载极限时自动的成倍增加容量。将原有的对象重新分配 ,放入新的桶里,叫做rehashing.较低的负载极限可以提高查询数据的性能,但会增加hash表
所占用的内存的开销。
如果最开始就知道HashSet和HashMap Hashtable会保存许多记录,就在创建时用较大的初始化容量。初始化容量大于 包含的最大记录数除以负载极限就不会rehashing.
使用足够大的初始化容量能更高效得增加记录。但是太高会浪费空间。
与hashMap基本相似,但是区别在于HashMap的Key保留了对实际对象的强引用。意思就是:只要该HashMap对象不销毁,所有的key引用的对象就不会被垃圾销毁。
但是WeakHashMap对象的key引用的对象没有被其他强引用变量引用,则这些key引用的对象就可能被垃圾回收。举例子:
.....
IdentityHashMap实现类
实现机制与HashMap基本类似。但是对于Key的判断相等不同。IdentityHashMap key===(查下资料)才等,而HashMap equals为true,且hashcode值相等即可。
,举例
Map集合-主要HashMap和Hashtable的更多相关文章
- Collections工具类、Map集合、HashMap、Hashtable(十八)
1.Map集合概述和特点 * A:Map接口概述 * 去重复, * 查看API可以知道, * 将键映射到值的对象, * 一个映射不能包含重复的键, * 每个键最多只能映射到一个值.* B:Map接口和 ...
- Map集合、HashMap集合、LinkedHashMap集合、Hashtable集合、Collections工具类和模拟斗地主洗牌和发牌
1.Map集合概述和特点 * A:Map接口概述 * 查看API可以知道: * 将键映射到值的对象 * 一个映射不能包含重复的键 * 每个键最多 ...
- Java基础知识强化之集合框架笔记57:Map集合之HashMap集合(HashMap<Student,String>)的案例
1. HashMap集合(HashMap<Student,String>)的案例 HashMap<Student,String>键:Student 要求:如果两个对象 ...
- Java基础知识强化之集合框架笔记56:Map集合之HashMap集合(HashMap<String,Student>)的案例
1. HashMap集合(HashMap<String,Student>)的案例 HashMap是最常用的Map集合,它的键值对在存储时要根据键的哈希码来确定值放在哪里. HashMap的 ...
- Java基础知识强化之集合框架笔记54:Map集合之HashMap集合(HashMap<String,String>)的案例
1. HashMap集合 HashMap集合(HashMap<String,String>)的案例 2. 代码示例: package cn.itcast_02; import java.u ...
- java 集合之HashMap、Hashtable、LinkedHashMap、TreeMap
HashMap 实现了Map接口,线程不安全. 实现原理: HashMap由数组+链表组成,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的. 如果通过hash定位到数组位置没有链表, ...
- Java自学-集合框架 HashMap和Hashtable的区别
HashMap和Hashtable之间的区别 步骤 1 : HashMap和Hashtable的区别 HashMap和Hashtable都实现了Map接口,都是键值对保存数据的方式 区别1: Hash ...
- Java基础知识强化之集合框架笔记63:Map集合之HashMap嵌套ArrayList
1. ArrayList集合嵌套HashMap集合并遍历. 需求:假设ArrayList集合的元素是HashMap.有3个.每一个HashMap集合的键和值都是字符串.元素我已经完成,请遍历. 结果: ...
- Java基础知识强化之集合框架笔记62:Map集合之HashMap嵌套HashMap
1. HashMap嵌套HashMap 传智播客 jc 基础班 陈玉楼 20 高跃 ...
- Java基础知识强化之集合框架笔记55:Map集合之HashMap集合(HashMap<Integer,String>)的案例
1. HashMap集合(键是Integer,值是String的案例) 2. 代码示例: package cn.itcast_02; import java.util.HashMap; import ...
随机推荐
- 【Java】修饰符
修饰符(Modifier):是用于限定类型以及类型成员的声明的一种符号. 其用来定义类.方法或者变量,通常放在语句的最前端. 例子: public class Person { default Str ...
- MySQL 的默认字符集为什么是 latin1?
是处于历史原因还是其他? 为什么至今不选择utf-8? West European Character Sets
- PDA自带有红外扫描头,不用点击焦点就能超高速超精准的扫条码、扫二维码
参考牛人DelphiTeacher的<PDA扫码?不要慌,只要20行代码!> 摘要: 实现监听器接口 然后在系统中注册该监听器,注册时指定只接收名称为com.kte.scan.result ...
- 🎀Charles激活
简介 Charles激活码计算 激活 Help -> Register Charles 添加 Registered Name 和计算出的 License key 点击 Register Java ...
- Python3_python2打包exe文件
最近要把绿盟报告导出脚本打包成一个exe,原本是一个py2的文件Vulreport.py,我做了如下步骤. 1.py2topy3 Python3 2to3.py -w Vulreport.py 2.p ...
- SpringCloud项目使用nacos配置
SpringCloud项目 pom.xml 注意SpringCloud和SpringCloudAlibaba的版本对应. Spring Cloud Alibaba Version Spring Clo ...
- 【漏洞扫描】Nuclei v3.4.1 下载方法(附快速下载链接)
简介 Nuclei v3.4.1是一款强大的漏洞扫描器,并且拥有社区维护的海量漏洞POC,工具质量十分的高.Nuclei 用于基于模板跨目标发送请求,从而实现零误报并提供对大量主机的快速扫描.Nucl ...
- 代码随想录第十四天 | Leecode 103. 二叉树的层序遍历、226. 翻转二叉树、101. 对称二叉树、104. 二叉树的最大深度、111. 二叉树的最小深度
写在前面 今天补一下昨天没有写的层序遍历,层序遍历有整整十道题,打算只在博客详细写一道,后续的题目就自己在Leecode上刷一刷得了,不准备全部写下来(计划是只在博客给出每一道题目的链接).除此之外还 ...
- 鸿蒙开发中console.log和hilog的区别
在日常开发中打印日志是调试程序非常常用的操作,在鸿蒙的官方文档中介绍了hilog这种方式,有些前端转过来的友友发现console.log也可以进行日志打印.有一段时候幽蓝君也非常喜欢使用console ...
- Python 面向对象 之 @property
Python 面向对象 之 Property 初识 @property Property 是 Python 类的一个内置的 装饰器. @property 的作用是 将一个方法, 变为属性来调用. 装饰 ...