目錄
1.可變參數
2.Collections工具類
?
不同集合類型的排序方法比較
3.斗地主游戲
4.Map集合
4.1 Map集合概述
4.2 Map集合的常用方法
?4.3 Map集合的遍歷方式
?4.4 Map集合案例—統計投票人數
4.5?HashMap
?4.6 LinkedHashMap
4.7 TreeMap
5.集合的嵌套
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略@Overridepublic 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;@Overridepublic 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>() {@Overridepublic 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 : 按照鍵,無序,不重復,無索引。值不做要求,鍵和值都可以是nullMap<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("娃娃")); // falseSystem.out.println(map.containsKey("huawei")); // trueSystem.out.println(map.containsKey(null)); // trueSystem.out.println(map.containsKey("手表2")); // false// 7、判斷是否包含某個值// map = {null=null, 手表=2, huawei=365, Java入門=1,iphone=1}System.out.println(map.containsValue(1)); // trueSystem.out.println(map.containsValue(365)); // trueSystem.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集合的遍歷方式三:LambdaMap<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>() {@Overridepublic 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值+1map.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-CSDN博客
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;@Overridepublic 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);}}
}
?