JDK8
测试:
public class test1 {
public static void main(String[] args) {
Map map = new HashMap();
map.put("nbo1","张三");
map.put("nbo2","李四");
map.put("nbo3","王五");
map.put("nbo1","李向");
System.out.println(map);
}
}
运行结果:
{nbo2=李四, nbo1=李向, nbo3=王五}
在之前Collection接口实现集合类,都是使用key来直接保存存储的数据。而Map接口实现集合类会使用key和value两个相互映射来保存数据,key可以看作是一个序号或者身份证号,value才是真正保存的数据
我们知道当使用Map实现集合类存放了一个元素时,会有key和value,也就是键和值,键key可以看作是一个序号,值valuie可以看作是内容,一个序号对应一个内容,而这两个东西是存放在一个Node节点中的。但是因为Map不是Collection接口,Map没有实现iterator接口,所以要遍历不是很方便。因此在添加元素时除了会保存到table数组时,还会做一件事情就是保存到一个EntrySet集合中,EntrySet集合中的保存类型不是Node类型而是Entry类型。
但是这里的意思不是说把table中的数组都复制一份到EntrySet集合中,而是单纯的引用,也就是把EntrySet中的一个个Entry指向的还是table中的一个个Node。而为什么要做这么一件事呢,这是因为在EntrySet集合中保存的key是Set接口类型的value是Collection接口类型的,当然实际运行类型还是Node,只不过这样就可以使用迭代器了。
public class test1 {
public static void main(String[] args) {
Map map = new HashMap();
map.put("nbo1","张三");
map.put("nbo2","李四");
map.put("nbo3","王五");
map.put("nbo1","李向");
Set set = map.entrySet();
for (Object obj:set) {
Map.Entry entry = (Map.Entry) obj;
System.out.println(entry.getClass());
System.out.println(entry.getKey()+"-"+entry.getValue());
}
}
}
运行结果:
class java.util.HashMap N o d e n b o 2 − 李四 c l a s s j a v a . u t i l . H a s h M a p Node nbo2-李四 class java.util.HashMap Nodenbo2−李四classjava.util.HashMapNode
nbo1-李向
class java.util.HashMap$Node
nbo3-王五
口语说法:key:键 ———— value:值
使用演示
public class test2 {
public static void main(String[] args) {
Map map = new HashMap();
// 1. put(key,value);添加,当再次添加同一个键,但是值不同时,会对值进行替换
map.put("no1","李青");
map.put("no2","绿意");
map.put("no1","李青");
System.out.println(map);
// 2. remove(key);根据键删除这对键和值
map.remove("no1");
System.out.println(map);
// 3. get(key);根据键获取值
System.out.println(map.get("no2"));
// 4. size();获取当前集合的元素个数
System.out.println(map.size());
// 5. isEmpty():判断当前集合元素个数是否为0
System.out.println(map.isEmpty());
// 6. containsKey(key);查找传入的键是否存在
System.out.println(map.containsKey("no2"));
// 7. clear:清除集合所有元素,归0
map.clear();
System.out.println(map);
}
}
运行结果:
{no2=绿意, no1=李青}
{no2=绿意}
绿意
1
false
true
{}
上面了解到了map存入的数据还会有一个EntrySet集合指向table数组中的数据,所以遍历也是围绕这个来操作
Map实现接口可以分为三大类:每类有两种方式
1.获取键key,再通过键来获取值value
2.直接获取值value,但是无法通过值value获取key,所以只能输出value
3.通过EntrySet,同时获取到键和值
遍历用到的方法
演示:
public class test3 {
public static void main(String[] args) {
Map map = new HashMap();
map.put("no1","淘宝");
map.put("no2","天猫");
map.put("no3","京东");
//第一类:获取所有键,再通过get方法获取值。
//第一种方式:获取键后使用增强for
System.out.println("第一种");
Set set = map.keySet();
for (Object key:set) {
System.out.println(key+"-"+map.get(key));
}
System.out.println("第二种");
//第二种方式:获取键后,使用迭代器
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next+"-"+map.get(next));
}
//第二类:获取所有值
//第三种方式:增强for,直接输出value
System.out.println("第三种");
Collection value = map.values();
for (Object o: value) {
System.out.println(o);
}
//第四种:使用迭代器直接输出
System.out.println("第四种");
Iterator iterator2 = value.iterator();
while (iterator2.hasNext()) {
Object next = iterator2.next();
System.out.println(next);
}
//第三类:获取所有键和值,再向下转型成Entry,使用它的getKey和getValue方法
//第五种:获取所有键和值,增强for操作
System.out.println("第五种");
Set entrySet = map.entrySet();
for (Object e:entrySet) {
Map.Entry entry = (Map.Entry) e;
System.out.println(entry.getKey()+"-"+entry.getValue());
}
//第六种:迭代器操作
System.out.println("第六种");
Iterator iterator1 = entrySet.iterator();
while (iterator1.hasNext()) {
Object next = iterator1.next();
Map.Entry entry = (Map.Entry) next;
System.out.println(entry.getKey()+"-"+entry.getValue());
}
}
}
运行结果:
第一种
no2-天猫
no1-淘宝
no3-京东
第二种
no2-天猫
no1-淘宝
no3-京东
第三种
天猫
淘宝
京东
第四种
天猫
淘宝
京东
第五种
no2-天猫
no1-淘宝
no3-京东
第六种
no2-天猫
no1-淘宝
no3-京东
使用HashMap添加三个员工对象,要求:
键:员工id
值:员工对象
且遍历显示工资18000的员工至少使用两种遍历方式
员工类:姓名,工资,员工id
public class test4 {
@SuppressWarnings({"all"})
public static void main(String[] args) {
HashMap map = new HashMap();
staff s1 = new staff(01,"李四",16000);
staff s2 = new staff(02,"王五",23000);
staff s3 = new staff(03,"赵三",12000);
staff s4 = new staff(04,"李明",19000);
map.put(s1.id,s1);
map.put(s2.id,s2);
map.put(s3.id,s3);
map.put(s4.id,s4);
//第一种:获取直接获取所有值,判断运行类型是否是staff,如果是就向下转型,再判断薪水决定是否输出
Collection c = map.values();
for (Object value:c) {
if (value instanceof staff){
staff s = (staff) value;
if (s.sal>18000){
System.out.println(s);
}
}
}
//第二种:直接获取所有键和值
Set entrySet = map.entrySet();
for (Object entry:entrySet) {
Map.Entry entry1 = (Map.Entry) entry;
staff s = (staff) entry1.getValue();
if (s.sal>18000){
System.out.println(s);
}
}
}
}
class staff{
String name;
int id;
double sal;
public staff(int id,String name,double sal) {
this.name = name;
this.id = id;
this.sal = sal;
}
@Override
public String toString() {
return "staff{" +
"name='" + name + '\'' +
", id=" + id +
", sal=" + sal +
'}';
}
}
Hashtable也是Map接口的实现类,与HashMap是同级关系
初始
实现类 | 出现版本 | 线程安全 | 效率 | 是否可以存null |
---|---|---|---|---|
HashMap | 1.2 | 不安全 | 高 | 允许 |
Hashtable | 1.0 | 安全 | 较低 | 不允许 |
public class test5 {
public static void main(String[] args) {
Properties properties = new Properties();
//增加
properties.put("no1",100);
properties.put("no2",200);
//删除,根据key,删除key-value
properties.remove("no1");
System.out.println(properties);
//改(替换)
properties.put("no2",90);
System.out.println(properties);
//查,根据key获取value
System.out.println(properties.get("no2"));
}
}