Map集合
概述
Map
接口下的集合与Collection
接口下的集合,它们存储数据的形式不同
java.util.Map<k,v>
集合
特点:
-
map集合是一个双列集合,一个元素包含两个值(一个key,一个value)
-
map集合的元素,key和value的数据类型可以不同,也可以相同
-
map集合中的元素,key是不可以重复的,value是可以重复的.
-
map集合中key和value是一一对应的.
常用子类
HashMap<k,v>
:
-
java.util.HashMap<k,v> implements Map<k,v>
-
无序的集合
-
底层也是一个哈希表(查询速度特别快)
-
1.8之前:数组+单向链表
-
1.8之后:数组+单项链表+红黑树(长度>8),提高查询速度
-
-
是不同步的
LinkedHashMap<k,v>
-
java.util.LinkedHashMap<k,v> extendes HashMap<k,v>
-
底层是哈希表+链表(保证有序)
-
LinkedHashMap<k,v>是有序的
Map中的常用方法
public V put(K key, V value)
: 把指定的键与指定的值添加到Map集合中。
-
返回值V
-
存储键值对的时候,key不重复,返回值是null
-
key重复的时候,会使用新的value替换map中重复的value,返回被替换的value的值
-
-
一般来说不会接收这个返回值.
public V remove(Object key)
: 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
-
返回值原理同上
-
注意在使用一个变量来接收的时候,尽量使用包装类,否则容易有空指针异常(因为不能把null赋值给基本数据类型)
public V get(Object key)
根据指定的键,在Map集合中获取对应的值。
public Set<K> keySet()
: 获取Map集合中所有的键,存储到Set集合中。
public Set<Map.Entry<K,V>> entrySet()
: 获取到Map集合中所有的键值对对象的集合(Set集合)
boolean containsKey(Object key)
:判断集合是否包含指定的键,包含返回true,不包含返回false
Map集合遍历方法
先找键,然后通过键寻找值(key-->value)
-
keySet()
获取所有的键,返回一个Set集合存储所有的键 -
遍历这个set集合,得到每一个键
-
调用
get(Object key)
,获取键所对应的值.
package com.qin.study;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Created by Sakura on 2018/8/5.
*/
public class Testmap {
public static void main(String[] args) {
Map<String,Integer> map = new HashMap<>();
map.put("迪丽热巴",18);
map.put("古力娜扎",18);
map.put("玛尔扎哈",20);
Set<String> keySet = map.keySet();
for (String key : keySet) {
Integer value = map.get(key);
System.out.println(key+ " 今年 "+value);
}
}
}
Entry键值和对象
Map 中存放的是两种对象,一种称为key(键),一种称为value(值),它们在在 Map 中是一一对应关系,这一对对象又称做 Map 中的一个 Entry(项) 。 Entry 将键值对的对应关系封装成了对象。即键值对对象,这样我们在遍历 Map 集合时,就可以从每一个键值对( Entry )对象中获取对应的键与对应的值
Entry表示了一对键和值,获取键和值的方法有:
public K getKey()
:获取Entry对象中的键
public V getValue()
:获取Entry对象中的值
在Map集合中也提供了获取所有Entry对象的方法:public Set<Map.Entry<K,V>> entrySet()
: 获取到Map集合中所有的键值对对象的集合(Set集合)
先获取一个实体对象(entry),遍历entry,调用getKey(),getValue()
-
获取map集合中所有的键值对Entry对象,以set集合的形式返回:entrySet()
-
遍历包含键值对(Entry)对象的集合,得到每一个键值对(Entry)对象
-
通过键值对(Entry)对象,获取Entry中的键和值:getKey() getValue()
package com.qin.study;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Created by Sakura on 2018/8/5.
*/
public class EntryMapTest {
public static void main(String[] args) {
Map<String,Integer> map = new HashMap<>();
map.put("迪丽热巴",18);
map.put("古力娜扎",18);
map.put("玛尔扎哈",20);
//获取Entry
Set<Map.Entry<String, Integer>> entries = map.entrySet();
//遍历可以使用增强for,也可以使用迭代器
for (Map.Entry<String, Integer> entry : entries) {
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key+" 年龄 "+value);
}
}
}
//结果:
//玛尔扎哈 年龄 20
//迪丽热巴 年龄 18
//古力娜扎 年龄 18
LinkedHashMap<k,v>
Map接口的哈希表和链表实现,具有可预知迭代顺序
底层原理:
-
哈希表+链表(记录元素的顺序)
Hashtable<k,v>(了解,已经不使用了)
是LinkedHashMap<k,v>
的兄弟,同样实现了map
接口,底层是一个哈希表.但是键和值都不能为空(之前学的所有集合都可以存储空值,空键),如果放进去,会有空指针异常.线程安全的,同步的(比较慢)
Hashtable和Vector集合一样,在jdk1.2之后就被更先进的集合(HashMap,ArrayList)取代了,但是hashtable的子类properties依然活跃在历史舞台
properties集合是唯一和IO流相结合的集合.
JDK9对集合添加的优化
jdk9的新特性:
-
list,set,map接口:里面增加了一个静态的方法of,可以给集合一次性添加多个元素
-
使用前提:当集合中存储的个数已经确定了,不再改变时使用
-
注意:
-
of方法只适用于list,set,map接口,不适用与接口的实现类
-
of方法的返回值是一个不能改变的集合,集合不能再使用add,put方法添加元素,会抛出异常
-
set接口和map接口在调用of方法的时候,不能有重复的元素,否则会抛出异常
-
Debug调试程序
-
可以让代码执行,查看代码的执行过程,调试程序出现的bug
-
使用方式:
-
在行号的右边,鼠标左键单击,添加断点,每个方法的第一行,或者哪里有bug添加到哪里
-
右键选择Debug执行程序
-
-
执行程序:
-
F8:逐行执行程序
-
F7:进去方法体
-
shift+f8:跳出方法
-
f9:跳到下一个断点,如果没有下一个断点,那么就结束程序
-
ctrl+f2:退出debug模式,停止程序
-
console:切换到控制台
-
打断点后debug, 那一行没有执行.
-
斗地主案例(使用HashMap)
package com.qin.study;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
/**
* Created by Sakura on 2018/8/5.
* 使用hashmap完成斗地主案例
*/
public class Landlords {
public static void main(String[] args) {
//首先创建一副牌
HashMap<Integer,String> poker = new HashMap<>();
//记录牌的索引
ArrayList<Integer>list = 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,"大王");
list.add(index++);
poker.put(index,"小王");
list.add(index++);
for (String number : numbers) {
for (String color : colors) {
poker.put(index,color+number);
list.add(index++);
}
}
// System.out.println(poker);
// System.out.println(list);
//洗牌
Collections.shuffle(list);
//新建四个arraylist接收
ArrayList<Integer> player1 = new ArrayList<>();
ArrayList<Integer> player2 = new ArrayList<>();
ArrayList<Integer> player3 = new ArrayList<>();
ArrayList<Integer> dipai = new ArrayList<>();
//发牌
for (int i = 0; i < list.size(); i++) {
Integer integer = list.get(i);
if (i >=51){
dipai.add(integer);
}else if (i % 3 == 0){
player1.add(integer);
}else if (i % 3 == 1){
player2.add(integer);
}else if (i % 3 == 2){
player3.add(integer);
}
}
//排序,默认升序
Collections.sort(player1);
Collections.sort(player2);
Collections.sort(player3);
Collections.sort(dipai);
//查看牌
// System.out.println(player1);
// System.out.println(player2);
// System.out.println(player3);
// System.out.println(dipai);
showPoker("刘德华",poker,player1);
showPoker("周星驰",poker,player2);
showPoker("周润发",poker,player3);
showPoker("底牌",poker,dipai);
}
public static void showPoker(String name,HashMap<Integer,String> map,ArrayList<Integer> list){
System.out.print(name+"的牌是:");
for (Integer key : list) {
String value = map.get(key);
System.out.print(value+" ");
}
System.out.println();
}
}