目录
1.可变参数
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
// 目标:掌握可变参数的使用。
// 需求:求任意个整数数据的和.
sum(); // 可以不传输参数
sum(10); // 可以传一个参数
sum(20, 15, 32,100); // 可以传多个参数
sum(new int[]{10, 20, 30, 40}); // 可以传一个数组
}
// 作用:接收数据非常灵活
// 注意事项:
// 可变参数在形参列表中只能出现一个!
// 可变参数必须放到形参列表的最后面!
public static void sum(int...nums){
// 本质:可变参数在方法内部本质就是一个数组。
System.out.println("个数:" + nums.length);
System.out.println("内容:" + Arrays.toString(nums));
}
}
2.Collections工具类
package com.itheima.d2_collections;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 目标:掌握Collections集合工具类的使用。
*/
public class CollectionsTest1 {
public static void main(String[] args) {
// 1、public static <T> boolean addAll(Collection<? super T> c, T...elements):为集合批量添加数据
List<String> names = new ArrayList<>();
Collections.addAll(names, "张无忌", "赵敏", "小昭", "殷素素");
System.out.println(names);
// 2、public static void shuffle(List<?> list):打乱List集合中的元素顺序
Collections.shuffle(names);
System.out.println(names);
// 3、 public static <T> void sort(List<T> list):对List集合中的元素进行升序排序。
List<Student> students = new ArrayList<>();
Student s1 = new Student("赵敏", 19, 169.5);
Student s2 = new Student("周芷若", 18, 171.5);
Student s3 = new Student("周芷若", 18, 171.5);
Student s4 = new Student("小昭", 17, 165.5);
Collections.addAll(students, s1, s2, s3, s4);
// 方式一:让对象的类实现Comparable接口,从写compare方法,指定大小比较规则
Collections.sort(students);
System.out.println(students);
// 4、public static <T> void sort(List<T> list, Comparator<? super T> c):
// 对List集合中元素,按照比较器对象指定的规则进行排序
// 方式二:指定Comparator比较器对象,再指定比较规则。
Collections.sort(students, ((o1, o2) -> Double.compare(o2.getHeight(), o1.getHeight())));
System.out.println(students);
}
}
List集合是结合Collections工具类提供的sort方法进行比较,并不是自己带的比较器
有以下两种方式:
而TreeSet是自己带的比较器,并不是调用其他工具类的方法
天然有序,创建时指定排序规则
// Set<Girl> set = new TreeSet<>(new Comparator<Girl>() {
// @Override
// public int compare(Girl o1, Girl o2) {
// return Double.compare(o2.getHeight(),o1.getHeight());
// }
// });//排序,不重复,无索引
//简化代码
Set<Girl> set = new TreeSet<>((o1, o2) -> Double.compare(o2.getHeight(),o1.getHeight()));
在Java中,对集合中的对象进行排序有两种方式
- 实现比较器(Comparator),用匿名内部类来实现
eg:
public class Person implements Comparable<Person> {
private int age;
// 构造器、getter/setter略
@Override
public int compareTo(Person other) {
return this.age - other.age; // 按年龄升序排序
}
}
- 让类实现Comparable接口来实现
eg:
// 按年龄降序排序
Comparator<Person> ageDescComparator = (p1, p2) -> p2.getAge() - p1.getAge();
不同集合类型的排序方法比较
- List集合(如ArrayList、LinkedList)
1.自然排序(在对象类中实现Comparable<对象类型>)
List<Person> personList = new ArrayList<>();
// 添加元素...
Collections.sort(personList); // 按Person的compareTo方法排序
2.定制排序(用匿名内部类写Comparator)
// 按姓名长度升序排序
Collections.sort(personList, (p1, p2) -> p1.getName().length() - p2.getName().length());
// 多条件排序:先按年龄升序,年龄相同则按姓名降序
Collections.sort(personList, (p1, p2) -> {
if (p1.getAge() != p2.getAge()) {
return p1.getAge() - p2.getAge();
} else {
return p2.getName().compareTo(p1.getName());
}
});
- Array(数组)
1.基本类型数组(如int[ ]):直接使用Arrays.sort( )
int[] nums = {5, 2, 8, 1};
Arrays.sort(nums); // 结果:[1, 2, 5, 8]
2.对象数组(如Person[ ]):
Person[] persons = new Person[3];
// 初始化数组...
Arrays.sort(persons, (p1, p2) -> p1.getName().compareTo(p2.getName())); // 按姓名升序
- Set集合(如TreeSet、HashSet)
1.TreeSet:天然有序,创建时指定排血规则
// 按年龄升序排序
Set<Person> personSet = new TreeSet<>((p1, p2) -> p1.getAge() - p2.getAge());
// 或在创建时传入Comparator
Set<Person> personSet = new TreeSet<>(Comparator.comparing(Person::getAge));
2.HashSet:无序,若需排序需先转为 List 再排序
Set<Person> hashSet = new HashSet<>();
// 添加元素...
List<Person> sortedList = hashSet.stream()
.sorted(Comparator.comparing(Person::getAge))
.collect(Collectors.toList());
3.斗地主游戏
Cards对象用来存储每一张牌的内容
package com.itheima.d3_collection_test;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
// Lombok : 使用注解简化get set 有参 无参构造器的写法
// IDEA >= 2022
// Lombok 是 30版本 不要用28
@Data
@NoArgsConstructor //无参构造器
@AllArgsConstructor //有参构造器
public class Card {
private String number;
private String color;
private int size;
@Override
public String toString() {
return number + color;
}
}
package com.itheima.d3_collection_test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
//房间对象
public class Room {
//1.准备一副牌
private ArrayList<Card> allCards = new ArrayList<>();
//2.初始化54张牌,用实例代码块初始化,创建房间对象时,为allCards集合初始化54张牌
{
//3.准备点数 : 个数确定,类型确定
String[] numbers = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
//4.准备花色 : 个数确定,类型确定
String[] colors = {"♠", "♥", "♣", "♦"};
//5.准备组装每一张牌对象
int size = 0;
for (String number : numbers) {
size++;
for (String color : colors) {
//6.创建对象封装这张牌数据
Card c = new Card(number,color,size);
//7.加入到集合中去
allCards.add(c);
}
}
//8.单独加入大小王
allCards.add(new Card("","小王",++size));
allCards.add(new Card("","大王",++size));
System.out.println("新牌是:" + allCards);
}
public void start() {
//9.洗牌
Collections.shuffle(allCards);
System.out.println("洗牌后" + allCards);
//10.发牌
//定义三个玩家。
List<Card> lhc = new ArrayList<>();
List<Card> ryy = new ArrayList<>();
List<Card> dfbb = new ArrayList<>();
//发出去51张
//allCards = [9♥, K♦, 8♣, 2♦, Q♦, 9♦, 8♠, 6♠, 3♠, 7♠, 4♥
// 0 1 2 3 4 5 6...轮询算法
for (int i = 0; i < allCards.size() - 3; i++) {
Card c = allCards.get(i);
if(i % 3 == 0){
//请lhc接牌
lhc.add(c);
} else if (i % 3 == 1) {
//请ryy接牌
ryy.add(c);
}else if (i % 3 == 2){
//请dfbb接牌
dfbb.add(c);
}
}
//拿到最后三张底牌:
//subList截取子集合到新的集合中去
List<Card> lastThreeCards = allCards.subList(allCards.size() - 3 ,allCards.size());
//抢地主
ryy.addAll(lastThreeCards);
//11.对牌排序
sortCards(lhc);
sortCards(ryy);
sortCards(dfbb);
//12.看牌
System.out.println("lhc" + lhc);
System.out.println("ryy" + ryy);
System.out.println("dfbb" + dfbb);
}
private void sortCards(List<Card> Cards) {
Collections.sort(Cards, new Comparator<Card>() {
@Override
public int compare(Card o1, Card o2) {
return o2.getSize() - o1.getSize();
}
});
}
}
package com.itheima.d3_collection_test;
public class Test {
public static void main(String[] args) {
// 目标:完成斗地主案例的实现。'
// "3","4","5","6","7","8","9","10","J","Q","K","A","2"
// "♠", "♥", "♣", "♦"
// 1、每张牌是一个对象,设计一个牌类。
// 2、设计一个房间类,用于创建房间对象,开启游戏。
Room r= new Room();
r.start();
}
}
4.Map集合
4.1 Map集合概述
注意!!!集合和泛型都不支持基本类型,可以写包装类
package com.itheima.d4_map;
import java.util.HashMap;
import java.util.Map;
public class MapDemo1 {
public static void main(String[] args) {
// 目标:掌握Map集合的特点。
// Map体系整体特点:HashMap : 按照键,无序,不重复,无索引。值不做要求,键和值都可以是null
Map<String, Integer> map = new HashMap<>(); // 多态 一行经典代码
map.put("华为手表", 31);
map.put("iphone15", 1);
map.put("mete60", 10);
map.put("Java入门到跑路", 2);
map.put("iphone15", 31); // 后面重复的键会覆盖前面整个数据!
map.put("娃娃", 1);
map.put("雨伞", 10);
map.put(null, null);
// {Java入门到跑路=2, null=null, iphone15=31, 雨伞=10, mete60=10, 华为手表=31, 娃娃=1}
System.out.println(map);
}
}
Map集合(如HashMap)的“无序”是指元素的存储顺序与插入顺序不一致:
- 当向 Map 中添加键值对时,元素的存储位置由键的哈希值决定(通过哈希函数计算存储位置),而非插入顺序。
- 遍历时,元素的输出顺序可能与插入顺序不同,甚至多次遍历的顺序也可能不一致。
4.2 Map集合的常用方法
为什么要先学习Map的常用方法?
- Map是双列集合的祖宗,它的功能是全部双列集合都可以继承过来使用
package com.itheima.d4_map;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo2 {
public static void main(String[] args) {
// 目标:掌握Map集合的常用API(重点)
Map<String, Integer> map = new HashMap<>();
map.put("手表" ,2);
map.put("iphone" ,31);
map.put("huawei" ,365);
map.put("iphone" ,1);
map.put("娃娃", 31);
map.put("Java入门",1);
map.put(null,null);
System.out.println(map);
// map = {null=null, 手表=2, huawei=365, Java入门=1, 娃娃=31, iphone=1}
// 1、获取集合的大小(元素个数)
System.out.println(map.size()); // 6
// 2、清空集合
// map.clear();
System.out.println(map);
// 3、判断集合是否为空
System.out.println(map.isEmpty());
// 4、根据键获取对应的值(重点)
System.out.println(map.get("手表"));
System.out.println(map.get("手表2")); // 如果没有这个键,返回null
// 5、根据键删除整个数据,返回删除数据对应的值。(重点)
System.out.println(map.remove("娃娃"));
System.out.println(map);
// 6、判断是否包含某个键(重点)'
// map = {null=null, 手表=2, huawei=365, Java入门=1,iphone=1}
System.out.println(map.containsKey("娃娃")); // false
System.out.println(map.containsKey("huawei")); // true
System.out.println(map.containsKey(null)); // true
System.out.println(map.containsKey("手表2")); // false
// 7、判断是否包含某个值
// map = {null=null, 手表=2, huawei=365, Java入门=1,iphone=1}
System.out.println(map.containsValue(1)); // true
System.out.println(map.containsValue(365)); // true
System.out.println(map.containsValue("1")); // false
// 8、获取Map集合的全部键,到一个Set集合中返回的
// map = {null=null, 手表=2, huawei=365, Java入门=1,iphone=1}
// public Set<K> keySet():
Set<String> keys = map.keySet();
for (String key : keys) {
System.out.println(key);
}
// 9、获取Map集合的全部值:到一个Collection集合中返回的。
Collection<Integer> values = map.values();
for (Integer value : values) {
System.out.println(value);
}
}
}
4.3 Map集合的遍历方式
package com.itheima.d5_map_travesal;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo1 {
public static void main(String[] args) {
// 目标:掌握Map集合的遍历方式一:键找值
Map<String, Integer> map = new HashMap<>(); // 一行经典代码
map.put("iphone", 6);
map.put("小米", 3);
map.put("huawei", 3);
map.put("诺基亚", 31);
System.out.println(map); // {huawei=3, 诺基亚=31, iphone=6, 小米=3}
// 1、获取map集合的全部键
Set<String> keys = map.keySet();
// 2、根据键提取值
for (String key : keys) {
Integer value = map.get(key);
System.out.println(key + "====>" + value);
}
}
}
package com.itheima.d5_map_travesal;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo2 {
public static void main(String[] args) {
// 目标:掌握Map集合的遍历方式二:键值对遍历(难度大点)
Map<String, Integer> map = new HashMap<>();
map.put("蜘蛛精", 1000);
map.put("小龙女", 23);
map.put("木婉清", 31);
map.put("黄蓉", 35);
System.out.println(map);
// map = {蜘蛛精=1000, 小龙女=23, 黄蓉=35, 木婉清=31}
// 1、一开始是想通过增强for直接遍历Map集合,但是无法遍历,因为键值对直接来看是不存在数据类型的。
// for (元素类型 变量: map){
//
// }
// 2、调用Map集合的一个方法,把Map集合转换成Set集合来遍历
/**
* map = {蜘蛛精=1000, 小龙女=23, 黄蓉=35, 木婉清=31}
* ↓
* map.entrySet()
* ↓
* Set<Map.Entry<String, Integer>> entries = [(蜘蛛精=1000), (小龙女=23), (黄蓉=35), (木婉清=31)]
* entry
*/
Set<Map.Entry<String, Integer>> entries = map.entrySet();
for (Map.Entry<String, Integer> entry : entries) {
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key + " ===> " + value);
}
}
package com.itheima.d5_map_travesal;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
public class MapDemo3 {
public static void main(String[] args) {
// 目标:掌握Map集合的遍历方式三:Lambda
Map<String, Integer> map = new HashMap<>();
map.put("蜘蛛精", 1000);
map.put("小龙女", 23);
map.put("木婉清", 31);
map.put("黄蓉", 35);
System.out.println(map);
// map = {蜘蛛精=1000, 小龙女=23, 黄蓉=35, 木婉清=31}
map.forEach(new BiConsumer<String, Integer>() {
@Override
public void accept(String key, Integer value) {
System.out.println(key + "===>" + value);
}
});
map.forEach((key, value) -> {
System.out.println(key + "===>" + value);
});
}
}
4.4 Map集合案例—统计投票人数
需要做一 一对应的数据时,我们就优先考虑用Map集合来做
package com.itheima.d5_map_travesal;
import java.util.*;
public class MapTest5 {
//需求:统计各个景点想去的人数
public static void main(String[] args) {
//1.把80个学生可选择的景点造出来
String[] locations = {"玉龙雪山", "伶仃岛", "三亚", "泰国"};
//2.定义一个List集合,来存储80个学生所挑选的想去的景点
List<String> data = new ArrayList<>();
//3.用随机数来随机数组里的景点,模拟80个学生进行选择
Random r = new Random();
//4.遍历80个学生,每一次都像List集合中存入想去的景点
for (int i = 0; i < 80; i++) {
data.add(locations[r.nextInt(locations.length)]);
}
System.out.println(data);
//5.定义一个Map集合,键存储景点,值存储想去的人数
Map<String, Integer> map = new HashMap<>();
//6.遍历data,向map中存入数据
for (String s : data) {
//7.判断map中存在data当前所遍历的景点键
if (map.containsKey(s)) {
//如果之前出现过,map值+1
map.put(s,map.get(s) + 1);
}else {
//第一次添加
map.put(s,1);
}
}
map.forEach((s,n) -> System.out.println(s + "选择的人数是:" + n));
}
}
4.5 HashMap
HasSet的底层就是基于HashMap实现的,HashSet中只展示键,不展示值
每次扩容为原来的两倍,关于哈希表的具体解释可以参考JAVA-异常、Collection-优快云博客
package com.itheima.d6_map_impl;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data // Data自带了无参 + get + set + toString + hashCode + equals
@NoArgsConstructor
@AllArgsConstructor//写了有参之后data中的无参就会消失,所以写了有参就必须写无参
public class Movie implements Comparable<Movie>{
private String name;
private double score;
private String actor;
}
package com.itheima.d6_map_impl;
import java.util.HashMap;
import java.util.Map;
public class MapTest1 {
public static void main(String[] args) {
// 目标:掌握Map集合(键)去重复的机制。
Map<Movie, String> map = new HashMap<>();
map.put(new Movie("摔跤吧,爸爸", 9.5, "阿米尔汗"), "19:00");
map.put(new Movie("三傻宝莱坞", 8.5, "阿米尔汗2"), "20:50");
map.put(new Movie("三傻宝莱坞", 8.5, "阿米尔汗2"), "21:50");
map.put(new Movie("阿甘正传", 7.5, "汤姆汉克斯"), "21:00");
System.out.println(map);
}
}
4.6 LinkedHashMap
类似于LinkedHashSet
4.7 TreeMap
package com.itheima.d6_map_impl;
import java.util.*;
public class MapTest3 {
public static void main(String[] args) {
// 目标:了解TreeMap集合:按照你键升序排序,不重复,无索引。
// 方式二:TreeMap集合肯定可以自带比较器对象指定比较规则
Map<Movie, String> map = new TreeMap<>((m1, m2) -> Double.compare(m2.getScore(), m1.getScore()));
// 方式一:Movie类实现Comparable接口指定比较规则
map.put(new Movie("摔跤吧,爸爸", 9.5, "阿米尔汗"), "19:00");
map.put(new Movie("三傻宝莱坞", 8.5, "阿米尔汗2"), "20:50");
map.put(new Movie("三傻宝莱坞", 8.5, "阿米尔汗2"), "21:50");
map.put(new Movie("阿甘正传", 7.5, "汤姆汉克斯"), "21:00");
System.out.println(map);
}
}
package com.itheima.d6_map_impl;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data // Data自带了无参 + get + set + toString + hashCode + equals
@NoArgsConstructor
@AllArgsConstructor//写了有参之后data中的无参就会消失,所以写了有参就必须写无参
public class Movie implements Comparable<Movie>{
private String name;
private double score;
private String actor;
@Override
public int compareTo(Movie o) {
return Double.compare(this.score, o.score);
}
}
5.集合的嵌套
package com.itheima.d6_map_impl;
import java.util.*;
public class MapTest4 {
public static void main(String[] args) {
// 目标:掌握集合的嵌套(重点)
// 1、定义一个Map集合存储全部省份和城市信息。
Map<String, List<String>> provinces = new HashMap<>();
// 2、存入省份信息
List<String> cities1 = new ArrayList<>();
Collections.addAll(cities1, "南京市", "扬州市", "苏州市", "无锡市", "常州市");
provinces.put("江苏省", cities1);
List<String> cities2 = new ArrayList<>();
Collections.addAll(cities2, "武汉市", "襄阳市", "孝感市", "十堰市", "宜昌市");
provinces.put("湖北省", cities2);
List<String> cities3 = new ArrayList<>();
Collections.addAll(cities3, "石家庄市", "唐山市", "邢台市", "保定市", "张家口市");
provinces.put("河北省", cities3);
System.out.println(provinces);
List<String> hbcities = provinces.get("湖北省");
for (String hbcity : hbcities) {
System.out.println(hbcity);
}
}
}