5 Day15--集合2

abu1216發表於2020-11-30

5.1  Set介面

5.1.1     概述

一個不包含重複元素的 collection。

資料無序(因為set集合沒有下標)。

由於集合中的元素不可以重複。常用於給資料去重。

5.1.2     特點

Ø  HashSet:底層是雜湊表,包裝了HashMap,相當於向HashSet中存入資料時,會把資料作為K,存入內部的HashMap中。當然K仍然不許重複。

Ø  TreeSet:底層就是TreeMap,也是紅黑樹的形式,便於查詢資料。

Ø  HashMap實現中,當雜湊值相同的物件,會在同一個hash值的位置儲存不同屬性的資料。

5.1.3     常用方法

boolean add(E e):新增元素。

boolean addAll(Collection  c):把小集合新增到大集合中 。

boolean contains(Object o) : 如果此 collection 包含指定的元素,則返回 true。

boolean isEmpty() :如果此 collection 沒有元素,則返回 true。

Iterator<E> iterator():返回在此 collection 的元素上進行迭代的迭代器。

boolean remove(Object o) :從此 collection 中移除指定元素的單個例項。

int size() :返回此 collection 中的元素數。

Objec[] toArray():返回物件陣列

5.1.4     練習1:測試常用方法

package seday12;

 

import java.util.HashMap;

import java.util.HashSet;

import java.util.Iterator;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Set;

 

public class Test0_Map {

       public static void main(String[] args) {

              Set set = new HashSet ();

              set.add("hello");

              set.add("b");

              set.add("a");

              set.add("world");

              set.add("b");

 

              //不存重複元素,元素無序

              System.out.println(set);

             

              //迭代器

              Iterator it = set.iterator();

              while(it.hasNext()) {

                     System.out.println(it.next());

              }

       }

}

5.2  HashSet

5.2.1     概述

此類實現 Set 介面,由雜湊表(實際上是一個 HashMap 例項)支援。它不保證 set 的迭代順序;特別是它不保證該順序恆久不變。此類允許使用 null 元素。

5.2.2     練習1:獲取HashSet裡的元素

package seday12;

 

import java.util.HashMap;

import java.util.HashSet;

import java.util.Iterator;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Set;

 

public class Test0_Map {

    public static void main(String[] args) {

       HashSet set = new HashSet();

       set.add("a");

       set.add("e");

       set.add("b");

       set.add("a");

       set.add("b");

      

       System.out.println(set);//無序,不重複

      

       Iterator it = set.iterator();

       while(it.hasNext()) {

           System.out.println(it.next());

       }

      

    }

}

5.2.3     練習2:Set儲存屬性值相同的物件

需求:我們仍然假設相同屬性的兩個人是同一個人

1、按照以前的經驗,這種需求只需要重寫equals()方法就可以實現。

2、但是我們提供以後,equals()根本就沒有執行。問題出現在新增功能。

3、查詢新增的原始碼發現,其實在新增時只是計算物件的hash值。

4、由於每次建立物件時hash值都不一樣,所以每次都會當做新物件存起來。

5、所以,現在我們必須保證兩個物件的hash值相同,重寫hashCode()。

package seday12;

 

import java.util.HashMap;

import java.util.HashSet;

import java.util.Iterator;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Set;

 

public class Test0_Map {

    public static void main(String[] args) {

       HashSet set = new HashSet();

       //建立元素

       Student s1 = new Student("西門慶",20);

       Student s2 = new Student("武大郎",19);

       Student s3 = new Student("潘金蓮",21);

       Student s4 = new Student("小龍女",23);

       Student s5 = new Student("武大郎",19);

       Student s6 = new Student("潘金蓮",21);

       //新增時,新元素會和老元素比

       set.add(s1);

       set.add(s2);

       set.add(s3);

       set.add(s4);

       //預設:新增時查詢物件的hash值,沒有查到就存起來

       //所以必須讓hash值一致才可以

       set.add(s5);

       set.add(s6);

       //問題1:屬性相同時還是認為是兩個物件...

       System.out.println(set);

      

//     遍歷

       Iterator it = set.iterator();

       while(it.hasNext()) {

           System.out.println(it.next());

       }

      

    }

}

 

建立Student

package seday12;

 

public class Student {

    private String name;

    private int age;

   

    public Student(String nameint age) {

       this.name = name;

       this.age = age;

    }

    public Student() {

    }

    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;

    }

   

    @Override

    public String toString() {

       return "Student [name=" + name + ", age=" + age + "]";

    }

   

    //需求:屬性值都一樣就看做是同一個物件

    @Override

    public boolean equals(Object obj) {

       if (this == obj)

           return true;

       if (obj == null)

           return false;

       if (getClass() != obj.getClass())

           return false;

       Student other = (Student) 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;

    }

   

    //HashSet預設:新增時查詢物件的hash值,沒有查到就存起來

    //所以必須讓hash值一致才可以

//必須用演算法,不然的話,hash值相同時會掛一串

    public int hashCode() {

       //return 0;//效率低

//讓基本型別*31,引用型別就用自己的hash值

       final int prime = 31;

       int result = 1;

       result = prime * result + age;

       result = prime * result + ((name == null) ? 0 : name.hashCode());

       return result;

    }

   

}

5.3  Map介面

5.3.1     概述

java.util介面 Map<K,V>

型別引數: K - 此對映所維護的鍵的型別V - 對映值的型別。

也叫雜湊表、雜湊表。常用於存 鍵值對 結構的資料。其中的鍵不能重複,值可以重複.

5.3.2     特點

Ø  可以根據鍵 提取對應的值

Ø  鍵不允許重複,如果重複值會被覆蓋

Ø  存放的都是無序資料

Ø  初始容量是16,預設的載入因子是0.75

5.3.3     繼承結構

5.3.4     常用方法

void clear()

          從此對映中移除所有對映關係(可選操作)。

 boolean containsKey(Object key)

          如果此對映包含指定鍵的對映關係,則返回 true。

 boolean containsValue(Object value)

          如果此對映將一個或多個鍵對映到指定值,則返回 true。

 V get(Object key)

          返回指定鍵所對映的值;如果此對映不包含該鍵的對映關係,則返回 null。

 boolean isEmpty()

          如果此對映未包含鍵-值對映關係,則返回 true。

 V put(K key, V value)

          將指定的值與此對映中的指定鍵關聯(可選操作)。

 void putAll(Map<? extends K,? extends V> m)

          從指定對映中將所有對映關係複製到此對映中(可選操作)。

 V remove(Object key)

          如果存在一個鍵的對映關係,則將其從此對映中移除(可選操作)。

 int size()

          返回此對映中的鍵-值對映關係數。

Set<Map.Entry<K,V>> entrySet()

          返回此對映所包含的對映關係的 Set 檢視。

5.3.5     練習1:測試常用方法

package seday12;

 

import java.util.HashMap;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Set;

 

 

public class Test0_Map {

       public static void main(String[] args) {

              Map map = new HashMap ();

              map.put("001""鋼鐵俠");

              map.put("002""蜘蛛俠");

              map.put("003""綠巨人");

              map.put("004""滅霸");

              map.put("005""美國隊長");

              map.put("005""鳳姐");

              System.out.println(map.containsKey("001"));

              System.out.println(map.containsValue("美國隊長"));

              System.out.println(map.isEmpty());

              System.out.println(map.get("003"));

              System.out.println(map.remove("001"));

              System.out.println(map.size());

              Map map2 = new HashMap ();

              map2.put("999""劉德華");

map.put(null,null);//可以存入鍵為null,值也null的資料

 

              map.putAll(map2);

              System.out.println(map);

             

              //keySet()返回鍵的set集合,把map的key形成set集合

              Set set = map.keySet();

              System.out.println(set);

             

             

              //map集合的遍歷,

              //方式1:keySet():把map中的可以放入set集合

              //遍歷方式1:keySet ()

Set set = m.keySet();

              Iterator it = set.iterator();

              while(it.hasNext()) {

                     String key = (String) it.next();

                     String val = (String) m.get(key);

                     System.out.println(key+"="+val);

              }

      

              //遍歷方式2:entrySet ()

Set set2 = m.entrySet();

              Iterator it2 = set2.iterator();

              while(it2.hasNext()) {

                     Entry en = (Entry) it2.next();

                     String key = (String) en.getKey();

                     String value = (String) en.getValue();

                     System.out.println(key+"=="+value);

              }

             

       }

}

5.4  HashMap

Ø  HashMap的鍵要同時重寫hashCode()和equals()

hashCode()用來判斷確定hash值是否相同

equals()用來判斷屬性的值是否相同

-- equals()判斷資料如果相等,hashCode()必須相同

-- equals()判斷資料如果不等,hashCode()儘量不同

5.4.1     概述

基於雜湊表的 Map 介面的實現。此實現提供所有可選的對映操作,並允許使用 null 值和 null 鍵。

HashMap底層是一個Entry陣列,當存放資料時會根據hash演算法計算資料的存放位置。演算法:hash(key)%n,n就是陣列的長度。

當計算的位置沒有資料時,就直接存放,當計算的位置有資料時也就是發生hash衝突的時候/hash碰撞時,採用連結串列的方式來解決的,在對應的陣列位置存放連結串列的頭結點。對連結串列而言,新加入的節點會從頭結點加入。

5.4.2     練習1:讀取HashMap的資料

package seday12;

 

import java.util.HashMap;

import java.util.Iterator;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Set;

 

public class Test0_Map {

       public static void main(String[] args) {

              HashMap map = new HashMap ();

              map.put(100, "劉德華");

              map.put(101, "梁朝偉");

              map.put(102, "古天樂");

              map.put(103, "周潤發");

 

//遍歷方式1:keySet ()

Set set = m.keySet();

              Iterator it = set.iterator();

              while(it.hasNext()) {

                     String key = (String) it.next();

                     String val = (String) m.get(key);

                     System.out.println(key+"="+val);

              }

      

              //遍歷方式2:entrySet ()

Set set2 = m.entrySet();

              Iterator it2 = set2.iterator();

              while(it2.hasNext()) {

                     Entry en = (Entry) it2.next();

                     String key = (String) en.getKey();

                     String value = (String) en.getValue();

                     System.out.println(key+"=="+value);

              }

       }

}

5.4.3     練習2:字串中的字元統計

接收使用者輸入的一串字串,統計出現的每個字元的個數

package seday12;

import java.util.HashMap;

import java.util.Scanner;

public class Test2_Count {

       public static void main(String[] args) {

              //abacbcda

              String s = new Scanner(System.in).nextLine();

             

              //a 1  b 2  c 1

              HashMap<Character,Integer> map = new HashMap<>();

              //遍歷字串獲取每個字元

              for(int i = 0;i<s.length();i++) {

                     //1,取出字串中的每個字元

                     char c = s.charAt(i);

                    

                     //拿著字元查個數

                     Integer count = map.get(c);

 

                     //如果取出來是null,就存1,

                     if(count==null) {

                            map.put(c, 1);

                     }else {

                            //如果取出來有值,計數加1

                            map.put(c,count+1);

                     }

              }

              System.out.println(map);

       }

}

5.5  Collections工具類

5.5.1     常用方法

Collections.sort(List<> list):根據元素的自然順序 對指定列表按升序進行排序。

Collections.max():根據元素的自然順序,返回給定 collection 的最大元素。

Collections.min():根據元素的自然順序 返回給定 collection 的最小元素。

Collections.swap(List,i,j):在指定列表的指定位置處交換元素。

Collections.addAll():

5.5.2     測試

package seday12;

import java.util.ArrayList;

import java.util.Collections;

import java.util.Comparator;

import java.util.List;

public class Test4_Collections {

       public static void main(String[] args) {

              List<String> list = new ArrayList();

             

              //新增多個元素

              Collections.addAll(list,

                            "3","30","23","15","29","12","26");

             

              //元素排序

              Collections.sort(list);

          //預設是字元順序:[12,15,23,26,29, 3, 30]

              System.out.println(list);

             

              //自己定義比較方式

              Collections.sort(list, new Comparator<String>() {

                     //自定義比較器,sort()自動呼叫

                     @Override

                     public int compare(String o1, String o2) {

                            //把字串轉成int比大小

                            int a = Integer.parseInt(o1);

                            int b = Integer.parseInt(o2);

//o1大是正數,o1小是負數,相等是0

                            return a-b;

                     }

              });

              System.out.println(list);

       }

}

5.6  擴充套件

5.6.1     集合和陣列的區別

5.6.2     HashMap實現原理

 

相關文章