Java
斗地主发牌阶段
package com.yu.Day0523Demo;
import java.util.*;
public class GameDemo {
//1.定义集合存储五十四张牌对象
public static List<Card> allCards = new ArrayList<>();
//2.定义静态代码块初始化牌数据
static {
//3. 定义点数:个数确定,类型确定,使用数组
String[] sizes = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
//4.定义花色: 个数确定,类型确定,使用数组
String[] colors = {"♠","♣","♦","♥"};
int index = 0;
//5.组合花色点数
for (int i = 0; i < sizes.length; i++) {
index++;
for (int j = 0; j < colors.length; j++) {
//6.封装成牌对象
Card c = new Card(sizes[i],colors[j],index);
//7.存入到集合容器中去
allCards.add(c);
}
}
//8.大小王存入到集合中去,"大🃏""小🃏"
Collections.addAll(allCards,new Card("","大🃏",++index),new Card("","小🃏",++index));
System.out.println(allCards);
}
public static void main(String[] args) {
//9.洗牌
Collections.shuffle(allCards);
System.out.println(allCards);
//10.打牌人(定义三个玩家,每个玩家的牌是一个集合容器
List<Card> linghuchong = new ArrayList<>();
List<Card> renwoxing = new ArrayList<>();
List<Card> fengqingyang = new ArrayList<>();
//10.开始发牌(从集合中取出五十一张牌发给三个玩家,留三张作为底牌
for (int i = 0; i < allCards.size() - 3; i++) {
Card c = allCards.get(i);
if(i % 3 == 0){
linghuchong.add(c);
}else if(i % 3 == 1){
renwoxing.add(c);
}else if(i % 3 == 2){
fengqingyang.add(c);
}
}
//11,拿到三张底牌(将最后三种底牌放到子集合中)
List<Card> lastThreeCards = allCards.subList(allCards.size()-3, allCards.size());
//12.给玩家牌排序
changeCards(linghuchong);
changeCards(renwoxing);
changeCards(fengqingyang);
//13.创建一个随机数来选择地主
Random random = new Random();
int dizhu = random.nextInt(3);
System.out.println(dizhu);
if(dizhu % 3 == 0){
linghuchong.addAll(lastThreeCards);
changeCards(linghuchong);
}else if(dizhu % 3 == 1){
renwoxing.addAll(lastThreeCards);
changeCards(renwoxing);
}else if(dizhu % 3 == 2){
fengqingyang.addAll(lastThreeCards);
changeCards(fengqingyang);
}
//14.输出当前玩家的牌
System.out.println("令狐冲"+linghuchong);
System.out.println("任我行"+renwoxing);
System.out.println("风清扬"+fengqingyang);
//15.显示底牌
System.out.println(lastThreeCards);
}
private static void changeCards(List<Card> cards) {
Collections.sort(cards, new Comparator<Card>() {
@Override
public int compare(Card o1, Card o2) {
return o1.getIndex()- o2.getIndex();
}
});
}
}
Map集合体系
概述
- Map集合是一种双列集合,每个元素包含两个数据
- Map集合的每个元素的格式:key=value(键值对元素)
- Map集合也称为"键值对集合"
整体格式
- Collection集合的格式:[元素1,元素2,元素3...]
- Map集合的完整格式:[key1 = value1,key2=value2,key3=value3...]
体系
- Map(接口)
- HashMap(实现类)
- LinkedHashMap(实现类)
- HashTable(实现类)
- porperties(实现类)
- ...(接口)
- TreeMap(实现类)
- HashMap(实现类)
说明
- 使用最多的Map集合是HashMap
- 重点掌握HashMap,LinkedHashMap,TreeMap,其他的后续理解
特点
- Map集合的特点都是由键决定的
- Map集合的键是无序,不重复的,无索引的,值不做要求(可重复)
- Map集合后面重复的键对应的值会覆盖前面的重复键的值
- Map集合的键值对都可以为null
实现类特点
-
HashMap: 元素按照键是无序,不重复无索引,值不做要求.(与Map体系一致)
-
LinkedHashMap :元素按照键是有序,不重复,无索引,值不做要求
-
TreeMap:元素按照键是排序,不重复,无索引的,值不做要求
常用API
- Map 是双列集合的祖宗接口,他的功能全部双列集合都可以继承使用的
方法名称 | 说明 |
---|---|
V put (K kye ,V value) | 添加元素 |
V remove(Object key) | 根据键删除键值对元素 |
void clear() | 移除所有的键值对元素 |
boolean containsKey(Object key) | 判断集合算法包含指定的键 |
boolean containsValue(Object value) | 判断集合算法包含指定的值 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合长度,也就是集合中键值对的个数 |
遍历方式
-
方式一
- 键找值方式遍历:先获取Map集合全部的键,在根据遍历
-
方式二
- 键值对的方式遍历,把"键值对"看成一个整体,难度较大
-
方式三
- JDK 1.8开始之后的新技术:Lambda表达式
方式一:键找值
- 先获取Map集合的全部键的Set集合
- 遍历键的Set集合,然后通过键提取对应值
键找值涉及到的API
方法名称 | 说明 |
---|---|
Set |
获取所有键的集合 |
V get(Object key) | 根据键获取值 |
方式二 :键值对
- 先把Map集合转换成Set集合,Set集合中每个元素都是键值对实体类型了
- 遍历Set集合,然后提取键以及提取值
键值对涉及到的API
方法名称 | 说明 |
---|---|
Set<Map.Entry<K,V>> entrySet() | 获取所有键值对对象的集合 |
K getKey() | 获取键 |
V getValue() | 获取值 |
方式三:Lambda
- 得益于JDK 8开始的新技术Lambda表达式,提供了中更简单,更直接的遍历集合的方式
Map结合Lambda遍历的API
方法名称 | 说明 |
---|---|
default void forEach(BiConsumer<? super K,? super V> action) | 结合Lambda遍历Map集合 |
package com.yu.Day0523Demo;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
public class MapDemo {
public static void main(String[] args) {
Map<String,Integer> shopping = new HashMap<>();
shopping.put("yu",18);
shopping.put("xiao",19);
shopping.put ("yu2",20);
shopping.put("yu3",18);
System.out.println(shopping);
// Set<Map.Entry<String, Integer>> entries = shopping.entrySet();
// for (Map.Entry<String, Integer> entrie:entries) {
// String a = entrie.getKey();
// int b =entrie.getValue();
// System.out.println(a+b);
// }
shopping.forEach(new BiConsumer<String, Integer>() {
@Override
public void accept(String s, Integer integer) {
System.out.println(s+integer);
}
});
shopping.forEach((k,v) -> {
System.out.println(k+" "+v);
});
}
}
实例:投票
vote 投票
option 选择
package com.yu.Day0523Demo;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class voteTest {
public static void main(String[] args) {
String[] option = {"A","B","C","D"};
StringBuilder sbs = new StringBuilder();
Random random = new Random();
//创建一个八十个人的选项
for (int i = 0; i < 80; i++) {
sbs.append(option[random.nextInt(option.length)]);
}
//输出随机八十个人的选项
System.out.println(sbs);
//创建一个HashMap集合
Map<Character , Integer> infos = new HashMap<>();
//根据选项进行键值对匹配
for (int i = 0; i < sbs.length(); i++) {
//想当与读取数组
char c = sbs.charAt(i);
if(infos.containsKey(c)){
//表示当前Map集合存在此选项,此选项加1
infos.put(c,infos.get(c)+1);
}else{
//表示当前数据第一次存储
infos.put(c,1);
}
}
System.out.println(infos);
}
}
实现类HashMap类
特点
- HashMap 是Map里面的一个实现类.特点都是由键决定的:无序,不重复,无索引
- HashMap和HashSet底层原理是一模一样的,都是哈希表结构,只是HashMap的每个元素包含两个值而已
实际上:Set系列集合的底层就是Map实现的,只是Set集合中的元素只要键数据,不要值数据而已
- 由键决定:无序,不重复,无索引.HashMap底层是哈希表结构的
- 依赖HashCode方法和equals方法保证键的唯一
- 如果键要存储的是自定义对象,需要重写HashCode和equals方法
- 基于哈希表.增删改查的性能都较好
实现类LinkedHashMap
- 由键决定:有序,不重复,无索引.
- 这里的有序指的是保证存储和取出的元素顺序一种
- 原理:底层数据结构依然是哈希表,只是每个键值对元素又额外的多了一个双链表的机制记录存储的顺序
实现类TreeMap
- 由键决定特性:不重复,无索引,可排序
- 可排序:按照键数据的大小默认升序(由小到大)排序,只能对键排序
- 注意:TreeMap集合是一定要排序的,可以默认排序,也可以将键按照指定的规则进行排序
- TreeMap和TreeSet的底层原理是一样的
自定义排序规则
- 类实现Comparable接口,重写比较规则
- 集合自定义Comparator比较器对象,重写比较规则
总结:各实现类特点
- HashMap:元素按照键是无序,不重复,无索引.值不做要求,基于哈希表(与Map体系一致)
- LinkedHashMap:元素按照键是有序,不重复,无索引,值不做要求,基于哈希表
- TreeMap:元素只能按照键排序,不重复无索引.值不做要求,可以做排序
package com.yu.Day0523Demo;
import java.util.*;
public class ColletionsTest {
public static void main(String[] args) {
//创建一个同学集合并记录他们的选票
Map<String, List<String>> ren = new HashMap<>();
//每个同学都要新建一个List集合,清空不管用在这,使用清空会导致所有选票都变成最后一次选票结果
List<String> option = new ArrayList<>();
Collections.addAll(option,"A","B","C","D");
ren.put("yu",option);
List<String> option1 = new ArrayList<>();
Collections.addAll(option1,"A","B");
ren.put("xiao",option1);
List<String> option2 = new ArrayList<>();
Collections.addAll(option2,"A","D");
ren.put("yu1",option2);
List<String> option3 = new ArrayList<>();
Collections.addAll(option3,"A","C");
ren.put("yu2",option3);
System.out.println(ren);
//创建一个接收同学们选择的多个地点的投票
Map<String,Integer> where = new HashMap<>();
//将投票结果取出
Collection<List<String>> votes = ren.values();
//投票存储格式[[A, D], [A, B], [A, C], [A, B, C, D]]
System.out.println(votes);
//使用循环遍历,选票信息
for (List<String> vote:votes) {
for (String s:vote) {
if(where.containsKey(s)){
where.put(s,where.get(s)+1);
}else{
where.put(s,1);
}
}
}
System.out.println(where);
}
}