集合Collection
1.1集合知识回顾
集合类的特点:提供一种存储空间可变的存储模型,存储的数据容量可以随时发生改变;
1.3 Collection概述及使用
Collection集合概述:
是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素;
JDK不提供此接口的任何直接实现,它提供更具体的子接口(如Set和List)实现;
创建Collection集合的对象:
多态的形式;
具体的实现类ArrayList;
1.4Collection集合常用方法
boolean add(E e):添加元素;
boolean remove(Object o):从集合中移除指定的元素;
void clear():清空集合中的元素;
boolean contains(Object o):判断集合中是否存在指定的元素;
boolean isEmpty():判断集合是否为空;
int size():集合的长度,也就是集合中元素的个数;
1.5 Collection集合的遍历
Iterator:迭代器,集合的专用遍历方式
Iterator iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到;
迭代器是通过集合的iterator()方法得到的,所以我们说它是依赖于集合而存在的。
Iterator中的常用方法:
E next():返回迭代中的下一个元素;
boolean hasNext():如果迭代具有更多元素,则返回true;
public class Main {
public static void main(String args[]) {
Collection list = new ArrayList<String>();
System.out.println(list.add("Hello "));
list.add("the ");
list.add("world!");
System.out.println(list);
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
输出:
true
[Hello , the , world!]
Hello
the
world!
1.6集合的使用步骤
创建集合-添加元素-遍历集合(通过集合对象获取迭代器对象-通过迭代器hasNext()判断是否还有元素-通过迭代器对象next()方法获取下一个元素)
案例:Collection集合存储学生对象并遍历
package Happy;
public class Student {
private String name;
private int age;
public Student() {};
public Student(String name,int age) {
this.name = name;
this.age = age;
}
public String toString() {
return "【学生信息】姓名:"+this.name+"、年龄:"+this.age;
}}
package Happy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Main {
public static void main(String args[]) {
Collection<Student> c = new ArrayList<Student>();
Student stu1 = new Student("张三",12);
Student stu2 = new Student("李四",12);
Student stu3 = new Student("王二麻",12);
c.add(stu1);
c.add(stu2);
c.add(stu3);
Iterator<Student> iterator = c.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
输出:
【学生信息】姓名:张三、年龄:12
【学生信息】姓名:李四、年龄:12
【学生信息】姓名:王二麻、年龄:12
2.List
2.1List集合特点 public interface List extends Collection
List集合概述:
有序集合(也称序列),用户可以精确控制列表中每个元素的插入位置。用户可以通过整数索引访问元素,并搜索列表中的元素;
与Set集合不同,列表通常允许重复的元素。
List集合特点:
有序:存储和取出的元素顺序一致;
可重复:存储的元素可以重复。
2.2 List集合特有方法
void add(int index,E el ement):在此集合中的指定位置插入指定的元素;
E remove(int index):删除指定索引处的元素,返回被删除的元素;
E set(int index,E element):修改指定索引处的元素,返回被修改的元素;
E get(int index):返回指定索引处的元素。
案例:List集合存储学生对象并遍历
与上面类似。
2.3 并发修改异常
public class ConcurrentModificationException
extends RuntimeException-运行时异常
产生原因:通过迭代器获取元素时会判断预期修改值和实际修改值是否一致,而add(E element)会使得实际修改值加一;
解决方法:使用for循环遍历,用get(int index)获取元素(不会改变实际修改值)。
2.4 ListIterator
ListIterator:列表迭代器
通过List集合的listIterator()方法得到,所以说它是List集合特有的迭代器;
用于允许程序员沿任意方向遍历列表的列表迭代器,在迭代期间修改列表,并获取列表中迭代器的当前位置。
ListIterator中的常用方法:
E next():返回迭代中的下一个元素;
boolean hasNext():如果迭代具有更多元素,则返回true;
E previous():返回列表中的上一个元素;
boolean hasPrevious():如果此列表迭代器在相反方向遍历列表时具有更多元素,则返回true;
void add(E e):将指定的元素插入列表。
2.5 增强for循环
增强for:简化数组和Collection集合的遍历
实现Iterable接口的类允许其对象称为增强型for语句的目标;
它是JDK5之后出现的,其内部原理是一个Iterator迭代器。
增强for的格式:
for(元素数据类型 变量名:数组或者Collection集合){
//在此处使用变量即可,该变量就是元素
}
案例:List集合存储学生对象,用三种方式遍历
迭代器-普通for-增强for,其余类似
2.6 数据结构
数据机构是计算机存储、组织数据的方式。是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或存储效率。
2.7常见的数据结构之栈
2.8常见的数据结构之队列
2.9常见的数据结构之数组
2.10常见的数据结构之链表
2.11 List集合子类的特点
List集合常用子类:ArrayList,LinkedList
ArrayList:底层数据结构是数组,查询快,增删慢;
LinkList:底层数据结构是链表,查询慢,增删快。
练习:分别用ArrayList和LinkedList完成存储字符串并遍历
2.12 LinkedList集合的特有功能
public void addFirst(E e):在该列表开头插入指定的元素;
public void addLast(E e):将指定的元素追加到此列表的末尾
public E getFirst():返回此列表的第一个元素;
public E getLast():返回此列表的末尾元素;、、
public E removeFirst():从此列表中删除并返回第一个元素;
public E removeLast():从此列表中删除并返回最后一个元素。
第四节 Set集合
3.1 Set集合概述和特点
Set集合特点:
不包含重复元素的集合;
没有带索引的方法,所以不能用普通for循环遍历。
3.2哈希值
哈希值:是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
Object类中有一个方法可以获取对象的哈希值
public int hashCode():返回对象的哈希码值;
只要在执行Java应用程序时多次在同一个对象上调用该方法, hashCode方法必须始终返回相同的整数,前提是修改了对象中equals比较中的信息。 该整数不需要从一个应用程序的执行到相同应用程序的另一个执行保持一致。
如果根据equals(Object)方法两个对象相等,则在两个对象中的每个对象上调用hashCode方法必须产生相同的整数结果。
不要求如果两个对象根据equals(java.lang.Object)方法不相等,那么在两个对象中的每个对象上调用hashCode方法必须产生不同的整数结果。 但是,程序员应该意识到,为不等对象生成不同的整数结果可能会提高哈希表的性能。
3.3 HashSet集合概述和特点
HashSet集合特点:
底层数据结构是哈希表;
对集合的迭代顺序不做任何保证,也就是说不保证存储和取出的元素顺序一致;
没有带索引的方法,所以不能用普通for循环遍历;
由于是Set集合,所以是不包含重复元素的集合。
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class Main {
public static void main(String args[]) {
Set<String> set = new HashSet<String>();
set.add("hello");
set.add("world");
set.add("java");
set.add("java");
for(String str:set) {
System.out.println(str);
}
}
}
3.4 HashSet集合保证元素唯一性源码分析
HashCode集合存储元素:
要保证元素唯一性,需要重写hashCode()和equals()。
3.6 LinkedHashSet集合概述和特点
LinkedHashSet集合特点:
哈希表和链表实现的Set接口,具有可预测的迭代次序;
由链表保证元素有序,也就是说元素的存储和取出顺序是一样的;
由哈希表保证元素唯一,也就是说没有重复的元素。
3.7 TreeSet集合概述和特点
TreeSet集合特点:
元素有序,这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方式取决于构造方法。
TreeSet():根据其元素的自然排序进行排序;
TreeSet(Comparator comparator):根据指定的比较器进行排序。
没有带索引的方法,所以不能使用普通for循环遍历;
由于是Set集合,所以不包含重复元素的集合
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
public class Main {
public static void main(String args[]) {
TreeSet<Integer> set = new TreeSet<Integer>();
set.add(10);
set.add(50);
set.add(20);
set.add(40);
for(Integer x:set) {
System.out.println(x);
}
}
}
输出:
10
20
40
50
3.8 自然排序Comparable的使用
存储学生对象并遍历,创建TreeSet集合使用无参构造方法;
要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序。
结论:
用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的;
自然排序,就是让元素所属的类实现Comparable接口,重写conpareTo()方法;
重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写。
package Happy;
public class Student implements Comparable<Student>{
private String name;
private int age;
public Student() {};
public Student(String name,int age) {
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
public String toString() {
return "【学生信息】姓名:"+this.name+"、年龄:"+this.age;
}
public boolean equals(Student stu) {
if((this.name == stu.getName())&&(this.age == stu.getAge())) {
return true;
}else {
return false;
}
}
@Override
public int compareTo(Student s) {
// TODO 自动生成的方法存根
int num = this.age - s.getAge();
int num2 = num== 0?this.name.compareTo(s.getName()):num;
return num2;
}
}
package Happy;
import java.util.TreeSet;
public class Main {
public static void main(String args[]) {
TreeSet<Student> set = new TreeSet<Student>();
Student stu1 = new Student("xishi",29);
Student stu2 = new Student("wangzhaojun",28);
Student stu3 = new Student("diaochan",33);
Student stu4 = new Student("yangguifei",33);
set.add(stu4);
set.add(stu3);
set.add(stu2);
set.add(stu1);
for(Student stu:set) {
System.out.println(stu);
}
}
}
输出:
【学生信息】姓名:wangzhaojun、年龄:28
【学生信息】姓名:xishi、年龄:29
【学生信息】姓名:diaochan、年龄:33
【学生信息】姓名:yangguifei、年龄:33
3.9 比较器Comparator的使用
存储学生对象并遍历,创建TreeSet集合使用带参构造方法;
要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序。
结论:
用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的;
比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compareTo()方法;
重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写。
package Happy;
import java.util.Comparator;
import java.util.TreeSet;
public class Main {
public static void main(String args[]) {
TreeSet<Student> set = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
int num1 = s1.getAge()-s2.getAge();
int num2 = num1==0?s1.getName().compareTo(s2.getName()):num1;
return num2;
}
}) ;
Student stu1 = new Student("xishi",29);
Student stu2 = new Student("wangzhaojun",28);
Student stu3 = new Student("diaochan",38);
Student stu4 = new Student("yangguifei",33);
set.add(stu4);
set.add(stu3);
set.add(stu2);
set.add(stu1);
for(Student stu:set) {
System.out.println(stu);
}
}
}
输出:
【学生信息】姓名:wangzhaojun、年龄:28
【学生信息】姓名:xishi、年龄:29
【学生信息】姓名:yangguifei、年龄:33
【学生信息】姓名:diaochan、年龄:38
案例:成绩排序
package Happy;
public class Student implements Comparable<Student>{
private String name;
private int mathScore;
private int chineseScore;
public Student() {};
public Student(String name,int chineseScore,int mathScore) {
this.name = name;
this.chineseScore = chineseScore;
this.mathScore = mathScore;
}
public String getName() {
return this.name;
}
public int getchineseScore() {
return this.chineseScore;
}
public int getmathScore() {
return this.mathScore;
}
public String toString() {
return "【学生信息】姓名:"+this.name+"、语文成绩:"+this.chineseScore+"、数学成绩:"+this.mathScore;
}
@Override
public int compareTo(Student s) {
return (this.chineseScore+this.mathScore)-(s.getchineseScore()+s.getmathScore());
}
}
package Happy;
import java.util.TreeSet;
public class Main {
public static void main(String args[]) {
TreeSet<Student> set = new TreeSet<Student>();
Student stu1 = new Student("xishi",20,25);
Student stu2 = new Student("wangzhaojun",28,66);
Student stu3 = new Student("diaochan",38,50);
Student stu4 = new Student("yangguifei",33,20);
set.add(stu4);
set.add(stu3);
set.add(stu2);
set.add(stu1);
for(Student stu:set) {
System.out.println(stu);
}
}
}
输出:
【学生信息】姓名:xishi、语文成绩:20、数学成绩:25
【学生信息】姓名:yangguifei、语文成绩:33、数学成绩:20
【学生信息】姓名:diaochan、语文成绩:38、数学成绩:50
【学生信息】姓名:wangzhaojun、语文成绩:28、数学成绩:66
案例:不重复的随机数
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class Main {
public static void main(String args[]) {
Set<Integer> set = new HashSet<Integer>();
Random random = new Random();
while(set.size()<10) {
int randomNum = random.nextInt(20)+1;
set.add(randomNum);
}
for(int x:set) {
System.out.println(x);
}
}
}
4 泛型
4.1泛型概述
泛型:是JDK中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型,它的本质是参数化模型,也就是说所操作的数据类型被指定为一个参数。
一提到参数,最熟悉的就是定义方法有形参,然后调用方法时传递实参。那么参数化类型如何理解呢?顾名思义,就是将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型。
这种参数类型可以用在类、方法和接口中,分别被称为泛型类、泛型方法、泛型接口。
泛型定义格式:
<类型>:指定一种类型的格式。这里的类型可以看成是形参;
<类型1,类型2,…>:指定多种类型的格式,多种类型之间用逗号隔开,这里的类型可以看做形参;
将来具体调用时候给定的类型可以看成是实参,并且实参的类型只能是引用数据类型。
泛型的好处:
把运行时期的问题提前到了编译时间;
避免了强制类型转换。(不确定泛型具体类型,集合将可以存储多类型元素)
4.2泛型类
泛型类的定义格式:
格式:修饰符 class 类名<类型>{ };
范例:public class Generic{ };
package Happy;
public class Generic <T>{
private T t;
public void setT(T t) {
this.t = t;
}
public T getT() {
return this.t;
}
}
package Happy;
public class Main {
public static void main(String args[]) {
Generic<String> g = new Generic<String>();
g.setT("hhello");
System.out.println(g.getT());
}
}
输出:
hhello
4.3泛型方法
package Happy;
public class Generic{
public <T> void show(T t) {
System.out.println(t);
}
}
package Happy;
public class Main {
public static void main(String args[]) {
Generic g = new Generic();
g.show(2);
g.show("hello");
g.show(true);
}
}
输出:
2
hello
true
4.4 泛型接口
定义格式:
修饰符 interface 接口名<类型>{ };
范例:public interface Generic{};
4.5 类型通配符
为了表示各种泛型List的父类,可以使用类型通配符
类型通配符:<?>;
List<?>:表示元素类型未知的List,它的元素可以匹配任何的类型。
这种带通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中。
如果说我们不希望List<?>是任何泛型List的父类,只希望它代表某一类泛型List的父类,可以使用类型通配符的上限。
类型通配符上限:<? extends 类型>
List<? extends Number>:它表示的类型是Number或者其子类型
除了可以指定类型通配符的上限,我们也可以指定类型通配符的下限
类型通配符下限:<? super 类型>
List<? super Number>:它表示的类型是Number或者其父类型
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String args[]) {
List<?> list1 = new ArrayList<Object>();
List<?> list2 = new ArrayList<Number>();
List<?> list3 = new ArrayList<Integer>();
System.out.println("----------------");
// List<? extends Number> list4 = new ArrayList<Object>(); 不行,因为上限是Number
List<? extends Number> list5 = new ArrayList<Number>();
List<? extends Number> list6 = new ArrayList<Integer>();
List<? super Number> list7 = new ArrayList<Object>();
List<? super Number> list8 = new ArrayList<Number>();
// List<? super Number> list9 = new ArrayList<Integer>(); 不行,因为下限是Number
}
}
4.6 可变参数
可变参数又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的了
格式:修饰符 返回值类型 方法名(数据类型 …变量名){ };
范例:public static int sum(int… a){ }; (a其实是一个数组)
注意事项:
这里的变量其实是一个数组;
如果一个方法有多个参数,包含可变参数,可变参数要放在最后。
public class Main {
public static void main(String args[]) {
System.out.println(sum(1,2));
System.out.println(sum(1,2,3));
System.out.println(sum(1,2,3,4));
}
public static int sum(int... a) {
int sum = 0;
for(int x:a) {
sum += x;
}
return sum;
}
}
输出:
3
6
10
4.7 可变参数的使用
Arrays工具类中有一个静态方法:
public static List asList(T… a):返回由指定数组支持的固定大小的列表;
List接口中有一个静态方法:
public static List of(E… elements):返回包含任意数量元素的不可变列表;
Set工具类中有一个静态方法:
public static Set of(T… a):返回一个包含任意数量元素的不可变集合;
第6节 Map集合
5.1 Map集合概述和使用
Map集合概述:
Interface Map<K,V> K:键的类型,V:值的类型;
将键映射到值的对象;不能包含重复的键;每个键可以映射到最多一个值。
举例:学生的学号和姓名
itheima001 林青霞
itheima002 张曼玉
itheima003 王祖贤
创建Map集合对象
多态的方式
具体的实现类HashMap
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String args[]) {
Map<String,String> map = new HashMap<String,String>();
map.put("itheima001", "林青霞");
map.put("itheima002", "张曼玉");
map.put("itheima003", "王祖贤");
map.put("itheima003", "柳岩");
System.out.println(map);
}
}
输出:
{itheima003=柳岩, itheima001=林青霞, itheima002=张曼玉}
5.2 Map集合的基本功能
V put(K key,V value):添加元素
V remove(Object key):根据键删除键值对元素
void clear():移除所有键值对元素
boolean containsKey(Object key):判断集合是否包含指点的键
boolean containsValue(Object value):判断集合是否包含指定的值
boolean isEmpty():判断集合是否为空
int size():集合的长度,也就是集合中键值对的个数。
5.3 Map集合的获取功能
V get(Object key):根据键值获取值
Set keySet():获取所有键的集合
Collection values():获取所有值的集合
Set<Map.Entry<K,V>> entrySet():获取所有键值对对象的集合
5.5 Map集合的遍历
我们刚才存储的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合
遍历思路:
获取所有结婚证的集合
遍历结婚证的集合,得到每一个结婚证
根据结婚证获取丈夫和妻子
转换为Map集合中的操作:
获取所有键值对对象的集合
Set<Map.Entry<K,V>> entrySet():获取所有键值对对象的集合
遍历键值对对象的集合,得到每一个键值对对象
用增强for实现,得到每一个Map.Entry
根据键值对对象获取键和值
用getKey()得到键
用getValue()得到值
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Main {
public static void main(String args[]) {
Map<String,String> map = new HashMap<String,String>();
map.put("张无忌", "赵敏");
map.put("郭靖", "黄蓉");
map.put("杨过", "小龙女");
Set<Map.Entry<String, String>> set = map.entrySet();
for(Map.Entry<String, String> s:set) {
System.out.println(s.getKey()+"-"+s.getValue());
}
}
}
输出:
杨过-小龙女
郭靖-黄蓉
张无忌-赵敏
案例:HashMap集合存储学生对象并遍历
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Main {
public static void main(String args[]) {
Map<String,Student> map = new HashMap<String,Student>();
map.put("001", new Student("张三",100,89));
map.put("002", new Student("李四",85,84));
map.put("003", new Student("王二麻",80,89));
Set<Map.Entry<String, Student>> set = map.entrySet();
for(Map.Entry<String, Student> stu:set) {
System.out.println(stu.getKey()+"_"+stu.getValue());
}
}
}
输出:
001_【学生信息】姓名:张三、语文成绩:100、数学成绩:89
002_【学生信息】姓名:李四、语文成绩:85、数学成绩:84
003_【学生信息】姓名:王二麻、语文成绩:80、数学成绩:89
案例:ArrayList集合存储HashMap元素并遍历
import java.util.ArrayList;
import java.util.HashMap;
public class Main {
public static void main(String args[]) {
ArrayList<HashMap<String,String>> array = new ArrayList<HashMap<String,String>>();
HashMap<String,String> map1 = new HashMap<String,String>();
map1.put("刘备", "关羽");
map1.put("刘备", "关羽");
HashMap<String,String> map2 = new HashMap<String,String>();
map2.put("吕布", "貂蝉");
map2.put("吕布", "貂蝉");
HashMap<String,String> map3 = new HashMap<String,String>();
map3.put("姐姐","妹妹");
map3.put("姐姐","妹妹");
array.add(map1);
array.add(map2);
array.add(map3);
for(HashMap<String,String> map:array) {
System.out.println(map);
}
}
}
输出:
{刘备=关羽}
{吕布=貂蝉}
{姐姐=妹妹}
案例:统计字符串中每个字符出现的次数
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
public class Main {
public static void main(String args[]) {
Scanner scan = new Scanner(System.in);
System.out.println("请输入一个字符串:");
String str = scan.nextLine();
HashMap<Character,Integer> hashmap = new HashMap<Character,Integer>();
for(int i = 0;i<str.length();i++) {
char key = str.charAt(i);
if(hashmap.keySet().contains(key)) {
int temp = hashmap.get(key);
hashmap.put(key, (temp+1));
}else {
hashmap.put(key,1);
}
}
Set<Map.Entry<Character, Integer>> set = hashmap.entrySet();
for(Map.Entry<Character, Integer> obj:set) {
System.out.println(obj);
}
}
}
输出:
请输入一个字符串:
qqqwwwa
q=3
a=1
w=3
第7节Collections工具类
案例:ArrayList存储学生对象,使用Collections对ArrayList进行排序
要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序;
package Happy;
public class Student {
private String name;
private int age;
public Student() {};
public Student(String name,int age) {
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
public String toString() {
return "【学生信息】姓名:"+this.name+"、年龄:"+this.age;
}
}
package Happy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class Main {
public static void main(String args[]) {
ArrayList<Student> array = new ArrayList<Student>();
Student stu1 = new Student("zhangsan",56);
Student stu2 = new Student("lisi",58);
Student stu3 = new Student("wangerma",23);
Student stu4 = new Student("aangerma",23);
array.add(stu3);
array.add(stu2);
array.add(stu1);
array.add(stu4);
Collections.sort(array, new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
int num1 = s1.getAge()-s2.getAge();
int num2 = num1==0?s1.getName().compareTo(s2.getName()):num1;
return num2;
}
});
for(Student stu:array) {
System.out.println(stu);
}
}
}
输出:
【学生信息】姓名:aangerma、年龄:23
【学生信息】姓名:wangerma、年龄:23
【学生信息】姓名:zhangsan、年龄:56
【学生信息】姓名:lisi、年龄:58
第8节 集合练习
案例:模拟斗地主
需求:通过程序实现斗地主过程中的洗牌,发牌和看牌。
package Happy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.TreeSet;
public class Main {
public static void main(String args[]) {
HashMap<Integer,String> hashmap = new HashMap<Integer,String>();
ArrayList<Integer> array = new ArrayList<Integer>();
String[] colors = {"黑桃","红桃","方片","梅花"};
String[] numbers = {"2","3","4","5","6","7","8","9","10","J","Q","K","A"};
int j =0;
for(String number:numbers) {
for(String color:colors) {
hashmap.put(j, color+number);
array.add(j);
j++;
}
}
array.add(52);
hashmap.put(52, "小王");
array.add(53);
hashmap.put(53, "大王");
Collections.shuffle(array); //打乱牌局
TreeSet<Integer> set1 = new TreeSet<Integer>();
TreeSet<Integer> set2 = new TreeSet<Integer>();
TreeSet<Integer> set3 = new TreeSet<Integer>();
TreeSet<Integer> setdipai = new TreeSet<Integer>();
for(int i = 0;i<array.size();i++) {
int temp = array.get(i);
if(i>=array.size()-3) {
setdipai.add(temp);
}else if(i%3 == 0) {
set1.add(temp);
}else if(i%3 == 1) {
set2.add(temp);
}else if(i%3 == 2) {
set3.add(temp);
}
}
look("玩家1",set1,hashmap);
look("玩家2",set2,hashmap);
look("玩家3",set3,hashmap);
look("底牌",setdipai,hashmap);
}
public static void look(String name,TreeSet<Integer> treeset,HashMap<Integer,String> hashmap) {
System.out.println(name+"的牌为:");
for(int i:treeset) {
System.out.print(hashmap.get(i)+"\t");
}
System.out.println();
}
}
输出:
玩家1的牌为:
黑桃2 红桃2 红桃3 方片3 方片6 梅花6 红桃7 黑桃8 红桃9 方片9 红桃10 梅花10 黑桃J 梅花J 梅花Q 方片K 黑桃A
玩家2的牌为:
方片4 红桃5 方片5 梅花5 黑桃6 黑桃7 红桃8 梅花8 黑桃9 黑桃10 方片10 红桃J 黑桃Q 红桃Q 黑桃K 红桃A 梅花A
玩家3的牌为:
方片2 梅花2 梅花3 红桃4 梅花4 黑桃5 红桃6 方片7 梅花7 方片8 梅花9 方片Q 红桃K 梅花K 方片A 小王 大王
底牌的牌为:
黑桃3 黑桃4 方片J