集合体系结构

集合类的特点:提供一种存储空间可变的存储模型,存储的数据容量可以随时发送改变

image

1.Collection

概述:
  • 是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素
  • JDK 不提供此接口的任何直接实现,它提供更具体的子接口(如Set和List)实现
创建Collection集合的对象:
  • 多态的方式
  • 具体的实现类ArrayList

Collection 集合的常用方法:

image

演示:

  • boolean add(E e)
// 创建集合对象
Collection<String> c = new ArrayList<String>();
// 添加元素
c.add("hello");
c.add("word");
c.add("java");
// 输出集合对象
System.out.println(c);

// 输出结果
[hello, word, java]
  • boolean remove(Object o)
// 创建集合对象
Collection<String> c = new ArrayList<String>();
// 添加元素
c.add("hello");
c.add("word");
c.add("java");
// 移除元素
System.out.println(c.remove("word"));
System.out.println(c.remove("javaSE"));
// 输出集合对象
System.out.println(c);

// 输出结果
true
false
[hello, java]
  • void clear()
// 创建集合对象
Collection<String> c = new ArrayList<String>();
// 添加元素
c.add("hello");
c.add("word");
c.add("java");
// 清空集合中的元素
c.clear();
// 输出集合对象
System.out.println(c);

// 输出结果
[]
  • boolean contains(Object o)
// 创建集合对象
Collection<String> c = new ArrayList<String>();
// 添加元素
c.add("hello");
c.add("word");
c.add("java");
// 判断集合中是否存在 word 指定元素
System.out.println(c.contains("word"));
// 输出集合对象
System.out.println(c);

// 输出结果
true
[hello, word, java]
  • boolean isEmpty()
// 创建集合对象
Collection<String> c = new ArrayList<String>();
// 添加元素
c.add("hello");
c.add("word");
c.add("java");
// 判断集合是否为空
System.out.println(c.isEmpty());
// 输出集合对象
System.out.println(c);

// 输出结果
false
[hello, word, java]
  • int size()
// 创建集合对象
Collection<String> c = new ArrayList<String>();
// 添加元素
c.add("hello");
c.add("word");
c.add("java");
// 计算集合的长度,即集合中元素的个数
System.out.println(c.size());
// 输出集合对象
System.out.println(c);

// 输出结果
3
[hello, word, java]
  • 集合的遍历

Iterator :迭代器,集合的专用遍历方式
  • Iterator iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到
  • 迭代器是通过集合的iterator() 方法得到的,所以我们说它是依赖于集合而存在的
Iterator 中的常用方法:
  • E next():返回迭代中的下一个元素
  • boolean hasNext():如果迭代具有更多元素,则返回true
// 创建集合对象
Collection<String> c = new ArrayList<String>();
// 添加元素
c.add("hello");
c.add("word");
c.add("java");
// 生成 迭代器
Iterator<String> it = c.iterator();
// 通过while循环遍历集合
while(it.hasNext()){
    String s = it.next();
    System.out.println(s);
}

// 输出结果
hello
word
java

2.List

概述:
  • 有序集合(也称为序列),用户可以精确控制列表中每个元素的插入位置。用户可以通过整数索引访问元素,并搜索列表中的元素
  • 与Set集合不同,列表通常允许重复的元素
List 集合的特点:
  • 有序:存储和取出的元素顺序一致
  • 可重复:存储的元素可以重复
方法:

image

    // 创建集合对象
    List<String> list = new ArrayList<String>();
    // 添加元素
    list.add("hello");
    list.add("word");
    list.add("java");
    // 在指定索引位置 添加元素
    list.add(1,"javaee");
    // 输出集合对象
    System.out.println(list);
    
    // 输出结果
    [hello, javaee, word, java]
    
    // 创建集合对象
    List<String> list = new ArrayList<String>();
    // 添加元素
    list.add("hello");
    list.add("word");
    list.add("java");
    // 删除指定索引的元素,并返回被删除的元素值
    System.out.println(list.remove(1));
    // 输出集合对象
    System.out.println(list);
    
    // 输出结果
    word
    [hello, java]
    
    // 创建集合对象
    List<String> list = new ArrayList<String>();
    // 添加元素
    list.add("hello");
    list.add("word");
    list.add("java");
    // 修改指定索引的元素,并返回被修改的元素值
    System.out.println(list.set(1,"javaee"));
    // 输出集合对象
    System.out.println(list);
    
    // 输出结果
    word
    [hello, javaee, java]
    
    // 创建集合对象
    List<String> list = new ArrayList<String>();
    // 添加元素
    list.add("hello");
    list.add("word");
    list.add("java");
    // 返回指定索引处的元素
    System.out.println(list.get(1));
    // 输出集合对象
    System.out.println(list);
    
    // 输出结果
    word
    [hello, word, java]
    
    // 创建集合对象
    List<String> list = new ArrayList<String>();
    // 添加元素
    list.add("hello");
    list.add("word");
    list.add("java");
    // 通过for循环遍历集合
    for(int i=0;i<list.size();i++){
        String s = list.get(i);
        System.out.println(s);
    }
    
    // 输出结果
    hello
    word
    java
    
    // 创建集合对象
    List<String> list = new ArrayList<String>();
    // 添加元素
    list.add("hello");
    list.add("word");
    list.add("java");
    // 生成 迭代器
    Iterator<String> it = list.iterator();
    // 通过while循环遍历集合
    while(it.hasNext()){
        String s = it.next();
        System.out.println(s);
    }
    
    // 输出结果
    hello
    word
    java
    
    // 创建集合对象
    List<String> list = new ArrayList<String>();
    // 添加元素
    list.add("hello");
    list.add("word");
    list.add("java");
    // 通过for循环遍历集合
    for(Sting s:list){
        System.out.println(s);
    }
    
    // 输出结果
    hello
    word
    java
    

ListIterator 列表迭代器

ListIterator 概述:
  • 通过List 集合的listIterator() 方法得到,所以说它是List集合特有的迭代器
  • 用于允许程序员沿任意方向遍历列表的列表迭代器,在迭代期间修改列表,并获取列表中迭代器的当前位置
ListIterator 中的常用方法:
  • E next():返回迭代器中的下一个元素
  • boolean hasNext():如果迭代器具有更多元素,则返回true
  • E previous():返回列表中的上一个元素
  • boolean hasPrevious():如果此列表迭代器在相反方向遍历列表时具有更多元素,则返回true
  • void add(E e):将指定的元素插入列表

演示:

// 创建集合对象
List<String> list = new ArrayList<String>();
// 添加元素
list.add("hello");
list.add("word");
list.add("java");
// 生成List集合的 ListIterator迭代器
ListIterator<String> lit = list.listIterator();
// 通过while循环 正向 遍历集合
while(lit.hasNext()){
    String s = lit.next();
    System.out.println(s);
}
System.out.println("--------------------------");
// 通过while循环 反向 遍历集合
while(lit.hasPrevious()){
    String s = lit.previous();
    System.out.println(s);
}
System.out.println("--------------------------");
// 通过while循环 判断列表 当列表中存在元素是 word 时,在列表中添加一个 javaee
while(lit.hasNext()){
    String s = lit.next();
    if(s.equals("word")){
        lit.add("javaee");
    }
}
System.out.println(list);

// 输出结果
hello
word
java
--------------------------
java
word
hello
--------------------------
[hello, word, javaee, java]

List 集合的特点

List集合常用子类:ArrayList,LinkedList
  • ArrayList:底层数据结构是数组,对元素 查询快,增删慢
  • LinkedList:底层数据结构是链表,对元素 查询慢,增删快
ArrayList 在其他篇章有详细讲解,这里我们重点说一下 LinkedList 的常用方法

image

    // 创建集合对象
    LinkedList<String> linkedList = new LinkedList<String>();
    // 添加元素
    linkedList.add("hello");
    linkedList.add("word");
    linkedList.add("java");
    // 在该列表开头插入指定的元素
    linkedList.addFirst("javase");
    // 输出集合对象
    System.out.println(linkedList);
    
    // 输出结果
    [javase, hello, word, java]
    
    // 创建集合对象
    LinkedList<String> linkedList = new LinkedList<String>();
    // 添加元素
    linkedList.add("hello");
    linkedList.add("word");
    linkedList.add("java");
    // 在该列表末尾插入指定的元素
    linkedList.addLast("javaee");
    // 输出集合对象
    System.out.println(linkedList);
    
    // 输出结果
    [hello, word, java, javaee]
    
    // 创建集合对象
    LinkedList<String> linkedList = new LinkedList<String>();
    // 添加元素
    linkedList.add("hello");
    linkedList.add("word");
    linkedList.add("java");
    // 输出此列表中第一个元素
    System.out.println(linkedList.getFirst());
    // 输出集合对象
    System.out.println(linkedList);
    
    // 输出结果
    hello
    [hello, word, java]
    
    // 创建集合对象
    LinkedList<String> linkedList = new LinkedList<String>();
    // 添加元素
    linkedList.add("hello");
    linkedList.add("word");
    linkedList.add("java");
    // 输出此列表中最后一个元素
    System.out.println(linkedList.getLast());
    // 输出集合对象
    System.out.println(linkedList);
    
    // 输出结果
    java
    [hello, word, java]
    
    // 创建集合对象
    LinkedList<String> linkedList = new LinkedList<String>();
    // 添加元素
    linkedList.add("hello");
    linkedList.add("word");
    linkedList.add("java");
    // 把此列表中第一个元素删除,并返回被删除的元素值
    System.out.println(linkedList.removeFirst());
    // 输出集合对象
    System.out.println(linkedList);
    
    // 输出结果
    hello
    [word, java]
    
    // 创建集合对象
    LinkedList<String> linkedList = new LinkedList<String>();
    // 添加元素
    linkedList.add("hello");
    linkedList.add("word");
    linkedList.add("java");
    // 把此列表中最后一个元素删除,并返回被删除的元素值
    System.out.println(linkedList.removeLast());
    // 输出集合对象
    System.out.println(linkedList);
    
    // 输出结果
    java
    [hello, word]
    

3.Set

Set集合特点:
  • 不包含重复元素的集合
  • 没有带索引的方法,所以不能使用普通for循环进行遍历
// 创建集合对象
Set<String> set = new Set<String>();
// 添加元素
set.add("hello");
set.add("word");
set.add("java");
// 不包含重复元素的集合
set.add("word");
// 遍历集合
for(String s : set){
    // 对迭代顺序不作任何保证
    System.out.println(s);
}

// 输出结果
word
java
hello

哈希值

哈希值:是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值

Object 类中有一个方法可以获取对象的哈希值

  • public int hashCode():返回对象的哈希码值
String s1 = "对象1";
// 同一个对象多次调用hashCode()方法返回的哈希值是相同的
System.out.println(s1.hashCode());
System.out.println(s1.hashCode());
System.out.println("----------");
// 默认情况下,不同对象的哈希值是不相同的
String s2 = "对象2";
System.out.println(s2.hashCode());

// 输出结果
23740841
23740841
----------
23740842

对象的哈希值特点:

  • 同一个对象多次调用hashCode()方法返回的哈希值是相同的
  • 默认情况下,不同对象的哈希值是不相同的。而重写hashCode()方法,可以自定义哈希值,实现让不同对象的哈希值相同

HashSet 集合

集合特点:
  • 底层数据结构是哈希表
  • 对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致
  • 没有带索引的方法,所以不能使用普通for循环遍历
  • 由于是Set集合,所以是不包含重复元素的集合
// 创建集合对象
HashSet<String> hs = new HashSet<String>();
// 添加元素
hs.add("hello");
hs.add("word");
hs.add("java");
// 不包含重复元素的集合
hs.add("word");
// 遍历集合
for(String s : hs){
    // 对迭代顺序不作任何保证
    System.out.println(s);
}

// 输出结果
word
java
hello

LinkedHashSet 集合

LinkedHashSet 集合特点:
  • 哈希表和链表实现的Set接口,具有可预测的迭代次序
  • 由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
  • 由哈希表保证元素唯一,也就是说没有重复的元素
// 创建集合对象
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<String>();
// 添加元素
linkedHashSet.add("hello");
linkedHashSet.add("word");
linkedHashSet.add("java");
// 不包含重复元素的集合
linkedHashSet.add("word");
// 遍历集合
for(String s : linkedHashSet){
    // 存储和取出顺序是一致的
    System.out.println(s);
}

// 输出结果
hello
word
java

TreeSet 集合

TreeSet 集合特点:
  • 元素有序,这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方式取决于构造方法
    • TreeSet():根据其元素的自然排序进行排序
    • TreeSet(Comparator comparator):根据指定的比较器进行排序
  • 没有带索引的方法,所以不能使用普通for循环遍历
  • 由于是Set集合,所以不包含重复元素的集合
// 创建集合对象
TreeSet<Integer> ts = new TreeSet<Integer>();
// 添加元素
ts.add(10);
ts.add(40);
ts.add(20);
// 不包含重复元素的集合
ts.add(20);
// 遍历集合
for(Integer i : ts){
    // 自然排序--即从小到大
    System.out.println(i);
}

// 输出结果
10
20
40

4.泛型

泛型:是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型。它的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数

参数化类型,顾名思义,就是将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型,这种参数类型可以用在类、方法和接口中,分别被称为泛型类、泛型方法、泛型接口。

泛型定义格式:
  • 修饰符 class 类名<类型>{}
    • 范例:public class Generic{}
    • 此处T 可以随便写为任意标识,常见的如 T、E、K、V 等形式的参数常用于标识泛型
  • <类型>:指定一种类型的格式。这里的类型可以看成是形参
  • <类型1,类型2,...>:指定多种类型的格式,多种类型之间用逗号隔开。这里的类型可以看成是形参
  • 将来具体调用时给定的类型可以看成是实参,并且实参的类型只能是引用数据类型
泛型的好处:
  • 把运行时期的问题提前到了编译时期
  • 避免了强制类型装换

可变参数

可变参数又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的了

集合自带的可变参数方法:

  • Arrays工具类中,public static List asList(T... a):返回由指定数组支持的固定大小的列表
  • List接口中,public static List of(E... elements):返回包含任意数量元素的不可变列表
  • Set接口中,public static Set of(E... elements):返回一个包含任意数量元素的不可变集合
List<String> list1 = Arrays.asList("hello","word","java");
List<String> list2 = List.of("hello","word","java","word");
List<String> list3 = Set.of("hello","word","java","word");
System.out.println(list1);
System.out.println(list2);
System.out.println(list3);

// 输出结果
[hello, word, java]
[hello, word, java, word]
[word, java, hello]

image

5.Map

Map集合概述:
  • Interface Map<K,V> K:键的类型;V:值的类型
  • 将键映射到值的对象;不能包含重复的键,每个键可以映射到最多一个值
  • 举例:学生的学号和姓名
    • vun001 小明
    • vun002 小花
    • vun003 小兰
  • 创建Map集合对象
    • 多态的方式
    • 具体的实现类HashMap
// 创建集合对象
Map<String,String> map = new HashMap<String,String>();
// 将指定的值与该映射中的指定键相关联
map.put("vun001","小明");
map.put("vun002","小花");
map.put("vun003","小兰");
// 输出集合对象
System.out.println(map);

// 输出结果
{vun003=小兰, vun001=小明, vun002=小花}
Map集合的基本功能:

image

    // 创建集合对象
    Map<String,String> map = new HashMap<String,String>();
    // 将指定的值与该映射中的指定键相关联
    map.put("小明","小美");
    map.put("小强","小花");
    map.put("小孙","小兰");
    // 输出集合对象
    System.out.println(map);
    
    // 输出结果
    {小孙=小兰, 小强=小花, 小明=小美}
    
    // 创建集合对象
    Map<String,String> map = new HashMap<String,String>();
    // 将指定的值与该映射中的指定键相关联
    map.put("小明","小美");
    map.put("小强","小花");
    map.put("小孙","小兰");
    // 根据 键 删除键值对元素,并返回被删除元素的 值
    System.out.println(map.remove("小强"));
    // 当删除的键不存在时,返回null
    System.out.println(map.remove("小华"));
    // 输出集合对象
    System.out.println(map);
    
    // 输出结果
    小花
    null
    {小孙=小兰, 小明=小美}
    
    // 创建集合对象
    Map<String,String> map = new HashMap<String,String>();
    // 将指定的值与该映射中的指定键相关联
    map.put("小明","小美");
    map.put("小强","小花");
    map.put("小孙","小兰");
    // 移除所有的键值对元素--慎重使用
    map.clear();
    // 输出集合对象
    System.out.println(map);
    
    // 输出结果
    {}
    
    // 创建集合对象
    Map<String,String> map = new HashMap<String,String>();
    // 将指定的值与该映射中的指定键相关联
    map.put("小明","小美");
    map.put("小强","小花");
    map.put("小孙","小兰");
    // 判断集合中是否包含指定的 键
    System.out.println(map.containKey("小明"));
    System.out.println(map.containKey("小川"));
    // 输出集合对象
    System.out.println(map);
    
    // 输出结果
    true
    false
    {小孙=小兰, 小强=小花, 小明=小美}
    
    // 创建集合对象
    Map<String,String> map = new HashMap<String,String>();
    // 将指定的值与该映射中的指定键相关联
    map.put("小明","小美");
    map.put("小强","小花");
    map.put("小孙","小兰");
    // 判断集合中是否包含指定的 值
    System.out.println(map.containValue("小美"));
    System.out.println(map.containValue("小川"));
    // 输出集合对象
    System.out.println(map);
    
    // 输出结果
    true
    false
    {小孙=小兰, 小强=小花, 小明=小美}
    
    // 创建集合对象
    Map<String,String> map = new HashMap<String,String>();
    // 将指定的值与该映射中的指定键相关联
    map.put("小明","小美");
    map.put("小强","小花");
    map.put("小孙","小兰");
    // 判断集合是否为 空
    System.out.println(map.isEmpty());
    // 输出集合对象
    System.out.println(map);
    
    // 输出结果
    false
    {小孙=小兰, 小强=小花, 小明=小美}
    
    // 创建集合对象
    Map<String,String> map = new HashMap<String,String>();
    // 将指定的值与该映射中的指定键相关联
    map.put("小明","小美");
    map.put("小强","小花");
    map.put("小孙","小兰");
    // 计算集合的长度,也就是集合中键值对的个数
    System.out.println(map.size());
    // 输出集合对象
    System.out.println(map);
    
    // 输出结果
    3
    {小孙=小兰, 小强=小花, 小明=小美}
    
Map集合的获取功能:

image

    // 创建集合对象
    Map<String,String> map = new HashMap<String,String>();
    // 将指定的值与该映射中的指定键相关联
    map.put("小明","小美");
    map.put("小强","小花");
    map.put("小孙","小兰");
    // 根据 键 获取对应 值
    System.out.println(map.get("小明"));
    System.out.println(map.get("小川"));
    // 输出集合对象
    System.out.println(map);
    
    // 输出结果
    小美
    null
    {小孙=小兰, 小强=小花, 小明=小美}
    
    // 创建集合对象
    Map<String,String> map = new HashMap<String,String>();
    // 将指定的值与该映射中的指定键相关联
    map.put("小明","小美");
    map.put("小强","小花");
    map.put("小孙","小兰");
    // 获取所有 键 的集合
    Set<String> keySet = map.keySet();
    for(String key : keySet){
        System.out.println(key);
    }
    // 输出集合对象
    System.out.println(map);
    
    // 输出结果
    小孙
    小强
    小明
    {小孙=小兰, 小强=小花, 小明=小美}
    
    // 创建集合对象
    Map<String,String> map = new HashMap<String,String>();
    // 将指定的值与该映射中的指定键相关联
    map.put("小明","小美");
    map.put("小强","小花");
    map.put("小孙","小兰");
    // 获取所有 值 的集合
    Collection<String> values = map.values();
    for(String value : values){
        System.out.println(value);
    }
    // 输出集合对象
    System.out.println(map);
    
    // 输出结果
    小兰
    小花
    小美
    {小孙=小兰, 小强=小花, 小明=小美}
    
Map集合的遍历
  • 方式一:
// 创建集合对象
Map<String,String> map = new HashMap<String,String>();
// 将指定的值与该映射中的指定键相关联
map.put("小明","小美");
map.put("小强","小花");
map.put("小孙","小兰");
// 获取所有 键 的集合
Set<String> keySet = map.keySet();
for(String key : keySet){
    // 通过get方法,根据键找对应值
    String value = map.get(key);
    System.out.println(key+","+value);
}

// 输出结果
小孙,小兰
小强,小花
小明,小美
  • 方式二:
// 创建集合对象
Map<String,String> map = new HashMap<String,String>();
// 将指定的值与该映射中的指定键相关联
map.put("小明","小美");
map.put("小强","小花");
map.put("小孙","小兰");
// 获取所有 键值对对象 的集合
Set<Map.Entry<String, String>> entrys = map.entrySet();
for(Map.Entry<String, String> entry : entrys){
    // 根据键值对对象获取键和值
    String key = entry.getKey();
    String value = entry.getValue();
    System.out.println(key+","+value);
}

// 输出结果
小孙,小兰
小强,小花
小明,小美
使用HashMap集合统计字符串中每个字符出现的次数
// 键盘录入一个字符串
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串:");
String s = sc.next();

// 创建HashMap集合,键是 Character,值是Integer
// HashMap集合默认没有排序,可以使用TreeMap集合默认键排序
// HashMap<Character, Integer> map = new HashMap<>();
TreeMap<Character, Integer> map = new TreeMap<>();

// 遍历字符串,得到每一个字符
for (int i = 0; i < s.length(); i++) {
    char key = s.charAt(i);
    Integer value = map.get(key);
    if (value == null) {
        map.put(key, 1);
    } else {
        value++;
        map.put(key, value);
    }
}

StringBuilder sb = new StringBuilder();

Set<Character> keySet = map.keySet();
for (Character key : keySet) {
    Integer value = map.get(key);
    // System.out.print(key+"("+value+")");
    sb.append(key).append("(").append(value).append(")");
}

String result = sb.toString();
System.out.println(result);

6.Collections

Collections 类的概述
  • 是针对集合操作的工具类
Collections 类的常用方法
  • public static <T entends Comparable<?super T>> void sort(List list):将指定的列表按升序排序
// 创建集合对象
List<Integer> list = new ArrayList<Integer>();
// 添加元素
list.add(30);
list.add(20);
list.add(50);
list.add(10);
list.add(40);
// 输出集合对象
System.out.println(list);
// 将指定的列表按升序排序
Collections.sort(list);
// 输出集合对象
System.out.println(list);

// 输出结果
[30, 20, 50, 10, 40]
[10, 20, 30, 40, 50]
  • public static void reverse(List<?> list):反转指定列表中的元素顺序
// 创建集合对象
List<Integer> list = new ArrayList<Integer>();
// 添加元素
list.add(30);
list.add(20);
list.add(50);
list.add(10);
list.add(40);
// 输出集合对象
System.out.println(list);
// 反转指定列表中的元素顺序
Collections.reverse(list);
// 输出集合对象
System.out.println(list);

// 输出结果
[30, 20, 50, 10, 40]
[40, 10, 50, 20, 30]
  • public static void shuffle(List<?> list):使用默认的随机源随机排列指定的列表
// 创建集合对象
List<Integer> list = new ArrayList<Integer>();
// 添加元素
list.add(30);
list.add(20);
list.add(50);
list.add(10);
list.add(40);
// 输出集合对象
System.out.println(list);
// 使用默认的随机源随机排列指定的列表
Collections.shuffle(list); // 每次执行 输出的排序都会不同--随机排列
// 输出集合对象
System.out.println(list);

// 输出结果
[30, 20, 50, 10, 40]
[10, 40, 50, 20, 30]

综合案例:通过集合对象,实现模拟斗地主中的洗牌,发牌,对每副牌排序和看牌

public static void main(String[] args) {
    // 创建一个集合对象,也就是一个牌盒
    HashMap<Integer, String> hm = new HashMap<>();
    // 用于存储每张牌的 编号
    ArrayList<Integer> array = new ArrayList<>();

    /*
            往牌盒中装牌
            方片:♦2,♦3,♦4,...,♦K,♦A
            梅花:♣2,♣3,♣4,...,♣K,♣A
            红桃:♥2,♥3,♥4,...,♥K,♥A
            黑桃:♠2,♠3,♠4,...,♠K,♠A
            王牌:小王,大王
         */
    // 定义花色、点数数组
    String[] colors = {"♦", "♣", "♥", "♠"};
    String[] numbers = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};

    // 定义编号,从0开始存储
    int index = 0;

    // 将每种花色和每种点数结合
    for (String number : numbers) {
        for (String color : colors) {
            hm.put(index, color + number);
            array.add(index);
            index++;
        }
    }
    hm.put(index, "小王");
    array.add(index);
    index++;
    hm.put(index, "大王");
    array.add(index);

    // 洗牌,把牌的编号顺序打散
    Collections.shuffle(array);

    // 创建三名玩家,并存储三名玩家牌的编号
    // TreeSet 集合的特点:根据其元素的自然排序进行排序
    TreeSet<Integer> array01ID = new TreeSet<Integer>();
    TreeSet<Integer> array02ID = new TreeSet<Integer>();
    TreeSet<Integer> array03ID = new TreeSet<Integer>();
    // 存储斗地主的三张底牌
    TreeSet<Integer> arrayDPID = new TreeSet<Integer>();

    // 发牌以及设置底牌
    for (int i = 0; i < array.size(); i++) {
        int pokerID = array.get(i);
        if (i >= array.size() - 3) {
            arrayDPID.add(pokerID);
        } else if (i % 3 == 0) {
            array01ID.add(pokerID);
        } else if (i % 3 == 1) {
            array02ID.add(pokerID);
        } else if (i % 3 == 2) {
            array03ID.add(pokerID);
        }
    }

    // 三名玩家 根据个人的牌编号去取牌并看牌
    lookPoker("小明", array01ID, hm);
    lookPoker("小兰", array02ID, hm);
    lookPoker("小华", array03ID, hm);
    lookPoker("底牌", arrayDPID, hm);
}

// 看牌--方法
public static void lookPoker(String name, TreeSet<Integer> arrayPokerID, HashMap<Integer, String> hm) {
    System.out.print(name + "的牌是:");
    for (Integer pokerID : arrayPokerID) {
        // 根据牌编号 去集合中拿牌
        String poker = hm.get(pokerID);
        System.out.print(poker + " ");
    }
    System.out.println();
}

// 输出结果
小明的牌是:♦3 ♠3 ♠4 ♥5 ♦6 ♦9 ♣10 ♠10 ♣J ♥J ♠J ♠Q ♣K ♣A ♠A ♦2 ♥2 
小兰的牌是:♣3 ♥3 ♣5 ♠5 ♠6 ♦7 ♣7 ♠7 ♣8 ♠9 ♦10 ♥10 ♦Q ♥Q ♦A ♣2 大王 
小华的牌是:♥4 ♦5 ♣6 ♥7 ♦8 ♥8 ♠8 ♣9 ♥9 ♦J ♣Q ♦K ♥K ♠K ♥A ♠2 小王 
底牌的牌是:♦4 ♣4 ♥6 
posted @ 2022-01-12 14:07  早晨9点  阅读(174)  评论(0)    收藏  举报