1. 程式人生 > 實用技巧 >java學習-Set和Map集合

java學習-Set和Map集合

1.Set集合

1.1Set集合介紹

  1. Set集合Collection集合的一個子介面
  2. Set集合特點:

    1)元素存取無序 : 儲存Set集合元素的順序與從Set集合中取出元素的順序不能保證一致

    2)無索引 : Set集合中的每一個元素沒有索引位置

    3)去重複 : Set集合中不儲存重複的元素

  3.Set介面,不能例項化物件, 找到實現類HashSet, 雜湊表資料結構

  Set<E> set = new HashSet<>();

程式碼

public class Demo01_Set集合介紹 {
    public static void
main(String[] args) { Set<String> set = new HashSet<>(); set.add("999"); set.add("999"); set.add("a"); set.add("Hello"); set.add("a"); set.add("a"); System.out.println(set);//[a, Hello, 999] } }

1.2Set集合遍歷

  1. toArray() : 將集合中的元素轉換到一個Object[] 型別陣列中
  2. toArray(T[] arr) : 集合轉陣列; 但是列表中需要提供一個與集合資料型別相同的陣列型別引數, 將集合中元素同步到引數陣列中, 這個陣列具有指定型別, 遍歷陣列時候不需要向下轉型; 如果arr陣列大小不夠集合中的元素個數, toArray方法會為你生成一個新的T[]作為方法的返回; 返回值型別T[]
  3. 迭代器
  4. 增強for(forEach) :

    1)forEach語句結構:

  for( 元素資料型別 變數名 : 需要遍歷的集合或者陣列 ){

    }

  2)說明 :

  a : 元素資料型別 : 表示需要遍歷的這個集合或者陣列中的元素具有的資料型別

  b : 變數名 : 表示集合或者陣列中的每一個元素

  3)注意 :

  a : 增強for 語法底層是使用了迭代器的遍歷原理

  b : 使用增強for有可能會發生併發修改異常

程式碼

public class Demo02_Set集合遍歷1 {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        set.add("999");
        set.add("a");
        set.add("Hello");
        
        Object[] objArr = set.toArray();
        for(int index = 0; index < objArr.length; index++) {
            Object obj = objArr[index];
            String s = (String)obj;
            System.out.println(s);
        }
    }
}
public class Demo03_Set集合遍歷2 {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        set.add("999");
        set.add("a");
        set.add("Hello");
        
        String[] a = new String[set.size()];
        
        set.toArray(a);
        
         for(int index = 0; index < a.length; index++) {
             String s = a[index];
             System.out.println(s);
         }
    }
}
public class Demo04_Set集合遍歷3 {

    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        set.add("999");
        set.add("a");
        set.add("Hello");
        
        Iterator<String> it = set.iterator();
        while(it.hasNext()) {
            String s = it.next();
            System.out.println(s);
        }
    }
}
public class Demo05_Set集合遍歷4 {

    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        set.add("999");
        set.add("a");
        set.add("Hello");
        
        /*for( 元素資料型別  變數名 : 需要遍歷的集合或者陣列 ){

        }*/
        for(String s : set) {
            System.out.println(s);
            set.add("world");
        }
    }
}

1.3HashSet保證元素唯一原理

  1.3.1HashSet儲存JDK提供型別

  HashSet儲存JDK提供的型別時, 可以保證元素儲存是去重複的

  1.3.2HashSet儲存自定義型別

  1. 自定義的類Person, Person中具有name和age屬性, 如果Person的姓名和年齡都相同,認為這是重複的資料,需要HashSet進行去重複儲存
  2. 設計好了Person型別之後,將多個Person物件儲存在HashSet中, 發現沒有給自定義型別進行去重複
  3. 認為與HashSet中add方法的實現有關, add方法中, 使用了hashCode() 和equals() 方法
  4. 試著將hashCode() 和equals() 方法在Person型別中重寫, alt + shift + s , 重寫後,去重複成功
  5. 總結 : 自定義型別重寫hashCode() 和equals() 方法,保證在HashSet中儲存元素唯一

程式碼

ublic class Person {
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    public Person() {
        super();
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Person other = (Person) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
}
public class Demo07_HashSet儲存自定義Person {
   public static void main(String[] args) {
       // 要求 : 如果人員資訊, 姓名和年齡都相同,認為Person重複資料
        HashSet<Person> set = new HashSet<>();
        set.add(new Person("張三",20));
        set.add(new Person("李四",20));
        set.add(new Person("張三",20));
        
        System.out.println(set);//[Person [name=李四, age=20], Person [name=張三, age=20]]   
  }
}

  1.3.3hashCode方法

  1. hashCode方法來自於Object型別中, 可以被所有類繼承使用
  2. hashCode原始碼在Object中功能: 比較物件是否是同一個

    1)求物件的雜湊碼值, 將一個物件在記憶體中的地址轉換成一個整數結果, 這個整數就稱為物件的雜湊碼值

    2)不同的物件計算出不同的整數(雜湊碼值), 因為整數結果不同,驗證物件是否是同一個

  3.hashCode計算規則:

    1)同一物件多次呼叫 hashCode 方法時,必須一致地返回相同的整數

    2)equals(Object) 方法,兩個物件是相等的,那麼對這兩個物件中的每個物件呼叫 hashCode 方法都必須生成相同的整數結果

    3)equals(Object) 方法,兩個物件是不相等的, 那麼對這兩個物件中的每個物件呼叫 hashCode 方法整數結果儘量不相同

  4.實際開發中, 比較兩個物件的地址沒有意義, 通過在子類中重寫hashCode方法, 重寫之後,比較的就是物件中的成員變數對應的hashCode值是否相等

  1.3.4LinkedHashSet

  1. LinkedHashSet是HashSet的一個子類, 子類中方法與HashSet中的方法一樣, 同樣也可以保證元素的唯一性
  2. LinkedHashSet 底層結構 : 雙向連結串列, 能夠保證新增進入到集合中的元素與從集合中取出的元素順序一致,保證迭代順序

程式碼

public class Demo08_LinkedHashSet {
    public static void main(String[] args) {
        LinkedHashSet<String> linkSet =  new LinkedHashSet<>();
        linkSet.add("999");
        linkSet.add("Hello");
        linkSet.add("a");
        
        System.out.println(linkSet);//[999, Hello, a]
        
        HashSet<String> set = new HashSet<>();
        set.add("999");
        set.add("Hello");
        set.add("a");
        
        System.out.println(set);// [a, Hello, 999]      
    }
}

2.Map集合

2.1Map集合的介紹

  1. Map是雙列集合頂層父介面, 來自於java.util包

  Map<K,V> : 描述的鍵值對對映關係, 一對一 , 一個Key的值對應1個Value

    K-----Key 鍵

    V----Value 值

  2.map類比記憶 : map英文中表示地圖概念, 地圖上的每一個點都對應現實生活中的一個地理位置, 將地圖一對一的關係類比成Map集合

  3.Map集合的儲存特點:

    1)Map集合中, Key值不重複(唯一)

    2)Map集合中, Value值可以重複

  通常對於Map集合的操作,使用唯一的Key值操作對應的Value的值

  4.Map介面, 不能例項化物件, 需要實現類, HashMap--->雜湊表結構

2.2Map集合中的常用方法

  1. put(K key, V vlue):

    1)如果新增的key值在Map集合中不存在, 那麼表示新增功能, 將鍵值對對映關係新增到Map集合中, 方法返回值型別V--->value

    2)如果新增的key值在Map集合中已經存在, 那麼表示修改功能, 修改(覆蓋)指定key對應的value值

  2.remove(Object key) : 將Map集合中指定key值所對應的鍵值對對映關係刪除, 返回值是value值

  3.clear() : 清空Map集合中的所有元素

  4.size() : 獲取Map集合中的鍵值對數量

  5.get(Object key) : 通過Map集合中的key值, 獲取到對應的value

  6.containsKey(Object k) : 驗證Map集合的key中,是否包含引數k, 包含返回true, 不包含返回false, 返回值型別boolean

  7.containsValue(Object v) : 驗證Map集合的value值中,是否包含引數v, 包含返回true, 不包含返回false, 返回值型別boolean

程式碼

public class Demo01_Map集合常用方法 {
    public static void main(String[] args) {
        Map<Integer, String> map = new HashMap<Integer, String>();
       // 1. put(K key, V vlue):如果新增的key的值在Map集合中不存在, 那麼表示新增功能, 
        // 將鍵值對對映關係新增到Map集合中, 方法返回值型別V--->value
        map.put(11, "a");
        map.put(12, "b");
        map.put(13, "a");
        System.out.println(map);// {11=a, 12=b, 13=a}
        System.out.println(map.size());// 3
        
        // 2.put(K key, V vlue):如果新增的key的值在Map集合中已經存在, 那麼表示修改功能, 修改(覆蓋)指定key對應的value值
        map.put(12, "new");
        
        System.out.println(map);// {11=a, 12=new, 13=a}
        
        
        // 3. remove(Object key) : 將Map集合中指定key值, 鍵值對對映關係刪除, 返回就是value值
        String value = map.remove(12);
        System.out.println(value);// new 
        
        System.out.println(map);// {11=a, 13=a}
        
        // 4. clear() : 清空Map集合中的所有元素(成對)
        /*map.clear();
        System.out.println(map);//{}
        
        // 5. size() : 獲取Map集合中的鍵值對數量
        System.out.println(map.size());// 0
*/        
        
        // 6. get(Object key) : 通過Map集合中的key的值, 獲取到對應的value
        String value1 = map.get(13);
        System.out.println(value1);// a
        
        // 7.containsKey(Object k) : 驗證Map集合的key中,是否包含引數k, 包含返回true, 不包含返回false, 返回值型別boolean
        System.out.println(map.containsKey(11));// true
        System.out.println(map.containsKey(12));// false
        
        // 8.containsValue(Object v) : 驗證Map集合的value值中,是否包含引數v, 包含返回true, 不包含返回false, 返回值型別boolean
        System.out.println(map.containsValue("a"));// true
        System.out.println(map.containsValue("b"));// false       
    }
}

2.3Map集合的第一種遍歷keySet(掌握)

  1. keySet() : 將Map集合中的所有的Key值獲取到, 放置到一個Set集合中
  2. 遍歷含有Key值的Set集合, 獲取到每一個Key值, 然後通過get(Key), 通過每一個Key值獲取到齊對應的Value值

程式碼

public class Demo02_Map第一種遍歷KetSet {
    public static void main(String[] args) {
        Map<Integer, String> map = new HashMap<Integer, String>();
        map.put(11, "a");
        map.put(13, "a");
        map.put(12, "b");
        
        // 1. 獲取到map中的所有的key的值
       Set<Integer> setK= map.keySet();
       // 2. 遍歷setK獲取到每一個Key值
       for(Integer key : setK) {
           // 3. 通過get方法獲取對應的value值
           String value = map.get(key);
           System.out.println(key + "-----" + value);
       }
       
       Iterator<Integer> it = setK.iterator();
       while(it.hasNext()) {
           Integer key1 = it.next();
           String value1 = map.get(key1);
           System.out.println(key1 + "*******" + value1);
       }
    }
}

2.4Map集合的第二種遍歷entrySet(掌握)

greregegr你

  1.entrySet() : 將Map集合中的所有的鍵值對關係獲取到(成對的資料), 放置到一個Set集合中, Map集合中的每一對資料就是Map.Entry<K,V>型別

  2.遍歷裝有Map.Entry<K,V>鍵值對型別的Set集合, 獲取到每一對關係

  3.在Map.Entry<K,V>型別中, 有方法能單獨獲取到一對元素中的key和value

    1)getKey() : 獲取到鍵值對中key值, 返回值型別K

    2)getValue() : 獲取到鍵值對中key值, 返回值型別V

程式碼

public class Demo03_Map第二中遍歷EntrySet {
    public static void main(String[] args) {
        Map<Integer, String> map = new HashMap<Integer, String>();
        map.put(11, "a");
        map.put(13, "a");
        map.put(12, "c");
        
        // 1. 獲取到Map集合中所有鍵值對資料
        Set<Map.Entry<Integer, String>> set = map.entrySet();
        // 2. 遍歷set集合, 將每一對對映關係獲取到
        for(Map.Entry<Integer, String> entry: set) {
            // 3. 獲取到一對關係中的key和value
            Integer key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + "?????" + value);
        }
    }
}

2.5HashMap

  1. HashMap : Map雙列集合實現類, 底層雜湊表結構
  2. HashMap 集合對於元素的存取無序, Map集合沒有索引
  3. HashMap集合中的key值唯一, 保證key值不重複實現原理與HashSet一致

    1)如果HashMap儲存JDK提供型別作為key, 直接保證key不重複

    2)如果HashMap儲存自定義的型別作為key, 要求自定義型別中重寫hashCode和equals兩個方法

程式碼

public class Person {
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    public Person() {
        super();
        // TODO Auto-generated constructor stub
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Person other = (Person) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
}
public class Demo04_HashMap儲存自定義型別 {
    public static void main(String[] args) {
        HashMap<Person, String> map = new HashMap<>();
        map.put(new Person("zs",19), "新加坡");
        map.put(new Person("lis",20), "香港");
        map.put(new Person("zs",19), "北京");        
        System.out.println(map);      
    }
}

2.6LinkedHashMap

  1. LinkedHashMap 是HashMap的子類, 方法功能與HashMap一致, 但是LinkedHashMap維護了雙向連結串列, 效果 : 保證元素的迭代順序 (元素的存取順序一致)

程式碼

package com.ujiuye.map;
import java.util.HashMap;
import java.util.LinkedHashMap;
public class Demo05_LinkedHashMap {
    public static void main(String[] args) {
        HashMap<Integer, String> map = new HashMap<Integer, String>();
        map.put(11, "a");
        map.put(13, "a");
        map.put(12, "c");
        
        System.out.println(map);// {11=a, 12=c, 13=a}
        
        LinkedHashMap<Integer, String> map1 = new LinkedHashMap<Integer, String>();
        map1.put(11, "a");
        map1.put(13, "a");
        map1.put(12, "c");
        
        System.out.println(map1);// {11=a, 13=a, 12=c}
    }
}