集合总结
一、可变参数
1.什么是可变参数
假如需要定义一个方法求和,该方法可以灵活的完成以下需求:
计算(1/2/3/4 …/n)个数据的和
public class ArgsTest01 {
public static void main(String[] args) {
int sum = getSum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
System.out.println(sum);
}
public static int getSum(int...args){
int sum = 0;
for (int i : args) {
sum = sum + i;
}
return sum;
}
}
2.可变参数的作用以及细节
①可变参数在本质上其实就是一个数组
②在方法的形参中最多只能写一个可变参数
③如果在方法中,除了可变参数还有其他的形参,那么可变参数要写在最后面
④可变参数的作用就实在形参中接受多个数据
⑤格式:数据类型 . . . 参数名称
二、集合的工具类Collections
1.什么是Collections
①Collections是定义在java.util.collections的一个工具类
②作用:Collections不是集合,而是集合的工具类
2.Collectioms常用的API
方法名称 | 说明 |
---|---|
public static < T > boolean addAll (Collection< T > c , T … elements) | 批量添加元素 |
public static void shuffle ( List < ? > list) | 打乱List集合元素的顺序 |
public static < T > void sort (List < T > list) | 排序 |
public static < T > void sort (List < T > list,Compartor < T > c) | 根据指定的规则进行排序 |
public static < T > int binarySearch(List< T > list , T key) | 以二分查找法查找元素 |
public static < T > void copy(List < T > list , List < T > src) | 拷贝集合中的元素 |
public static < T > void fill(List< T > list,T obj) | 使用指定的元素天机集合 |
public static < T > void max/min (Collection < T > coll) | 根据默认的自然排序获取最大/小值 |
public static < T > void swap (List <?> list, int i , int j) | 交换集合中指定位置的元素 |
import java.util.ArrayList;
import java.util.Collections;
public class CollectionsTest01 {
public static void main(String[] args) {
/*
方法名称说明
public static < T > boolean addAll (Collection< T > c , T ... elements) 批量添加元素
public static void shuffle ( List < ? > list) 打乱List集合元素的顺序
public static < T > void sort (List < T > list) 排序
public static < T > void sort (List < T > list,Compartor < T > c) 根据指定的规则进行排序
public static < T > int binarySearch(List< T > list , T key) 以二分查找法查找元素
public static < T > void copy(List < T > list , List < T > src) 拷贝集合中的元素
public static < T > int fill(List< T > list,T obj) 使用指定的元素填充集合
public static < T > void max/min (Collection < T > coll) 根据默认的自然排序获取最大/小值
public static < T > void swap (List <?> list, int i , int j) 交换集合中指定位置的元素
*/
//创建集合
ArrayList<String> list = new ArrayList<>();
//1.public static < T > boolean addAll (Collection< T > c , T ... elements) 批量添加元素
Collections.addAll(list,"abc","bcd","qwer","df","asdf","zxcv","1234","qwer");
System.out.println(list); //[abc, bcd, qwer, df, asdf, zxcv, 1234, qwer]
//2.public static void shuffle ( List < ? > list) 打乱List集合元素的顺序
Collections.shuffle(list);
System.out.println(list); //[bcd, df, 1234, qwer, abc, qwer, zxcv, asdf]
//3.public static < T > void sort (List < T > list) 排序
Collections.sort(list);
System.out.println(list); //[1234, abc, asdf, bcd, df, qwer, qwer, zxcv]
//4.public static < T > void sort (List < T > list,Compartor < T > c) 根据指定的规则进行排序
Collections.sort(list, ( o1, o2)-> {
if (o1.length()<o2.length()){
return -1;
} else if (o1.length() == o2.length()) {
return 0;
}
return 1;
});
//打印集合
System.out.println(list); //[df, abc, bcd, 1234, asdf, qwer, qwer, zxcv]
//5.public static < T > int binarySearch(List< T > list , T key) 以二分查找法查找元素
int binarySearch = Collections.binarySearch(list, "qwer");
System.out.println(binarySearch); //5 返回元素所在的索引
//6.public static < T > void copy(List < T > list , List < T > src) 拷贝集合中的元素
ArrayList<String> list2 = new ArrayList<>();
Collections.addAll(list2,"00","00","00","00","00","00","00","00");
Collections.copy(list2,list);
System.out.println(list); //[df, abc, bcd, 1234, asdf, qwer, qwer, zxcv]
System.out.println(list2); //[df, abc, bcd, 1234, asdf, qwer, qwer, zxcv]
//7.public static < T > void fill(List< T > list,T obj) 使用指定的元素填充集合
Collections.fill(list2,"222");
System.out.println(list2); //[222, 222, 222, 222, 222, 222, 222, 222]
//8.public static < T > void max/min (Collection < T > coll) 根据默认的自然排序获取最大/小值
String max = Collections.max(list);
System.out.println(max); //zxcv
//public static < T > void swap (List <?> list, int i , int j) 交换集合中指定位置的元素
System.out.println(list); //[df, abc, bcd, 1234, asdf, qwer, qwer, zxcv]
Collections.swap(list,3,6); //交换3索引和6索引上元素的位置
System.out.println(list); //[df, abc, bcd, qwer, asdf, qwer, 1234, zxcv]
}
}
三、综合练习
(1)需求:班级里有N个学生,实现随机点名
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
public class Test01 {
public static void main(String[] args) {
//需求:班级里有N个学生,实现随机点名
//1.创建集合并添加元素
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"范闲","范建","范统","杜子腾","杜琦燕","宋合泛","侯笼藤","朱益群","朱穆朗玛峰","袁明媛");
//2.随机点名
Random r = new Random();
int index = r.nextInt(list.size());
String name = list.get(index);
System.out.println(name);
//第二种随即方法
Collections.shuffle(list);
System.out.println(list.get(0));
}
}
(2)需求:班级里有N个学生,要求:70%的概率随机到男生,30%的概率随机到女生
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
public class Test02 {
public static void main(String[] args) {
/* 2)需求:班级里有N个学生,要求:70%的概率随机到男生,30%的概率随机到女生 */
//1.创建集合并添加元素
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list,1,1,1,1,1,1,1,0,0,0);
//2.打乱顺序
Collections.shuffle(list);
//3.从list集合中随机抽取0或1
Random r = new Random();
int index = r.nextInt(list.size());
int number = list.get(index);
//4.创建两个集合分别存储男生和女生,并添加数据
ArrayList<String> boyList = new ArrayList<>();
ArrayList<String> girlList = new ArrayList<>();
Collections.addAll(boyList,"范闲","范建","范统","杜子腾","宋合泛","侯笼藤","朱益群","朱穆朗玛峰");
Collections.addAll(girlList,"袁明媛","杜琦燕","李猜","田蜜蜜");
//5.判断此时是从boyList里卖弄抽取还是从girlList里面抽取
if (number == 1){
String name = boyList.get(r.nextInt(boyList.size()));
System.out.println(name);
}else{
String name = girlList.get(r.nextInt(girlList.size()));
System.out.println(name);
}
}
}
(3)需求:班级里有N个学生,要求:被点到的学生不会被再次点到,如果班级里所有的学生都点过了,需要重新开启第二轮点名
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
public class Test03 {
public static void main(String[] args) {
/*(3)需求:班级里有N个学生,要求:被点到的学生不会被再次点到,如果班级里所有的学生都点过了,需要重新开启第二轮点名 */
//1.创建集合并添加元素
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "范闲", "范建", "范统", "杜子腾", "杜琦燕", "宋合泛", "侯笼藤", "朱益群", "朱穆朗玛峰", "袁明媛");
//创建新集合存储被删除的元素,用来开始第二轮点名
ArrayList<String> temp = new ArrayList<>();
//外循环表示点名的轮数
for (int i = 0; i < 10; i++) {
System.out.println("=====第" + i + 1 + "轮=====");
//2.随机点名
//获取集合的长度
int count = list.size();
for (int j = 0; j < count; j++) {
Random r = new Random();
int index = r.nextInt(list.size());
String name = list.remove(index);
System.out.println(name);
temp.add(name);
}
//代码到这里,表示第一轮点名已经结束,
list.addAll(temp);
temp.clear();
}
}
}
(4)
(5) 需求
定义一个Map集合,键用表示省份名称province,值表示市city,但是市会有多个。
添加完毕后,遍历结果格式如下:
江苏省 = 南京市,扬州市,苏州市,无锡市,常州市
湖北省 = 武汉市,孝感市,十堰市,宜昌市,鄂州市
河北省 = 石家庄市,唐山市,邢台市,保定市,张家口市
import java.util.*;
public class Test05 {
public static void main(String[] args) {
//1.创建双列集合Map并添加元素
HashMap<String,ArrayList<String>> hm = new HashMap();
//2.创建单列结合存储市的信息
ArrayList<String> city1 = new ArrayList<>();
Collections.addAll(city1,"南京市","扬州市","苏州市","无锡市","常州市");
ArrayList<String> city2 = new ArrayList<>();
Collections.addAll(city2,"武汉市","孝感市","十堰市","宜昌市","鄂州市");
ArrayList<String> city3 = new ArrayList<>();
Collections.addAll(city3,"石家庄市","唐山市","邢台市","保定市","张家口市");
hm.put("江苏省",city1);
hm.put("湖北省",city2);
hm.put("河北省",city3);
Set<Map.Entry<String, ArrayList<String>>> entries = hm.entrySet();
for (Map.Entry<String, ArrayList<String>> entry : entries) {
String key = entry.getKey();
ArrayList<String> value = entry.getValue();
StringJoiner sj = new StringJoiner(",","","");
for (String city : value) {
sj.add(city);
}
System.out.println(key+"<===>"+sj);
}
}
}
五、阶段练习:斗地主小游戏
(1)思路:
=》准备牌=》洗牌===》发牌===》排序
①版本1:在控制台简单输出
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
public class game {
static ArrayList<String> list = new ArrayList<>();
static {
//准备牌
String[] color = {"♠", "♥", "♦", "♣"};
String[] number = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2", "", "", ""};
for (String c : color) {
for (String n : number) {
list.add(c + n);
}
}
list.add("大王");
list.add("小王");
}
public game() {
//洗牌
Collections.shuffle(list);
//发牌
//准备四个集合
ArrayList<String> dipai = new ArrayList<>();
ArrayList<String> player1 = new ArrayList<>();
ArrayList<String> player2 = new ArrayList<>();
ArrayList<String> player3 = new ArrayList<>();
//遍历集合得到每一张牌
for (int i = 0; i < list.size(); i++) {
if (i <= 2) {
dipai.add(list.get(i));
continue;
}
if (i % 3 == 0) {
player1.add(list.get(i));
} else if (i % 3 == 1) {
player2.add(list.get(i));
} else {
player3.add(list.get(i));
}
}
//看牌
look("刚脑壳",player1);
look("大帅比",player2);
look("蛋筒",player3);
}
public void look(String name,ArrayList<String> list) {
System.out.print(name + ": ");
for (String poker : list) {
System.out.print(poker);
}
System.out.println();
}
}
//测试类
public class App {
public static void main(String[] args) {
//控制台版本的三个步骤:准备牌、洗牌、发牌
new game();
}
}
运行结果:
刚脑壳: ♣Q♠6♠大王♠♦2♠K♥7♠9♣♥4♦6♥6♠8♦4♠Q♥K♠5♥2♦K♥J
大帅比: ♣2♦9♥5♥10♣9♦8♣5♦A♦3♦7♦♣10♠2♠J♥9♦♥Q♣J♣A♥8♠A
蛋筒: 小王♦5♣6♥♣7♦♣8♥3♦Q♠10♣♣4♣♠7♦J♥♥A♣K♠♠4♣3
②版本二:给扑克牌进行排序
两种排序方式:
方式一:利用序号进行排序
方式二:给每一张牌计算价值
注意:
①如果原始数据的规律比较复杂,我们可以先手动让每一个数据跟唯一的序号产生对应的关系
②序号就是数字,规律比较简单,后续的所有操作,我们以序号为主
③当我们需要操作原始数据的时候,再通过序号找到原始数据即可
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.TreeSet;
public class game {
static HashMap<Integer,String> hm = new HashMap<>();
static ArrayList<Integer> list = new ArrayList<>();
static {
//准备牌
int serialNumber = 1;
String[] color = {"♠", "♥", "♦", "♣"};
String[] number = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
for (String n : number) {
for (String c : color) {
hm.put(serialNumber,c+n);
serialNumber++;
list.add(serialNumber);
}
}
hm.put(serialNumber,"小王");
list.add(serialNumber);
serialNumber++;
hm.put(serialNumber,"大王");
list.add(serialNumber);
}
public game(){
//洗牌
Collections.shuffle(list);
//发牌
TreeSet<Integer>diapi = new TreeSet();
TreeSet<Integer>player1 = new TreeSet();
TreeSet<Integer>player2 = new TreeSet();
TreeSet<Integer>player3 = new TreeSet();
for (int i = 0; i < list.size(); i++) {
if(i<=2){
diapi.add(list.get(i));
continue;
}
if (i % 3 == 0){
player1.add(list.get(i));
} else if (i % 3 == 1) {
player2.add(list.get(i));
}else{
player3.add(list.get(i));
}
}
//看牌
lookPoker("底牌",diapi);
lookPoker("刚脑阔",player1);
lookPoker("蛋筒",player2);
lookPoker("大帅比",player3);
}
public void lookPoker(String name,TreeSet<Integer>ts){
System.out.print(name+": ");
for (int serialNumber : ts) {
System.out.print(hm.get(serialNumber)+" ");
}
System.out.println();
}
}
③版本3:第二种排序方式
利用双列集合给扑克牌指定价值
package banben3;
import java.util.*;
public class game {
static ArrayList<String> list = new ArrayList<>();
static HashMap<String,Integer> hm = new HashMap();
static {
//准备牌
String[] color = {"♠", "♥", "♦", "♣"};
String[] number = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
for (String c : color) {
for (String n : number) {
list.add(c + n);
}
}
list.add(" 大王");
list.add(" 小王");
}
public game() {
//洗牌
Collections.shuffle(list);
//发牌
//准备四个集合
ArrayList<String> dipai = new ArrayList<>();
ArrayList<String> player1 = new ArrayList<>();
ArrayList<String> player2 = new ArrayList<>();
ArrayList<String> player3 = new ArrayList<>();
//遍历集合得到每一张牌
for (int i = 0; i < list.size(); i++) {
if (i <= 2) {
dipai.add(list.get(i));
continue;
}
if (i % 3 == 0) {
player1.add(list.get(i));
} else if (i % 3 == 1) {
player2.add(list.get(i));
} else {
player3.add(list.get(i));
}
}
//指定牌的价值
//牌上的数字到Map集合中判断是否存在
//不存在获取,本身的数字就是价值
//存在,获取价值
hm.put("J",11);
hm.put("Q",12);
hm.put("K",13);
hm.put("A",14);
hm.put("2",15);
hm.put("小王",16);
hm.put("大王",17);
//排序
order(dipai);
order(player1);
order(player2);
order(player3);
//看牌
look("底牌",dipai);
look("刚脑壳",player1);
look("大帅比",player2);
look("蛋筒",player3);
}
public void order(ArrayList<String> list){
Collections.sort(list, ( o1, o2) ->{
//计算o1的花色和价值
String color1 = o1.substring(0);
int value1 = getValue(o1);
//计算o1的花色和价值
String color2 = o1.substring(0);
int value2 = getValue(o2);
//比较o1和o2的价值,
int i = value1 - value2;
//如果价值一样按花色排序
return i == 0 ? color1.compareTo(color2) : i;
}
);
}
public int getValue(String poker){
//获取数字
String number = poker.substring(1);
//拿着数字到map集合中判断是否存在
//如果存在直接获取价值
if(hm.containsKey(number)){
return hm.get(number);
}else{
//如果不存在直接类型转换
return Integer.parseInt(number);
}
}
public void look(String name,ArrayList<String> list) {
System.out.print(name + ": ");
for (String poker : list) {
System.out.print(poker);
}
System.out.println();
}
}
//测试类
package banben3;
public class App {
public static void main(String[] args) {
new game();
}
}
//运行结果:
底牌: ♣10♠Q♠2
刚脑壳: ♦3♦4♠5♠6♠7♣7♥8♣9♠9♦10♥10♥J♣K♣A♠A♦A♥A
大帅比: ♣3♠4♥5♣8♠8♦8♥9♠10♠J♦J♥Q♦K♥K♠K♣2 小王 大王
蛋筒: ♥3♠3♣4♥4♦5♣5♦6♣6♥6♥7♦7♦9♣J♣Q♦Q♦2♥2