1、Map集合概述
1.1Map概述
查找API文档:Map是一个接口,将键映射到值的对象。一个映射不能包含重复的键,每个键最多能映射到一个值。
1.2 Map接口和Collection接口的不同
Map是双列的,Collection是单列的。
Map的键是唯一的,Collection的子体系Set是唯一的。
Map集合的数据结构针对键有效,跟值无关:Collection集合的数据结构针对元素有效。
2、Map集合的功能概述
a:添加功能
V put(K key,V value):添加元素。这个其实还有另一个功能?替换
如果键是第一次存储,就直接存储元素,返回null
如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
b:删除功能
void clear():移除所有的键值对元素
V remove(Object key):根据键删除键值对元素,并把值返回
c:判断功能
boolean containsKey(Object key):判断集合是否包含指定的键
boolean containsValue(Object value):判断集合是否包含指定的值
boolean isEmpty():判断集合是否为空
d:获取功能
Set<Map.Entry<K,V>> entrySet(): 返回一个键值对的Set集合
V get(Object key):根据键获取值
Set keySet():获取集合中所有键的集合
Collection values():获取集合中所有值的集合
e:长度功能
int size():返回集合中的键值对的对数
public class MyTest {
public static void main(String[] args) {
HashMap<Integer, String> hashMap = new HashMap<>();
//添加方法 put
String s = hashMap.put(001, "小芳");
System.out.println(s);//null
String s1 = hashMap.put(001, "小王");
System.out.println(s1);//小芳
hashMap.put(002, "小明");
hashMap.put(003,"小红");
hashMap.put(004,"小花");
System.out.println(hashMap);//{1=小王, 2=小明, 3=小红, 4=小花}
//String s2 = hashMap.remove(002);//,删除键值对,返回值
//System.out.println(s2);//小明
//System.out.println(hashMap);//{1=小王, 3=小红, 4=小花}
//hashMap.clear();//清空
//System.out.println(hashMap);//{}
//判断集合是否包含指定的键
boolean key = hashMap.containsKey(003);
System.out.println(key);//true
//判断集合是否包含指定的值
boolean value = hashMap.containsValue("小明");
System.out.println(value);//true
//判断集合是否为空
boolean empty = hashMap.isEmpty();
System.out.println(empty);//false
//返回一个键值对的Set集合
Set<Map.Entry<Integer, String>> set = hashMap.entrySet();
for (Map.Entry<Integer, String> entry : set) {
System.out.println(entry);
}
//根据键获取值
String s2 = hashMap.get(003);
System.out.println(s2);//小红
//获取集合中所有键的集合
Set<Integer> set1 = hashMap.keySet();
System.out.println(set1);//[1, 2, 3, 4]
//获取集合中所有值的集合
Collection<String> values = hashMap.values();
System.out.println(values);//[小王, 小明, 小红, 小花]
//返回集合中的键值对的对数
int size = hashMap.size();
System.out.println(size);//4
}
}
3、Map集合的遍历
- 方式一:键找值
键找值思路:
获取所有键的集合
遍历键的集合,获取到每一个键
根据键找值
public class MyTest2 {
public static void main(String[] args) {
HashMap<Integer, String> hashMap = new HashMap<>();
hashMap.put(001, "小芳");
hashMap.put(002, "小明");
hashMap.put(003, "小红");
hashMap.put(004, "小花");
Set<Integer> keySet = hashMap.keySet();
for (Integer integer : keySet) {
String s = hashMap.get(integer);
System.out.println(integer+"==="+s);
}
}
}
- 方式二:键值对对象找键和值
键值对对象找键和值思路:
获取所有键值对对象的集合
遍历键值对对象的集合,获取到每一个键值对对象
根据键值对对象找键和值
Set<Map.Entry<Integer, String>> entrySet = hashMap.entrySet();
for (Map.Entry<Integer, String> entry : entrySet) {
Integer key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"==="+value);
4、HashMap集合键是Stirng值是String的案例
HashMap集合的数据结构是哈希表,只跟键有关。
public class MyTest3 {
public static void main(String[] args) {
HashMap<String, String> hashMap = new HashMap<>();
String s = hashMap.put("中国", "姚明");
System.out.println(s);//null
hashMap.put("美国","科比");
hashMap.put("阿根廷","梅西");
hashMap.put("葡萄牙","C罗");
hashMap.put(null,null);//可以插入null键,null值
System.out.println(hashMap);//{美国=科比,null=null, 葡萄牙=C罗, 中国=姚明, 阿根廷=梅西}
}
}
5、HashMap集合键是String值是Student的案例
public class MyTest4 {
public static void main(String[] args) {
//map集合只跟键有关,与值无关
HashMap<String, Student> hashMap = new HashMap<>();
hashMap.put("s001",new Student("张三",20));
hashMap.put("s002",new Student("李四",20));
hashMap.put("s003",new Student("王五",20));
hashMap.put("s004",new Student("张三",20));
System.out.println(hashMap);
//{s004=org.westos.demo.Student@1b6d3586,
// s003=org.westos.demo.Student@4554617c,
// s002=org.westos.demo.Student@74a14482,
// s001=org.westos.demo.Student@1540e19d}
}
}
6、HashMap集合键是Student值是String的案例
保证键唯一,需要重写hashCode方法 和 equals 方法
public class MyTest5 {
public static void main(String[] args) {
HashMap< Student,String> hashMap = new HashMap<>();
//保证键唯一,需要重写hashCode方法 和 equals 方法
hashMap.put(new Student("张三",20),"s001wwwwww");
hashMap.put(new Student("李四",20),"s002");
hashMap.put(new Student("王五",20),"s003");
hashMap.put(new Student("张三",20),"s004hahah");
System.out.println(hashMap);
//{org.westos.demo.Student@16e8e0c=s004hahah,
// org.westos.demo.Student@18e5428=s002,
// org.westos.demo.Student@1bb448c=s003}
}
}
7、LinkedHashMap
LinkedHashMap的概述:Map 接口的哈希表和链接列表实现,具有可预知的迭代顺序。
LinkedHashMap的特点:
底层的数据结构是哈希表和链表,元素有序,且唯一。
元素的有序性由链表数据结构保证 唯一性由 哈希表数据结构保证。Map集合的数据结构只和键有关。
8、HashMap和Hashtable
HashMap和Hashtable底层数据结构都是哈希表。
区别:
hashMap:线程不安全,效率高,允许null值和null键
hashtable:线程安全,效率低,不允许null值和null键
9、TreeMap
TreeMap概述:键的数据结构是二叉树,可保证键的排序和唯一性。
TreeMap特点:键不允许插入null
10、案例演示
- 统计字符串中每个字符出现的次数
需求:统计字符串中每个字符出现的次数
“aababcabcdabcde”,获取字符串中每一个字母出现的次数要求结果:a(5)b(4)c(3)d(2)e(1)
public class MyTest2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一段字符串");
String s = scanner.next();
//统计字符串中的字符个数,将其添加到集合中
HashMap<Character, Integer> hashMap = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (!hashMap.containsKey(ch)){
hashMap.put(ch,1);
}else {
Integer integer = hashMap.get(ch);
integer++;
hashMap.put(ch,integer);
}
}
//遍历集合
StringBuffer sb = new StringBuffer();
Set<Character> keySet = hashMap.keySet();
for (Character character : keySet) {
Integer integer = hashMap.get(character);
sb.append(character).append("(").append(integer).append(")");
}
System.out.println(sb);
}
}
- 集合嵌套之HashMap嵌套HashMap
打印效果如下:
基础班
张三 20
李四 22
就业班
王五 21
赵六 23
public class MyTest3 {
public static void main(String[] args) {
HashMap<String, Integer> jcMap = new HashMap<>();
jcMap.put("张三",20);
jcMap.put("李四",22);
HashMap<String, Integer> jyMap = new HashMap<>();
jyMap.put("王五",21);
jyMap.put("赵六",23);
HashMap<String, HashMap<String, Integer>> maxMap = new HashMap<>();
maxMap.put("基础班",jcMap);
maxMap.put("就业班",jyMap);
Set<String> set = maxMap.keySet();
for (String s : set) {
HashMap<String, Integer> stringIntegerHashMap = maxMap.get(s);
System.out.println(s);
Set<String> strings = stringIntegerHashMap.keySet();
for (String string : strings) {
Integer integer = stringIntegerHashMap.get(string);
System.out.println("\t"+string+"\t\t"+integer);
}
}
}
}
- 集合嵌套之HashMap嵌套ArrayList
假设HashMap集合的元素是ArrayList。有3个。
每一个ArrayList集合的值是字符串。
public class MyTest4 {
public static void main(String[] args) {
ArrayList<String> sgList = new ArrayList<>();
sgList.add("吕布");
sgList.add("周瑜");
ArrayList<String> xaList = new ArrayList<>();
xaList.add("令狐冲");
xaList.add("林平之");
ArrayList<String> sdList = new ArrayList<>();
sdList.add("郭靖");
sdList.add("杨过");
HashMap<String, ArrayList<String>> Map = new HashMap<>();
Map.put("三国演义",sgList);
Map.put("笑傲江湖",xaList);
Map.put("神雕侠侣",sdList);
Set<String> strings = Map.keySet();
for (String string : strings) {
System.out.println(string);
ArrayList<String> list = Map.get(string);
for (String s : list) {
System.out.println("\t"+s);
}
}
}
}
- 集合嵌套之ArrayList嵌套HashMap
假设ArrayList集合的元素是HashMap。有3个。
每一个HashMap集合的键和值都是字符串。
public class MyTest5 {
public static void main(String[] args) {
HashMap<String, String> map1 = new HashMap<>();
map1.put("周瑜","小乔");
map1.put("吕布","貂蝉");
HashMap<String, String> map2 = new HashMap<>();
map2.put("郭靖","黄蓉");
map2.put("杨过","小龙女");
HashMap<String, String> map3 = new HashMap<>();
map3.put("令狐冲","任盈盈");
map3.put("林平之","岳灵珊");
ArrayList<HashMap<String, String>> list = new ArrayList<>();
list.add(map1);
list.add(map2);
list.add(map3);
for (HashMap<String, String> map : list) {
Set<String> set = map.keySet();
for (String s : set) {
String s1 = map.get(s);
System.out.println(s+"---"+s1);
}
System.out.println();
}
}
}
11、Collections工具类
Collections概述:针对集合操作的工具类
Collections成员方法
public static void sort(List list): 排序,默认按照自然顺序
public static int binarySearch(List<?> list,T key): 二分查找
public static T max(Collection<?> coll): 获取最大值
public static void reverse(List<?> list): 反转
public static void shuffle(List<?> list): 随机置换
public class MyTest6 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(20);
list.add(35);
list.add(82);
list.add(60);
list.add(2360);
System.out.println(list);
//二分查找
int i = Collections.binarySearch(list, 82);
System.out.println(i);//2
//排序
Collections.sort(list);
System.out.println(list);
//随机置换集合中的元素
Collections.shuffle(list);
System.out.println(list);
}
}
12、案例:模拟斗地主洗牌和发牌
public class MyTest7 {
public static void main(String[] args) {
//创建一副牌
ArrayList<String> pokerBox = new ArrayList<>();
//生成54张牌
String[] pokerColers={"♠","♥","♣","♦"};
String[] pokerNum={"A","1","2","3","4","5","6","7","8","9","J","Q","K"};
for (int i = 0; i < pokerColers.length; i++) {
for (int j = 0; j < pokerNum.length; j++) {
pokerBox.add(pokerColers[i].concat(pokerNum[j]));
}
}
//添加大小王
pokerBox.add("大王");
pokerBox.add("小王");
//洗牌
Collections.shuffle(pokerBox);
Collections.shuffle(pokerBox);
Collections.shuffle(pokerBox);
//发牌
ArrayList<String> 赌神 = new ArrayList<>();
ArrayList<String> 赌侠 = new ArrayList<>();
ArrayList<String> 赌圣 = new ArrayList<>();
ArrayList<String> 底牌 = new ArrayList<>();
/*分析:
三个人,一人17张 底牌三张
赌神 0 3 6 3====0
赌侠 1 4 7 3====1
赌圣 2 5 8 3====2
底牌 最后3张
*/
for (int i = 0; i < pokerBox.size(); i++) {
//留底牌
if (i>pokerBox.size()-3){
底牌.add(pokerBox.get(i));
}else if (i % 3 ==0){
赌神.add(pokerBox.get(i));
}else if (i % 3 ==1){
赌侠.add(pokerBox.get(i));
}else {
赌圣.add(pokerBox.get(i));
}
}
//看牌
lookPoker("赌神",赌神);
lookPoker("赌侠",赌侠);
lookPoker("赌圣",赌圣);
lookPoker("底牌",底牌);
}
private static void lookPoker(String name,ArrayList<String> list) {
System.out.println(name);
for (String s : list) {
System.out.print(s+"\t");
}
System.out.println();
}
}