什么是Map集合
现实生活中,常会看到这样的一种集合:IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等,这种一一对应的关系,就叫做映射。Java提供了专门的集合类用来存放这种对象关系的对象,即java.util.Map
接口。
Map与Collection集合区别
Collection集合
单列集合,一次只能添加一个元素
有的是有索引,有的没有索引
有的集合可以存储重复的元素,有的则不可以
有的元素是无序的,有的是有序的
Map集合
Map集合是双列集合,由Key和Value组成
Key是不允许重复的,Value是允许重复
Key允许存null值的,但是只能存储唯一的一个
Map集合中常用的子类
- HashMap
存储数据采用的哈希表结构,元素的存取顺序不能保证一致。由于要保证键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。
- LinkedHashMap
HashMap下有个子类LinkedHashMap,存储数据采用的哈希表结构+链表结构。通过链表结构可以保证元素的存取顺序一致;通过哈希表结构可以保证的键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。
Map接口中常用的方法
方法名 |
说明 |
public V put(K key, V value) |
把指定的键与指定的值添加到Map集合中。 |
public V remove(Object key) |
把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。 |
public V get(Object key) |
根据指定的键,在Map集合中获取对应的值。 |
boolean containsKey(Object key) |
判断集合中是否包含指定的键。 |
public Set keySet() |
获取Map集合中所有的键,存储到Set集合中。 |
public Set |
获取到Map集合中所有的键值对对象的集合(Set集合)。 |
==代码演示==
public class MapDemo {
public static void main(String[] args) {
//创建 map对象
HashMap map = new HashMap();
//添加元素到集合
map.put("唐三", "小舞");
map.put("戴沐白", "朱竹清");
map.put("奥奇卡", "宁荣荣");
System.out.println(map);
//String remove(String key)
System.out.println(map.remove("奥斯卡"));
System.out.println(map);
// 想要查看 谁是谁的对象
System.out.println(map.get("唐三"));
System.out.println(map.get("戴沐白"));
System.out.println(map.get("马红俊"));//找不到返回null
}
}
==注意事项==
使用put方法时,若指定的键(key)在集合中没有,则没有这个键对应的值,返回null,并把指定的键值添加到集合中;
若指定的键(key)在集合中存在,则返回值为集合中键对应的值(该值为替换前的值),并把指定键所对应的值,替换成指定的新值。
Map集合的遍历
keySet
即通过元素中的键,获取键所对应的值
分析步骤
1. 获取Map中所有的键,由于键是唯一的,所以返回一个Set集合存储所有的键。方法提示:keyset()
2. 遍历键的Set集合,得到每一个键。
3. 根据键,获取键所对应的值。方法提示:get(K key)
代码演示
public class MapDemo01 {
public static void main(String[] args) {
//创建Map集合对象
HashMap map = new HashMap();
//添加元素到集合
map.put("唐三", "小舞");
map.put("戴沐白", "朱竹清");
map.put("奥奇卡", "宁荣荣");
//获取所有的键 获取键集
Set keys = map.keySet();
// 遍历键集 得到 每一个键
for (String key : keys) {
//key 就是键
//获取对应值
String value = map.get(key);
System.out.println(key+"的CP是:"+value);
}
}
}
EntrySet
什么是Entry
Map
中存放的是两种对象,一种称为key(键),一种称为value(值),它们在Map
中是一一对应关系,这一对对象又称做Map
中的一个Entry(项)
。Entry
将键值对的对应关系封装成了对象。即键值对对象,这样我们在遍历Map
集合时,就可以从每一个键值对(Entry
)对象中获取对应的键与对应的值。
获取Entry
Map集合中通过
entrySet()
方法获取Entry对象
public Set
Entry对象中的常用方法
既然Entry表示了一对键和值,那么也同样提供了获取对应键和对应值得方法
方法名 |
说明 |
public K getKey() |
获取Entry对象中的键 |
public V getValue() |
获取Entry对象中的值 |
System.out.println("---------通过iterator-------------");
Iterator
Map存储自定义类型元素
需求
每位学生(姓名,年龄)都有自己的家庭住址。那么,既然有对应关系,则将学生对象和家庭住址存储到map集合中。学生作为键, 家庭住址作为值。
需要: 学生姓名相同并且年龄相同视为同一名学生。
编写学生类
public class Student {
private String name;
private int age;
public Student() { }
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
@Override
public boolean equals(Ob服务器托管网ject o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
编写测试类
public class HashMapTest {
public static void main(String[] args) {
//1,创建Hashmap集合对象。
Mapmap = new HashMap();
//Mapmap2=new HashMap();
//2,添加元素。
map.put(newStudent("lisi",28), "上海");
map.put(newStudent("wangwu",22), "北京");
map.put(newStudent("zhaoliu",24), "成都");
map.put(newStudent("zhouqi",25), "广州");
map.put(newStudent("wangwu",22), "南京");
//3,取出元素。键找值方式
SetkeySet = map.keySet();
for(Student key: keySet){
String value = map.get(key);
System.out.println(key.toString()+"....."+value);
}
}
}
总结
- 当给HashMap中存放自定义对象时,如果自定义对象作为key存在,这时要保证对象唯一,必须复写对象的hashCode和equals方法(如果忘记,请回顾HashSet存放自定义对象)。
- 如果要保证map中存放的key和取出的顺序一致,可以使用
java.util.LinkedHashMap
集合来存放。
LinkedHashMap
什么是LinkedHashMap
我们知道HashMap保证成对元素唯一,并且查询速度很快,可是成对元素存放进去是没有顺序的,那么我们要保证有序,还要速度快怎么办呢?我们就可以使用LinkedHashMap
LinkedHashMap的特点
有序的,而且key不允许重复
数据结构: 哈希表 + 链表
总结:有序,key唯一
代码演示
public class LinkedHashMapDemo {
public static void main(String[] args) {
LinkedHashMap map = new LinkedHashMap();
map.put("唐三", "小舞");
map.put("戴沐白", "朱竹清");
map.put("奥奇卡", "宁荣荣");
Set> entrySet = map.entrySet();
for (Entry entry : entrySet) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
}
}
TreeMap
TreeMap类概述
键是红黑树结构,可以保证键的排序和保证唯一
public static void main(String[] args) {
// 创建集合对象 会对key进行排序,并且唯一
TreeMap tm = new TreeMap();
// 创建元素并添加元素
tm.put("a", "你好");
tm.put("c", "世界");
tm.put("e", "爪哇");
tm.put("b", "世界2");
tm.put("e", "爪哇EE");
// 遍历集合
Set set = tm.keySet();
for (String key : set) {
String value = tm.get(key);
System.out.println(key + "---" + value);
}
}
HashMap和Hashtable的区别?—面试题
/*
HashMap和Hashtable是Java中两种常用的哈希表实现,它们在功能和使用上有一些区别。
1. 线程安全性:
- HashMap是非线程安全的,不保证在多线程环境下的正确性。
- Hashtable是线程安全的,通过使用同步方法来确保线程安全。
2. 空值(null)的处理:
- HashMap允许使用null作为键(key)和值(value),即可以存储null键和null值。
- Hashtable不允许使用null作为键和值,如果尝试存储null,则会抛出NullPointerException。
3. 继承和实现关系:
- HashMap是Hashtable的轻量级实现,实现了Map接口,不是线程安全的。
- Hashtable是Dictionary类的子类,实现了Map接口,并且是线程安全的。
4. 性能:
- HashMap因为不需要进行线程安全的同步处理,通常比Hashtable的性能更好。
- Hashtable在多线程环境下具有额外的开销,可能对性能产生负面影响。
总体来说,如果你在单线程环境下使用哈希表,并且可能需要处理空值,推荐使用HashMap。而如果在多线程环境下使用哈希表,或者需要线程安全性,可以选择Hashtable。
*/
public class HashtableDemo {
public static void main(String[] args) {
// HashMap hm = new HashMap();
Hashtable hm = new Hashtable();
hm.put("it001", "hello");
// hm.put(null, "world"); //NullPointerException
// hm.put("java", null); // NullPointerException
System.out.println(hm);
}
}
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net