Java基礎(十一)

2018-03-02 08:31:47來源:cnblogs.com作者:ZT1994人點擊

分享

一、集合框架

1、集合框架定義

  集合框架是一個用來代表和操縱集合的統一架構。所有的集合框架都包含如下內容:

  • 接口:是代表集合的抽象數據類型。接口允許集合獨立操縱其代表的細節。在面向對象的語言,接口通常形成一個層次。
  • 實現(類):是集合接口的具體實現。從本質上講,它們是可重復使用的數據結構。
  • 算法:是實現集合接口的對象里的方法執行的一些有用的計算,例如:搜索和排序。這些算法被稱為多態,那是因為相同的方法可以在相似的接口上有著不同的實現。

除了集合,該框架也定義了幾個Map接口和類。Map里存儲的是鍵/值對。盡管Map不是collections,但是它們完全整合在集合中。

二、List 接口

1、ArrayList 的使用

ArrayList 是一個集合容器類。

1、ArrayList 的構造方法

2、 ArrayList 方法

  測試ArrayList:

 1 import org.junit.Test; 2  3 import java.util.ArrayList; 4 import java.util.Iterator; 5 import java.util.ListIterator; 6  7 public class ArrayListTest { 8  9     /**10      * 測試ArrayList11      */12     @Test13     public void test() {14         ArrayList<Object> list = new ArrayList<>();15 16         list.add("test1");17         list.add("test2");18         list.add("test3");19         list.add("test4");20 21         list.add(1, "test5"); //插入 1 是索引22         System.out.println(list);  //[test1, test5, test2, test3, test4]  打印出值,因為ArrayList覆寫了 toString方法23         System.out.println("size:" + list.size());  //size:524 25         //遍歷ArrayList 1、普通for循環26         for (int i = 0; i < list.size(); i++) {27             System.out.println(" list = " + list.get(i));28         }29         System.out.println("=======");30         for (Object o : list) {  //2、增強for循環31             System.out.println(" list = " + o);32         }33         System.out.println("=======");34         //3.迭代器遍歷ArrayList35         Iterator<Object> iterator = list.iterator();36         while (iterator.hasNext()) {37             System.out.println(" list = " + iterator.next());38         }39         System.out.println("=======");40         //ListIterator迭代41         ListIterator<Object> listIterator = list.listIterator();42         while (listIterator.hasNext()) {43             System.out.println(" list = " + listIterator.next());44         }45         System.out.println("=======");46         while (listIterator.hasPrevious()) {47             //反向打印,順序相反48             System.out.println(" list = " + listIterator.previous());49         }50     }51 }

2、LinkedList 使用

  基于鏈表結構的集合 LinkedList。LinkedList 屬于 java.util 包下面,也實現Iterable接口,說明可以使用迭代器遍歷;LinkedList 還實現 Deque<E>,Queue<E> 操作。Deque 和 Queue 是 LinkedList 的父接口,那么 LinkedList 也可以看成一種 Deque 或者 Queue;Queue表示一種隊列,也是一種數據結構,它的特點是先進先出,因此在隊列這個接口里面提供了一些操作隊列的方法,同時LinkedList也具有這些方法;Deque(Double ended queues雙端隊列),支持在兩端插入或者移除元素; 那也應該具有操作雙端隊列的一些方法;LinkedList 是他們的子類,說明都具有他們兩者的方法;LinkedList也可以充當隊列,雙端隊列,堆棧多個角色。

1、 LinkedList 構造方法

2、 LinkedList 方法

  測試 LinkedList:

 1 import org.junit.Test; 2  3 import java.util.LinkedList; 4  5 public class LinkedListTest { 6  7     /** 8     * 測試LinkedList 9      ArrayList : 基于數組,可以重復,有索引,記錄添加順序(有序), 查找比較快;10      LinkedList: 基于鏈表,可以重復,有索引,記錄添加順序(有序),添加刪除比較快;多了一些操作頭尾的方法,可以充當堆棧,隊列;11     */12     @Test13     public void test(){14         LinkedList<Object> linkedList = new LinkedList<>();15         linkedList.add("11");16         linkedList.add("22");17         linkedList.add("33");18         linkedList.add("44");19 20         System.out.println(linkedList);21         //遍歷LinkedList22         for (int i = 0; i < linkedList.size(); i++) {23             System.out.println(linkedList.pop());24         }25         System.out.println(linkedList);26     }27 }

 3、 ArrayList 和 LinkedList 的區別

  ArrayList 和 LinkedList 都是線程不安全的。

  ArrayList 是 List 接口的一種實現,它是使用數組來實現的,即使用數組方式存儲。

  LinkedList 是 List 接口的一種實現,它是使用鏈表來實現的,即使用雙向鏈表實現存儲。

  ArrayList 遍歷和查找元素比較快。LinkedList 遍歷和查找元素比較慢。

  ArrayList 添加、刪除元素比較慢。LinkedList 添加、刪除元素比較快。

三、set 接口

1、HashSet

   不能添加重復的元素,并且是無序的。

  HashSet判斷是否相同的規則: ①判斷hashcode    ②判斷equals ,如果兩個對象的hashCode值相等,并且equals返回為true 就表示相等(重復)。

 1 import org.junit.Test; 2  3 import java.util.HashSet; 4  5 public class HashSetTest { 6     /** 7      * 測試HashSet 8      * 如果兩個對象的hashCode值相等,并且equals返回為true 就表示相等(重復). 9      */10     @Test11     public void testHashSet() {12         HashSet<Object> hashSet = new HashSet<>();13         hashSet.add("11");14         hashSet.add("55");15         hashSet.add("22");16         hashSet.add("33");17         hashSet.add("44");18         hashSet.add("22");19 20         System.out.println(hashSet);  //[11, 55, 22, 33, 44] 和添加順序不一樣21 22     }23 24     /**25      * 測試HashSet126      * HashSet特點:27      * ①不能添加重復元素,(通過調用對象的hashcode和equals);28      * ②無序(添加順序,和打印出來的順序并不相同);29      * <p>30      * 區別31      * HashSet :通過hashcode和equals判斷重復;32      * TreeSet : 判斷重復33      * ①使用元素的自然排序,(Comparable接口,使用其中的compareTo方法,返回0,表示相等,compareTo里面的參數只有一個);34      * ②使用比較器Comparator接口,其中的方法compare(Object o1,Object o2)返回0,表示相等35      */36     @Test37     public void testHashSet1() {38         HashSet set = new HashSet();39         Student s1 = new Student("悟空", 500);40         Student s2 = new Student("悟空", 500);41         set.add(s1);42         set.add(s2);43 44         System.out.println(set);  //[Student{name='悟空', age=500}]45     }46 }

  自定義類 Student :

 1 public class Student { 2     private String name; 3     private Integer age; 4  5     public Student(String name, Integer age) { 6         this.name = name; 7         this.age = age; 8     } 9 10     public String getName() {11         return name;12     }13 14     public void setName(String name) {15         this.name = name;16     }17 18     public Integer getAge() {19         return age;20     }21 22     public void setAge(Integer age) {23         this.age = age;24     }25 26 27     /**28      * 假設傳入的對象也是student,根據業務對象的字段進行比較29      *30      * @param o31      * @return32      */33     @Override34     public boolean equals(Object o) {35         if (this == o) return true;36         if (o == null || getClass() != o.getClass()) return false;37 38         Student student = (Student) o;39 40         if (this.name.equals(student.getName()) && this.age == student.getAge()) {41             return true;42         } else {43             return false;44         }45     }46 47     @Override48     public int hashCode() {49         int result = name != null ? name.hashCode() : 0;50         result = 31 * result + (age != null ? age.hashCode() : 0);51         return result;52     }53 54     @Override55     public String toString() {56         return "Student{" +57                 "name='" + name + '/'' +58                 ", age=" + age +59                 '}';60     }61 }

2、TreeSet

  TreeSet 和 HashSet 很多方面也是類似的;特點和 HashSet 也是一樣的;

  TreeSet 的特點:不能添加重復元素,無序的(不記錄添加順序)。

2.1 TreeSet 排序

1、自然排序

  自然排序:此接口強行對實現它的每個類的對象進行整體排序,這種排序被稱為類的自然排序。

  可以讓類實現 Comparable 接口,通過 compareTo(Object obj) 方法,如果方法返回 0 表示相等,否則不等。

  實現了 Comparable 接口的 student 類:

 1 public class Student implements Comparable<Student> { 2     private String name; 3     private Integer age; 4  5     public Student(String name, Integer age) { 6         this.name = name; 7         this.age = age; 8     } 9 10     public String getName() {11         return name;12     }13 14     public void setName(String name) {15         this.name = name;16     }17 18     public Integer getAge() {19         return age;20     }21 22     public void setAge(Integer age) {23         this.age = age;24     }25 26 27     /**28      * 假設傳入的對象也是student,根據業務對象的字段進行比較29      *30      * @param o31      * @return32      */33     @Override34     public boolean equals(Object o) {35         if (this == o) return true;36         if (o == null || getClass() != o.getClass()) return false;37 38         Student student = (Student) o;39 40         if (this.name.equals(student.getName()) && this.age == student.getAge()) {41             return true;42         } else {43             return false;44         }45     }46 47     @Override48     public int hashCode() {49         int result = name != null ? name.hashCode() : 0;50         result = 31 * result + (age != null ? age.hashCode() : 0);51         return result;52     }53 54     @Override55     public String toString() {56         return "Student{" +57                 "name='" + name + '/'' +58                 ", age=" + age +59                 '}';60     }61 62 63     /**64      * 覆寫 compareTo65      *66      * @param s67      * @return68      */69     @Override70     public int compareTo(Student s) {71         if (this.age > s.getAge()) {72             return -1;73         } else if (this.age < s.getAge()) {74             return 1;75         } else {76             //return this.name.compareTo(s.getName()); 自動比較77             return 0;78         }79     }80 }

2、定制排序

  如果沒有實現 Comparable 接口,需要自定義一個類,實現 Comparator 接口,覆寫比較方法;

  比較器的實現代碼:

 1 import java.util.Comparator; 2  3 /** 4  * 定制排序 5  */ 6 public class StudentComparator implements Comparator { 7     @Override 8     public int compare(Object o1, Object o2) { 9         Student s1 = (Student)o1;10         Student s2 = (Student)o2;11         if (s1.getAge() > s2.getAge()){12             return 1;13         }else if(s1.getAge() < s2.getAge()){14             return -1;15         }else {16             return 0;17         }18     }19 }

3、TreeSet 自然排序和定制排序的區別

  一般來說,先寫一個比較規則,讓它實現 Comparable 接口,作為默認的比較規則,如果不寫比較器,則比較使用默認規則,如果覺得默認比較規則不夠好,可以自己寫個比較器,當通過存在默認比較規則和比較器時,優先選擇使用比較器,因為比較器更能滿足需求。

  測試TreeSet:

 1 import org.junit.Test; 2  3 import java.util.TreeSet; 4  5 public class TreeSetTest { 6  7     /** 8      * 測試TreeSet 9      */10     @Test11     public void testTreeSet() {12         TreeSet<Object> treeSet = new TreeSet<>();13         treeSet.add("11");14         treeSet.add("33");15         treeSet.add("22");16         treeSet.add("44");17 18         System.out.println(treeSet);  //[11, 22, 33, 44]19     }20 21     @Test22     public void testTreeSet2() {23         TreeSet<Object> treeSet = new TreeSet<>();24         Student student1 = new Student("張", 8);25         Student student2 = new Student("張", 10);26         Student student3 = new Student("張", 7);27         Student student5 = new Student("張", 9);28         Student student4 = new Student("張", 11);29         treeSet.add(student3);30         treeSet.add(student4);31         treeSet.add(student2);32         treeSet.add(student1);33         treeSet.add(student5);34 35         System.out.println(treeSet);36     }37 38 39     /**40      * 測試比較器TreeSet41      */42     @Test43     public void testTreeSet3() {44         TreeSet<Object> treeSet = new TreeSet<>(new StudentComparator()); //優先選擇比較器,如果選默認的,就不能滿足要求呢;45         Student student1 = new Student("張", 8);46         Student student2 = new Student("張", 10);47         Student student3 = new Student("張", 7);48         Student student5 = new Student("張", 9);49         Student student4 = new Student("張", 11);50         treeSet.add(student3);51         treeSet.add(student4);52         treeSet.add(student2);53         treeSet.add(student1);54         treeSet.add(student5);55 56         System.out.println(treeSet);  57     }58 }

3、HashSet 和 TreeSet 總結

  HashSet特點:不重復,無序(通過 hashCode 方法和equals 方法,判斷重復)。

  TreeSet 特點:不重復,無序(添加順序與打印順序不一樣),但是打印順序按照一定規則排序;排序有自然排序和定制排序。

四、Map 接口

  Map 簡單理解成映射;

  Map:將鍵映射到值的對象。一個映射不能包含重復的鍵;每個鍵最多只能包含一個值。

1、hashMap

1、hashMap 的構造方法

2、hashMap 的方法

3、測試 hashMap

  具體測試代碼:

 1 import org.junit.Test; 2  3 import java.util.*; 4  5 public class HashMapTest { 6     /** 7      * Map是什么? 8      * 簡單理解成是映射; 9      * 判斷重復的標準和HashSet一致,通過鍵的hashCode和equals;10      * 測試hashMap11      */12     @Test13     public void testHashMap() {14         Map<Object, Object> hashMap = new HashMap<>();15         hashMap.put("key1", "test1");  //存值16         hashMap.put("key2", "test2");17         hashMap.put("key2", "test3");18 19         System.out.println(hashMap);  //{key1=test1, key2=test3} 一個鍵只能有一個值,后面的值覆蓋了前面的值20         System.out.println(hashMap.get("key1")); //取值 test121         System.out.println(hashMap.containsKey("key")); //判斷是否包含這個鍵 false22         System.out.println(hashMap.containsValue("test"));  //判斷是否包含著個值 false23 24         Map<Object, Object> hashMap1 = new HashMap<>();25         hashMap1.put("key3", "test3");26         hashMap1.put("key4", "test4");27         System.out.println(hashMap1);  //{key3=test3, key4=test4}28 29         hashMap.putAll(hashMap1); //將hashMap1的所有映射關系復制到hashMap30         System.out.println(hashMap);  //{key1=test1, key2=test3, key3=test3, key4=test4}31         System.out.println(hashMap.size());  // 432 33         //遍歷方法一:獲取所有映射34         Set<Map.Entry<Object, Object>> entrySet = hashMap.entrySet();35         for (Map.Entry<Object, Object> entry : entrySet) {36             System.out.println("entry ==[" + entry);37         }38 39         //遍歷方法二:獲取所有鍵的集合40         Set<Object> keySet = hashMap.keySet();41         for (Object o1 : keySet) {42             //通過鍵返回值43             System.out.println("key = [" + o1 + "] ---> value = " + "[" + hashMap.get(o1) + "]" );44 45         }46     }47 }

2、Map小結

  HashMap 是一個散列表,它存儲的內容是鍵值對(key-value)映射。該類實現了Map 接口,根據鍵的 HashCode 值存儲數據,具有很快的訪問速度,最多允許一條記錄的鍵為null,不支持線程同步

  Map接口

  HashMap 判斷重復的標準和HashSet一致,通過鍵的 hashCode 和 equals;

  TreeMap  判斷重復的標準和TreeSet一致,1:通過自然排序(Comparable 接口),2:定制排序(Compartor 比較器)。

五、集合算法 Collections

  完全由在 collection 上進行操作或返回 collection 的靜態方法組成。它包含在 collection 上操作的多態算法,即“包裝器”,包裝器返回由指定 collection 支持的新 collection,以及少數其他內容。例如:搜索和排序。

1、Collections 的方法

  上面是 Collections 類的一些常用方法,具體所有方法,可以自己查看API文檔。

   測試 Collections 的一些常用方法:

 1 import org.junit.Test; 2  3 import java.util.ArrayList; 4 import java.util.Collections; 5 import java.util.List; 6  7 /** 8  * 測試collections 9  */10 public class CollectionsTest {11     @Test12     public void testCollections(){13         List list = new ArrayList();14 15         //addAll 將所有指定元素添加到指定 collection 中。16         Collections.addAll(list, 123, 456, false, null, "2333");17         System.out.println(list); //[123, 456, false, null, 2333]18 19         List list2 = new ArrayList();20         Collections.addAll(list2, 1, 1, 1, 1, 1, 2222222, 333333, "444444");21         Collections.copy(list2, list);  //復制22         System.out.println(list2);  //[123, 456, false, null, 2333, 2222222, 333333, 444444]23 24         List list3 = new ArrayList();25         for (int i =0; i<10; i++){26             list3.add(i);27         }28         System.out.println("list3 "+ list3);  //list3 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]29         Collections.shuffle(list3);  //亂序30         System.out.println("list3 " + list3);  //list3 [4, 1, 9, 7, 2, 6, 3, 8, 0, 5]31 32         System.out.println(Collections.max(list3));  //數組中最大值 933         Collections.sort(list3); //排序34         System.out.println(list3);  //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]35 36         Collections.fill(list3, 2);  // fill 使用指定元素替換指定列表中的所有元素。37         System.out.println(list3);  //[2, 2, 2, 2, 2, 2, 2, 2, 2, 2]38     }39 }

六、集合框架總結

1、List,Set,還有它們下面的子類都可以看成容器,都實現了超級的接口Collection;(查看API文檔)

  List,Set 和Collection之間的關系是繼承關系,因為接口與接口之后,只能是繼承的關系。

2、ArrayList,LinkedList,HashSet,TreeSet 四個容器類的特點:

  ArrayList:實現 List 接口,基于數組,可以重復,有索引,記錄添加順序,即有序,查找比較快。

  LinkedList:實現 List 接口,基于鏈表,可以重復,有索引,記錄添加順序,即有序,添加刪除比較快,多了一些操作頭尾的方法,可以充當堆棧,隊列。

  HashSet:實現 Set 接口,不重復,無序(通過 hashCode 方法和equals 方法,判斷重復)。

  TreeSet:實現 Set 接口,不重復,無序(添加順序與打印順序不一樣),但是打印順序按照一定規則排序;排序有自然排序和定制排序。①使用元素的自然排序,(Comparable 接口,使用其中的 compareTo 方法,返回0,表示相等,compareTo  里面的參數只有一個);②使用比較器 Comparator 接口,其中的方法 compare(Object o1,Object o2)返回0,表示相等。

3、Comparable 和 Comparator 的區別:

  Comparable 是一個比較的標準,里面有比較的方法,對象要具有比較的標準,就必須實現 Comparable 接口;類實現這個接口,就有比較的方法;把元素放到 TreeSet 里面去,就會自動的調用 CompareTo 方法;但是這個 Comparable  并不是專為 TreeSet 設計的;只是說,TreeSet 順便利用而已;就像 HashCode 和 equals  也一樣,不是專門為 HashSet 設計一樣;只是你順便利用而已。

  Compartor 是個比較器,也不是專門為TreeSet設計. 就是一個第三方的比較器接口;如果對象沒有比較性,自己就可以按照比較器的標準,設計一個比較器,創建一個類,實現這個接口,覆寫方法。

4、HashMap,TreeMap的特點:

  HashMap:實現 Map 接口,是一個散列表,它存儲的內容是鍵值對(key-value)映射。根據鍵的 HashCode 值存儲數據,具有很快的訪問速度,最多允許一條記錄的鍵為null,不支持線程同步。判斷重復的標準和 HashSet 一致,通過鍵的 hashCode 和 equals。

  TreeMap:實現 Map 接口,判斷重復的標準和TreeSet一致,1:通過自然排序(Comparable 接口),2:定制排序(Compartor 比較器)。

相關文章

    無相關信息

微信掃一掃

第七城市微信公眾平臺
捕鱼达人小游戏