1. 程式人生 > >集合【Map、可變引數、Collections】

集合【Map、可變引數、Collections】

第9天 集合
今日學習內容
 Map集合
今日學習目標
 能夠說出Map集合特點
 使用Map集合新增方法儲存資料
 使用”鍵找值”的方式遍歷Map集合
 使用”鍵值對”的方式遍歷Map集合
 能夠使用HashMap儲存自定義鍵值對的資料
 能夠說出可變引數的作用
 能夠使用集合工具類
 能夠使用HashMap編寫鬥地主洗牌發牌案例
第1章 Map介面概述
1.1 Map集合的特點
我們通過檢視Map介面描述,發現Map介面下的集合與Collection介面下的集合,它們儲存資料的形式不同,如下圖。
 Collection中的集合,元素是孤立存在的(理解為單身),向集合中儲存元素採用一個個元素的方式儲存。
 Map中的集合,元素是成對存在的(理解為夫妻)。每個元素由鍵與值兩部分組成,通過鍵可以找對所對應的值。
 Collection中的集合稱為單列集合,Map中的集合稱為雙列集合。
 需要注意的是,Map中的集合不能包含重複的鍵,值可以重複;每個鍵只能對應一個值。
 Map中常用的集合為HashMap集合、LinkedHashMap集合。

1.2 Map介面中常用集合概述
通過檢視Map介面描述,看到Map有多個子類,這裡我們主要講解常用的HashMap集合、LinkedHashMap集合。
 HashMap:儲存資料採用的雜湊表結構,元素的存取順序不能保證一致。由於要保證鍵的唯一、不重複,需要重寫鍵的hashCode()方法、equals()方法。
 LinkedHashMap:HashMap下有個子類LinkedHashMap,儲存資料採用的雜湊表結構+連結串列結構。通過連結串列結構可以保證元素的存取順序一致;通過雜湊表結構可以保證的鍵的唯一、不重複,需要重寫鍵的hashCode()方法、equals()方法。
 注意:Map介面中的集合都有兩個泛型變數,在使用時,要為兩個泛型變數賦予資料型別。兩個泛型變數的資料型別可以相同,也可以不同。
1.3 Map介面中的常用方法


 put方法:將指定的鍵與值對應起來,並新增到集合中
 方法返回值為鍵所對應的值
使用put方法時,若指定的鍵(key)在集合中沒有,則沒有這個鍵對應的值,返回null,並把指定的鍵值新增到集合中;
使用put方法時,若指定的鍵(key)在集合中存在,則返回值為集合中鍵對應的值(該值為替換前的值),並把指定鍵所對應的值,替換成指定的新值。
 get方法:獲取指定鍵(key)所對應的值(value)
 remove方法:根據指定的鍵(key)刪除元素,返回被刪除元素的值(value)。

Map介面的方法演示
public class MapDemo {
public static void main(String[] args) {
//建立Map物件
Map map = new HashMap();
//給map中新增元素
map.put("星期一", "Monday");
map.put("星期日", "Sunday");
System.out.println(map); // {星期日=Sunday, 星期一=Monday}

    //當給Map中新增元素,會返回key對應的原來的value值,若key沒有對應的值,返回null
    System.out.println(map.put("星期一", "Mon")); // Monday
    System.out.println(map); // {星期日=Sunday, 星期一=Mon}

    //根據指定的key獲取對應的value
    String en = map.get("星期日");
    System.out.println(en); // Sunday

    //根據key刪除元素,會返回key對應的value值
    String value = map.remove("星期日");
    System.out.println(value); // Sunday
    System.out.println(map); // {星期一=Mon}
}

}

1.4 Map集合遍歷鍵找值方式
鍵找值方式:即通過元素中的鍵,獲取鍵所對應的值
操作步驟與圖解:
1.獲取Map集合中所有的鍵,由於鍵是唯一的,所以返回一個Set集合儲存所有的鍵


2.遍歷鍵的Set集合,得到每一個鍵
3.根據鍵,獲取鍵所對應的值

程式碼演示:
public class MapDemo {
public static void main(String[] args) {
//建立Map物件
Map map = new HashMap();
//給map中新增元素
map.put("鄧超", "孫儷");
map.put("李晨", "范冰冰");
map.put("劉德華", "柳巖");
//獲取Map中的所有key
Set keySet = map.keySet();
//遍歷存放所有key的Set集合
Iterator it =keySet.iterator();
while(it.hasNext()){
//得到每一個key
String key = it.next();
//通過key獲取對應的value
String value = map.get(key);
System.out.println(key+"="+value);
}
}
}
1.5 Entry鍵值對物件(補充一下內部類和內部介面)
在Map類設計時,提供了一個巢狀介面:Entry。Entry將鍵值對的對應關係封裝成了物件。即鍵值對物件,這樣我們在遍歷Map集合時,就可以從每一個鍵值對(Entry)物件中獲取對應的鍵與對應的值。


 Entry是Map介面中提供的一個靜態內部巢狀介面。
 getKey()方法:獲取Entry物件中的鍵
 getValue()方法:獲取Entry物件中的值

 entrySet()方法:用於返回Map集合中所有的鍵值對(Entry)物件,以Set集合形式返回。
1.6 Map集合遍歷鍵值對方式
鍵值對方式:即通過集合中每個鍵值對(Entry)物件,獲取鍵值對(Entry)物件中的鍵與值。
操作步驟與圖解:
1.獲取Map集合中,所有的鍵值對(Entry)物件,以Set集合形式返回。

2.遍歷包含鍵值對(Entry)物件的Set集合,得到每一個鍵值對(Entry)物件
3.通過鍵值對(Entry)物件,獲取Entry物件中的鍵與值。

public class MapDemo {
public static void main(String[] args) {
//建立Map物件
Map map = new HashMap();
//給map中新增元素
map.put("鄧超", "孫儷");
map.put("李晨", "范冰冰");
map.put("劉德華", "柳巖");
//獲取Map中的所有key與value的對應關係
Set> entrySet = map.entrySet();
//遍歷Set集合
Iterator> it =entrySet.iterator();
while(it.hasNext()){
//得到每一對對應關係
Map.Entry entry = it.next();
//通過每一對對應關係獲取對應的key
String key = entry.getKey();
//通過每一對對應關係獲取對應的value
String value = entry.getValue();
System.out.println(key+"="+value);
}
}
}
注意:Map集合不能直接使用迭代器或者foreach進行遍歷。但是轉成Set之後就可以使用了。
1.7 HashMap儲存自定義型別鍵值
練習1:使用map儲存:鍵為學號,值為一個學生的物件, 學生物件有屬性(姓名,年齡)
練習2:使用map儲存:鍵為學生(姓名,年齡)值為學生自己的家庭住址。那麼,既然有對應關係,則將學生物件和家庭住址儲存到map集合中。學生作 為鍵, 家庭住址作為值。
注意,學生姓名相同並且年齡相同視為同一名學生。
 學生類
public class Student {
private String name;
private int age;

//編寫構造方法,文件中已省略
//編寫get,set方法,文件中已省略
//編寫toString方法,文件中已省略

}
 測試類
public class HashMapTest {
public static void main(String[] args) {
//1,建立hashmap集合物件。
Map map = new HashMap();

    //2,新增元素。
    map.put(new Student("lisi",28), "上海");
    map.put(new Student("wangwu",22), "北京");
    map.put(new Student("zhaoliu",24), "成都");
    map.put(new Student("zhouqi",25), "廣州");
    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);
    }

    //取出元素。鍵值對方式
    Set<Map.Entry<Student, String>> entrySet = map.entrySet();
    for (Map.Entry<Student, String> entry : entrySet) {
        Student key = entry.getKey();
        String value = entry.getValue();
        System.out.println(key.toString()+"....."+value);
    }
}

}
 當給HashMap中存放自定義物件時,如果自定義物件作為key存在,這時要保證物件唯一,必須複寫物件的hashCode和equals方法(如果忘記,請回顧HashSet存放自定義物件)。
 如果要保證map中存放的key和取出的順序一致,可以使用LinkedHashMap集合來存放。
1.8 LinkedHashMap
我們知道HashMap保證成對元素唯一,並且查詢速度很快,可是成對元素存放進去是沒有順序的,那麼我們要保證有序,還要速度快怎麼辦呢?
在HashMap下面有一個子類LinkedHashMap,它是連結串列和雜湊表組合的一個數據儲存結構。

public class LinkedHashMapDmeo {
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());
   }

}
}
結果:
鄧超 孫儷
李晨 范冰冰
劉德華 柳巖
1.9 Properties類介紹
Properties 類表示了一個持久的屬性集。Properties 可儲存在流中或從流中載入。屬性列表中每個鍵及其對應值都是一個字串。
特點:
1、Hashtable的子類,map集合中的方法都可以用。
2、該集合沒有泛型。鍵值都是字串。
3、它是一個可以持久化的屬性集。鍵值可以儲存到集合中,也可以儲存到持久化的裝置(硬碟、U盤、光碟)上。鍵值的來源也可以是持久化的裝置。
4、有和流技術相結合的方法。


 load(InputStream) 把指定流所對應的檔案中的資料,讀取出來,儲存到Propertie集合中
 load(Reader)
 store(OutputStream,commonts)把集合中的資料,儲存到指定的流所對應的檔案中,引數commonts代表對描述資訊
 Store(Writer,comments);
5.成員方法:
  • public Object setProperty(String key, String value)呼叫 Hashtable 的方法 put。
  • public String getProperty(String key)用指定的鍵在此屬性列表中搜索屬性
  • public Set stringPropertyNames()返回此屬性列表中的鍵集,

程式碼演示:
/*

    • Properties集合,它是唯一一個能與IO流互動的集合
    • 需求:向Properties集合中新增元素,並遍歷
    • 方法:
  • public Object setProperty(String key, String value)呼叫 Hashtable 的方法 put。

  • public Set stringPropertyNames()返回此屬性列表中的鍵集,

  • public String getProperty(String key)用指定的鍵在此屬性列表中搜索屬性
    */
    public class PropertiesDemo01 {
    public static void main(String[] args) {
    //建立集合物件
    Properties prop = new Properties();
    //新增元素到集合
    //prop.put(key, value);
    prop.setProperty("周迅", "張學友");
    prop.setProperty("李小璐", "賈乃亮");
    prop.setProperty("楊冪", "劉愷威");

    //System.out.println(prop);//測試的使用
    //遍歷集合
    Set<String> keys = prop.stringPropertyNames();
    for (String key : keys) {
        //通過鍵 找值
        //prop.get(key)
        String value = prop.getProperty(key);
        System.out.println(key+"==" +value);
    }

    }
    }
    1.10 讀取檔案中的資料,並儲存到集合
    需求:從屬性集檔案prop.properties 中取出資料,儲存到集合中
    分析:
    1,建立集合
    2,建立流物件
    3,把流所對應檔案中的資料 讀取到集合中
    load(InputStream) 把指定流所對應的檔案中的資料,讀取出來,儲存到Propertie集合中
    load(Reader)
    4,關閉流
    5,顯示集合中的資料
    程式碼演示:
    public class PropertiesDemo03 {
    public static void main(String[] args) throws IOException {
    //1,建立集合
    Properties prop = new Properties();
    //2,建立流物件
    FileReader in = new FileReader("prop.properties");
    //3,把流所對應檔案中的資料 讀取到集合中
    prop.load(in);
    //4,關閉流
    in.close();
    //5,顯示集合中的資料
    System.out.println(prop);

    }
    }
    1.11 可變引數
    在JDK1.5之後,如果我們定義一個方法需要接受多個引數,並且多個引數型別一致,我們可以對其簡化成如下格式:
    修飾符 返回值型別 方法名(引數型別… 形參名){ }
    其實這個書寫完全等價與
    修飾符 返回值型別 方法名(引數型別[] 形參名){ }
    只是後面這種定義,在呼叫時必須傳遞陣列,而前者可以直接傳遞資料即可。

jdk1.5以後。出現了簡化操作。… 用在引數上,稱之為可變引數。
同樣是代表陣列,但是在呼叫這個帶有可變引數的方法時,不用建立陣列(這就是簡單之處),直接將陣列中的元素作為實際引數進行傳遞,其實編譯成的class檔案,將這些元素先封裝到一個數組中,在進行傳遞。這些動作都在編譯.class檔案時,自動完成了。
程式碼演示:
public class ParamDemo {
public static void main(String[] args) {
int[] arr = {21,89,32};
int sum = add(arr);
System.out.println(sum);
sum = add(21,89,32);//可變引數呼叫形式
System.out.println(sum);

}

//JDK1.5之後寫法
public static int add(int...arr){
    int sum = 0;
    for (int i = 0; i < arr.length; i++) {
        sum += arr[i];
    }
    return sum;
}

//原始寫法
/*
public static int add(int[] arr) {
    int sum = 0;
    for (int i = 0; i < arr.length; i++) {
        sum += arr[i];
    }
    return sum;
}
*/

}
 上述add方法在同一個類中,只能存在一個。因為會發生呼叫的不確定性
注意:
1,一個方法中只能有一個可變引數.
2這個方法擁有多引數,引數中包含可變引數,可變引數一定要寫在引數列表的末尾位置。
1.12 Collections集合工具類(可補充靜態匯入和Map巢狀)
Collections是集合工具類,用來對集合進行操作。部分方法如下:


 public static void sort(List list) // 集合元素排序
//排序前元素list集合元素 [33,11,77,55]
Collections.sort( list );
//排序後元素list集合元素 [11,33,55,77]

 public static void shuffle(List list) // 集合元素儲存位置打亂
//list集合元素 [11,33,55,77]
Collections.shuffle( list );
//使用shuffle方法後,集合中的元素為[77,33,11,55],每次執行該方法,集合中儲存的元素位置都會隨機打亂
第2章 模擬鬥地主洗牌發牌
2.1 案例介紹
按照鬥地主的規則,完成洗牌發牌的動作。

具體規則:
1. 組裝54張撲克牌

  1. 將54張牌順序打亂
    1. 三個玩家參與遊戲,三人交替摸牌,每人17張牌,最後三張留作底牌。
    2. 檢視三人各自手中的牌(按照牌的大小排序)、底牌
       手中撲克牌從大到小的擺放順序:大王,小王,2,A,K,Q,J,10,9,8,7,6,5,4,3

2.2 案例需求分析
 準備牌:
完成數字與紙牌的對映關係:
使用雙列Map(HashMap)集合,完成一個數字與字串紙牌的對應關係(相當於一個字典)。
 洗牌:
通過數字完成洗牌發牌
 發牌:
將每個人以及底牌設計為ArrayList,將最後3張牌直接存放於底牌,剩餘牌通過對3取模依次發牌。
存放的過程中要求數字大小與鬥地主規則的大小對應。
將代表不同紙牌的數字分配給不同的玩家與底牌。
 看牌:
通過Map集合找到對應字元展示。
通過查詢紙牌與數字的對應關係,由數字轉成紙牌字串再進行展示。


2.3 實現程式碼步驟

首先,要修改java檔案編碼,由GBK修改為UTF-8,因為預設的字元編碼GBK沒有我們要的梅花、方片、黑桃、紅桃(♠♥♦♣)等特殊字元。
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;

/*
 * 鬥地主洗牌發牌排序
 */
public class Poker {

    public static void main(String[] args) {

        //準備花色
        ArrayList<String> color = new ArrayList<String>();
        color.add("♠");
        color.add("♥");
        color.add("♦");
        color.add("♣");

        //準備數字
        ArrayList<String> number = new ArrayList<String>();
Collections.addAll(number,"3","4","5","6","7","8","9","10","J","Q","K","A","2");

        //定義一個map集合:用來將數字與每一張牌進行對應
        HashMap<Integer, String> map = new HashMap<Integer, String>();

        int index = 0;
        //加入大小王
        map.put(index++, "小☺");
        map.put(index++, "大☻");

        for (String thisNumber : number) {
            for (String thisColor : color) {
                map.put(index++, thisColor+thisNumber);
            }
        }

        //一副54張的牌 ArrayList裡邊為0-53的數的新牌
        ArrayList<Integer> cards = new ArrayList<Integer>();

        for (int i = 0; i <= 53; i++) {
            cards.add(i);
        }

        //洗牌
        Collections.shuffle(cards);

        //建立三個玩家和底牌
        ArrayList<Integer> iPlayer = new ArrayList<Integer>();
        ArrayList<Integer> iPlayer2 = new ArrayList<Integer>();
        ArrayList<Integer> iPlayer3 = new ArrayList<Integer>();
        ArrayList<Integer> itCards = new ArrayList<Integer>();

        //遍歷這副洗好的牌,遍歷過程中,將牌發到三個玩家和底牌中
        

相關推薦

集合Map可變引數Collections

第9天 集合今日學習內容 Map集合今日學習目標 能夠說出Map集合特點 使用Map集合新增方法儲存資料 使用”鍵找值”的方式遍歷Map集合 使用”鍵值對”的方式遍歷Map集合 能夠使用HashMap儲存自定義鍵值對的資料 能夠說出可變引數的作用 能夠使用集合工具類 能夠使用HashM

20_集合_第20天(Map可變引數Collections)_講義

今日內容介紹 1、Map介面 2、模擬鬥地主洗牌發牌 第20天 集合 第1章 Map介面 1.1 Map介面概述 我們通過檢視Map介面描述,發現Map介面下的集合與Collection介面下的集合,它們儲存資料的形式不同,如下圖。  Collection中的

靜態匯入可變引數Collections集合工具類集合巢狀

靜態匯入和可變引數 在導包的過程中我們可以直接匯入靜態部分,這樣某個類的靜態成員就可以直接使用了。在原始碼中經常會出現靜態匯入。 import static java.lang.System.out; public class Demo03 { public static void main(

java-ArrayList中去重複字串或重複物件LinkedList集合泛型增強for靜態匯入可變引數asList()方法集合巢狀

1、去除ArrayList中重複字串元素方式  * A:案例演示     * 需求:ArrayList去除集合中字串的重複值(字串的內容相同)     * 思路:建立新集合方式     /**     * A:案例演示     * 需求:ArrayList去除集合中字串的重複值(字串的內容相同)     

Python 3.X | 一文看懂不懵圈:位置引數(必選引數預設引數可變引數關鍵字引數形參實參...

Win 10+Python 3.6.3 不管是什麼引數,它們身處環境是:函式(function)。引數讓函式如虎添翼,靈活、強大。 1、概念釋義: def func(x, y=2, *arg, *, z, **kwargs): #print(x, y) #print(len(ar

函式引數(預設引數可變引數關鍵字引數

原文地址:https://www.cnblogs.com/mingshengling/p/7842826.html 1、預設引數 預設引數降低了函式呼叫的難度,而一旦需要更復雜的呼叫時,又可以傳遞更多的引數來實現。無論是簡單呼叫還是複雜呼叫,函式只需要定義一個。 有多個預設引數時,呼叫的時候,

Python中“i+=i與i=i+i”的區別梳理:(引用記憶體可變引數可變引數

Python中“i+=i與i=i+i”的區別梳理 一、 "i+=i"執行時資料記憶體的變化 當num+=num執行時,num原引用的記憶體空間中,根據空間中儲存的引數的資料型別是否為可變型別而進行變化,***可變的引數資料型別***有:列表、字典;***不可變引

Python中位置引數預設引數可變引數命名關鍵字引數關鍵字引數的區別

Python中必選引數、預設引數、可變引數、命名關鍵字引數、關鍵字引數的區別: Num01–>必選引數(亦即位置引數): 定義:就是在給函式傳引數時,按照順序,依次傳值。 先寫一個下面的函式: def power(m, n): result=1

python函式的引數(預設引數可變引數關鍵字引數引數組合)

函式的引數 定義函式的時候,我們把引數的名字和位置確定下來,函式的介面定義就完成了。對於函式的呼叫者來說,只需要知道如何傳遞正確的引數,以及函式將返回什麼樣的值就夠了,函式內部的複雜邏輯被封裝起來,呼叫者無需瞭解。 Python的函式定義非常簡單,但靈活度卻

python--函式(必選引數預設引數可變引數關鍵字引數

# -*-encoding:utf-8 -*- #name = raw_input("please input your name:") #print "Hello", name """ 小結: Python的函式具有非常靈活的引數形態,即可以實現簡單的呼叫,又可以傳入非常

1.5新特性靜態匯入增強for可變引數自動裝箱拆箱列舉

第一  靜態匯入 一、概述: 1、import語句:是匯入一個類或某個包中的所有類。 2、import static語句:匯入一個類中的某個靜態方法或所有靜態方法。 3、特點:簡化了書寫,但是程式碼的閱讀性較差。 import static java.lang.M

Python函式引數總結(位置引數預設引數可變引數關鍵字引數和命名關鍵字引數)

Python函式的引數多達5種,不像Java那樣引數只有一種,而是像C++那樣提供預設引數,除此之外,還提供可變引數、關鍵字引數、命名關鍵字引數,這樣就使得Python函式的引數變得十分複雜。但複雜意味著靈活便捷,Python語言之所以流行起來,與起本身巨大

28可變引數集合陣列的互轉

可變引數 在定義方法的時候不確定該定義多少個引數時,可以使用可變引數來定義,這樣方法的引數個數會根據呼叫者來確定。注意:如果一個方法有可變引數,並且有多個引數,那麼,可變引數肯定是最後一個。格式: 修飾符 返回值型別 方法名(資料型別… 變數名){} 例: public class

C語言(五 可變引數排序問題)

可變引數 有時我們想呼叫一個函式,卻又想給它傳不同數量的引數,C語言為我們提供了可變引數這個功能。 #include <stdio.h> #include <stdarg.h> //要想使用可變引數,必須引入此標頭檔案 void cal(int num,.

Java之Set可變引數

一、java.util.Set 是Collection介面的子介面,特點: 不允許重複元素 不保證先後順序 沒有索引值 二、常用的實現類: HashSet:底層使用雜湊表,查詢物件的速度嗷嗷快。 LinkedHashSet:底層也是雜湊

Python的位置引數預設引數關鍵字引數可變引數

普通引數 (位置引數) 定義的時候直接定義變數名,呼叫的時候直接把變數或者值放入指定的位置 呼叫的時候,具體參考的是位置,按位置賦值 語法: def 函式名 (引數1,引數2,……)

python的位置引數預設引數關鍵字引數可變引數區別

一、位置引數 呼叫函式時根據函式定義的引數位置來傳遞引數。 #!/usr/bin/env python # coding=utf-8 def print_hello(name, sex): sex_dict = {1: u'先生', 2: u'女士'}

python學習:位置引數預設引數可變引數 RF例項

1、位置引數 (根據函式定義的引數位置來傳遞引數,必須一一對應)2、關鍵字引數(使用者函式呼叫,通過“鍵-值”形式加以指定,不需一一對應)3、預設引數(引數提供預設值,呼叫函式時可傳可不傳該預設引數的值

Python中函式引數(預設列表可變長度字典型別)

#_*_coding:UTF-8_*_ # 1.預設引數 # 函式的引數支援預設。當某個引數沒有傳遞實際值時,函式將使用預設引數計算。例如,可以向login()函式的username引數和passwo

C# 定義了 7 種變數類別:靜態變數例項變數陣列元素引數引用引數輸出引數和區域性變數

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!