一.Map集合
1.Map集合的概述
1.Map集合:双列集合的顶层接口,来自于java.util包
map:地图,地图上的每一个点都与现实生活中的一个地理位置一一对应的关系。
2.Map<K,V>:Map集合中,带有两个泛型,这两个泛型,都是引用数据类型。
K-->Key-->键
V-->Value-->值
因此Map集合中存储的一对元素,称为键值对映射关系,是一种一对一的关系。
3.Map集合的特点
Map集合中,Key值是不能重复的,Value是彼此可以重复的。2.Map集合的常用方法
Map是一个接口,不能实例化对象,于是需要一个实现类,HashMap。
HashMap来自于java.util包
//接口的多态性,父接口的引用指向一个实现类的对象
Map<K,V> map = new HashMap();
1.put(K key,V value):表示将key与value的键值对映射对映射关系对象,添加到map集合中。
(1)通过put方法,向map中添加不存在的key值,直接添加成功。
(2)通过put方法,向Map中添加已经存在的key值,相当于修改,将后添加的value值,替换掉原来的key值对应的value。
2.remove(K key):将map集合对应的key值键值对删掉。返回值类型,V--->value,返回所删除的键值对中的value
3.clear():表示清空map集合,将集合中所有的键值对映射关系删除,Map集合仍然存在
4.isEmpty():判断Map集合中,是否还有键值对的映射关系对象,如果没有,返回true,如果没有,返回false。
5.containsKey(Object key):判断Map集合中,是否包含指定的key值,包含返回true,不包含返回false。
6.containsValue(Object value):判断Map集合中,是否包含指定的value值,包含返回true,不包含返回false。
7.get(Object key):通过Map集合中的key的值,获取到对应的value值,返回值类型就是value。
8.size():求Map集合中的键值对映射关系数量,返回值类型int类型import java.util.HashMap;
import java.util.Map;
public class MapMethod {
public static void main(String[] args) {
//Map集合存储的K和V的值,都必须是引用数据类型
Map<Integer,String> map = new HashMap<>();
putMethod(map);
System.out.println(map);//{1=a, 2=hello, 3=c}
removeMethod(map);
clearMethod(map);
isEmptyMethod(map);
containsMethod();
}
//1.put(K,V):向map集合中添加键值对元
public static void putMethod(Map<Integer,String> map){
//1.通过put方法,向map中添加不存在的key值,直接添加成功。
map.put(1,"a");
map.put(2,"b");
map.put(3,"c");
System.out.println(map);//{1=a, 2=b, 3=c}
//2.通过put方法,向Map中添加已经存在的key值,相当于修改。
map.put(2,"hello");
System.out.println(map);//{1=a, 2=hello, 3=c}
}
//2.map(K key):将map集合对应的key值键值对删掉。返回值类型,V--->value,返回所删除的键值对中的value
public static void removeMethod(Map<Integer,String> map){
String s = map.remove(1);
System.out.println("刚刚删掉的是: "+s);//刚刚删掉的是: a
System.out.println(map);//{2=hello, 3=c}
}
//3.clear():
public static void clearMethod(Map<Integer,String> map){
map.clear();
System.out.println(map);//{}
}
//4.isEmpty():判断是否含有键值对关系,若没有返回true
public static void isEmptyMethod(Map<Integer,String> map){
if(map.isEmpty()){
System.out.println("该map集合不存在键值对关系!");//该map集合不存在键值对关系!
}
}
//5.containsKey():判断Map集合中,是否包含指定的key值,包含返回true,不包含返回false。
//6.containsValue():判断Map集合中,是否包含指定的value值,包含返回true,不包含返回false。
//7.get(Object key):通过Map集合中的key的值,获取到对应的value值,返回值类型就是value。
//8.size():获取键值对数量
public static void containsMethod(){
Map<Integer,String> map = new HashMap<>();
map.put(11,"a");
map.put(22,"b");
map.put(33,"c");
System.out.println(map.containsKey(33));//true
System.out.println(map.containsValue("def"));//false
//7.get(Object key)
String value = map.get(11);
System.out.println(value);//a
System.out.println(map.size());//3
}
}3.Map集合的遍历
1.keySet遍历
keySet():将Map集合中的所有的Key值获取到,将所有Key值放置在一个Set集合中。
2.entrySet遍历
Map.entrySet<Integer,String>:获取Map集合中的键值对映射关系对象,放置到一个Set集合中。
映射关系对象:Map接口中的Entry<K,V>接口,表示Map集合中
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class MapBianLi {
public static void main(String[] args) {
//1.创建一个Map集合
Map<Integer,String> map = new HashMap<>();
//2.向Map集合中添加元素
map.put(1,"a");
map.put(2,"b");
map.put(3,"c");
bianLi1(map);
bianLi2(map);
bianLi3(map);
bianLi4(map);
}
//1.使用keySet()+增强for遍历
public static void bianLi1(Map<Integer,String> map){
//3.keySet():获取到Map集合中的所有Key值,添加到set集合中
Set<Integer> set = map.keySet();
//4.将所有的Key值获取到,通过key值获取到对应的value值
for(Integer key: set){
//5.通过get(Object key)获取value值
String value = map.get(key);
System.out.println(key+"----"+value);
}
}
//2.使用keySet()+迭代器遍历
public static void bianLi2(Map<Integer,String> map){
//3.keySet():获取到Map集合中的所有Key值,添加到set集合中
Set<Integer> set = map.keySet();
//4.获取到Set集合的迭代器对象iterator()
Iterator<Integer> it = set.iterator();
while(it.hasNext()){
//获取到集合的key值
Integer key = it.next();
String value = map.get(key);
System.out.println(key+"++++"+value);
}
}
//3.使用entrySet()和增强for遍历
public static void bianLi3(Map<Integer,String> map){
//3.使用entrySet()方法,获取到Map集合中的所有键值对映射关系
//每一个键值对对象关系,都是一个Map.Entry<Integer,String>
Set<Map.Entry<Integer,String>> set = map.entrySet();//一次性地获取到一对键值对关系,Map.Entry<Integer,String>键值对类型,放入set集合
//4.使用增强for遍历这个set集合
for(Map.Entry<Integer,String> entry: set){//然后单独拿出key,value
//5.通过entry方法
//getKey():将键值对关系中的key值获取到
Integer key = entry.getKey();
//getValue():将键值对关系中的value值获取到
String value = entry.getValue();
System.out.println(key+"~~~~"+value);
}
}
//4.使用entrySet()+迭代器遍历
public static void bianLi4(Map<Integer,String> map){
//3.使用entrySet()获取到Map集合中所有的键值对
Set<Map.Entry<Integer,String>> set = map.entrySet();//集合中装的是键值对映射关系
//4.使用迭代器进行set集合遍历
Iterator<Map.Entry<Integer,String>> it = set.iterator();
//循环将每一个键值对关系获取到
while(it.hasNext()){
Map.Entry<Integer,String> entry = it.next();
Integer key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"!!!!"+value);
}
}
}练习:定义一个字符串:aaaabbccddd!@#@$@#$%cc66f
统计字符串中每个字符出现的次数,分析:
1.拥有的字符串-->获取到字符串中的每一个字符-->String-->
toCharArray():将一个字符串每个字符获取到,返回一个字符数组
2.结果 a---4 b--2 c--3 键值对关系,最终结果用Map集合承装
字符-->key值 数量-->value
3.数字符出现次数:
Map<Character,Integer> map
(1)遍历char数组,获取到每一个数组
(2)判断这个字符在map中是否存在
不存在,证明第一次计数,put(字符,1)
存在,原有计数(get(字符)-->字符对应的计数)基础上+1
import java.util.HashMap;
import java.util.Map;
public class MapTest {
public static void main(String[] args) {
//1.定义一个字符串
String s = "aaaabbccddd!@#@$@#$%cc66f";
//2.将字符串转换成字符数组。
char[] ch = s.toCharArray();
//3.准备一个Map集合
Map<Character,Integer> map = new HashMap<>();
//4.将字符串中的每一个字符获取到
for (int i = 0; i < ch.length; i++) {
//5.判断字符在Map集合中是否存在
if(!map.containsKey(ch[i])){
map.put(ch[i],1);//第一次不在集合中存在赋值1
}else{
map.put(ch[i],map.get(ch[i])+1);//在集合中存在,获取到当前的值+1
}
}
System.out.println(map);//{@=3, a=4, !=1, b=2, c=4, #=2, d=3, $=2, %=1, 6=2, f=1}
}
}4.HashMap的key值保证元素唯一
- 1.HashMap()是Map接口的实现类,来自于java.util包,也是带有两个泛型 HashMap<K,V>
- 2.HashMap如果存储的是 JDK定义好的引用数据类型,key值可以自动去重复 HashMap如果存储的是自定义好的引用数据类型,若果需要将自定义类型通过成员变量的值进行去重复,那么需要重写hashcode+equals方法。
- 原因:HashMap中的key值,去重复原理与HashSet原理一致
- 要求:定义一个person类,类中属性姓名,年龄,要求相同的姓名和年龄认为是重复的Person数据
5.LinkedHashMap
- LinkedHash 是 HashMap 的子类
- HashMap 的 key 值,与 HashSet 原理一致,因此在HashMap中存储的元素,无序。
- LinkedHashMap 与 HashMap的区别就是能够让元素的存取是有序的
import java.util.HashMap;
import java.util.LinkedHashMap;
public class MapOnly {
public static void main(String[] args) {
//1.创建Map集合
HashMap<Person,String> map = new HashMap<>();
map.put(new Person("李四",25),"a");
map.put(new Person("张三",20),"a");
map.put(new Person("张三",20),"b");
//没有做到去重复
//System.out.println(map);//{Person{name='李四', age=25}=a, Person{name='张三', age=20}=a, Person{name='张三', age=20}=b}
//若想做到去重复,Person类中重写HashCode()+equals方法
System.out.println(map);//{Person{name='张三', age=20}=b, Person{name='李四', age=25}=a}
//2.使用LinkedHashMap进行有序存储
LinkedHashMap<Person,String> lhm = new LinkedHashMap<>();
lhm.put(new Person("李四",25),"a");
lhm.put(new Person("张三",20),"a");
lhm.put(new Person("张三",20),"b");
System.out.println(lhm);//{Person{name='李四', age=25}=a, Person{name='张三', age=20}=b}
}
}6.HashMap 与 HashTable 的区别
- HashMap 与 Hashtable 都是Map接口的实现类,都是用于键值对映射关系的存储
- 所有的引用数据类型的一个默认值都可以设置为null,null在堆内存中什么都没有。
- 区别:
2.Hashtable 线程安全,运行速度慢; HashMap 线程不安全,运行速度快
3.Hashtable 不支持null的键或值; HashMap支持存储null的键或值
import java.util.HashMap;
import java.util.Hashtable;
public class HashTableDemo {
public static void main(String[] args) {
HashMap<Integer,String> map = new HashMap<>();
map.put(null,"a");
map.put(1,null);
map.put(2,"b");
System.out.println("---"+map);//---{null=a, 1=null, 2=b}
Hashtable<Integer,String> table = new Hashtable<>();
//table.put(null,"a");//java.lang.NullPointerException
//table.put(1,null);
table.put(2,"b");
System.out.println(table);
}
}二.Collections集合类
Arrays工具类:功能,针对于数组做一些操作
Collections工具类:功能,针对于集合进行一些操作,来自于java.util包,其中所有的方法都是静态的,不需要new对象
1.sort(List list):对list集合进行默认升序排列,set集合不能排序
2.binarySearch(List list,Object key):检索key在List集合中的索引位置,返回值 索引int类型
如果找到了,返回一个>=0的int整数; 如果没有找到,返回一个负数
注意:1.要求List集合升序排列的;2.通过结果是否>=0来进行判断元素key是否存在于集合中
3.max(Collection c):将集合中的最大值获取到,一般比较数值有意义
4.min(Collection c):将集合中的最小值获取到,一般比较数值有意义
5.shuffle(List list):将List集合中的数据任意打乱
使用场景:洗牌发牌,需要每次将牌任意打乱
import java.util.ArrayList;
import java.util.Collections;
public class CollectionsDemo {
public static void main(String[] args) {
//1.sort(List list):升序排序
ArrayList<Integer> arr = new ArrayList<>();
arr.add(12);
arr.add(-8);
arr.add(1);
arr.add(99);
arr.add(0);
Collections.sort(arr);
System.out.println(arr);//[-8, 0, 1, 12, 99]
//2.binarySearch(List list,Object key)
int index = Collections.binarySearch(arr,99);
System.out.println(index);//4
System.out.println(Collections.binarySearch(arr,199));//-6 [-8, 0, 1, 12, 99,199](-1,-2,-3,-4,-5,-6)
System.out.println(Collections.binarySearch(arr,11));//-4 [-8, 0, 1,11, 12, 99](-1,-2,-3,-4,-5,-6)
//3.max(Collection c);min(Collection c)
int max = Collections.max(arr);
int min = Collections.min(arr);
System.out.println("该集合最大值为:"+max+"最小值为:"+min);//该集合最大值为:99最小值为:-8
//4.shuffle(List list):任意打乱
Collections.shuffle(arr);
System.out.println("~~"+arr);//~~[1, 12, 0, -8, 99]
}
}斗地主案例,完成洗牌发牌动作
规则:
1.组装54张扑克牌
2.将54张牌顺序打乱
3.三个玩家参与游戏,三人交替摸牌,每人17张牌,最后三张留作底牌
4.查看三人手中各自的牌(升序排序)、底牌
手中扑克牌从大到小的摆放顺序:大王、小王、2、A、K、Q、J、10、9、8、7、6、5、4、3
分析:
牌共54张
大王 小王 2 A K Q....3(2...3 每张牌有4个花色)
每一张牌对应一个数字,牌从大到小,对应的数字从小到大----小数字对应大牌 查表法
1.组装牌 Map<Integer,String>
2.洗牌 Collections.shuffle(List list) <--创建list集合存放key值
3.发牌
底牌 -- 3张 list索引0,1,2
玩家1 --17张 list索引%3==0
玩家2 --17张 list索引%3==1
玩家3 --17张 list索引%3==2
4.看牌:需要将玩家和底牌按照从大到小的顺序进行排列
看牌逻辑
1.将玩家手中的牌号码,进行升序排列,对应牌从大到小
2.通过牌号码,获取到对应的真实牌,展示到控制台上import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class DouDiZhu {
public static void main(String[] args) {
//1.设置牌的4个花色
String[] flower = {"?","?","?","?"};
//2.准备牌
String[] puke = {"2","A","K","Q","J","10","9","8","7","6","5","4","3"};
//3.创建Map集合,用于装54张牌和牌大小号的对应关系
Map<Integer,String> map = new HashMap<>();
//创建一个List集合,用于存放所有牌的牌号,为了后面的洗牌和发牌
ArrayList<Integer> list = new ArrayList<>();
//定义一个牌号的初始值,0和1留给大小王
int count = 2;
for(String pai : puke){
for(String f : flower){
//4.将带有花色的牌放入Map集合中
map.put(count,f+pai);
list.add(count);
count++;
}
}
map.put(0,"大王");
list.add(0);
map.put(1,"小王");
list.add(1);
System.out.println("李英楠新买一个puke儿: "+map);
System.out.println("puke儿不少,一共"+map.size()+"张");
//5.洗牌,将List中对的所有牌号打乱
System.out.println("小张把牌洗一下!~~");
System.out.println("好嘞!");
Collections.shuffle(list);
//6.创建玩家牌,底牌的容器
ArrayList<Integer> play1 = new ArrayList<>();
ArrayList<Integer> play2 = new ArrayList<>();
ArrayList<Integer> play3 = new ArrayList<>();
ArrayList<Integer> bottom = new ArrayList<>();
//7.发牌,三个玩家每人17张,底牌三张,实际上是发给玩家的是list集合中的牌号
//前三张发给底牌
System.out.println("开始发牌:");
for (int i = 0; i < list.size(); i++) {
if(i<3){//发给底牌
bottom.add(list.get(i));
}else{
if(i%3==0){//发给玩家1
play1.add(list.get(i));
}else if(i%3==1){//发给玩家2
play2.add(list.get(i));
}else{//发给玩家3
play3.add(list.get(i));
}
}
}
//8.看牌
System.out.print("小李的牌是:");
lookPai(play1,map);
System.out.print("小张的牌是:");
lookPai(play2,map);
System.out.print("小英的牌是:");
lookPai(play3,map);
System.out.println("底牌是:");
lookPai(bottom,map);
}
public static void lookPai(ArrayList<Integer> play,Map<Integer,String> map){
//1.将玩家手中的牌号进行升序排序
Collections.sort(play);
//2.通过牌号到map集合中获取到真实的value值,就是真实底牌
for(Integer key : play){
String value = map.get(key);
System.out.print(value+" ");
}
System.out.println();
}
}