Map
特点
- Map集合的特点
将键映射到值的对象。一个映射不能包含重复的键;
每个键最多只能映射到一个值 - Map集合和Collection集合的区别?
- Map集合存储元素是成对出现的,Map集合的键是唯一的,值是可重复的,可以把这个理解为夫妻对
- Collection集合存储元素是单独出现的,Collection的儿子Set是唯一的,List是可重复的,可以理解为光棍
功能
// 添加功能
V put(K key, V value) // 添加元素。这个其实还有另一个功能先不 告诉你
// 如果键是第一次存储,就直接存储元素,返回null
// 如果键不是第一次存储,就用值把以前的值替换掉,返回以前的值
// 删除功能
void clear() // 移除所有的键值对元素
V remove(Object key) // 根据键删除键值对元素,并把值返回
// 判断功能
boolean containsKey(Object key) // 判断集合是否包含指定的键
boolean containsValue(Object value) // 判断集合是否包含指定的值
boolean isEmpty() // 判断集合是否为空
// 获取功能
Set<Map.Entry<K,V>> entrySet() // 返回元素对集合
V get(Object key) // 根据键获取值
Set<K> keySet() // 获取集合中所有键的集合
Collection<V> values() // 获取集合中所有值的集合
// 长度功能
int size() // 返回集合中键值对的对数
遍历
- 思路一
/*
A:获取所有的键
B:遍历键的集合,获取得到每一个键
C:根据键去找值
*/
// 举例
// 创建集合对象
Map<String,String> map = new HashMap<String,String>();
// 创建元素并添加到集合
map.put("杨过", "小龙女");
map.put("郭靖", "黄蓉");
map.put("杨康", "穆念慈");
map.put("陈玄风", "梅超风");
// 遍历
Set<String> set = map.keySet();
for(String key:set) {
// 根据键去找值
String value = map.get(key);
System.out.println(key+"---"+value);
}
- 思路二
/*
A:获取所有键值对对象的集合
Set<Map.Entry<K,V>> entrySet():
返回的是键值对对象的集合
B:遍历键值对对象的集合,得到每一个键值对对象
C:根据键值对对象获取键和值
*/
public static void main(String[] args) {
// 创建集合对象
Map<String, String> map = new HashMap<String, String>();
// 创建元素并添加到集合
map.put("杨过", "小龙女");
map.put("郭靖", "黄蓉");
map.put("杨康", "穆念慈");
map.put("陈玄风", "梅超风");
// 获取所有键值对对象的集合
Set<Map.Entry<String,String>> set = map.entrySet();
for(Map.Entry<String, String> me :set) {
// 根据键值对对象获取键和值
String key = me.getKey();
String value = me.getValue();
System.out.println(key+"---"+value);
}
}
HashMap
- HashMap是基于哈希表的Map接口实现,哈希表的作用是用来保证键的唯一性
- 需要HashMap的键的唯一性。对于String和Integer类,都重写了hashCode()和equals()方法。但是对于自定义对象,例如Student类,要它做为键,就必须重写它的hashCode()和equals()方法,自动生成即可。
- LinkedHashMap
是Map接口的哈希表和链接列表实现,具有可预知的迭代顺序- 由哈希表保证键的唯一性
- 由链表保证键的有序性(存储和取出的顺序一致)
TreeMap
- 是基于红黑树的Map接口的实现
- TreeMap用法和day17的TreeSet基本一样。
面试题
- Hashtable和HashMap的区别
- Hashtable:线程安全,效率低。不允许null键和null值
- HashMap:线程不安全,效率高。允许null键和null值
- List,Set,Map区别
- List,Set不是继承自Map接口,它们继承自Collection接口
- Map接口本身就是一个顶层接口
举例
- HashMap嵌套HashMap
/*
*传智播客
* jc 基础班
* 陈玉楼 20
* 高跃 22
* jy 就业班
* 李杰 21
* 曹石磊 23
*
* 先存储元素,然后遍历元素
*/
public static void main(String[] args) {
HashMap<String,HashMap<String,Integer>> czbkMap = new HashMap<String,HashMap<String,Integer>>();
// 创建基础班集合对象
HashMap<String,Integer> jcMap = new HashMap<String,Integer>();
jcMap.put("陈玉楼", 20);
jcMap.put("高跃", 22);
czbkMap.put("jc", jcMap);
HashMap<String,Integer> jyMap = new HashMap<String,Integer>();
jyMap.put("李杰", 21);
jyMap.put("曹石磊",23);
czbkMap.put("jy", jyMap);
// 遍历集合
Set<String> czbkMapSet = czbkMap.keySet();
for(String czbkMapKey:czbkMapSet) {
System.out.println(czbkMapKey);
HashMap<String,Integer> czbkMapValue = czbkMap.get(czbkMapKey);
Set<String> czbkMapValueSet = czbkMapValue.keySet();
for(String czbkMapValueKey:czbkMapValueSet) {
Integer czbkMapValueValue = czbkMapValue.get(czbkMapValueKey);
System.out.println("\t"+czbkMapValueKey+"---"+czbkMapValueValue);
}
}
}
- HashMap嵌套ArrayList
/* 需求:
* 假设HashMap集合的元素是ArrayList。有3个
* 每一个ArrayList集合的值是字符串。
* 元素我已经完成,请遍历
* 结果:
* 三国演义
* 吕布
* 周瑜
* 笑傲江湖
* 令狐冲
* 林平之
* 神雕侠侣
* 郭靖
* 杨过
*/
public static void main(String[] args) {
// 创建集合对象
HashMap<String,ArrayList<String>> hm = new HashMap<String,ArrayList<String>>();
// 创建元素集合1
ArrayList<String> array1 = new ArrayList<String>();
array1.add("吕布");
array1.add("周瑜");
hm.put("三国演义",array1);
// 创建元素集合2
ArrayList<String> array2 = new ArrayList<String>();
array2.add("令狐冲");
array2.add("林平之");
hm.put("笑傲江湖", array2);
// 创建元素集合3
ArrayList<String> array3 = new ArrayList<String>();
array3.add("郭靖");
array3.add("杨过");
hm.put("神雕侠侣", array3);
// 遍历集合
Set<String> set = hm.keySet();
for(String key:set) {
System.out.println(key);
ArrayList<String> array = hm.get(key);
for(String s:array) {
System.out.println("\t"+s);
}
}
}
- ArrayList集合嵌套HashMap集合
/* ArrayList集合嵌套HashMap集合并遍历
* 需求:
* 假设ArrayList集合的元素是HashMap.有3个
* 每一个HashMap集合的键和值都是字符串
* 元素我已经完成,请遍历
* 结果:
* 周瑜---小乔
* 吕布---貂蝉
*
* 郭靖---黄蓉
* 杨过---小龙女
*
* 令狐冲---任盈盈
* 林平之---岳灵珊
*/
public static void main(String[] args) {
// 创建集合对象
ArrayList<HashMap<String, String>> array = new ArrayList<HashMap<String, String>>();
// 创建元素1
HashMap<String, String> hm1 = new HashMap<String, String>();
hm1.put("周瑜", "小乔");
hm1.put("吕布", "貂蝉");
array.add(hm1);
HashMap<String, String> hm2 = new HashMap<String, String>();
hm2.put("郭靖", "黄蓉");
hm2.put("杨过", "小龙女");
array.add(hm2);
HashMap<String, String> hm3 = new HashMap<String, String>();
hm3.put("令狐冲", "任盈盈");
hm3.put("林平之", "岳灵珊");
array.add(hm3);
for (HashMap<String, String> hm : array) {
Set<String> set = hm.keySet();
for (String key : set) {
String value = hm.get(key);
System.out.println(key + "---" + value);
}
System.out.println();
}
}
Collections类
是针对集合进行操作的工具类,都是静态方法
- 面试题
Collection和Collections的区别?- Collection:是单列集合的顶层接口,有子接口List和Set
- Collections:是针对集合操作的工具类,有对集合进行排序和二分查找的方法
- 方法
public static <T> void sort(List<T> list)
// 排序默认情况下是自然排序
public static <T> int binarySearch(List<?> list,T key)
// 二分查找
public static <T> T max(Collection<?> coll)
// 最大值
public static void reverse(List<?> list)
// 反转
public static void shuffle(List<?> list)
// 随机置换
- 举例
Collections可以针对ArrayList存储基本包装类元素排序
存储自定义对象可不可以排序呢?
// 方法1:Collections.sort(list);
// 自定义类要实现comparable接口,重写CompareTo()方法
@Override
public int compareTo(Student s) {
// TODO Auto-generated method stub
int num = this.age-s.age;
int num2 = num==0?this.name.compareTo(s.name):num;
return num2;
}
// 方法2:
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
// TODO Auto-generated method stub
int num = s1.getAge()-s2.getAge();
int num2 = num==0?s1.getName().compareTo(s2.getName()):num;
return num2;
}
});
模拟斗地主发牌
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.TreeSet;
/*
* 思路:
* A:创建一个HashMap集合
* B:创建一个ArrayList集合
* C:创建花色数组和点数数组
* D:从0开始往HashMap存储编号,并存储对应的牌
* 同时往ArrayList里面存储编号即可
* E:洗牌(洗的是编号)
* F:发牌(发的也是编号,为了保证编号是排序的就创建
* TreeSet集合接收)
* G:看牌(遍历TreeSet集合,获取编号,到HashMap集合
* 找对应的牌)
*
*/
public class PokerDemo {
public static void main(String[] args) {
// 创建一个HashMap集合
HashMap<Integer, String> hm = new HashMap<Integer, String>();
// 创建一个ArrayList集合
ArrayList<Integer> array = new ArrayList<Integer>();
String[] colors = { "♠", "♥", "♣", "♦" };
// 定义一个点数数组
String[] numbers = { "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2" };
int index = 0;
for (String number : numbers) {
for (String color : colors) {
String poker = color.concat(number);
hm.put(index, poker);
array.add(index);
index++;
}
}
hm.put(index, "小王");
array.add(index);
index++;
hm.put(index, "大王");
array.add(index);
// 洗牌
Collections.shuffle(array);
TreeSet<Integer> fengQingYang = new TreeSet<Integer>();
TreeSet<Integer> linQingXia = new TreeSet<Integer>();
TreeSet<Integer> liuYi = new TreeSet<Integer>();
TreeSet<Integer> diPai = new TreeSet<Integer>();
for(int x=0; x<array.size();x++) {
if(x>=array.size()-3) {
diPai.add(array.get(x));
}else if(x%3==0) {
fengQingYang.add(array.get(x));
}else if(x%3==1) {
linQingXia.add(array.get(x));
}else if(x%3==2) {
liuYi.add(array.get(x));
}
}
// 看牌
lookPoker("风清扬", fengQingYang, hm);
lookPoker("林青霞", linQingXia, hm);
lookPoker("刘意", liuYi, hm);
lookPoker("底牌", diPai, hm);
}
// 写看牌的功能
public static void lookPoker(String name, TreeSet<Integer> ts,
HashMap<Integer,String> hm) {
System.out.print(name+"的牌是:");
for(Integer key:ts) {
System.out.print(hm.get(key)+" ");
}
System.out.println();
}
}