国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

黑馬程序員----java基礎--集合

2019-11-15 01:06:23
字體:
來源:轉載
供稿:網友
黑馬程序員----java基礎--集合

------Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! -------

一、集合類的描述

  面向對象語言對事物的體現都是以對象的形式,所以為了方便對多個對象的操作,就對對象進行存儲,集合就是存儲對象最常用的一種方式。數組雖然也可以存儲對象,但長度是固定的;集合長度是可變的。數組中可以存儲基本數據類型,集合只能存儲對象。數組很難對其數據進行操作,而集合可以很方便對存儲的對象進行增刪改查等操作。可以說集合比數組功能更加強大而且使用起來也更加方便。所以我們有必要深入的學習一下集合類。

集合的特點:

(1)、用于存儲對象的容器

(2)、集合的長度是可變的

(3)、集合中不可以存儲基本數據類型值

(4)、集合中存儲的都是對象的引用(地址)

二、集合框架的構成以及分類

根據數據結構的不同,可以分為不同的集合(容器)。下圖是集合框架構成圖。

從途中可以看出集合類主要分為兩大接口:1、Collection接口 2、Map接口。

Collection接口

  |--List集合:元素都是有序的(存入和取出的順序一致),元素是可以重復的,因為該集合體系具有索引。

    |--ArrayList:底層的數據結構使用的是數組結構。特點:查詢速度快,但增刪稍慢,線程不同步。

    |--LinkedList:底層使用的是鏈表數據結構。特點:增刪速度很快,查詢稍慢,線程不同步。

    |--Vector:底層是數組數據結構,線程同步,已被ArrayList替代了,因為效率低。

  |--Set集合:元素是無序的(存入和取出的順序不一定一致),元素不可重復。Set接口中的方法和Collection接口中的方法一致。

    |--HashSet集合:底層數據結構是哈希表,線程不安全,不同步。

      |--LinkedHashSet:底層是鏈式的哈希表,該集合特點:存入數據和取出數據順序一致,而且元素不重復,線程不同步。

    |--TreeSet:底層是二叉樹數據結構,可以對Set集合中的元素進行排序,線程不同步。

Map接口

  |--Hashtable集合:底層是哈希表數據結構,不可以存入null鍵null值,該集合是線程同步的,效率低。JDK1.0出現的。

    |--PRoperties集合:用來存儲鍵值對型的配置文件的信息,可以和IO技術相結合。

  |--HashMap集合:底層是哈希表數據結構,允許使用null鍵null值,該集合是不同步的。該集合替換了Hashtable集合,效率高。JDK1.2出現的。

    |--LinkedHashMap集合:底層是鏈式的哈希表結構,使用LinkedHashMap存入和取出的順序是一致的。

  |--TreeMap集合:底層是二叉樹數據結構,線程不同步。可以用于給Map集合中的鍵進行排序。

Java集合類大部分的都增加了泛型,已增加程序的安全性,以后會詳細的介紹的。了解了集合類的大致下面我們具體的介紹這幾大集合類。

三、Collection<E>接口

Collection是集合框架中的常用接口。其下有兩個子接口:List(列表),Set(集)。

1、Collection集合集成體系:

  |--Lsit

    |--ArrayList

    |--LinkedList

    |--Vector

  |--Set

    |--HashSet

      |--LinkedHashSet

    |--TreeSet

2、Collection接口常見的方法

(1)、添加元素

1 boolean  add(Object obj);//往集合中添加元素2 boolean  addAll(Collection c);//將另一Collection集合中的所有元素添加進Collection集合中

(2)、刪除元素

1 boolean  remove(Object obj);//刪除指定元素2 boolean  removeAll(Collection  con);//調用者只保留另一集合中沒有的元素3 void clear();//清空Collection集合全部元素

(3)、判斷

1 boolean  contains(Object obj);//判斷集合中是否包含指定元素2 boolean  containsAll();//判斷此Collection集合中是否包含另一個Collection集合3 boolean  isEmpty();//判斷集合是否有元素

(4)、獲取

1 int  siez();//獲取集合的大小,其實就是在判斷集合是否為空2 Iterator<E>   iterator();//獲取Collection集合的迭代器

(5)、獲取交集

1 boolean   retainAll(Collection c);//調用者只保留兩集合的共性元素

(6)、集合變數組

1 Object[]   toArray();//把集合轉換成數組2  <T> T[]  toArray(T[] a);//把集合轉換成數組

代碼演示:

 1 import java.util.*; 2 class CollectionDemo  3 { 4     public static void main(String[] args)  5     { 6         //因為Collection是接口無法創建對象,所以找子類來創建對象,多態的應用。 7         Collection<String> c1=new ArrayList<String>(); 8         Collection<String> c2=new ArrayList<String>(); 9         add(c1);        10         addAll(c1,c2);11         remove(c1);12         removeAll(c1,c2);13     }14     //演示add方法15     public static void add(Collection<String> con){16         con.add("小明");17         con.add("趙四");18         con.add("王五");19         con.add("老王");20         con.add("黑馬");21         con.add("安卓");22         //獲取集合的大小23         System.out.println("size="+con.size());24         //打印一下集合25         System.out.println(con);26     }27     //演示addAll方法28     public static void addAll(Collection<String> co1,Collection<String>co2){29         co1.add("小明");30         co1.add("趙四");31         co1.add("王五");32         co1.add("錢峰");33 34         co2.add("黑馬");35         co2.add("趙四");36         co2.add("錢峰");37         //將co2中的元素添加到co1中38         co1.addAll(co2);39         System.out.println("addAll:"+co1);40 41         //獲取兩個集合的交集,保留和指定的集合相同的元素42         co1.retainAll(co2);43         System.out.println("co1和co2取交集:"+co1);44     }45     //演示remove方法46     public static void remove(Collection<String> con){47         con.add("小明");48         con.add("趙四");49         con.add("王五");50         con.add("老王");51         con.add("黑馬");52         con.add("安卓");53         System.out.println(con.remove("老王"));54         System.out.println(con.remove("java"));55         System.out.println("remove:"+con);56 57         //清空集合58         con.clear();        59         //判斷集合是否為空60         System.out.println("con是否為空:"+con.isEmpty());61     }62     //演示removeAll方法63     public static void removeAll(Collection<String> co1,Collection<String>co2){64         co1.add("小明");65         co1.add("趙四");66         co1.add("王五");67         co1.add("老王");68 69         co2.add("老王");70         co2.add("趙四");71         co2.add("錢峰");72         //從co1集合中刪除與co2集合相同的元素73         co1.removeAll(co2);74         System.out.println("removeAll:"+co1);75     }76     77 }

3、Collection集合迭代器:Iterator<E>接口

迭代器:是一個接口。作用:用于取集合中的元素。

  每一個集合都有自己的數據結構,都有特定的取出自己內部元素的方式。為了便于操作所有的容器,取出元素。將容器內部的取出方式按照一個統一的規則向外提供,這個規則就是Iterator接口。也就說,只要通過該接口就可以取出Collection集合中的元素,至于每一個具體的容器依據自己的數據結構,如何實現的具體取出細節,這個不用關心,這樣就降低了取出元素和具體集合的耦合性。

注:在迭代時循環中next調用一次,就要hasNext判斷一次。

獲取Collection集中中元素的三種方式:

 1 import java.util.*; 2 class CollectionDemo  3 { 4     public static void main(String[] args)  5     { 6         //因為Collection是接口無法創建對象,所以找子類來創建對象,多態的應用。 7         Collection<String> c=new ArrayList<String>(); 8         c.add("小明"); 9         c.add("黑馬");10         c.add("安卓");11         c.add("小明");12         c.add("王五");13         //用Collection中的iterator()方法。調用集合中的迭代器方法,是為了獲取集合中的迭代器對象。14         //這種方式比較占用內存,因為循環結束后it變量還在內存中沒有被釋放        15         Iterator<String> it=c.iterator();16         while (it.hasNext())17         {18             String name=it.next();19             System.out.println(name);20         }21         22         //建議使用這種方法,不消耗內存空間,it變量在for循環中,循環結束變量也就消失了23         for (Iterator<String> it=c.iterator();it.hasNext() ; )24         {        //Iterator中不能使用add添加方法,因為沒有該方法,只能刪除(remove)25             System.out.println(it.next());26         }27         28         //這種方式是增強for循環,是Iterator迭代器的簡寫,但是這種方式有很大的弊端29         //如果遍歷Collection集合過程中還需要對元素進行操作,比如刪除,需要使用迭代器。30         for(String name:c){            31             System.out.println(name);32 33         }34 }

迭代注意事項

  (1)、迭代器在Collcection接口中是通用的,它替代了Vector類中的Enumeration(枚舉)。

  (2)、迭代器的next方法是自動向下取元素,要避免出現NoSuchElementException。

  (3)、迭代器的next方法返回值類型是Object,所以要記得類型轉換。加上泛型后則不需要轉換。

四、List<E>集合(接口)

List集合繼承體系:

  |--ArrayList

  |--LinkedList

  |--Vector

  List本身是Collection接口的子接口,具備了Collection的所有方法。現在學習List體系特有的共性方法,查閱方法發現List的特有方法都有索引,這是該集合最大的特點。

凡是可以操作角標的方法都是該體系特有的方法。

1、List集合特有的方法

(1)、添加

1 void  add(int index,E element);//在指定索引位置上添加元素2 void  addAll(int index,Collection<? extends E> c);//在指定索引位置上添加一堆元素

(2)、刪除

1 Object  remove(int index);//刪除指定索引位置上的元素

(3)、修改

1 Object  set(int index, E  element);//對指定索引位進行元素的修改

(4)、獲取

1 Object  get(int index);//獲取指定索引位置上的元素2 int  indexOf(Object obj);//獲取指定元素第一次出現的索引位,如果該元素不存在返回-1;所以通過-1,可以判斷一個元素是否存在。3 int  lastIndexOf(Object obj);//反向索引指定元素的位置。4 List  subList(int from,int to);//獲取子列表,包含頭不包含尾5 Iterator  listIterator();//List集合特有的迭代器6 Iterator  listIterator(int index);//從列表的指定位置開始返回List集合迭代器

注意:對于List集合,底層判斷元素是否相同,其實用的是元素自身的equals方法完成的。所以建議元素都要復寫equals方法,建立元素對象自己的比較相同的條件依據。

代碼演示:

 1 import java.util.*; 2 class ListDemo  3 { 4     public static void main(String[] args)  5     { 6         List<String> list=new ArrayList<String>(); 7         list.add("黑馬"); 8         list.add("安卓"); 9         list.add("小明");10         list.add("王武");11         list.add("安卓");12         System.out.println("list:"+list);13         //在指定位置上添加元素14         list.add(3,"我愛黑馬");15         System.out.println("listadd:"+list);16 17         //刪除指定位置上的元素18         list.remove(4);19         System.out.println("listremove:"+list);20 21         //設置元素        22         System.out.println("listset:"+list.set(2,"我愛安卓"));23 24         //獲取指定位置上的元素25         System.out.println("listget"+list.get(2));26 27         //獲取元素第一次出現的位置。28         System.out.println("indexOf="+list.indexOf("安卓"));29 30         //獲取子列表,包含頭不包含尾31         System.out.println(list.subList(2,4));32     }33     34 }

2、List集合元素取出方式

(1)、List集合第一種取出方式:因為List集合有索引(角標)這個特殊的原因,所以List集合有自己特有的迭代方式,get方法。

 1 import java.util.*; 2 class ListIteratorDemo  3 { 4     public static void main(String[] args)  5     { 6         List<String> list=new ArrayList<String>(); 7         list.add("黑馬"); 8         list.add("安卓"); 9         list.add(".NET");10         list.add("IOS");11         //用集合的長度做循環條件,get方法取出元素12         for (int x=0;x<list.size() ;x++ )13         {            14             System.out.println(list.get(x));15         }16     }17 }

(2)、List集合第二種取出方式:用Collection集合中的iterator()方法,這種方法有弊端只能遍歷的過程中對集合刪除操作。

 1 import java.util.*; 2 class ListIteratorDemo  3 { 4     public static void main(String[] args)  5     { 6         List<String> list=new ArrayList<String>(); 7         list.add("黑馬"); 8         list.add("安卓"); 9         list.add(".NET");10         list.add("IOS");11         //Collection接口中的iterator方法。12         for (Iterator<String> it=list.iterator();it.hasNext() ; )13         {14             String s=it.next();15             if(s.equals("IOS")){16 //                list.add("JAVA");//ConcurrentModificationException異常,出現并發操作。17                 it.remove();//將IOS的引用從集合中刪除了18             }19             System.out.println(s);20         }21 22     }23 }

  在迭代時,不可以通過集合對象的方法操作集合中的元素。因為會發生ConcurrentModificationException異常。Iterator方法是有限的,只能對元素進行判斷,取出,刪除的操作。那么如果想要其他的操作如添加,修改等,該怎么辦呢?這時候就需要使用其子接口ListIterator,該接口只能通過List集合的ListIterator方法獲取。

(3)、List集合取出方式第三種方式:Lsit集合特有迭代器:ListIterator

ListIterator迭代器中的方法:

 1 import java.util.*; 2 class ListIteratorDemo  3 { 4     public static void main(String[] args)  5     { 6         List<String> list=new ArrayList<String>(); 7         list.add("黑馬"); 8         list.add("安卓"); 9         list.add(".NET");10         list.add("IOS");11         //獲取ListIterator迭代器對象12         for (ListIterator<String> li=list.listIterator();li.hasNext() ; )13         {14             //它可以實現在迭代過程中完成對元素的增刪改查。15             //注意:只有list集合具備該迭代功能。16             String s=li.next();17             if(s.equals("IOS"))18                 li.add("JAVA");//增加元素19             if(s.equals(".NET"))20                 li.remove();//刪除元素21             if(s.equals("安卓"))22                 li.set("JAVAEE");//修改元素23         }24         System.out.println(list);25 26     }27 }

五、ArrayList、LinkedList、Vector集合

1、ArrayList集合的方法和List集合的方法差不多一樣。所以可參照List的方法。

2、LinkedList集合

LinkedList集合中特有的方法:

(1)、添加元素

1 addFirst();//將指定元素插入集合元素的開頭2 addLast();//將指定元素插入集合元素的末尾

------JDK1.6版本后新的方法----------------

1 offerFirst();//與addFirst方法沒有區別2 offerLast();//與addLast方法沒有區別

(2)、獲取但不刪除元素

1 //獲取但不刪相互,如果鏈表為空,拋出NoSuchElementException2 E  getFirst();//返回此集合的第一個元素3 E  getLast();//返回此集合的最后一個元素

------JDK1.6版本后新的方法----------------

1 //獲取但不移除,如果鏈表為空,返回null。2 peekFirst();3 peekLast();

(3)、獲取并刪除元素

1 //獲取并移除,如果鏈表為空,拋出NoSuchElementException。2 E   removeFirst();//移除并返回此集合的第一個元素3 E   removeLast();//移除并返回此集合的最后一個元素

------JDK1.6版本后新的方法----------------

1 //獲取并移除,如果鏈表為空,返回null;2 pollFirst();3 pollLast();

  因為LinkedList中有特有的方法removeFirst()或者removeLast()(pollFirst、pollLast),所以LinkedList有4種迭代的方法。一種是:Iterator,一種是:iterator,一種是for循環遍歷get方法,一種是LinkedList特有的方法。

 1 //LinkedList特有取出方式 2 import java.util.*; 3 class LinkedListDemo  4 { 5     public static void main(String[] args)  6     { 7         LinkedList<String> list=new LinkedList<String>(); 8         list.add("黑馬"); 9         list.add("安卓");10         list.add(".NET");11         list.add("IOS");12         while(!(list.isEmpty()))//通過判斷集合是否為空來循環刪除元素,知道為空停止循環13             System.out.println(list.removeFirst());    //獲取元素并且刪除元素    14     }15 }

3、Vector集合

(1)、Vector中特有的方法:

枚舉就是Vector特有的取出方式。發現枚舉和迭代器很像。其實枚舉和迭代是一樣的。因為枚舉的名稱以及方法的名稱都過長。所以被迭代器取代了。

1 //獲取枚舉接口的方法2 Enumeration<E>   elements();//返回此集合的枚舉

而Eumeration枚舉接口中的方法:

1 boolean  hasMoreElements();//相當于Iterator中的hasNext()2 E  nextElement();//相當與Iterator中的next()

另外Collections集合工具類中也提供了Collection集合獲取枚舉接口的方法

1  static Enumeration< T>   enumeratio(Collection<T> c);//返回一個指定 collection 上的枚舉。

代碼演示:

 1 import java.util.*; 2 class VectorDemo  3 { 4     public static void main(String[] args)  5     { 6         Vector<String> v=new Vector<String>(); 7         v.add("黑馬"); 8         v.add("安卓"); 9         v.add("IOS");10         v.add("JAVAEE");11 12         //用Iterator迭代器方法取出元素13         for (Iterator<String> it=v.iterator();it.hasNext() ; )14         {15             System.out.println(it.next());16         }17 18         //用Enumeration枚舉的方法取出元素19         for (Enumeration<String> en=v.elements();en.hasMoreElements() ; )20         {21             System.out.println(en.nextElement());22         }23 24         //Collections.enumeration()方法獲取枚舉Enumeration接口25         for (Enumeration<String> en=Collections.enumeration(v);en.hasMoreElements() ; )26         {27             System.out.println(en.nextElement());28         }29     }30 }

4、List集合綜合練習

(1)、請使用LinkedList來模擬一個堆棧或者隊列數據結構。

  堆棧:先進后出 First In Last Out FILO  隊列:先進先出 First In First Out FIFO

思路:應該自定義一個LinkedList類,把要LinkedList封裝到自己的類中。

 1 import java.util.*; 2 class DuiLie 3 { 4     private LinkedList link; 5     //對象一初始化就創建了LinkedList集合 6     DuiLie(){ 7         link=new LinkedList(); 8     } 9     //隊列的添加元素的功能。10     public void myAdd(Object obj){11         link.addFirst(obj);12     }13     //隊列的刪除元素的功能。14     public Object myRemove(){15         return link.removeLast();16     }17     //判斷隊列是否為空18     public boolean isNull(){19         return link.isEmpty();20     }21 22 }23 class DuiLieDemo24 {25     public static void main(String[] args) 26     {27         DuiLie dl=new DuiLie();28         dl.myAdd("黑馬");29         dl.myAdd("IOS");30         dl.myAdd("安卓");31         dl.myAdd(".NET");32         dl.myAdd("JAVAEE");33         while (!(dl.isNull()))34         {35             System.out.println(dl.myRemove());36         }37 38     }39 }

(2)、將自定義對象作為元素存到ArrayList集合中,并去除重復元素。比如:存人對象,同姓名同年齡,視為同一個人。為重復元素。

 1 /* 2 List集合中必須定義一個新的容器來過濾重復元素. 3 而set集合則不用,因為set集合是無序的,不可重復的。 4 */ 5 import java.util.*; 6 class Person 7 { 8     private String name; 9     private int age;10     Person(String name,int age)11     {12         this.name=name;13         this.age=age;14     }15     public void setName(String name){16         this.name=name;17     }18     public String getName(){19         return name;20     }21     public void setAge(int age){22         this.age=age;23     }24     public int getAge(){25         return age;26     }27     public String toString(){28         return "name="+name+"....."+"age="+age;29     }30     public boolean equals(Object obj){//即使使用了泛型,equals方法中的參數也是Object obj,31         if(!(obj instanceof Person))//因為復寫的Object類中的方法,Object類的equals方法參數就是Object obj。32             throw new RuntimeException("類型轉換異常");33         Person p=(Person)obj;34         return this.name.equals(p.name)&&this.age==p.age;//判斷name和age是否相同35     }36 }37 class ArrayListDemo38 {39     public static void main(String[] args) 40     {41         List<Person> list=new ArrayList<Person>();42         list.add(new Person("黑馬",120));43         list.add(new Person("安卓",110));44         list.add(new Person("IOS",45));45         list.add(new Person(".NET",97));46         list.add(new Person("JVAEE",12));47         list.add(new Person("IOS",45));48         list.add(new Person("黑馬",120));49         //迭代原集合50         printCollection(list);        51         System.out.println("---去除重復元素后的集合---------");52         list=getSingleElement(list);53         printCollection(list);54 55     }56     public static List<Person> getSingleElement(List<Person> list){57         //1、定義一個臨時容器用來裝過濾后的數據58         List<Person> newList=new ArrayList<Person>();59         //2、迭代list集合60         for (Iterator<Person> it=list.iterator();it.hasNext() ;)61         {62             Person p=it.next();63         //3、判斷被迭代到的元素是否在臨時容器存在64         //contains方法內部依靠的是equals方法,其實remove方法也調用equals方法的   65             if(!(newList.contains(p)))66                 newList.add(p);67         }68         return newList;69 70     }71     //迭代器取出集合中的元素72     private static void printCollection(List<Person> list){73         for (Iterator<Person> it=list.iterator();it.hasNext() ; )74         {75             System.out.println(it.next());76         }77     }78 }

六、Set<E>集合(只能用Iterator迭代器取數據)

Set接口中的方法和Collection中方法一致的。Set集合元素不可重復且無序。Set接口取出方式只有一種:迭代器。

Set集合繼承體系

  |--HashSet

    |--LinkedHashSet

  |--TreeSet

 1 import java.util.*; 2 class  SetDemo 3 { 4     public static void main(String[] args)  5     { 6         //Set集合無需并且不可重復,方法和Collection方法一樣 7         Set<String> set=new HashSet<String>(); 8         set.add("黑馬");//添加元素 9         set.add("JAVAEE");10         set.add("安卓");11         set.add("IOS");12         set.add(".NET");13         set.add("JAVAEE");14         set.remove("IOS");//刪除元素15 16         //Iterator迭代器取出元素17         for (Iterator<String> it=set.iterator();it.hasNext() ; )18         {19             System.out.println(it.next());20         }21     }22 }

七、HashSet、LinkedHashSet、TreeSet集合

(1)、HashSet集合

HashSet實現Set接口,由哈希表(實際上是一個HashMap實例)支持。

哈希表確定元素是否相同:因為集合本身不可重復的特點所以不用定義新的Set集合來存放不重復元素。(1)、 先判斷的是兩個元素的哈希值是否相同。如果相同,再判斷兩個對象的內容是否相同。

(2)、 判斷哈希值相同,其實判斷的是對象的HashCode方法。判斷內容相同,用的是equals方法。如果哈希值不同,不需要判斷equals。

判斷HastSet集合中的元素是否相同,一般要復寫對象的hashCode方法和equals方法。

哈希表的原理:

(1)、對對象元素中的關鍵字(對象中的特有數據),進行哈希算法的運算,并得出一個具體的算法值,這個值 稱為哈希值。

(2)、哈希值就是這個元素的位置。

(3)、如果哈希值出現沖突,再次判斷這個關鍵字對應的對象是否相同。如果對象相同,就不存儲,因為元素重復。如果對象不同,就存儲,在原來對象的哈希值基礎 +1順延。

(4)、存儲哈希值的結構,我們稱為哈希表。

(5)、既然哈希表是根據哈希值存儲的,為了提高效率,最好保證對象的關鍵字是唯一的。這樣可以盡量少的判斷關鍵字對應的對象是否相同,提高了哈希表的操作效率。

需求:往HashSet集合中存儲Person對象。如果姓名和年齡相同,視為同一個人,視為相同元素。

 1 /* 2 如果姓名和年齡相同,視為同一個人,視為相同元素 3 */ 4  5 import java.util.*; 6 class Person 7 { 8     private String name; 9     private int age;10     Person(String name,int age)11     {12         this.name=name;13         this.age=age;14     }15     public void setName(String name){16         this.name=name;17     }18     public String getName(){19         return name;20     }21     public void setAge(int age){22         this.age=age;23     }24     public int getAge(){25         return age;26     }27     public String toString(){28         return "name="+name+"....."+"age="+age;29     }30     public int hashCode(){//復寫了hashCode方法31         return name.hashCode()+age*37;32     }33     public boolean equals(Object obj){//即使使用了泛型,equals方法中的參數也是Object obj,34         if(!(obj instanceof Person))//因為復寫的Object類中的方法,Object類的equals方法參數就是Object obj。35             throw new RuntimeException("類型轉換異常");36         Person p=(Person)obj;37         return this.name.equals(p.name)&&this.age==p.age;//建立了自己的比較方式38     }39 }40 class HashSetDemo41 {42     public static void main(String[] args) 43     {44         Set<Person> set=new HashSet<Person>();45         set.add(new Person("黑馬",98));46         set.add(new Person("安卓",76));47         set.add(new Person("IOS",67));48         set.add(new Person(".NET",34));49         set.add(new Person("JAVAEE",21));50         set.add(new Person("IOS",67));51         set.add(new Person("安卓",76));52         for (Iterator<Person> it=set.iterator();it.hasNext() ; )53         {54             System.out.println(it.next());55         }56     }57 }

2、LinkedHashSet集合

LinkedHashSet這個集合不僅存入的順序和取出的順序一致,并且該集合可以自動去除重復元素。

需求:數組去重復,例如: 原始數組是{4,2,4,6,1,2,4,7,8},得到結果{4,2,6,1,7,8}

 1 import java.util.*; 2 class LinkedHashSetDemo 3 { 4     public static void main(String[] args)  5     { 6         int[] arr={4,2,4,6,1,2,4,7,8}; 7         Integer[] in=getSingleElement(arr); 8         for (int x=0;x<in.length ;x++ ) 9         {10             if(x<in.length-1)11                 System.out.print(in[x]+",");12             else13                 System.out.print(in[x]);14         }15 16     }17     public static Integer[] getSingleElement(int[] arr){18         //無序變有序,并且去重19         LinkedHashSet<Integer> lhs=new LinkedHashSet<Integer>();20         for (int x=0;x<arr.length ;x++ )21         {22             lhs.add(arr[x]);23         }24         //集合變成數組返回25         return (Integer[])lhs.toArray(new Integer[lhs.size()]);26     }27 }

3、TreeSet集合

用于對Set集合進行元素的指定順序排序,排序需要依據元素自身具備的比較性。如果元素不具備比較性,在運行時會發生ClassCastException異常。

TreeSet判斷元素唯一性的方式:就是根據比較方法的返回結果是否為0,是0就是相同元素,不存。

TreeSet集合排序的兩種方式:

(1)、TreeSet排序的第一種方式:讓元素自身具備比較性。元素需要實現Comparable接口,覆蓋compareTo(T)方法。也種方式也成為元素的自然順序,或者叫做默認順序。

(2)、TreeSet的第二種排序方式:讓集合具備比較性。當元素自身不具備比較性時,或者具備的比較性不是所需要的。這時就需要讓集合自身具備比較性。在集合初始化時,就有了比較方式。集合需要傳入比較器(Comparator接口),讓集合具備比較行為。定義一個Comparator的子類對象,復寫compare(T o1, T o2)方法。 將該類對象作為參數傳遞給TreeSet集合的構造函數。如果自定義類實現了Comparable接口,并且TreeSet的構造函數中也傳入了比較器,那么將以比較器的比較規則為準。記住,排序時,當主要條件相同時,一定判斷一下次要條件。Comparable<T>、Comparator<T>都帶著泛型的。第二種方式較為靈活。

注:只有TreeSet和TreeMap集合的構造函數能接收Comparator比較器。

需求:往TreeSet集合中存儲Student對象,并按照學生的姓名排序。

第一種方式:讓學生自身具備比較性,實現Comparable接口,復寫compareTo方法

 1 import java.util.*; 2 class Student implements Comparable<Student> 3 { 4     private String name; 5     private int age; 6     Student(String name,int age){ 7         this.name=name; 8         this.age=age; 9     }10     public void setName(String name){11         this.name=name;12     }13     public String getName(){14         return name;15     }16     public void setAge(int age){17         this.age=age;18     }19     public int getAge(){20         return age;21     }22     public String toString(){23         return "name="+name+"....."+"age="+age;24     }25     //復寫Comparable接口的compareTo方法26     public int compareTo(Student stu){27         int num=this.name.compareTo(stu.name);//先按照姓名排序,如果姓名相同然后再按照年齡排序28         if(num==0)29             return new Integer(this.age).compareTo(new Integer(stu.age));//按照年齡排序30         return num;31     }32 }33 class TreeSetDemo 34 {35     public static void main(String[] args) 36     {37         Set<Student> set=new TreeSet<Student>();38         set.add(new Student("黑馬",120));39         set.add(new Student("安卓",43));40         set.add(new Student("IOS",87));41         set.add(new Student(".NET",21));42         set.add(new Student("JAVAEE",12));43         set.add(new Student("php",98));44         set.add(new Student("黑馬",34));45         for (Iterator<Student> it=set.iterator();it.hasNext() ; )46         {47             System.out.println(it.next());48         }49     }50 }

第二種方式:學生自身不具備比較性,這時候就可以定義一個類實現Comparator接口,覆蓋compare(T o1, T o2)方法。

 1 //Student類接上例 2 //實現Comparator接口,復寫compare方法。比較器 3 class StuComparator implements Comparator<Student> 4 { 5     public int compare(Student s1,Student s2){ 6         int num=s1.getAge()-s2.getAge();//先按照年齡排序 7         if(num==0) 8             return s1.getName().compareTo(s2.getName());//年齡相同的再按照姓名排序 9         return num;10     }11 }12 class TreeSetDemo 13 {14     public static void main(String[] args) 15     {16         Set<Student> set=new TreeSet<Student>(new StuComparator());//兩種方式同時存在以比較器為主17         set.add(new Student("黑馬",120));18         set.add(new Student("安卓",43));19         set.add(new Student("IOS",87));20         set.add(new Student(".NET",21));21         set.add(new Student("JAVAEE",12));22         set.add(new Student("PHP",98));23         set.add(new Student("黑馬",34));24         for (Iterator<Student> it=set.iterator();it.hasNext() ; )25         {26             System.out.println(it.next());27         }28     }29 }

練習:對字符串進行長度排序。

 1 import java.util.*; 2 class LenComparator implements Comparator<String> 3 { 4     public int compare(String s1,String s2){ 5         int num=s1.length()-s2.length();//按照長度排序 6         return (num==0)?s1.compareTo(s2):num;//如果長度相同,按照字符串自然排序 7     } 8 } 9 class StringLength 10 {11     public static void main(String[] args) 12     {13         TreeSet<String> ts=new TreeSet<String>(new LenComparator());14         ts.add("aaaa");15         ts.add("zz");16         ts.add("nbag");17         ts.add("cba");18         ts.add("abc");        19         for (Iterator it=ts.iterator();it.hasNext() ; )20         {21             System.out.println(it.next());22         }23 24     }25 }

八、Map<K,V>接口

Map集合該集合存儲鍵值對。一對一對往里存。而且要保證鍵的唯一性。Map也稱為雙列集合;Collection集合稱為單列集合,Collection一次存一個元素。和Set很像,Set底層就是使用了Map集合。

Map集合繼承體系:

  |--Hashable

    |--Properties

  |--HashMap

    |--LinkedHashMap

  |--TreeMap

1、Map集合常用方法

(1)、添加元素

1 Value  put(key,value);//返回前一個和key關聯的值,如果沒有返回null。如果出現添加相同的鍵,那么后添加的值會覆蓋原有鍵對應的值,并且put方法會返回被覆蓋的值

(2)、刪除

1 void  clear();//清空map集合2 value  remove(Object key);//根據指定的key刪除這個鍵值對

(3)、判斷

1 boolean  containsKey(key);//判斷集合中是否存在指定的鍵2 boolean  containsValue(value);//判斷集合中是否存在指定的值3 boolean  isEmpty();//判斷集合是否為null

(4)、獲取

1 value  get(Key);//通過鍵獲取值,如果沒有該鍵返回null,可以通過返回null來判斷是否存在指定鍵。當然有特殊情況,就是在hashmap集合中,是可以存儲null鍵null值的。2 int  size();//獲取鍵值對個數,也就是Map集合的長度3 Set<Key>  keySet();//返回Set集合,該集合中存放的是Map集合中的全部鍵(Key)的值4 Set<Map.Entry<Key,Value>>  entrySet();//返回Set集合,該集合存放的是Map集合的映射關系,關系的數據類型就是:Map.Entry。5 Collection<Value>   values();//返回Collection集合,該集合中存放的是Map集合中的全部值。返回的Collection集合可以通過Iterator迭代器獲取到全部值

map中是沒有迭代器的,collection具備迭代器,只要將map集合轉成Set集合,可以使用迭代器了。之所以轉成set,是因為map集合具備著鍵的唯一性,其實set集合就來自于map,set集合底層其實用的就是map的方法。

2、Map集合的三種取出方式

(1)、取出map集合中所有元素的方式一: Set<Key> keySet()方法。

將Map集合中的所有鍵存入到Set集合中。因為Set集合具備迭代器,所以可以通過迭代方式取出所有的鍵,然后根據Map集合中的get方法獲取每一個鍵所對應的值。

 1 import java.util.*; 2 class KeySetDemo  3 { 4     public static void main(String[] args)  5     { 6         Map<Integer,String> map=new HashMap<Integer,String>(); 7         map.put(1,"王武"); 8         map.put(7,"孫琦"); 9         map.put(6,"李四");10         map.put(4,"趙四");11         map.put(2,"錢楓");12         //先獲取map集合的所有鍵的Set集合,keySet();13         Set<Integer> keyset=map.keySet();14         //有了Set集合。就可以獲取其迭代器。15         for (Iterator<Integer> it=keyset.iterator();it.hasNext() ; )16         {17             Integer key=it.next();18             //有了鍵可以通過map集合的get方法獲取其對應的值。19             String value=map.get(key);20             System.out.println("key="+key+":::"+"value="+value);21         }22     }23 }

(2)、取出map集合中所有元素的方式二:Set<Map.Entry<Key,Value>> entrySet()方法。

將map集合中的映射關系存入到了set集合中,而這個關系的數據類型就是:Map.Entry. Map.Entry 其實Entry也是一個接口,它是Map接口中的一個內部接口。為什么要定義在內部呢?

因為只有有了Map集合,有了鍵值對,才會有鍵值的映射關系。關系屬于Map集合中的一個內部事物。而且該事物在直接訪問Map集合中的元素。

接口 Map.Entry<K,V>中的方法:

 1 import java.util.*; 2 class EntrySetDemo  3 { 4     public static void main(String[] args)  5     { 6         Map<Integer,String> map=new HashMap<Integer,String>(); 7         map.put(1,"王武"); 8         map.put(7,"孫琦"); 9         map.put(6,"李四");10         map.put(4,"趙四");11         map.put(2,"錢楓");12         //將Map集合中的映射關系(Map.Entry)取出。存入到Set集合中。13         Set<Map.Entry<Integer,String>> entryset=map.entrySet();14         //用迭代器進行迭代Set集合15         for (Iterator<Map.Entry<Integer,String>> it=entryset.iterator();it.hasNext() ; )16         {17             //it.next()返回的是Map集合中的映射關系(Map.Entry<K,V>)18             Map.Entry<Integer,String> en=it.next();19             //通過Map.Entry中的getKey()和getValue()取到Map集合鍵和值。20             int key=en.getKey();21             String value=en.getValue();22             System.out.println("key="+key+":::"+"value="+value);23         }24     }25 }

(3)、取出map集合中所有元素的方式三:Collection<Value> values();返回Collection集合,然后在用Iterator迭代器來取出元素

 1 import java.util.*; 2 class ValuesDemo  3 { 4     public static void main(String[] args)  5     { 6         Map<Integer,String> map=new HashMap<Integer,String>(); 7         map.put(1,"王武"); 8         map.put(7,"孫琦"); 9         map.put(6,"李四");10         map.put(4,"趙四");11         map.put(2,"錢楓");12         //用values方法取到Map集合中的全部的值,存放到Collection中13         Collection<String> value=map.values();14         //用迭代器進行迭代這個存放Map集合全部值的Collection集合15         for (Iterator<String> it=value.iterator();it.hasNext() ; )16         {17             System.out.println("value="+it.next());18         }19     }20 }

3、Map集合綜合練習

(1)、需求:描述一個學生,學生屬性:姓名,年齡。每一個學生都有對應的歸屬地。學生Student,地址String。注意:姓名和年齡相同的視為同一個學生。保證學生的唯一性。

 1 import java.util.*; 2 class Student  3 { 4     private String name; 5     private int age; 6     Student(String name,int age){ 7         this.name=name; 8         this.age=age; 9     }10     public void setName(String name){11         this.name=name;12     }13     public void setAge(int age){14         this.age=age;15     }16     public String getName(){17         return name;18     }19     public int getAge(){20         return age;21     }22     public String toString(){23         return "name="+name+"....."+"age="+age;24     }25     public int hashCode(){26         return name.hashCode()+age*37;27     }28     public boolean equals(Object obj){29         if(!(obj instanceof Student))30             throw new RuntimeException("類型轉換異常");31         Student stu=(Student)obj;32         return this.name.equals(stu.name)&&this.age==stu.age;33     }34 }35 class HashMapDemo36 {37     public static void main(String[] args) 38     {39         //將學生對象和學生的歸屬地通過鍵與值的形式存儲到map集合中40         Map<Student,String> map=new HashMap<Student,String>();41         map.put(new Student("張三",20),"北京");42         map.put(new Student("錢楓",21),"深圳");43         map.put(new Student("王武",19),"鄭州");44         map.put(new Student("趙四",33),"香港");45         map.put(new Student("孫琦",29),"廣州");46         map.put(new Student("錢楓",21),"上海");47         //第一種方式:keySet();48         for (Iterator<Student> it=map.keySet().iterator();it.hasNext() ; )49         {50             Student stu=it.next();51             String address=map.get(stu);52             System.out.println(stu+":::"+address);53         }54         //第二種取出方式55         for (Iterator<Map.Entry<Student,String>> it=map.entrySet().iterator();it.hasNext() ; )56         {57             Map.Entry<Student,String> me=it.next();58             Student stu=me.getKey();59             String address=me.getValue();60             System.out.println(stu+":::"+address);61         }62     }63 }

(2)、需求:對學生對象的年齡進行升序排序。因為數據是以鍵值對形式存在的。所以要使用可以排序的Map集合中TreeMap集合。

 1 import java.util.*; 2 class Student implements Comparable<Student> 3 { 4     private String name; 5     private int age; 6     Student(String name,int age){ 7         this.name=name; 8         this.age=age; 9     }10     public void setName(String name){11         this.name=name;12     }13     public void setAge(int age){14         this.age=age;15     }16     public String getName(){17         return name;18     }19     public int getAge(){20         return age;21     }22     public String toString(){23         return "name="+name+"....."+"age="+age;24     }25     public int compareTo(Student stu){26         int num=this.age-stu.age;//按年齡排序27         if(num==0)28             return this.name.compareTo(stu.name);//按姓名排序29         return num;30     }31     /*32     因為寫的Student類,使用者有可能存放到HashMap集合中。33     所以有必要復寫hashCode方法和equals方法。34     而且即使你不寫,這兩個方法都會存在Student類中,因為Object類中有這兩個方法35     public int hashCode(){36         return name.hashCode()+age*37;37     }38     public boolean equals(Object obj){39
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 陆川县| 温宿县| 西乌珠穆沁旗| 鲜城| 峡江县| 开阳县| 常德市| 无锡市| 广河县| 连城县| 西充县| 安西县| 富蕴县| 新宾| 高碑店市| 登封市| 修水县| 桃源县| 奉化市| 新竹市| 宜良县| 虎林市| 永胜县| 碌曲县| 乐平市| 闽清县| 沅江市| 南乐县| 云南省| 肇庆市| 咸丰县| 贵港市| 洪雅县| 乌拉特后旗| 绵竹市| 土默特右旗| 景泰县| 桃源县| 壤塘县| 福建省| 福建省|