案例:统计字符串中每个字符出现的次数
- 需求:键盘录入一个字符串,要求统计字符串中每个字符串出现的次数
- 举例:键盘录入aababcabcdabcde,在控制台输出 ”a(5)b(4)c(3)d(2)e(1)“,统计他出现的次数。
- 分析:
- 我们可以把结果分成几个部分来看:a(5),b(4),c(3),d(2),e(1)
- 每个部分可以看成是:字符和字符对应的次数组成的
- 这样的数据,可以通过HashMap集合来存储,键是字符,值是字符出现的次数
注意:键是字符,类型应该是包装类Character。值是字符出现的次数,类型应该是Integer。
- 思路:
1.键盘录入一个字符串
2.创建HashMap集合,键是Character,值是Integer。
3.遍历字符串得到每一个字符
4.拿得到的每一个字符作为键到HashMap集合中去找对应的值,看起返回值。如果返回值是null,说明该字符在HashMap集合中不存在,就把字符作为键,1作为存储值。如果返回值不是null,说明该字符在HashMap集合中存在,把该值加1,然后重新存储该字符和对应的值。
5.遍历HashMap集合,得到键和值,按照要求进行拼接。
6.输出结果
import java.util.HashMap;
import java.util.Scanner;
import java.util.Set;
public class HashMapDemo {
public static void main(String[] args) {
//键盘录入字符串
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串:");
String line = sc.nextLine();
//创建HashMap集合,键是Character,值是Integer
HashMap<Character, Integer> hm = new HashMap<Character, Integer>();
//遍历字符串,得到每一个字符
for (int i = 0; i < line.length(); i++) {
char key = line.charAt(i);
//拿得到的每一个字符作为键到HashMap集合中去找对应的值,看其返回值
Integer value = hm.get(key);
if (value == null) {
//如果返回null说明在HashMap中不存在
hm.put(key,1);
}else{
//如果不是null,说明在HashMap中存在,存在我就要把值做一个++操作
value++;
hm.put(key , value);
}
}
StringBuilder sb = new StringBuilder();
Set<Character> keySet = hm.keySet();
for(Character key : keySet){
Integer value = hm.get(key);
sb.append(key).append("(").append(value).append(")");
}
String result = sb.toString();
System.out.println(result);
}
}
- 假如输入一个 fqylovelingqingxia,就会发现他输出的没有顺序
- 因为HashMap他的键是没有排序的,如果想要进行排序,只要选择用另外一个map集合就可以了—treemap
TreeMap<Character, Integer> hm = new TreeMap<Character, Integer>();
Collections 的概述和使用
- Collections是一个具体的类,Collection是单列集合的顶层接口,而Collections是一个具体的类。此类仅有静态方法组成,可以通过类名调用方法,他包含对集合进行操作的多态算法。可以Collections看做是对集合操作的工具类
- 他里面的方法都是由静态修饰的、
- Collections类的常用方法
- public static <T extends Comparable<?super T>> void sort(List list): 将指定的列表按升序排列
- public static void reverse(List<?>list): 反转指定列表中元素的顺序
- public static void shuffle(List<?> list): 使用默认的随机源随机排列指定的列表。
import java.util.ArrayList;
import java.util.List;
public class CollectionDemo01 {
public static void main(String[] args) {
//创建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)
- 然后我们来看反转的方法,发现和正常的输出相反
Collections.reverse(list);
- 然后来看一下随机置换,可以看到顺序被打乱了。每一次运行都会得到不一样的结果。
Collections.shuffle(list);
ArrayList存储学生对象病排序
- 需求:ArrayList存储学生对象,使用Collections对Arraylist进行排序。
- 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序。
- 这里的要求Arraylist本身是不能实现了,所以采用了Collections的方式来进行实现。
- 思路
- 定义学生类
- 创建Arraylist集合对象
- 创建学生对象
- 把学生添加到集合
- 使用Collections对Arraylist集合排序
- 遍历集合
- Student类仍然是int age 和String name两个属性。
- 主程序
//创建Arraylist集合对象
ArrayList<Student> array = new ArrayList<Student>();
//创建学生对象
Student s1 = new Student("linqingxia",30);
Student s2 = new Student("zhangmayu",35);
Student s3 = new Student("wangzuxian",33);
Student s4 = new Student("liuyan",33);
//把学生添加到集合
array.add(s1);
array.add(s2);
array.add(s3);
array.add(s4);
- 然后用Collections是他表示需要List,而我们给Arraylist会报错,Student不能跟Comparable<? super T> 匹配上。这是自然排序接口
- 文档里面写sort是根据列表进行自然排序的。而我们用自然排序就得让集合中元素实现自然排序接口。
- Student类里面并没有实现自然排序接口,我们现在不采用这个方法。我们看用比较器的规则来指定排序
Collections.sort(array, new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
//按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
int num = s1.getAge()-s2.getAge();
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
return num2;
}
})\
//遍历集合
for(Student s : array){
System.out.println(s.getName()+","+s.getAge());
}
模拟斗地主
- 需求:通过程序实现斗地主过程中的洗牌,发票和看牌。
- 思路:
- 创建一个牌盒,也就是定义一个集合对象,用ArrayList集合实现
- 在牌盒里面装牌
- 洗牌,也就是把牌打散,用Collections的shuffle() 方法实现
- 发牌,也就是遍历集合,给三个玩家发牌。
- 看牌,也就是三个玩家要分别遍历自己的牌
import java.util.ArrayList;
import java.util.Collections;
public class PokerDemo {
public static void main(String[] args) {
//创建一个牌盒
ArrayList<String> array = new ArrayList<String>();
//装牌
//定义花色数组
String[] colors = {"♦️","♠","♥","♣"};
//定义点数数组
String[] numbers = {"2","3","4","5","6","7","8","9","10","J","Q","K","A"};
for(String color : colors){
for(String number : numbers){
array.add(color + number);
}
}
array.add("小王");
array.add("大王");
Collections.shuffle(array);
// System.out.println(array);
//给三个玩家发牌
ArrayList<String> lqxArray = new ArrayList<String>();
ArrayList<String> lyArray = new ArrayList<String>();
ArrayList<String> fqyArray = new ArrayList<String>();
ArrayList<String> dpArray = new ArrayList<String>();
for(int i = 0; i < array.size() ; i++){
String poker = array.get(i);
if(i >= array.size()-3){
dpArray.add(poker);
}else if(i%3==0){
lqxArray.add(poker);
}else if(i%3==1){
lyArray.add(poker);
}else if(i%3==2){
fqyArray.add(poker);
}
}
//看牌,三个玩家分别遍历自己的牌
lookPoker("林青霞",lqxArray);
lookPoker("柳岩",lyArray);
lookPoker("风清扬",fqyArray);
lookPoker("底牌",dpArray);
}
//看牌的方法
public static void lookPoker(String name,ArrayList<String> array){
System.out.println(name + "的牌是: ");
for(String poker : array){
System.out.print(poker + " ");
}
System.out.println();
}
}
## 案例:模拟斗地主升级版
- 需求:通过程序实现斗地主过程中的洗牌、发牌和看牌。要求:对牌进行排序
- 实现方式:使用Hashmap,key为0到53一共54个索引,值为方块3到大王。索引在HashMap里面,为了同时洗索引,可以定义一个Arraylist,里面存储0-53这个54个索引。
- 然后发牌,发的牌也是索引。这里有三个玩家,所以给三个玩家发牌,发牌之后是顺序排列的,按理说洗牌之后索引是乱的,为什么能够顺序排列呢?因为我们会使用TreeSet来保存他的索引,进行自然的升序排列。
- 那么牌发到手上之后,我们要做看牌的动作。看牌就是那索引到map集合中去找对应的牌就可以了。
- 思路:
- 创建Hashmap,键是编号,值是牌
- 创建Arraylist,存储编号
- 创建花色数组和点数数组
- 从0开始往HashMap里面存储编号,并存储对应的牌。同事往Arraylist里面存储编号。
- 洗牌(洗的是编号),用Collections的shuffle()方法实现
- 发牌(发的也是编号,为了保证编号是排序的,创建Treeset集合接收)
- 定义方法来看牌(遍历TreeSet集合,获取编号,到HashMap集合找对应的牌)
- 调用看牌方法
package com.itheima_01;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.TreeSet;
public class PokerDemo02 {
public static void main(String[] args) {
//创建HashMap,键是编号,值是牌
HashMap<Integer,String> hm = new HashMap<Integer,String>();
//创建ArrayList集合,存储编号
ArrayList<Integer> array = new ArrayList<Integer>();
//创建花色数组和点数数组
String[] colors = {"♦️","♠","♥","♣"};
String[] numbers = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
//从0开始往HashMap里面存储编号,并存储对应的牌,同时往ArrayList里面存储编号
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()方法实现
Collections.shuffle(array);
//发牌
TreeSet<Integer> lqxSet = new TreeSet<Integer>();
TreeSet<Integer> lySet = new TreeSet<Integer>();
TreeSet<Integer> fqySet = new TreeSet<Integer>();
TreeSet<Integer> dpSet = new TreeSet<Integer>();
for(int i = 0 ; i < array.size(); i++){
int x = array.get(i);
if(i >= array.size() -3 ){
dpSet.add(array.get(x));
}else if(i%3==0){
lqxSet.add(x);
}else if(i%3==1){
lySet.add(x);
}else if(i%3==2){
fqySet.add(x);
}
}
//调用看牌方法
lookPoker("林青霞",lqxSet,hm);
lookPoker("柳岩",lySet,hm);
lookPoker("风清扬",fqySet,hm);
lookPoker("底牌",dpSet,hm);
}
//定义方法来看牌
public static void lookPoker(String name,TreeSet<Integer> ts,HashMap<Integer,String> hm){
System.out.println(name + "的牌是: ");
for(Integer key: ts){
String poker = hm.get(key);
System.out.print(poker + " ");
}
System.out.println();
}
}