第三章 Collections類
3.1 Collections常用功能
java.utils.Collections
是集合工具類,用來對集合進(jìn)行操作。常用方法如下:
public static void shuffle(List<?> list)
:打亂集合順序。
public static <T> void sort(List<T> list)
:將集合中元素按照默認(rèn)規(guī)則排序。
public static <T> void sort(List<T> list,Comparator<? super T> )
:將集合中元素按照指定規(guī)則排序。
代碼演示:
public class CollectionsDemo { ? ?public static void main(String[] args) { ? ? ? ?ArrayList<Integer> list = new ArrayList<Integer>(); ? ? ? ? ?list.add(100); ? ? ? ?list.add(300); ? ? ? ?list.add(200); ? ? ? ?list.add(50); ? ? ? ?//排序方法 ? ? ? ?Collections.sort(list); ? ? ? ?System.out.println(list); ? } } 結(jié)果: [50,100, 200, 300]
我們的集合按照默認(rèn)的自然順序進(jìn)行了排列,如果想要指定順序那該怎么辦呢?
3.2 Comparator比較器
創(chuàng)建一個學(xué)生類,存儲到ArrayList集合中完成指定排序操作。
Student 類
public class Student{ ? ?private String name; ? ?private int age; //構(gòu)造方法 ? ?//get/set //toString }
測試類:
public class Demo {
? ?public static void main(String[] args) {
? ? ? ?// 創(chuàng)建四個學(xué)生對象 存儲到集合中
? ? ? ?ArrayList<Student> list = new ArrayList<Student>();
?
? ? ? ?list.add(new Student("rose",18));
? ? ? ?list.add(new Student("jack",16));
? ? ? ?list.add(new Student("abc",20));
Collections.sort(list, new Comparator<Student>() {//注意和TreeSet比較
?@Override
? public int compare(Student o1, Student o2) {
? ? ? return o1.getAge()-o2.getAge();//以學(xué)生的年齡升序(前-后是升序)
? }
});
?
?
? ? ? ?for (Student student : list) {
? ? ? ? ? ?System.out.println(student);
? ? ? }
? }
}
Student{name='jack', age=16}
Student{name='rose', age=18}
Student{name='abc', age=20}
總結(jié):回顧一下TreeSet的比較,也是用Lambda表達(dá)式,和這個一模一樣。
3.3 可變參數(shù)
在JDK1.5之后,如果我們定義一個方法需要接受多個參數(shù),并且多個參數(shù)類型一致,我們可以對其簡化.
格式:
修飾符 返回值類型 方法名(參數(shù)類型... 形參名){ }
底層:
其實(shí)就是一個數(shù)組
好處:
在傳遞數(shù)據(jù)的時候,省的我們自己創(chuàng)建數(shù)組并添加元素了,JDK底層幫我們自動創(chuàng)建數(shù)組并添加元素了
代碼演示:
?public class ChangeArgs { ? ?public static void main(String[] args) { ? ? ? ?int sum = getSum(6, 7, 2, 12, 2121); ? ? ? ?System.out.println(sum); ? } ? ? ? ?public static int getSum(int... arr) { ? int sum = 0; ? ? ? for (int a : arr) { ? ? ? ? sum += a; ? ? ? } ? return sum; ? } }
注意:
1.一個方法只能有一個可變參數(shù)
2.如果方法中有多個參數(shù),可變參數(shù)要放到最后。
應(yīng)用場景: Collections
在Collections中也提供了添加一些元素方法:
public static <T> boolean addAll(Collection<T> c, T... elements)
:往集合中添加一些元素。
代碼演示:
public class CollectionsDemo { public static void main(String[] args) { ? ? ?ArrayList<Integer> list = new ArrayList<Integer>(); ? ? ?//原來寫法 ? ? ?//list.add(12); ? ? ?//list.add(14); ? ? ?//list.add(15); ? ? ?//list.add(1000); ? ? ?//采用工具類 完成 往集合中添加元素 ? ? ? ?Collections.addAll(list, 5, 222, 1,2); ? ? ?System.out.println(list); }
第四章 斗地主發(fā)牌
4.1 案例介紹
按照斗地主的規(guī)則,完成洗牌發(fā)牌的動作。 具體規(guī)則:
使用54張牌打亂順序,三個玩家參與游戲,三人交替摸牌,每人17張牌,最后三張留作底牌。
4.2 案例分析
-
準(zhǔn)備牌:
牌可以設(shè)計為一個ArrayList<String>,每個字符串為一張牌。 每張牌由花色數(shù)字兩部分組成,我們可以使用花色集合與數(shù)字集合嵌套迭代完成每張牌的組裝。 牌由Collections類的shuffle方法進(jìn)行隨機(jī)排序。
-
發(fā)牌
將每個人以及底牌設(shè)計為ArrayList<String>,將最后3張牌直接存放于底牌,剩余牌通過對3取模依次發(fā)牌。
-
看牌
直接打印每個集合。
4.3 代碼實(shí)現(xiàn)
public class CollectionsDemo3 { ? ?//準(zhǔn)備牌盒 ? ?static ArrayList<String> list = new ArrayList<>(); ? ?//靜態(tài)代碼塊 ? ?static{ ? ? ? ?//1.準(zhǔn)備牌 ? ? ? ?String[] colorArr = {"黑桃","紅桃","梅花","方塊"}; ? ? ? ?String[] numberArr = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"}; ? ? ? ?for (String color : colorArr) { ? ? ? ? ? ?for (String number : numberArr) { ? ? ? ? ? ? ? ?list.add(color + number); ? ? ? ? ? } ? ? ? } ? ? ? ?list.add("大王"); ? ? ? ?list.add("小王"); ? } ? ? ? ? ? ?public static void main(String[] args) { ? ? ? ?//2.洗牌 ? ? ? ?Collections.shuffle(list);//隨機(jī)打亂牌的順序 ? ? ? ?//3.發(fā)牌 ? ? ? ?ArrayList<String> diPai = new ArrayList<>(); ? ? ? ?ArrayList<String> zhouXC = new ArrayList<>();//定義三個不同玩家的集合 ? ? ? ?ArrayList<String> zhouRF = new ArrayList<>(); ? ? ? ?ArrayList<String> liuDH = new ArrayList<>(); ? ? ? ?//遍歷的時候。如果僅僅只想獲取元素,增強(qiáng)for ? ? ? ?//如果在遍歷的時候,要添加或者刪除,用迭代器 ? ? ? ?//如果在遍歷的時候,要操作索引,用普通for ? ? ? ?for (int i = 0; i < list.size(); i++) { ? ? ? ? ? ?//索引 跟 牌 有一個對應(yīng)關(guān)系 ? ? ? ? ? ?//索引 % 3 == 0 發(fā)給第一個人 ? ? ? ? ? ?//索引 % 3 == 1 發(fā)給第二個人 ? ? ? ? ? ?//索引 % 3 == 2 發(fā)給第三個人 ? ? ? ? ? ?String poker = list.get(i); ? ? ? ? ? ?if(i <= 2){//最后三張牌是底牌 ? ? ? ? ? ? ? ?diPai.add(poker); ? ? ? ? ? ? ? ?continue; ? ? ? ? ? } ? ? ? ? ? ?if(i % 3 == 0){ ? ? ? ? ? ? ? ?zhouXC.add(poker); ? ? ? ? ? }else if(i % 3 == 1){ ? ? ? ? ? ? ? ?zhouRF.add(poker); ? ? ? ? ? }else{ ? ? ? ? ? ? ? ?liuDH.add(poker); ? ? ? ? ? } ? ? ? } ? ? ? ?//4.遍歷 ? ? ? ?System.out.println("底牌:" + diPai); ? ? ? ?System.out.println("周星馳:" + zhouXC); ? ? ? ?System.out.println("周潤發(fā):" + zhouRF); ? ? ? ?System.out.println("劉德華:" + liuDH); ? ? } }
第五章 Map集合
5.1 概述
現(xiàn)實(shí)生活中,我們常會看到這樣的一種集合:IP地址與主機(jī)名,身份證號與個人,系統(tǒng)用戶名與系統(tǒng)用戶對象等,這種一一對應(yīng)的關(guān)系,就叫做映射。Java提供了專門的集合類用來存放這種對象關(guān)系的對象,即java.util.Map
接口。
我們通過查看Map
接口描述,發(fā)現(xiàn)Map
接口下的集合與Collection
接口下的集合,它們存儲數(shù)據(jù)的形式不同,如下圖。
?
Collection
中的集合,元素是孤立存在的(理解為單身),向集合中存儲元素采用一個個元素的方式存儲。
Map
中的集合,元素是成對存在的(理解為夫妻)。每個元素由鍵與值兩部分組成,通過鍵可以找對所對應(yīng)的值。
Collection
中的集合稱為單列集合,Map
中的集合稱為雙列集合。需要注意的是,
Map
中的集合不能包含重復(fù)的鍵,值可以重復(fù);每個鍵只能對應(yīng)一個值。
5.2 Map的常用子類
通過查看Map接口描述,看到Map有多個子類,這里我們主要講解常用的HashMap集合、LinkedHashMap集合。
HashMap<K,V>:存儲數(shù)據(jù)采用的哈希表結(jié)構(gòu),元素的存取順序不能保證一致。由于要保證鍵的唯一、不重復(fù),需要重寫鍵的hashCode()方法、equals()方法。
LinkedHashMap<K,V>:HashMap下有個子類LinkedHashMap,存儲數(shù)據(jù)采用的哈希表結(jié)構(gòu)+鏈表結(jié)構(gòu)。通過鏈表結(jié)構(gòu)可以保證元素的存取順序一致;通過哈希表結(jié)構(gòu)可以保證的鍵的唯一、不重復(fù),需要重寫鍵的hashCode()方法、equals()方法。
TreeMap<K,V>:TreeMap集合和Map相比沒有特有的功能,底層的數(shù)據(jù)結(jié)構(gòu)是紅黑樹;可以對元素的鍵進(jìn)行排序,排序方式有兩種:自然排序和比較器排序
tips:Map接口中的集合都有兩個泛型變量<K,V>,在使用時,要為兩個泛型變量賦予數(shù)據(jù)類型。兩個泛型變量<K,V>的數(shù)據(jù)類型可以相同,也可以不同。
5.3 Map的常用方法
Map接口中定義了很多方法,常用的如下:
public V put(K key, V value)
: 把指定的鍵與指定的值添加到Map集合中。
public V remove(Object key)
: 把指定的鍵所對應(yīng)的鍵值對元素 在Map集合中刪除,返回被刪除元素的值。
public V get(Object key)
根據(jù)指定的鍵,在Map集合中獲取對應(yīng)的值。
public Set<K> keySet()
: 獲取Map集合中所有的鍵,存儲到Set集合中。
public Set<Map.Entry<K,V>> entrySet()
: 獲取到Map集合中所有的鍵值對對象的集合(Set集合)。
public boolean containKey(Object key)
:判斷該集合中是否有此鍵。
先看put()方法:
當(dāng)鍵值相同時,后面的值會覆蓋掉前面的值,這是put()方法的一個特點(diǎn)。
再看:
發(fā)現(xiàn)put()方法的返回值是返回被覆蓋的那個值。但是這個我們一般用不到。
Map接口的方法演示
public class MapDemo {
? ?public static void main(String[] args) {
? ? ? ?//創(chuàng)建 map對象
? ? ? ?HashMap<String, String> ?map = new HashMap<String, String>();
?
? ? ? ?//添加元素到集合
? ? ? ?map.put("黃曉明", "楊穎");
? ? ? ?map.put("文章", "馬伊琍");
? ? ? ?map.put("鄧超", "孫儷");
? ? ? ?System.out.println(map);
?
? ? ? ?//String remove(String key)
? ? ? ?System.out.println(map.remove("鄧超"));//remove返回值是被刪除的鍵值對的值
? ? ? ?System.out.println(map);
?
? ? ? ?// 想要查看 黃曉明的媳婦 是誰
? ? ? ?System.out.println(map.get("黃曉明"));
? ? ? ?System.out.println(map.get("鄧超")); ? ?
? }
}
總結(jié):
使用put方法時,若指定的鍵(key)在集合中沒有,則沒有這個鍵對應(yīng)的值,返回null,并把指定的鍵值添加到集合中;
若指定的鍵(key)在集合中存在,則返回值為集合中鍵對應(yīng)的值(該值為替換前的值),并把指定鍵所對應(yīng)的值,替換成指定的新值。
5.4 Map的遍歷
首先要知道一點(diǎn)的是:Map不能直接用迭代器進(jìn)行遍歷。
方式1:鍵找值方式
通過元素中的鍵,獲取鍵所對應(yīng)的值
分析步驟:
獲取Map中所有的鍵,由于鍵是唯一的,所以返回一個Set集合存儲所有的鍵。方法提示:
keyset()
遍歷鍵的Set集合,得到每一個鍵。
根據(jù)鍵,獲取鍵所對應(yīng)的值。方法提示:
get(K key)
遍歷圖解:
代碼示例:
//1.創(chuàng)建一個集合 HashMap<String,String> hm = new HashMap<>(); //2.添加元素 hm.put("郭靖","黃蓉"); hm.put("尹志平","小龍女"); hm.put("林平之","岳靈珊"); ? //3.遍歷 //方式一:鍵找值 //先把所有的鍵都獲取出來,放到一個Set集合中 Set<String> keys = hm.keySet(); for (String key : keys) { ? ?//得到每一個鍵之后,再通過鍵找值 ? ?String value = hm.get(key); ? ?System.out.println(key + ", " + value);
方式2:鍵值對方式
即通過集合中每個鍵值對(Entry)對象,獲取鍵值對(Entry)對象中的鍵與值。
Entry鍵值對對象:
我們已經(jīng)知道,Map
中存放的是兩種對象,一種稱為key(鍵),一種稱為value(值),它們在在Map
中是一一對應(yīng)關(guān)系,這一對對象又稱做Map
中的一個Entry(項)
。Entry
將鍵值對的對應(yīng)關(guān)系封裝成了對象。即鍵值對對象,這樣我們在遍歷Map
集合時,就可以從每一個鍵值對(Entry
)對象中獲取對應(yīng)的鍵與對應(yīng)的值。
在Map集合中也提供了獲取所有Entry對象的方法:
-
public Set<Map.Entry<K,V>> entrySet()
: 獲取到Map集合中所有的鍵值對對象的集合(Set集合)。(注意這里有泛型的嵌套)
獲取了Entry對象 , 表示獲取了一對鍵和值,那么同樣Entry中 , 分別提供了獲取鍵和獲取值的方法:
public K getKey()
:獲取Entry對象中的鍵。
public V getValue()
:獲取Entry對象中的值。
操作步驟與圖解:
獲取Map集合中,所有的鍵值對(Entry)對象,以Set集合形式返回。方法提示:
entrySet()
。遍歷包含鍵值對(Entry)對象的Set集合,得到每一個鍵值對(Entry)對象。
通過鍵值對(Entry)對象,獲取Entry對象中的鍵與值。 方法提示:
getkey() getValue()
遍歷圖解:
?
tips:Map集合不能直接使用迭代器或者foreach進(jìn)行遍歷。但是轉(zhuǎn)成Set之后就可以使用了。
代碼示例:
//1.創(chuàng)建一個集合 HashMap<String,String> hm = new HashMap<>(); //2.添加元素 hm.put("郭靖","黃蓉"); hm.put("尹志平","小龍女"); hm.put("林平之","岳靈珊"); hm.put("韋小寶","雙兒"); hm.put("成昆","陽夫人"); ? //3.獲取Map集合中的每一個鍵值對對象Entry //把每一個鍵值對對象放到一個Set集合中 Set<Map.Entry<String, String>> entries = hm.entrySet(); //遍歷Set集合 for (Map.Entry<String, String> entry : entries) { ? ?//entry 依次表示每一個鍵值對對象 ? ?String key = entry.getKey(); ? ?String value = entry.getValue(); ? ?System.out.println(key + ", " + value); }
方式3:lambda表達(dá)式方式
和單列集合一樣,涉及到forEach方法:
代碼示例:
package com.itheima.a08mapdemo; ? import java.util.HashMap; import java.util.function.BiConsumer; ? public class MapDemo4 { ? ?public static void main(String[] args) { ? ? ? ?//1.創(chuàng)建一個集合 ? ? ? ?HashMap<String, String> hm = new HashMap<>(); ? ? ? ?//2.添加元素 ? ? ? ?hm.put("郭靖", "黃蓉"); ? ? ? ?hm.put("尹志平", "小龍女"); ? ? ? ?hm.put("林平之", "岳靈珊"); ? ? ? ?hm.put("韋小寶", "雙兒"); ? ? ? ?hm.put("成昆", "陽夫人"); ? ? ? ? ?//3.利用匿名內(nèi)部類來遍歷集合 ? ? ? ?hm.forEach(new BiConsumer<String, String>() { ? ? ? ? ? ?@Override ? ? ? ? ? ?public void accept(String key, String value) { ? ? ? ? ? ? ? ?System.out.println(key + ", " + value); ? ? ? ? ? } ? ? ? }); ? ? ? ? ?//4.利用lambda表達(dá)式來遍歷集合 ? ? ? ?hm.forEach((String key, String value) -> { ? ? ? ? ? ?System.out.println(key + ", " + value); ? ? ? } ? ? ? ? ? ? ? ? ); ? ? ? ? ?//5.簡化lambda表達(dá)式來遍歷集合 ? ? ? ?hm.forEach((key, value) -> System.out.println(key + ", " + value) ); ? } } ?
(下面的知識點(diǎn)明天講)
練習(xí):統(tǒng)計景點(diǎn)次數(shù)
需求:
某個班級80名學(xué)生,現(xiàn)在需要組成秋游活動,班長提供了四個景點(diǎn)依次是(A、B、C、D), ? 每個學(xué)生只能選擇一個景點(diǎn),請統(tǒng)計出最終哪個景點(diǎn)想去的人數(shù)最多。
代碼示例:
//1.讓同學(xué)們進(jìn)行選擇 String[] arr = {"A","B","C","D"}; Random r = new Random(); //把同學(xué)們的選擇都存入到集合中 ArrayList<String> list = new ArrayList<>(); for (int i = 0; i < 80; i++) { ? ?int randomIndex = r.nextInt(arr.length); ? ?list.add(arr[randomIndex]); } //2.統(tǒng)計每個景點(diǎn)的選擇次數(shù) //A=10 ? B=20 C=30 D=40 HashMap<String,Integer> hm = new HashMap<>(); //遍歷list集合,拿到每一個景點(diǎn)的名字 for (String name : list) { ? ?if(hm.containsKey(name)){ ? ? ? ?//表示已經(jīng)存在 ? ? ? ?//如果當(dāng)前景點(diǎn)已經(jīng)存在,把原有的次數(shù)拿出來+1 ? ? ? ?//此時put(景點(diǎn)的名字,新的次數(shù)) ? ? ? ?int count = hm.get(name); ? ? ? ?count++; ? ? ? ?hm.put(name,count); ? }else{ ? ? ? ?//表示不存在 ? ? ? ?//如果當(dāng)前景點(diǎn)在map集合不存在,表示第一次選擇 ? ? ? ?//此時put(景點(diǎn)的名字,1) ? ? ? ?hm.put(name,1); ? } } //3.遍歷map集合 hm.forEach((key,value)->System.out.println(key + ", " + value));
5.5 HashMap存儲自定義類型
小結(jié):
還有:
練習(xí):每位學(xué)生(姓名,年齡)都有自己的家庭住址。那么,既然有對應(yīng)關(guān)系,則將學(xué)生對象和家庭住址存儲到map集合中。學(xué)生作為鍵, 家庭住址作為值。
注意,學(xué)生姓名相同并且年齡相同視為同一名學(xué)生。
編寫學(xué)生類:
public class Student { ? ?private String name; ? ?private int age; ? ? ?//構(gòu)造方法 ? ?//get/set ? ?@Override ? ?public boolean equals(Object o) {//必須重寫equals方法 ? ? ? ?if (this == o) ? ? ? ? ? ?return true; ? ? ? ?if (o == null || getClass() != o.getClass()) ? ? ? ? ? ?return false; ? ? ? ?Student student = (Student) o; ? ? ? ?return age == student.age && Objects.equals(name, student.name); ? } ? ? ?@Override ? ?public int hashCode() {//必須重寫hashCode方法 ? ? ? ?return Objects.hash(name, age); ? } }
編寫測試類:
public class HashMapTest { ? ?public static void main(String[] args) { ? ? ? ?//1,創(chuàng)建Hashmap集合對象。 ? ? ? ?Map<Student,String> map = new HashMap<Student,String>(); ? ? ? ?//2,添加元素。 ? ? ? ?map.put(new Student("lisi",28), "上海"); ? ? ? ?map.put(new Student("wangwu",22), "北京"); ? ? ? ?map.put(new Student("wangwu",22), "南京"); ? ? ? ? ? ? ? ?//3,取出元素。鍵找值方式 ? ? ? ?Set<Student> keySet = map.keySet(); ? ? ? ?for(Student key: keySet){ ? ? ? ? ? ?String value = map.get(key); ? ? ? ? ? ?System.out.println(key.toString()+"....."+value); ? ? ? } ? } }
當(dāng)給HashMap中存放自定義對象時,如果自定義對象作為key存在,這時要保證對象唯一,必須重寫對象的hashCode和equals方法(如果忘記,請回顧HashSet存放自定義對象)。
如果要保證map中存放的key和取出的順序一致,可以使用
java.util.LinkedHashMap
集合來存放。
5.6 LinkedHashMap介紹(底層有雙鏈表機(jī)制保證數(shù)據(jù)添加的時候有序,打印的時候也是有序)
我們知道HashMap保證成對元素唯一,并且查詢速度很快,可是成對元素存放進(jìn)去是沒有順序的,那么我們要保證有序,還要速度快怎么辦呢?
在HashMap下面有一個子類LinkedHashMap,它是鏈表和哈希表組合的一個數(shù)據(jù)存儲結(jié)構(gòu)。
面試加分:LinkedHashMap保證有序是怎么實(shí)現(xiàn)的?
用雙鏈表,它保證數(shù)據(jù)的存的順序和取的順序是一致的!!
public class LinkedHashMapDemo { ? ?public static void main(String[] args) { ? ? ? ?LinkedHashMap<String, String> map = new LinkedHashMap<String, String>(); ? ? ? ?map.put("鄧超", "孫儷"); ? ? ? ?map.put("李晨", "范冰冰"); ? ? ? ?map.put("劉德華", "朱麗倩"); ? ? ? ?Set<Entry<String, String>> entrySet = map.entrySet(); ? ? ? ?for (Entry<String, String> entry : entrySet) { ? ? ? ? ? ?System.out.println(entry.getKey() + " " + entry.getValue()); ? ? ? } ? } }
結(jié)果:
鄧超 孫儷 李晨 范冰冰 劉德華 朱麗倩
5.7 TreeMap集合
1.TreeMap介紹
TreeMap集合和Map相比沒有特有的功能,底層的數(shù)據(jù)結(jié)構(gòu)是紅黑樹;可以對元素的鍵進(jìn)行排序,注意,是對鍵進(jìn)行排序,而不是對值進(jìn)行排序!排序方式有兩種:自然排序和比較器排序;到時使用的是哪種排序,取決于我們在創(chuàng)建對象的時候所使用的構(gòu)造方法;
public TreeMap() 使用自然排序 public TreeMap(Comparator<? super K> comparator) 比較器排序
2.演示
案例演示自然排序
public static void main(String[] args) { TreeMap<Integer, String> map = new TreeMap<Integer, String>(); map.put(1,"張三"); map.put(4,"趙六"); map.put(3,"王五"); map.put(6,"酒八"); map.put(5,"老七"); map.put(2,"李四"); System.out.println(map); } ? 控制臺的輸出結(jié)果為: {1=張三, 2=李四, 3=王五, 4=趙六, 5=老七, 6=酒八}
案例演示比較器排序
需求:
創(chuàng)建一個TreeMap集合,鍵是學(xué)生對象(Student),值是居住地 (String)。存儲多個元素,并遍歷。
要求按照學(xué)生的年齡進(jìn)行升序排序,如果年齡相同,比較姓名的首字母升序, 如果年齡和姓名都是相同,認(rèn)為是同一個元素;
實(shí)現(xiàn):
為了保證age和name相同的對象是同一個,Student類必須重寫hashCode和equals方法,這兩個方法重寫的場景只有兩種:
1、只有在HashSet中存儲自定義對象
2、HashMap的鍵存儲自定義對象
3、TreeSet、TreeMap的鍵底層是用紅黑樹實(shí)現(xiàn)的,我們不需要重寫hashCode和equals方法,我們只需要給TreeSet里面的元素還有TreeMap的鍵指定排序規(guī)則。
public class Student { ? ?private int age; ? ?private String name; //省略get/set.. ? ?public Student() {} ? ?public Student(int age, String name) { ? ? ? ?this.age = age; ? ? ? ?this.name = name; ? } ? ?@Override ? ?public String toString() { ? ? ? ?return "Student{" + ? ? ? ? ? ? ? ?"age=" + age + ? ? ? ? ? ? ? ?", name='" + name + '\'' + ? ? ? ? ? ? ? ?'}'; ? } ? ?@Override ? ?public boolean equals(Object o) { ? ? ? ?if (this == o) return true; ? ? ? ?if (o == null || getClass() != o.getClass()) return false; ? ? ? ?Student student = (Student) o; ? ? ? ?return age == student.age && ? ? ? ? ? ? ? ?Objects.equals(name, student.name); ? } ? ?@Override ? ?public int hashCode() { ? ? ? ?return Objects.hash(age, name); ? } }
public static void main(String[] args) { TreeMap<Student, String> map = new TreeMap<Student, String>(new Comparator<Student>() { ? @Override ? public int compare(Student o1, Student o2) { ? ? //先按照年齡升序 ? ? int result = o1.getAge() - o2.getAge(); ? ? if (result == 0) { ? ? ? //年齡相同,則按照名字的首字母升序 ? ? ? return o1.getName().charAt(0) - o2.getName().charAt(0); ? ? } else { ? ? ? //年齡不同,直接返回結(jié)果 ? ? ? return result; ? ? } ? } }); map.put(new Student(30, "jack"), "深圳"); map.put(new Student(10, "rose"), "北京"); map.put(new Student(20, "tom"), "上海"); map.put(new Student(10, "marry"), "南京"); map.put(new Student(30, "lucy"), "廣州"); System.out.println(map); } 控制臺的輸出結(jié)果為: { ?Student{age=10, name='marry'}=南京, ?Student{age=10, name='rose'}=北京, ?Student{age=20, name='tom'}=上海, ?Student{age=30, name='jack'}=深圳, ?Student{age=30, name='lucy'}=廣州 }
5.8 Map集合練習(xí)
需求:
輸入一個字符串中每個字符出現(xiàn)次數(shù)。
分析:
-
獲取一個字符串對象
-
創(chuàng)建一個Map集合,鍵代表字符,值代表次數(shù)。
-
遍歷字符串得到每個字符。
-
判斷Map中是否有該鍵。
-
如果沒有,第一次出現(xiàn),存儲次數(shù)為1;如果有,則說明已經(jīng)出現(xiàn)過,獲取到對應(yīng)的值進(jìn)行++,再次存儲。
-
打印最終結(jié)果
這種方法就比之前單純的計算器思想高級的多。
方法介紹
public boolean containKey(Object key)
:判斷該集合中是否有此鍵。
代碼:文章來源:http://www.zghlxwxcb.cn/news/detail-425870.html
public class MapTest { public static void main(String[] args) { ? ? ? ?//友情提示 ? ? ? ?System.out.println("請錄入一個字符串:"); ? ? ? ?String line = new Scanner(System.in).nextLine(); ? ? ? ?// 定義 每個字符出現(xiàn)次數(shù)的方法 ? ? ? ?findChar(line); ? } ? ?private static void findChar(String line) { ? ? ? ?//1:創(chuàng)建一個集合 存儲 字符 以及其出現(xiàn)的次數(shù) ? ? ? ?HashMap<Character, Integer> map = new HashMap<Character, Integer>(); ? ? ? ?//2:遍歷字符串 ? ? ? ?for (int i = 0; i < line.length(); i++) { ? ? ? ? ? ?char c = line.charAt(i); ? ? ? ? ? ?//判斷 該字符 是否在鍵集中 ? ? ? ? ? ?if (!map.containsKey(c)) {//說明這個字符沒有出現(xiàn)過 ? ? ? ? ? ? ? ?//那就是第一次 ? ? ? ? ? ? ? ?map.put(c, 1); ? ? ? ? ? } else { ? ? ? ? ? ? ? ?//先獲取之前的次數(shù) ? ? ? ? ? ? ? ?Integer count = map.get(c); ? ? ? ? ? ? ? ?//count++; ? ? ? ? ? ? ? ?//再次存入 更新 ? ? ? ? ? ? ? ?map.put(c, ++count); ? ? ? ? ? } ? ? ? } ? ? ? ?System.out.println(map); ? } }
集合的知識多而雜亂,大家學(xué)習(xí)的時候一定要結(jié)構(gòu)化學(xué)習(xí),對比學(xué)習(xí),學(xué)習(xí)的過程中的同時要總結(jié)。我相信,你多學(xué)幾遍,集合一定能拿下!文章來源地址http://www.zghlxwxcb.cn/news/detail-425870.html
到了這里,關(guān)于JavaSE學(xué)習(xí)進(jìn)階day06_03 Collections類和Map集合的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!