JavaSE-Map
Map集合
5.0 重点掌握
5.1 Map集合概述
现实生活中,经常会出现这么一种集合:如 身份证与个人,ip与主机名等,这种一一对应的关系,就叫做映射,
Java提供了专门的集合来存放这种对象关系映射,即java.util.Map接口
其中,Map接口和Collection接口存储数据的形式是不同的
- Collection接口定义了单列集合规范,每次存储一个元素。Collection
- Collection中的集合,元素是独立存在的 ( 单身狗 ),向集合中存储元素采用一个一个的方式存储
- Map接口定义了双列集合的规范,每次存放一对元素。Map<K,V>
- Map中的集合。元素是成对成对的 ( 小情侣 ),每个元素由键和值两部分组成,通常键可以找到指定的值,
- Map中的集合,键是唯一的,值可以重复,每个键只能对应一个值
5.2 Map常用的子类
Map有多个子类,其中常用的事HashMap和LinkedHashMap
- HashMap<K,V> : 存储数据采用的是哈希表结构,元素的存取顺序不能保持一致,由于要保证键的唯一,不重复,需要重写键的hashCode()方法、equals()方法
- LinkedHashMap(K,V) :HashMap下的子类LinkedHashMap,存储数据采用的事哈希表+链表结构,通过链表结构可以保证元素的存储顺序一致。通过哈希表结构可以保证键的唯一和不重复。需要重写键的hashCode()方法和equals()方法
5.3 Map接口中的常用方法
Map接口中定义了很多方法:常用如下:
Map接口常用方法案例
import java.util.HashMap;
import java.util.Map;public class Demo01Map {/*Map集合的特点1、Map是一个双列集合,一个元素包含两个值:一个key一个value2、Map集合中的元素,key和value的数据类型,可以相同,也可以不同3、Map集合中的元素,key是不允许重复的,value是可以重复的4、Map集合中的元素,key和value是一一对应的HashMap实现了Map接口1、HashMap底层是哈希表,查询速度快2、HashMap是一个无序的集合,存储元素和取出元素的顺序可能不一致LinkHashMap继承自HashMap1、LinkHashMap集合底层是哈希表+链表,保证了迭代的顺序2、LinkHashMap是一个有序的集合,存储元素和取出元素的顺序是一致的*/public static void main(String[] args) {/*1 将指定的值与此映射中的指定键相关联public V put(K key, V value)返回值:Vkey不重复,返回值是nullkey重复,原先value被覆盖,返回覆盖的value值*/method1();/*2 从该集合中删除指定键的映射(如果存在public V remove(Object key)返回值:Vkey存在,键值对被删除,返回被删除的key对应的值key不存在,返回值为null*/method2();/*3 如果此映射包含指定键的映射,则返回 trueboolean containsKey(Object key)包含返回true,不包含返回false*/method3();/*4 public V get(Object key)返回到指定键所映射的值返回值:V如果key存在,返回对应的value的值如果key不存在,返回null*/method4();}private static void method4() {Map<Integer,String> map = new HashMap<>();map.put(1,"赵四");map.put(2,"刘能");map.put(3,"谢广坤");map.put(4,"王老七");String s1 = map.get(1);System.out.println(s1);//赵四String s2 = map.get(5);//nullSystem.out.println(s2);System.out.println(map);}private static void method3() {Map<String,String> map = new HashMap<>();map.put("悟空","猴子");map.put("八戒","飞猪");map.put("白龙马","小白龙");boolean b1 = map.containsKey("八戒");System.out.println(b1);//trueboolean b2 = map.containsKey("唐僧");System.out.println(b2);//falseSystem.out.println(map);}private static void method2() {Map<String,String> map = new HashMap<>();map.put("季军","克罗地亚");map.put("亚军","法国");map.put("冠军","阿根廷");String s1 = map.remove("亚军");System.out.println(s1);//法国String s2 = map.remove("冷军");System.out.println(s2);//nullSystem.out.println(map);}private static void method1() {Map<String, String> map = new HashMap<>();String s1 = map.put("阿根廷", "梅西");System.out.println(s1);//nullString s2 = map.put("阿根廷", "夺冠");System.out.println(s2);//梅西System.out.println(map);}
}
5.4 Map集合遍历键找值方式
步骤图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sYp0FDSH-1681714245814)(photo/JavaSE12_集合.assest/1671431571924.png)]
Map集合遍历键找值方式案例
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;public class Demo02_MapKeySet {/*Map集合的遍历方式一:通过键找值的方式返回Map中包含的键的Set视图。Set<K> keySet();实现步骤:1、使用Map集合中的keySet()方法,将Map集合中所有的key取出,存储在Set集合中2、遍历Set集合,获取Map集合中的每个Key3、通过Map集合中的get(key)方法,通过key找到value*/public static void main(String[] args) {Map<Integer,String> map = new HashMap<>();map.put(1,"tom");map.put(2,"anny");map.put(3,"jack");map.put(4,"mary");//1、第一步使用keySet()方法。将key存储在Set集合中Set<Integer> s1 = map.keySet();//2、第二步,遍历Set集合//迭代器遍历Iterator<Integer> iterator = s1.iterator();while (iterator.hasNext()){Integer key = iterator.next();//3、第三步,获取Map集合中key对应的valueString value = map.get(key);System.out.println(key+"="+value);}System.out.println("--------------------");//加强for遍历for (Integer key : s1) {//3、第三步,获取Map集合中key对应的valueString value = map.get(key);System.out.println(key+"="+value);}}
}
5.5 Entry键值对对象
Map中存放的是两种对象,一种称为key键,一种称为value值,它们是一一对应的关系
这样的一对对象又称之为Map的一个Entry项,Entry将键值对的对应关系封装成了对象,即键值对对象
在遍历Map集合的时候,就可以从每一个键值对对象Entry中获取对应的键和对应的值
Entry表示一对键和值,同时提供了获取对应键和对应值的方法
- public V getKey( ); 获取Entry对象中的键
- publi V getValue( ); 获取Entry对象中的值
Map集合提供了获取所有Entry对象的方法
- public Set<Map.Entry<K,V>> entrySet( ); 获取所有Map集合中的键值对对象的集合(Set集合)
5.6 Map集合遍历键值对方式
遍历步骤:
遍历键值对方式:通过集合中每个键值对对象Entry,获取键值对对象Entry中的键和值
实现步骤:
- 1、获取Map集合中的所有键值对Entry对象,以Set集合的形式返回,使用entrySet()
- 2、遍历Set集合,得到每一个Entry对象
- 3、通过键值对Entry对象,获取Entry对象的键和值,方式使用getKey()和getValue()
Map集合遍历键值对方式案例
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;public class Demo03_MapEntrySet {/*遍历键值对方式:通过集合中每个键值对对象Entry,获取键值对对象Entry中的键和值实现步骤:1、获取Map集合中的所有键值对Entry对象,以Set集合的形式返回,使用entrySet()2、遍历Set集合,得到每一个Entry对象3、通过键值对Entry对象,获取Entry对象的键和值,方式使用getKey()和getValue()*/public static void main(String[] args) {Map<Integer,String> map = new HashMap<>();map.put(1,"卡卡");map.put(2,"姆巴佩");map.put(3,"梅西");map.put(4,"C罗");//1、获取Map集合中的所有键值对Entry对象,以Set集合的形式返回,使用entrySet()Set<Map.Entry<Integer, String>> set = map.entrySet();//2、遍历Set集合,得到每一个Entry对象//迭代器遍历set集合Iterator<Map.Entry<Integer, String>> it = set.iterator();while (it.hasNext()){Map.Entry<Integer, String> entry = it.next();//3、通过键值对Entry对象,获取Entry对象的键和值,方式使用getKey()和getValue()Integer key = entry.getKey();String value = entry.getValue();System.out.println(key+"="+value);}System.out.println("-------------------------");//加强for遍历set集合for (Map.Entry<Integer, String> entry:set){//3、通过键值对Entry对象,获取Entry对象的键和值,方式使用getKey()和getValue()Integer key = entry.getKey();String value = entry.getValue();System.out.println(key+"="+value);}}
}
5.7 HashMap存储自定义类型键值
HashMap存储自定义类型键值,Map集合保证key是唯一的,
作为key的元素,必须重写hashCode()和equals()方法。
案例:
import java.util.Objects;public class User {private String name;private String address;public User() {}public User(String name, String address) {this.name = name;this.address = address;}@Overridepublic String toString() {return "User{" +"name='" + name + '\\'' +", address='" + address + '\\'' +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;User user = (User) o;return Objects.equals(name, user.name) && Objects.equals(address, user.address);}@Overridepublic int hashCode() {return Objects.hash(name, address);}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}
}
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;public class Demo04_MapDefined {public static void main(String[] args) {/*方式1:String字符串作为key,user对象作为valuekey相同,值会覆盖*/method1();System.out.println("------------------");/*方式2:user对象作为key。字符串作为value使用对象作为key,必须重写实体类的hashCode和equals方法否则,key相同,值也不会覆盖*/method2();}private static void method1() {Map<String,User> map = new HashMap<>();map.put("东北",new User("赵本山","辽宁"));map.put("华北",new User("司马南","北京"));map.put("华南",new User("刘德华","香港"));map.put("东北",new User("小沈阳","哈尔冰"));//1、通过keySet获取Map集合所有的keySet<String> set = map.keySet();//2.加强for遍历Set集合,得到key,再通过key获取Map集合中的valuefor (String key:set) {//3、通过key获取valueUser user = map.get(key);System.out.println(key+"="+user);}}private static void method2() {Map<User,String> map = new HashMap<>();map.put(new User("张三","北京"),"喜欢篮球");map.put(new User("李四","上海"),"喜欢排球");map.put(new User("王五","广州"),"喜欢足球");map.put(new User("张三","北京"),"喜欢棒球");//1、使用wntrySet()获取Map集合中的键值对对象EntrySet<Map.Entry<User, String>> entrySet = map.entrySet();//2.使用迭代器遍历获取entry对象Iterator<Map.Entry<User, String>> it = entrySet.iterator();while (it.hasNext()){Map.Entry<User, String> entry = it.next();//3、获取entry中的键和值User user = entry.getKey();String value = entry.getValue();System.out.println(user+"="+value);}}
}
- 重写之后,key相同,值会被覆盖
- 未重写,key相同,值不会被覆盖
5.8 LinkedHashMap
HashMap保证课成对元素的唯一,但是无法保证数据的有序。其子类LinkedHashMap即可以实现
LinkedHashMap的底层是链表+哈希表的存储结构,链表用于记录元素的顺序
- HashMap 存取顺序不同
- LinkedHashMap 存取顺序相同
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;public class Demo05_LinkedHashMap {public static void main(String[] args) {//1、创建HashMap对象,添加数据并打印HashMap<String,String> map = new HashMap<>();map.put("a","英文");map.put("c","俄文");map.put("b","中文");map.put("d","德文");System.out.println(map);//2、创建LinkedHashMap对象,添加数据并打印LinkedHashMap<Integer,String> linkedHashMap = new LinkedHashMap();linkedHashMap.put(1,"AAA");linkedHashMap.put(3,"CCC");linkedHashMap.put(2,"BBB");linkedHashMap.put(4,"DDD");System.out.println(linkedHashMap);}
}
5.9 HashMap和HashTable的区别
- HashTable实现了Map接口
- HashTable底层是哈希表,是一个线程安全的集合,是单线程集合,速度慢
- HashMap底层也是哈希表,是一个线程不安全的集合,是多线程集合,速度快
- HashMap可以存储null值,null键。但是HashTable不可以存储null值,null键
- HashTable在1,2版本之后被HashMap、Arraylist取代了,但是其子类Properties集合依然在使用
- Properties集合是一个唯一可以与IO流两结合的集合
import java.util.HashMap;
import java.util.Hashtable;public class Demo06_HashTable {public static void main(String[] args) {//!、创建HashMap集合,存储null值,null键,并打印输出HashMap<String, String> map = new HashMap<>();map.put(null, "AAA");map.put("A", null);map.put(null, null);System.out.println(map);//2、创建HashTable集合,存储null值,null键,并打印输出Hashtable<Integer, String> table = new Hashtable<>();table.put(1, "AAA");table.put(null, "BBB");table.put(2, null);table.put(null, null);System.out.println(table);/*Hashtable的键和值都不能为null,否则会报空指针异常*/}
}