Java學習第十七天

  1. 集合
    1. 爲何要使用集合框架?

傳統的容器(數組)在進行增、刪等破壞性操做時,須要移動元素,可能致使性能問題;同時添加、刪除等算法和具體業務耦合在一塊兒,增長了程序開發的複雜度。java

 

Java集合框架提供了一套性能優良、使用方便的接口和類,它們位於java.util包中c++

 

    1. Collection

Collection是java集合框架(collection-frame)中的頂層接口。程序員

Collection接口表示一個容器,容器中只能存儲引用數據類型,建議存同一類型的引用類型,方便後續遍歷等操做。算法

容器中的元素能夠是有序的、可重複的,稱爲List接口數組

也多是無序的、惟一的,稱爲Set接口。安全

 

 

      1. 集合經常使用方法

public static void main(String[] args) {數據結構

        

         /**併發

          * :add/addAllapp

          * :clear/remove/removeAll/retainAll框架

          * :

          * :contains/containsAll/isEmpty/size

          */

        

         Collection c1 = new ArrayList();

        

         // 追加

         c1.add("apple"); // Object object = new String("apple");

         // c1.add(1);      // Object object = new Integer(1);

         c1.add("banana");

         System.out.println(c1);

        

         // 追加一個集合

         Collection c2 = new ArrayList();

         c2.add("java");

         c2.add("c++");

         c1.addAll(c2);

         System.out.println(c1);

        

         // clear

         //c1.clear();

        

         // c1.remove("apple");

         // c1.removeAll(c2);

         //c1.retainAll(c2);

         //System.out.println(c1);

        

         System.out.println(c1.contains("apple"));

         c2.add("js");

         System.out.println(c1.containsAll(c2));

         // c1.clear();

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

         // 返回集合元素的個數

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

        

         System.out.println(c1.equals(c2));

        

     }

 

      1. 集合的遍歷

Iterable 可遍歷的接口,集合接口繼承於它,集合支持快速遍歷。

// 快速遍歷

         // for-each

         // Object 表示元素類型

         // item表示迭代變量

         // c1表示集合

         for (Object item : c1) {

              System.out.println(item.toString());

         }

 

快速遍歷的本質

Collection繼承Iterable接口,表示集合支持快速遍歷。Iterable接口定義了一個方法iterator()用於獲取集合的迭代器,是一個Iterator接口類型,iterator()內部返回一個實現類實現類Iterator接口。這個實現類必定具備hasNext和next方法用於判斷是否有下一個元素和獲取下一個元素。快速遍歷就是基於迭代器工做的。

 

public static void main(String[] args) {

        

 

         Collection c1 = new ArrayList();

         c1.add("apple");

         c1.add("banana");

         c1.add("coco");

        

        

         // 快速遍歷

         // for-each

         // Object 表示元素類型

         // item表示迭代變量

         // c1表示集合

         for (Object item : c1) {

              System.out.println(item.toString());

         }

        

         // 迭代器遍歷(國內)

         Iterator it = c1.iterator();

         while(it.hasNext()) {

              Object item = it.next();

              System.out.println(item.toString());

         }

        

         // 國外

         for(Iterator it2=c1.iterator();it2.hasNext();) {

              Object item = it2.next();

              System.out.println(item.toString());

         }   

     }

 

 

    1. List接口

List 接口中的元素時有序的、可重複的。List接口中的元素經過索引(index)來肯定元素的順序。

有序的 collection(也稱爲序列)。能夠對列表中每一個元素的插入位置進行精確地控制。用戶能夠根據元素的整數索引(在列表中的位置)訪問元素,並搜索列表中的元素

 

      1. List經常使用方法

public static void main(String[] args) {

        

         /**

          * :add/addAll/add(index,el)/addAll(index,collection)

          * :clear/remove/removeAll/remove(index)

          * :set(index,el)

          * :get(index)/indexOf/lastIndexOf()

          * 其餘:contains/containsAll/isEmpty/size

          */

         List list1 = new ArrayList();

         // 添加元素

         list1.add("apple");

         list1.add("banana");

         // 在指定位置添加元素

         list1.add(0, "coco");

        

         System.out.println(list1);

        

         List list2 = new ArrayList();

         list2.add("java");

         list2.add("c++");

        

         list1.addAll(1, list2);

         System.out.println(list1);

        

         // 刪除

         list1.remove(0);

         System.out.println(list1);

        

         // 修改

         list1.set(0, "javax");

         System.out.println(list1);

        

         //

         System.out.println(list1.get(0));

         list1.add("apple");

         list1.add("apple");

         System.out.println(list1);

         System.out.println(list1.indexOf("apple"));

         System.out.println(list1.lastIndexOf("apple"));

     }

 

      1. List接口遍歷

ListIterator 繼承於Iterator,在Iterator的基礎上提供了以正向遍歷集合,也能夠以逆序遍歷集合。

hasNext/next 以正向遍歷

hasPrevious/previous 以逆序遍歷

 

public static void main(String[] args) {

        

        

         List list1 = new ArrayList();

         list1.add("apple");

         list1.add("banana");

         list1.add("coco");

        

         // 1】快速遍歷

         System.out.println("--for each--");

         for (Object item : list1) {

              System.out.println(item.toString());

         }

        

         // 2】普通for

         System.out.println("--for--");

         for(int i=0;i<list1.size();i++) {

              System.out.println(list1.get(i));

         }

        

         // 3】集合迭代器

         System.out.println("--iterator--");

         Iterator it = list1.iterator();

         while(it.hasNext()) {

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

         }

        

         System.out.println("--list iterator--");

         // 正向遍歷

         ListIterator it2 = list1.listIterator();

         while(it2.hasNext()) {

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

         }

        

         // 逆序遍歷

         while(it2.hasPrevious()) {

              System.out.println(it2.previous());

         }

        

         System.out.println("--list iterator with index--");

         ListIterator it3 = list1.listIterator(1);

         while(it3.hasNext()) {

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

         }

     }

 

 

    1. 數據結構(補充)

數據結構就是數據在內存中存儲結構。根據存儲的方式不一樣,分爲線性表、二叉樹、圖、棧、隊列等

 

      1. 線性表

線性表數據按照必定的邏輯順序存儲在內存中。線性表是有序的。線性表根據內存的物理結構分爲兩種:數組和鏈表

 

數組是一種邏輯上有序的線性表,物理上也連續。

 

鏈表是一種邏輯上有序的線性表,但物理上不連續。

數組和鏈表的區別

 

相同點

不一樣點

 

數組在查詢時效率高,在添加、刪除元素時效率低(涉及移動元素)

鏈表在查詢時效率低(每次從頭開始,不能跳躍訪問),在添加、刪除元素時效率高(不涉及移動元素)

特性:先進後出,後進先出

 

  1. 隊列

特性:先進先出

    1. ArrayList/Vector

ArrayList 是List接口的實現類,底層數據結構是數組,實現大小可變的數組。

ArrayList 線程不安全,jdk1.2

 

ArrayList 底層數據結構是數組,默認數組大小是10,若是添加的元素個數超過默認容量,ArrayList會自動拓容,拓容原則:newCapacity = oldCapacity + oldCapacity / 2;

若是將來肯定序列的元素不在增長,經過調用trimToSize()調製容量至合適的空間。

 

ArrayList做爲List接口的實現類,經常使用方法和遍歷方法參考List接口。

 

Vector 是List接口的實現類,底層數據結構也是數組,也是大小可變的數組。

Vector是線程安全的,jdk1.0

 

Vector底層數據結構是數組,默認數組大小是10,若是添加的元素個數超過默認容量,Vector會自動拓容,拓容原則:newCapacity = oldCapacity +capacityIncrement(增加因子);若是將來肯定序列的元素不在增長,經過調用trimToSize()調製容量至合適的空間。

 

注意:Vector 在實現List接口的同時,同添加了自身特有的方法xxxElement,將來使用時爲了程序的可拓展性,必定要按照接口來操做Vector。

 

    1. LinkedList

LinkedList是List接口的實現類,底層數據結構是鏈表。

LinekList經常使用方法和遍歷方法參照List接口。

LinkedList 線程不安全。

 

除了實現List接口, 還實現棧接口

push入棧操做 / pop出棧操做

public class Test01 {

     public static void main(String[] args) {

         LinkedList list = new LinkedList();

         list.push("apple");

         list.push("banana");

         list.push("coco");

        

        

         System.out.println(list.pop());

          System.out.println(list.pop());

         System.out.println(list.pop());

        

         // java.util.NoSuchElementException

         System.out.println(list.pop());

     }

}

 

隊列(Queue)接口

 

add/remove/element() 可能會出現NoSuchElementException異常

public static void main(String[] args) {

       

        LinkedList queue = new LinkedList();

        // 入隊

        /**

         * 隊列頭                        隊列尾

         *<-----          <-----

         * [apple, banana, coco]

         */

        queue.add("apple");

        queue.add("banana");

        queue.add("coco");

        System.out.println(queue);

       

        // 出隊

        System.out.println(queue.remove());

        System.out.println(queue.remove());

        System.out.println(queue.remove());    

        System.out.println(queue);

       

        // java.util.NoSuchElementException

        System.out.println(queue.remove());

       

       

        // 獲取表頭元素

        System.out.println(queue.element());

    }

 

offer/poll/peek 可能會返回特殊值(null)

public static void main(String[] args) {

        

         LinkedList queue = new LinkedList();

         // 入隊

         /**

          * 隊列頭                       隊列尾

          *<-----          <-----

          * [apple, banana, coco]

          */

         queue.offer("apple");

         queue.offer("banana");

         queue.offer("coco");

        

         // 出隊列

         //System.out.println(queue.poll());

         //System.out.println(queue.poll());

         //System.out.println(queue.poll());

         System.out.println(queue);

 

         //System.out.println(queue.poll());

        

         // 獲取表頭元素

         System.out.println(queue.peek());

    

     }

 

雙向隊列(Deque)接口

 

/**

 * 以雙向隊列形式操做LinkedList

 */

public class Test04 {

     public static void main(String[] args) {

        

         LinkedList queue = new LinkedList();

         // 入隊

         /**

          *<-----          <-----

          * [apple, banana, coco]

          * ---->          ----->

          */

        

         queue.addFirst("apple");

         queue.addFirst("banana");

         queue.addFirst("coco");

         System.out.println(queue);

        

         System.out.println(queue.removeLast());

         System.out.println(queue.removeFirst());

         System.out.println(queue.removeFirst());

         System.out.println(queue);

        

         // 獲取頭元素

         System.out.println(queue.getFirst());

    

     }

}

 

    1. IteratorListIterator

Iterator在迭代過程當中不容許向集合中添加元素

 

public static void main(String[] args) {

         ArrayList list = new ArrayList();

         list.add("apple");

         list.add("banana");

         list.add("coco");

        

         Iterator it = list.iterator();

         while(it.hasNext()) {

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

              if(item.equals("banana")) {

                   list.add("test");

              }

         }

        

         System.out.println(list);

     }

當經過Iterator集合迭代器遍歷集合過程當中,不能再向集合彙總添加元素,不然出現ConcurrentModificationException 併發修改異常。

 

ListIterator容許程序員按任一方向遍歷列表、迭代期間修改列表,並得到迭代器在列表中的當前位置

public class Test01 {

    public static void main(String[] args) {

        ArrayList list = new ArrayList();

        list.add("apple");

        list.add("banana");

        list.add("coco");

       

        ListIterator it = list.listIterator();

        while(it.hasNext()) {

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

            if(item.equals("banana")) {

                it.add("test");

            }

        }

       

        System.out.println(list);

    }

}

 

熟悉Iterator實現類的源碼hasNext/next

    1. 泛型(generic)
      1. 泛型的概念

泛型容許開發者在強類型程序設計語言(java)編寫代碼時定義一些可變部分,這些部分在使用前必須做出指明。

 

泛型就是將類型參數化

ArrayList<E>  list表示聲明瞭一個列表list,列表的元素是E類型

ArrayList<String> list = new ArrayList<String>();

聲明瞭一個列表list,列表的元素只能是String類型。

 

泛型在編譯器起做用,運行時jvm察覺不到泛型的存在。

 

      1. 泛型的擦除

泛型在運行時已經被擦除了。

 

public static void main(String[] args) {

        ArrayList<String> list = new ArrayList<String>();

        list.add("apple");

        System.out.println(list instanceof ArrayList);

        System.out.println(list instanceof ArrayList<String>);

}

Cannot perform instanceof check against parameterized type ArrayList<String>. Use the form ArrayList<?> instead since further generic type information will be erased at runtime

 

      1. 泛型的應用
        1. 泛型類

當一個類中屬性的數據類型不肯定時,具體是什麼類型由使用者來肯定時,使用泛型。泛型類的形式

public class 類名<T> {

    

}

 

定義一個泛型類

public class FanClass<T> {

     private T t;

 

     public T getT() {

         return t;

     }

 

     public void setT(T t) {

         this.t = t;

     }

 

     public FanClass(T t) {

         super();

         this.t = t;

     }

 

     public FanClass() {

         super();

     }

}

 

public class Test01 {

     public static void main(String[] args) {

         FanClass<String> fan = new FanClass<String>();

         fan.setT("apple");

        

         FanClass<Integer> fan2 = new FanClass<Integer>();

         fan2.setT(1);

     }

}

 

 

        1. 泛型方法

當一個方法的參數類型不肯定時,具體是什麼類型由使用者來肯定,能夠考慮使用泛型方法。形式:

public <T> void xxx(T a) {

    System.out.println(a);

}

 

public class Student {

    

    

     /*public void showInfo(int a) {

         System.out.println(a);

     }

    

     public void showInfo(float a) {

         System.out.println(a);

     }

    

     public void showInfo(String a) {

         System.out.println(a);

     }*/

    

     public <T> void showInfo(T a) {

         System.out.println(a);

     }

}

 

public static void main(String[] args) {

        

         Student stu = new Student();

         stu.showInfo(1);

         stu.showInfo("apple");

         stu.showInfo(1.0f);

     }

 

泛型方法在調用時肯定(指明)類型。

泛型方法在必定程度上優化了方法重載。

 

泛型方法能夠定義多個泛型類型

// 能夠定義多個泛型的類型

    public <A,B> void showInfo(A a,B b) {

        System.out.println(a);

        System.out.println(b);

    }

多個泛型類型進一步優化了方法重載。

 

多個同類型的泛型

// 多個同類型的泛型

     /*public <A> void print(A a) {

          System.out.println(a);

     }

     public <A> void print(A a,A b) {

         System.out.println(a);

         System.out.println(b);

     }*/

    

     public <A> void print(A...a) {

         System.out.println(a);

     }

 

A… a 表示方法能夠接受多個參數。當調用方法傳遞多個參數時,多個參數被放到a數組中,a是什麼類型的數組由開發者調用處傳參決定。

stu.print(1);

stu.print(1,2);

        

stu.print("apple");

stu.print("apple","banana");

print(A...a) 方法稱爲可變參數的泛型形式。

 

        1. 泛型接口(C

若是接口中的方法的參數(形參、返回值)不肯定時,能夠考慮使用泛型接口。形式

public interface FanInterface<T> {

    public void showInfo(T t);

}

 

[1]實現類能肯定泛型接口的類型

public class ImplClass implements FanInterface<String>{

 

     @Override

     public void showInfo(String t) {

         // TODO Auto-generated method stub

        

     }

}

 

[2]實現類不能肯定泛型接口的類型->繼續泛。

public class ImplClass2<T> implements FanInterface<T>{

 

     @Override

     public void showInfo(T t) {

        

     }

}

 

        1. 泛型的上限和下限 (C)

public static void print(ArrayList<? extends Pet> list) {

        for (Pet pet : list) {

            pet.showInfo();

        }

    }

 

泛型的上限ArrayList(? extends Pet) list 聲明瞭一個容器,容器中的元素類型必定要繼承於Pet,咱們稱這種形式叫作泛型的上限。

 

泛型的下限ArrayList(? super Pet) list 聲明瞭一個容器,容器中的元素類型必定要是Pet的父類,咱們稱這個形式爲泛型的下限。

 

    1. Set接口

Set接口表示一個惟1、無序的容器(和添加順序無關)

 

      1. Set接口提供的方法

public static void main(String[] args) {

         /**

          * :add/addAll

          * :clear/remove/removeAll/retainAll

          * :

          * :contains/containsAll

          * 遍歷:iterator

          * 其餘:size/isEmpty

          */

        

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

         // [1]添加

         // 無序

         set.add(10);

         set.add(3);

         set.add(20);

         set.add(0);

         // 不能添加劇復元素

         boolean r = set.add(1);

         System.out.println(set);

        

         // 2】刪除

//       set.remove(1);

//       set.clear();

//       System.out.println(set);

        

         // 3】查看是否包含

         System.out.println(set.contains(1));

        

         // 4】其餘

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

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

     }

 

      1. Set接口的遍歷

public static void main(String[] args) {

        

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

         set.add("banana");

         set.add("apple");

         set.add("coco");

        

         // 快速遍歷

         for (String item : set) {

              System.out.println(item);

         }

        

         // 迭代器

         Iterator<String> it = set.iterator();

         while(it.hasNext()) {

              String item = it.next();

              System.out.println(item);

         }

     }

 

 

Set接口的實現類常見的有HashSet、LinkedHashSet、TreeSet

 

    1. HashSet

HashSet是Set接口的實現類,底層數據結構是哈希表。

HashSet是線程不安全的(不保證同步)

 

  1. 添加自定義對象

根據哈希表的工做原理,請存儲一個自定義對象到HashSet中。

package cn.sxt03.hashset;

 

public class Student {

     private String id;

     private String name;

     private int age;

 

     // …

    

 

     @Override

     public int hashCode() {

         final int prime = 31;

         int result = 1;

         result = prime * result + age;

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

         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;

         Student other = (Student) obj;

         if (age != other.age)

              return false;

         if (id == null) {

              if (other.id != null)

                   return false;

         } else if (!id.equals(other.id))

              return false;

         if (name == null) {

              if (other.name != null)

                   return false;

         } else if (!name.equals(other.name))

              return false;

         return true;

     }

 

     @Override

     public String toString() {

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

     }

 

}

 

 

總結

[1]若是向HashSet中存儲元素時,元素必定要實現hashCode方法和equals方法。

[2] 優勢:添加、刪除、查詢效率高;缺點:無序

 

 

    1. LinkedHashSet

LinkedHashSet是Set接口的實現類,底層數據結構哈希表+鏈表

哈希表用於散列元素;鏈表用於維持添加順序。

 

若是要添加自定義對象元素,也須要重寫hashCode和equals方法。

 

    1. TreeSet

TreeSet 是Set接口的實現類,底層數據結構是二叉樹。

TreeSet 存儲的數據按照必定的規則存儲。存儲規則讓數據表現出天然順序。

 

      1. TreeSet工做原理

 

添加一個新元素t的存儲的步驟

[1] 若是集合無元素,t直接加入;若是集合有元素,t和根節點比較;

[2] 若是t小於根節點;把t放到根節點的左子樹上;重複1-3步驟

[3] t大於根節點;把t放到根節點的右子樹上;重複1-3步驟

 

輸出時按照必定的規則:左子樹->根節點->右子樹

 

根據TreeSet的工做原理,向TreeSet添加自定義元素?

向TreeSet中添加元素時,必定要提供比較策略,不然會出現ClassCastException。

 

比較策略分兩種:內部比較器和外部比較器

 

      1. 內部比較器

當一個自定義對象實現Comparable並實現compareTo方法時,經過指定具體的比較策略,此時稱爲內部比較器。

package cn.sxt05.treeset;

 

public class Student implements Comparable<Student>{

    private String id;

    private String name;

    private int age;

 

    // 。。。

 

    @Override

    public String toString() {

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

    }

 

    @Override

    public int compareTo(Student o) {

        if(this.getAge()<o.getAge()) {

            return -1;

        }else if(this.getAge() == o.getAge()) {

            return 0;

        }else {

            return 1;

        }

    }

 

}

 

 

比較策略的幾種狀況

[1]比較策略通常當前對象寫在前面,待比較對象也在後面,比較結果默認升序

return  this.getAge() - o.getAge() ;

若是想要降序,改變兩個比較對象的位置便可。

 

[2] 多種比較因素

     @Override

     public int compareTo(Student o) {

         /*if(this.getAge()<o.getAge()) {

              return -1;

         }else if(this.getAge() == o.getAge()) {

              return 0;

         }else {

              return 1;

         }*/

        

         // return  this.getAge() - o.getAge() ;

        

         if(this.getAge()<o.getAge()) {

              return -1;

         }else if(this.getAge() == o.getAge()) {

              return this.getName().compareTo(o.getName());

         }else {

              return 1;

         }

     }

 

      1. 外部比較器

當實際開發過程當中不知道添加元素的源代碼、無權修改別人的代碼,此時能夠使用外部比較器。

 

Comparator 位於java.util包中,定義了compare(o1,o2) 用於提供外部比較策略。

TreeSet接受一個指定比較策略的構造方法,這些比較策略的實現類必須實現Comparator

接口。

 

需求:按照字符串的長度比較

public class Test01 {

    public static void main(String[] args) {

       

        LenComparator lenComparator = new LenComparator();

        TreeSet<String> set2 = new TreeSet<String>(lenComparator);

       

        set2.add("banana");

        set2.add("coco");

        set2.add("apple");

       

        set2.add("apple");

        System.out.println(set2);

       

    }

}

 

class LenComparator implements Comparator<String>{

 

    @Override

    public int compare(String o1, String o2) {

        return o1.length() - o2.length();

    }  

}

 

使用匿名內部類優化

public class Test02 {

     public static void main(String[] args) {

        

         TreeSet<String> set2 = new TreeSet<String>(new Comparator<String>() {

 

              @Override

              public int compare(String o1, String o2) {

                   return o1.length() - o2.length();

              }

             

         });

        

         set2.add("banana");

         set2.add("coco");

         set2.add("apple");

        

         set2.add("apple");

         System.out.println(set2);

         

     }

}

 

    1. Map接口

Map接口稱爲鍵值對集合或者映射集合,其中的元素(entry)是以鍵值對(key-value)的形式存在。

Map 容器接口中提供了增、刪、改、查的方式對集合進行操做。

Map接口中都是經過key來操做鍵值對,通常key是已知。經過key獲取value。

      1. map經常使用方法

public static void main(String[] args) {

        

         /**

          * :put/putAll

          * :clear/remove

          * :put

          * :get/containsKey/containsValue

          * 其餘:isEmpty/size

          */

        

         Map<String, String> map = new HashMap<String,String>();

        

         // 1put

         map.put("A", "apple");

         map.put("B", "banana");

         map.put("C", "coco");

        

         // 2】刪除

         // map.clear();

         // smap.remove("A");

        

         // 3】修改

         //map.put("A", "apple x");

        

         // 4】查看

         String val = map.get("A");

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

        

        

         System.out.println(map);

     }

 

      1. map接口的遍歷

 

經過keySet() 返回map中鍵的set集合。

public static void main(String[] args) {

 

         Map<String, String> map = new HashMap<String,String>();

        

         map.put("B", "banana");

         map.put("A", "apple");

         map.put("C", "coco");

         // map無序

         // 能夠根據key的天然順序 map有序  => 通常用string做爲key

         System.out.println(map);

        

        

         // 遍歷

         Set<String> keys = map.keySet();

         for (String key : keys) {

              System.out.println(key+"=>"+map.get(key));

         }

        

         Iterator<String> it = keys.iterator();

         while(it.hasNext()) {

              String key = it.next();

              System.out.println(key+"=>"+map.get(key));

         }

     }

 

map中以鍵值對做爲元素,鍵值對在map中稱爲entry,entrySet返回鍵值對的set集合。

public static void main(String[] args) {

 

         Map<String, String> map = new HashMap<String,String>();

        

         map.put("B", "banana");

         map.put("A", "apple");

         map.put("C", "coco");

         // map無序

         // 能夠根據key的天然順序 map有序  => 通常用string做爲key

         System.out.println(map);

        

         // entrySet

         Set<Entry<String, String>> entrySet = map.entrySet();

         for (Entry<String, String> entry : entrySet) {

              System.out.println(entry.getKey()+"=>"+entry.getValue());

         }

        

         Iterator<Entry<String, String>> it2 = entrySet.iterator();

         while(it2.hasNext()) {

              Entry<String, String> entry = it2.next();

              System.out.println(entry.getKey()+"=>"+entry.getValue());

         }

     }

 

Map接口的實現類HashMap、LinkedHashMap、TreeMap

 

    1. HashMap

HashMap 是Map的實現類,key以HashSet存儲。

 

public static void main(String[] args) {

        

         /*

         HashMap<String, Object> map = new HashMap<String,Object>();

        

         ArrayList<String> list1 = new ArrayList<String>();

         list1.add("alex");

         list1.add("alice");

         list1.add("allen");

         map.put("A", list1);

        

        

         ArrayList<String> list2 = new ArrayList<String>();

         list2.add("ben");

         list2.add("bill");

         map.put("B", list2);

        

         System.out.println(map);

         */

        

        

         HashMap<Student, Object> map = new HashMap<Student,Object>();

        

         ArrayList<String> list1 = new ArrayList<String>();

         list1.add("alex");

         list1.add("alice");

         list1.add("allen");

         Student s1 = new Student("001", "大狗", 20);

         map.put(s1, list1);

        

        

         ArrayList<String> list2 = new ArrayList<String>();

         list2.add("ben");

         list2.add("bill");

         Student s2 = new Student("001", "大狗", 20);

         // 修改

         map.put(s2, list2);

         System.out.println(map);

        

     }

 

總結:

[1] 向HashMap中存儲元素時,key必定要實現hashCode和equals

[2] 通常建議使用String做爲Map接口的key

 

    1. LinkedHashMap

LinkedHashMap是Map接口的實現類,key以LinkedHashSet存儲。

哈希表散列key,鏈表維持key的添加順序。

 

public static void main(String[] args) {

        

        

         /*LinkedHashMap<String, Object> map = new LinkedHashMap<String,Object>();

        

         ArrayList<String> list2 = new ArrayList<String>();

         list2.add("ben");

         list2.add("bill");

         map.put("B", list2);

        

         ArrayList<String> list1 = new ArrayList<String>();

         list1.add("alex");

         list1.add("alice");

         list1.add("allen");

         map.put("A", list1);

        

         System.out.println(map);*/

        

        

        

         HashMap<Student, Object> map = new HashMap<Student,Object>();

        

         ArrayList<String> list1 = new ArrayList<String>();

         list1.add("alex");

         list1.add("alice");

         list1.add("allen");

         Student s1 = new Student("001", "大狗", 20);

         map.put(s1, list1);

        

        

         ArrayList<String> list2 = new ArrayList<String>();

         list2.add("ben");

         list2.add("bill");

         Student s2 = new Student("001", "大狗", 20);

         // 修改

         map.put(s2, list2);

         System.out.println(map);

        

     }

 

 

    1. TreeMap

TreeMap是Map的實現類,key以TreeSet存儲。

 

public static void main(String[] args) {

        

        

         /*TreeMap<String, Object> map = new TreeMap<String,Object>(new Comparator<String>() {

 

              @Override

              public int compare(String o1, String o2) {

                   return o1.length() - o2.length();

              }

         });

        

         ArrayList<String> list2 = new ArrayList<String>();

         list2.add("ben");

         list2.add("bill");

         map.put("Aa", list2);

        

         ArrayList<String> list1 = new ArrayList<String>();

         list1.add("alex");

         list1.add("alice");

         list1.add("allen");

         map.put("B", list1);

        

         System.out.println(map);*/

        

         

        

         TreeMap<Student, Object> map = new TreeMap<Student,Object>(new Comparator<Student>() {

 

              @Override

              public int compare(Student o1, Student o2) {

                   return o1.getAge() - o2.getAge();

              }

         });

        

         ArrayList<String> list1 = new ArrayList<String>();

         list1.add("alex");

         list1.add("alice");

         list1.add("allen");

         Student s1 = new Student("001", "大狗", 20);

         map.put(s1, list1);

        

        

         ArrayList<String> list2 = new ArrayList<String>();

         list2.add("ben");

         list2.add("bill");

         Student s2 = new Student("001", "2", 20);

         // 修改

         map.put(s2, list2);

         System.out.println(map);

        

     }

 總結

 

相關文章
相關標籤/搜索