1. Map 集合
(1)概述
Map接口实现将键映射到值。一个映射不能包含重复的键;每个键最多只能映射到一个值。
(2)Map接口和Collection接口的不同
Map 是双列的,Collection是单列的;Map的键是唯一的,Collection 的子体系Set是唯一的;Map 集合的数据结构只对键有效,和值无关,Collection 集合的数据结构是对元素有效。
(3)Map 集合的功能
添加功能:
● public V put(K key, V value) 把指定键和值关联起来存放在集合中,若添加之前这个键已经存在,就会覆盖之前的值,并返回之前的值。
● public void putAll(Map<? extends K,? extends V> m) 从指定的Map集合中拿到对应的键值对应关系存放到当前Map集合中。
删除功能:
● public V remove(Object key) 如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。
● public void clear() 移除集合中所有的键值对应关系。
判断功能:
● public boolean containsKey(Object key) 返回集合中的这个指定的键。
● public boolean containsValue(Object value) 返回集合中的指定的值。
● public boolean isEmpty() 判断集合中是否为空。
获取功能:
● public V get(Object key) 返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。
● public Set< K > keySet() 返回此集合中映射关系的键的 Set 集合。
● public Set<Map.Entry<K,V>> entrySet() 返回此映射中包含的映射关系的 Set 集合。
● public Collection values() 返回此映射中包含的值的 Collection 集合。
● public int size() 返回此映射中的键-值映射关系数。
Map集合的遍历:
① 通过获取键来查找值,Map的方法keySet获取键的集合,再通过Map的方法get获取到值。
② 通过Map的方法entrySet获取键和值的集合。
代码演示:
package com.westos.demo1;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Demo {
public static void main(String[] args) {
HashMap<Integer, String> hashMap = new HashMap<>();
hashMap.put(1,"Lebron");
hashMap.put(2,"Kobe");
hashMap.put(3,"Curry");
hashMap.put(4,"Kyrie");
hashMap.put(5,"Wade");
Set<Integer> keySet = hashMap.keySet();
for (Integer key : keySet) {
String s = hashMap.get(key);
System.out.println(key+"=="+s);
}
System.out.println("--------------------");
Set<Map.Entry<Integer, String>> entries = hashMap.entrySet();
for (Map.Entry<Integer, String> entry : entries) {
Integer key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"->"+value);
}
String s = hashMap.remove(1);
System.out.println(s);
boolean b = hashMap.containsValue("Kyrie");
System.out.println(b);
Collection<String> values = hashMap.values();
System.out.println(values);
}
}
执行结果:
2.HashMap、HashTable、 LinkedHashMap和TreeMap的区别
(1)HashMap
1、 是线程不安全的,HashMap 是一个接口,是 Map 的一个子接口,是将键映射到值得对象
2、不允许键值重复,允许空键和空值;
3、由于非线程安全,HashMap 的效率要较 HashTable 的效率高一些。
4、HashMap 在被多个线程访问的时候需要自己为它的方法实现同步
5、HashMap提供了可供应用迭代的键的集合,因此,HashMap是快速失败的
(2)HashTable
1、内部存储的键值对是无序的是按照哈希算法进行排序,与 HashMap 最大的区别就是线程安全。
2、键或者值不能为 null,为 null 就会抛出空指针异常。
3、HashTable 是 sychronize,多个线程访问时不需要自己为它的方法实现同步。
4、Hashtable提供了对键的列举(Enumeration)。
(3)LinkedHashMap
1、底层数据结构是链表和哈希表,元素唯一。
2、有序的 Map 集合实现类,相当于一个栈,先 put 进去的最后出来,先进后出。
(4)TreeMap
1、键的数据结构是红黑树,可保证键的有序性和唯一性。
2、排序可以通过自然排序和比较器排序实现。
3、线程不安全,效率比较高。
3. Collections(集合工具类)
Collections是Java提供的针对集合进行操作的工具类。
Collections 成员方法:
1、public static <T> void sort(List<T> list) :对集合进行排序
2、public static <T> int binarySearch(List<?> list,T key ):对集合的二分查找
3、public static <T> T max(Collection<?> coll):获取最大值
4、public static void reserve(List<?> list):将集合翻转
5、public static void shuffle(List<?> list):将集合随机置换
斗地主小案例:实现斗地主的发牌洗牌和看牌
package com.westos.demo1;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.TreeSet;
public class DouDiZhu {
public static void main(String[] args) {
//用数组存储牌号和牌的花色
String[] colors = {"♥","♠","♣","♦"};
String[] nums = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
//用一个HashMap充当牌盒,一个ArrayList中的号来代表每张牌
HashMap<Integer, String> pooker = new HashMap<>();
ArrayList<Integer> pookerNum = new ArrayList<>();
//遍历花色和数字组合牌
//index代表ArrayList的序号
int index = 0;
for (String num : nums) {
for (String color : colors) {
pooker.put(index, color.concat(num));
pookerNum.add(index);
index++;
}
}
//存储大小王
pooker.put(52,"大王");
pookerNum.add(52);
index++;
pooker.put(53,"小王");
pookerNum.add(53);
//洗牌,洗牌的编号即可
Collections.shuffle(pookerNum);
//用TreeSet存储玩家的牌和底牌
TreeSet<Integer> player1 = new TreeSet<>();
TreeSet<Integer> player2 = new TreeSet<>();
TreeSet<Integer> player3 = new TreeSet<>();
TreeSet<Integer> bottom = new TreeSet<>();
//发牌
for (int i = 0; i < pookerNum.size(); i++) {
if (pookerNum.size()-i <= 3){
bottom.add(pookerNum.get(i));
}else if (i%3 == 0){
player1.add(pookerNum.get(i));
}else if (i%3 == 1){
player2.add(pookerNum.get(i));
}else {
player3.add(pookerNum.get(i));
}
}
//看牌,抽取成一个方法,用编号在牌盒中比较查看牌
lookPooker("张三",player1,pooker);
lookPooker("李四",player2,pooker);
lookPooker("王五",player3,pooker);
lookPooker("底牌",bottom,pooker);
}
private static void lookPooker(String name, TreeSet<Integer> player, HashMap<Integer, String> pookerbox) {
System.out.println(name);
for (Integer num : player) {
String p = pookerbox.get(num);
System.out.print(p+"\t");
}
System.out.println();
System.out.println();
}
}
执行结果: