Map集合
map集合使用的场景
比如:IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等,这种一 一对应的关系,就叫做映射。Java提供了专门的集合类用来存放这种对象关系的对象,即 java.util.Map 接
口。
map的存储数据方式和Collection存储数据方式?
map
Collection
由此可见
Collection中集合试独立存在的(称为单列集合)
map中集合成对出现的(称为双列集合)
注意:Map 中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。
常用的Map集合
1.HashMap
- HashMap<K,V>:存储数据采用的哈希表结构,元素的存取顺序不能保证一致。由于要保证键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。
2.LinkedHashMap
- HashMap下有个子类LinkedHashMap,存储数据采用的哈希表结构+链表结构。通过链表结构可以保证元素的存取顺序一致;通过哈希表结构可以保证的键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。
Map接口中的集合都有两个泛型变量<K,V>,在使用时,要为两个泛型变量赋予数据类型。两个泛型变量<K,V>的数据类型可以相同,也可以不同。
Map常用方法
案例一
public class test0 {
public static void main(String[] args) {
//创建map集合
HashMap<String, String> map = new HashMap<>();
//给map添加元素 <k,v>
map.put("张三","张三老婆");
map.put("李四","李四老婆");
map.put("王五","王五老婆");
map.put("我","我老婆");
//输出 {李四=李四老婆, 我=我老婆, 张三=张三老婆, 王五=王五老婆}
System.out.println(map);
//通过指定的K删除
System.out.println(map.remove("我"));
//输出 {李四=李四老婆, 张三=张三老婆, 王五=王五老婆}
System.out.println(map);
//通过指定的k 查询对应的v
System.out.println(map.get("张三"));//输出 张三老婆
System.out.println(map.get("李四"));//输出 李四老婆
System.out.println(map.get("王五"));//输出 王五老婆
}
}
案例二 map遍历方式通过 keyset()方法
public class test1 {
public static void main(String[] args) {
/**
* Map遍历方式
* 键找值方式:即通过元素中的键,获取键所对应的值
* 1. 获取Map中所有的键,由于键是唯一的,所以返回一个Set集合存储所有的键。方法提示: keyset()
* 2. 遍历键的Set集合,得到每一个键。
* 3. 根据键,获取键所对应的值。方法提示: get(K key)
*
*/
HashMap<String, String> m = new HashMap<>();
m.put("张三","张三老婆");
m.put("李四","李四老婆");
m.put("王五","王五老婆");
m.put("我","我老婆");
//获取所有的k
Set<String> ks = m.keySet();
//遍历集合获取每一个K
for (String k : ks) {
String v = m.get(k);//通过K 获取对应的V
System.out.println(k+"**"+v);
/*
李四**李四老婆
我**我老婆
张三**张三老婆
王五**王五老婆
*/
}
}
}
k=键 v=值
案例三 Map通过entrySet()遍历键值
public class test2 {
public static void main(String[] args) {
/**
* 键值对方式:即通过集合中每个键值对(Entry)对象,获取键值对(Entry)对象中的键与值。
* 1. 获取Map集合中,所有的键值对(Entry)对象,以Set集合形式返回。方法提示: entrySet() 。
* 2. 遍历包含键值对(Entry)对象的Set集合,得到每一个键值对(Entry)对象。
* 3. 通过键值对(Entry)对象,获取Entry对象中的键与值。 方法提示: getkey() getValue()
*/
HashMap<String, String> m = new HashMap<>();
m.put("张三","张三老婆");
m.put("李四","李四老婆");
m.put("王五","王五老婆");
m.put("我","我老婆");
// 获取 所有的 entry对象 entrySet
Set<Map.Entry<String, String>> set = m.entrySet();
// 遍历得到每一个entry对象
for (Map.Entry<String, String> entry : set) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"--"+value);
/**
*李四--李四老婆
* 我--我老婆
* 张三--张三老婆
* 王五--王五老婆
*/
}
}
}
Map的特点
Map特点
1.Map集合是一个双列集合,一个元素包含两个值(一个key,一个value)
2.Map集合中的元素,key和value的数据类型可以相同,也可以不同
3…Map集合中的元素,key是不允许重复的,value是可以重复的
4.Map集合中的元素,key和value是一一对应
HashMap特点
1.HashMap集合底层是哈希表:查询的速度特别的快
java1.8之前数组+单向链表
java1.8之后数组+单向链表|红黑树
2.hashMap集合是一个无序的集合,存储元素和取出元素的顺序有可能不一致
3.线程不安全
LinkedHashMap的特点
1…LinkedHashMap集合底层是哈希表+链表(保证迭代的顺序)
2.LinkedHashMap集合是一个有序的集合,存储元素和取出元素的顺序是一致的
Map自定义存储
public class Student {
private String name;
private Integer age;
public Student() { }
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return Objects.equals(name, student.name) &&
Objects.equals(age, student.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
public class test00 {
public static void main(String[] args) {
Map<Student,String>map = new HashMap<Student,String>();
map.put(new Student("张无忌",11),"武当山");
map.put(new Student("赵敏",11),"蒙古");
Set<Student> students = map.keySet();
for (Student k: students) {
String v = map.get(k);
System.out.println(k+"xx"+v);
/**
*Student{name='张无忌', age=11}xx武当山
* Student{name='赵敏', age=11}xx蒙古
*/
}
}
}
LinkedHashMap
public class test3 {
public static void main(String[] args) {
LinkedHashMap<String, String> m = new LinkedHashMap<String, String>();
/**
* 元素存放有序
*/
m.put("张三","张三老婆");
m.put("李四","李四老婆");
m.put("王五","王五老婆");
m.put("我","我老婆");
Set<Map.Entry<String, String>> entries = m.entrySet();
for (Map.Entry<String, String> entry : entries) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key +"**"+value);
/**
*张三**张三老婆
* 李四**李四老婆
* 王五**王五老婆
* 我**我老婆
*/
}
}
}
面试
HashMap 和 HashTable 有什么区别?
1.HashMap 线程不安全,HashTable 线程安全
2.HashMap 允许键值为null,HashTable 不允许
3.HashMap 默认容量16,HashTable 为11
4.由于线程安全,所以 HashTable 的效率低 HashMap效率高;