1、Map集合
- java.util.Map集合与Collection集合是两个体系,Collection是单列集合。
- Map集合的特点:
- Map集合是一个双列集合,一个元素包含两个值:key和value。
- Map集合中的元素key和value的数据类型可以相同也可以不同。
- Map集合中的元素key是不允许重复的,value是可以重复的。
- Map集合中的元素key和value是一一对应的。
2、Map常用子类
- java.util.HashMap集合 implements Map接口
- HashMap集合的特点:
- 底层是哈希表,查询速度特别快,JDK1.8之前:数组+单向链表;JDK1.8之后:数组+单向链表/红黑树(链表长度超过8)
- 是一个无序集合,存储元素和取出元素的顺序不一致。
- java.util.LinkedHashMap集合 extends HashMap集合
- LinkedHashMap集合的特点:
- 底层是哈希表+链表(保证迭代的顺序)
- 是一个有序集合,存储元素和取出元素的顺序一致。
3、Map接口中的常用方法
public V put(K key, V value)
:将指定的键与值添加到Map集合中,返回值为V,若key不重复,则返回V是null,若key重复,将新的value替换重复的value,则返回被替换后的value值。
public V remove(Object key)
:将指定的键对应的键值对元素在Map中删除,返回被删元素的值,若key存在,则返回被删除的值,若key不存在,则返回null。
public V get(Object key)
:根据指定的键,在Map集合中获得对应的值,若key存在,返回对应的value值,若key不存在,返回null。
boolean containsKey(Object key)
:判断集合中是否包含指定的键,若包含,返回true,否则,返回false。
public class Demo01Map {
public static void main(String[] args) {
Map<String,Integer> map = new HashMap<>();
map.put("赵丽颖",168);
map.put("杨颖",165);
map.put("林志玲",178);
boolean b1 = map.containsKey("赵丽颖");
System.out.println("b1:"+b1);
boolean b2 = map.containsKey("赵颖");
System.out.println("b2:"+b2);
Map<String,Integer> map = new HashMap<>();
map.put("赵丽颖",168);
map.put("杨颖",165);
map.put("林志玲",178);
Integer v1 = map.get("杨颖");
System.out.println("v1:"+v1);
Integer v2 = map.get("迪丽热巴");
System.out.println("v2:"+v2);
Map<String,Integer> map = new HashMap<>();
map.put("赵丽颖",168);
map.put("杨颖",165);
map.put("林志玲",178);
System.out.println(map);
Integer v1 = map.remove("林志玲");
System.out.println("v1:"+v1);
System.out.println(map);
Integer v2 = map.remove("林志颖");
System.out.println("v2:"+v2);
System.out.println(map);
Map<String,String> map = new HashMap<>();
String v1 = map.put("李晨", "范冰冰1");
System.out.println("v1:"+v1);
String v2 = map.put("李晨", "范冰冰2");
System.out.println("v2:"+v2);
System.out.println(map);
map.put("冷锋","龙小云");
map.put("杨过","小龙女");
map.put("尹志平","小龙女");
System.out.println(map);
}
}
4、Map集合遍历——方法一:键找值方式
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class Demo02KeySet {
public static void main(String[] args) {
Map<String,Integer> map = new HashMap<>();
map.put("赵丽颖",168);
map.put("杨颖",165);
map.put("林志玲",178);
Set<String> set = map.keySet();
Iterator<String> it = set.iterator();
while (it.hasNext()){
String key = it.next();
Integer value = map.get(key);
System.out.println(key+"="+value);
}
System.out.println("-------------------");
for(String key : set){
Integer value = map.get(key);
System.out.println(key+"="+value);
}
System.out.println("-------------------");
for(String key : map.keySet()){
Integer value = map.get(key);
System.out.println(key+"="+value);
}
}
}
5、Map集合遍历——方法二:使用Entry键值对对象
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class Demo03EntrySet {
public static void main(String[] args) {
Map<String,Integer> map = new HashMap<>();
map.put("赵丽颖",168);
map.put("杨颖",165);
map.put("林志玲",178);
Set<Map.Entry<String, Integer>> set = map.entrySet();
Iterator<Map.Entry<String, Integer>> it = set.iterator();
while(it.hasNext()){
Map.Entry<String, Integer> entry = it.next();
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key+"="+value);
}
System.out.println("-----------------------");
for(Map.Entry<String,Integer> entry:set){
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key+"="+value);
}
}
}
6、HashMap存储自定义类型键值
- Map集合保证key唯一,作为key的元素,必须重写hashCode方法和equals方法,以保证key唯一。
import java.util.HashMap;
import java.util.Map;
public class HashMapPersonDemo {
public static void main(String[] args) {
HashMap<Person,String> map = new HashMap<>();
map.put(new Person("XX1",18),"法国");
map.put(new Person("XX2",19),"英国");
map.put(new Person("XX3",20),"美国");
map.put(new Person("XX1",18),"中国");
for(Map.Entry<Person,String> entry : map.entrySet()){
Person key = entry.getKey();
String value = entry.getValue();
System.out.println(key + "→" + value);
}
}
}
程序结果:
Person{name='XX1', age=18}→中国
Person{name='XX2', age=19}→英国
Person{name='XX3', age=20}→美国
7、LinkedHashMap集合
- java.uti.LinkedHashMap extends HashMap
- LinkedHashMap集合由Map接口的哈希表和链表实现,具有可预知的迭代顺序,有序。
- 底层原理:**哈希表+链表(**记录元素的顺序)
public class LinkedHashMapDemo {
public static void main(String[] args) {
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
map.put("邓超", "孙俪");
map.put("李晨", "范冰冰");
map.put("刘德华", "朱丽倩");
Set<Entry<String, String>> entrySet = map.entrySet();
for (Entry<String, String> entry : entrySet) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
}
}
程序结果:
邓超 孙俪
李晨 范冰冰
刘德华 朱丽倩
8、Hashtable集合
- java.util.Hashtable集合 implements Map接口
- HashMap底层是哈希表,是一个线程不安全的集合,是多线程集合,速度快
- Hashtable底层也是哈希表,是一个线程安全的集合,是单线程集合,速度慢
- HashMap集合(和之前学的所有集合)可以存储null值,null键
- Hashtable集合不能存储null值,null键,若存储null会导致空指针异常NullPointerException
- Hashtable和Vector集合一样,在jdk1.2版本后被更先进的集合(HashMap,ArrayList)取代了。
- Hashtable的子类Properties依然活跃在历史舞台,Properties集合是唯一一个yu与IO流相结合的集合。
9、Map集合练习
- 计算一个字符串中每个字符出现的次数
- 分析
import java.util.HashMap;
import java.util.Scanner;
public class CountCharactersDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串:");
String str = sc.next();
HashMap<Character,Integer> map = new HashMap<>();
for(char c : str.toCharArray()){
if(map.containsKey(c)){
Integer value = map.get(c);
value++;
map.put(c,value);
}else{
map.put(c,1);
}
}
for(Character key : map.keySet()){
Integer value = map.get(key);
System.out.println(key + "="+ value);
}
}
}
10、JDK9对集合添加的优化——of方法
- jdk9的新特性:List接口、Set接口、Map接口里边增加了一个静态方法of,可以给集合一次性添加多个元素。
static List of (E...elements
- 使用前提:当集合中存储的元素的个数已经确定,不再改变时使用
- 注意:
- of方法只适用于List接口、Set接口、Map接口,不适用于接口的实现类;
- of方法的返回值是一个不能改变的集合,集合不能再使用add、put方法添加元素,否则会出现异常;
- Set接口和Map接口调用of方法时,不能有重复元素,否则会抛出异常。
import java.util.List;
import java.util.Map;
import java.util.Set;
public class OfDemo {
public static void main(String[] args) {
List<String> list = List.of("a","b","c","a","d");
System.out.println(list);
Set<String> set = Set.of("a","b","c","d");
System.out.println(set);
Map<String,Integer> map = Map.of("张三",18,"李四",19,"张三三",20);
System.out.println(map);
}
}
11、Debug追踪
- Debug调试程序:可以让代码逐行执行,查看代码执行过程,调试程序中出现的bug
- 使用方式:在行号的右边,鼠标左键点击,添加断点(每个方法的第一行或bug出现的地方),右键选择Debug执行程序,程序就会留在添加的第一个断点处
- 执行程序:
- f8:逐行执行程序
- f7:进入到方法中
- Shift+f8:跳出方法
- f9:跳到下一个断点,如果没有下一个断点,则结束程序
- Ctrl+f2:退出Debug模式,停止程序
- Console:切换到控制台
12、斗地主案例——有序版
- 需求分析:
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
public class DouDiZhu02 {
public static void main(String[] args) {
HashMap<Integer,String> poker = new HashMap<>();
ArrayList<Integer> pokerIndex = new ArrayList<>();
List<String> colors = List.of("♠","♥","♣","♦");
List<String> numbers = List.of("2","A","K","Q","J","10","9","8","7","6","5","4","3");
int index = 0;
poker.put(index,"大王");
pokerIndex.add(index);
index ++;
poker.put(index,"小王");
pokerIndex.add(index);
index ++;
for(String number : numbers){
for (String color : colors) {
poker.put(index,color+number);
pokerIndex.add(index);
index ++;
}
}
Collections.shuffle(pokerIndex);
ArrayList<Integer> player01 = new ArrayList<>();
ArrayList<Integer> player02 = new ArrayList<>();
ArrayList<Integer> player03 = new ArrayList<>();
ArrayList<Integer> diPai = new ArrayList<>();
for (int i = 0; i < pokerIndex.size(); i++) {
Integer in = pokerIndex.get(i);
if(i>=51){
diPai.add(in);
}else if(i%3==0){
player01.add(in);
}else if(i%3==1){
player02.add(in);
}else if(i%3==2){
player03.add(in);
}
}
Collections.sort(player01);
Collections.sort(player02);
Collections.sort(player03);
Collections.sort(diPai);
lookPoker("玩家1",poker,player01);
lookPoker("玩家2",poker,player02);
lookPoker("玩家3",poker,player03);
lookPoker("底牌",poker,diPai);
}
private static void lookPoker(String name,HashMap<Integer,String> poker, ArrayList<Integer> list) {
System.out.print(name + " ");
for(Integer key : list){
String value = poker.get(key);
System.out.print(value +" ");
}
System.out.println();
}
}
程序结果:
玩家1 ♣2 ♦2 ♥A ♦K ♦Q ♣10 ♥9 ♣9 ♠8 ♥8 ♣6 ♠5 ♣5 ♣4 ♦4 ♥3 ♦3
玩家2 小王 ♥2 ♦A ♠K ♠Q ♣Q ♠J ♦10 ♦8 ♠7 ♠6 ♥6 ♥5 ♦5 ♥4 ♠3 ♣3
玩家3 大王 ♠2 ♠A ♣A ♥K ♣K ♥Q ♥J ♣J ♦J ♠10 ♥10 ♠9 ♦9 ♣8 ♣7 ♦7
底牌 ♥7 ♦6 ♠4