------- android培訓、java培訓、期待與您交流! ----------
集合1、集合和對象數組的區別: 數組的長度不可變,集合的可變; 數組可以存儲基本數據類型和對象,集合只能存儲對象。
集合的框架圖

集合派系的頂層接口Collection1、Collection集合存儲對象的方法: add(E e)將元素存儲到集合中 addAll(Collection c)將一個集合添加到另外的集合中2、Collection集合提取對象的方法: 通過迭代器iterator中的方法;hasNext()和next()來取出
Iterator it=new iterator(); while(it.hasNext()){ System.out.PRintln(it.next()); }3、Collection集合移除對象的方法: boolean remove (Object o)移除一個對象,移除成功返回true。 boolean removeAll(Collection c)移除兩個集合中的共性內容,成功返回true。4、Collection集合中的其他方法: void clear()移除集合中所以元素 int size()返回集合中元素的個數 boolean contains(Object o)判斷是否包含該對象,包含返回true。 boolean contains(Collection c)判斷一個集合是否包含另一個集合,包含就返回true。 boolean retainAll(Collection c)將這兩個集合的交集賦值給調用者,沒有交集就是[]。 再判斷調用者的元素是否改變,改變了就是true。 Collection中不常用的方法: static reverse(List)反轉集合 static fill(List,Object)替換集合
迭代器1、概念: 是取出集合中存儲對象的方式。
2、原理:
在接口Collection中,定義了一個方法 Iterator iterator(),是集合中所有子類都具備的。
iterator()返回的是一個Iterator接口類型,由于接口本身不能創建對象,所以返回的是接口的實現類對象3、Iterator接口中的三個方法: boolean hasNext()判斷集合中還有沒有元素,有返回true。 Object next() 獲取集合中的元素,可以看成數組中的arr[i]。 void remove()移除遍歷的集合中的元素4、實現迭代器的三個步驟: //通過集合對象的iterator()方法,返回一個Iterator接口的實現類對象
Iterator it=集合.iterator(); //使用迭代器對象的hasNext()方法,判斷集合中還有沒有對象可以被取出 while(it.hasNext()){ //使用迭代器對象的next()方法直接獲取存在集合中的元素 it.next(); }注:迭代器是獲取集合中對象的通用方式。5、注意事項: a.如果迭代器已經獲取玩了,再次獲取,會出現沒有元素被取出的異常。 b.在迭代的過程中不要使用集合的方法改變集合的長度。 并發修改異常ConcurrentMOdificationException: 原因:使用集合的方法修改了集合的長度,而迭代器不知道。 c:一次迭代中,不能多次出現next()方法,否則可能出現異常,出現數據錯亂。 因為每用一次next(),指針就會往后移一次。 解決辦法:Object o=迭代器.next();
List接口1、特點: 有序:取出的順序和存的時候一樣 具有下標 允許存儲重復元素2、List集合存對象的方法: add(int index,Objext o)index不能超過List集合原有的大小3、List集合獲取對象的方法 A、一般情況下也是通過iterator()來獲取 但是List派系有特有的迭代器ListIterator,ListIterator接口是繼承Iterator的。 ListIterator接口的特點: 在迭代的過程中可以對集合中的元素進行添加、修改和刪除。 ListIterator接口的方法: add(Object o) set(Object o) boolean hasprevious()功能和hasNext()相同 Object previous()==next() B、Object get(int index)獲取指定下標的元素4、List集合修改對象的方法: Object remove(int index) Object set(int index,Object Obj)5、List集合其他方法: List subList(int start,int end)注:List集合由于繼承關系的存在,也有Collection集合的添加、修改和刪除等方法。后面學習 的子類也是這樣。
ArrayList類1、屬于List派系下的子類,具備List派系的所有特點: 有序,下標,重復 ArrayList自己的特點: 底層數據結構是數組 底層是可變數組,導致了查詢快,增刪慢 數組的大小默認是10,每次增長50% 線程不同步,不安全,但執行效率高 注:是通過復制數組的形式實現數組的可變。2、關于ArrayList集合的面試題 A、用戶通過鍵盤輸入姓名和成績,姓名和成績封裝成學生對象,存到ArrayList中。 如果用戶輸入了"over",結束鍵盤的輸入,迭代集合,迭代出已經存儲的學生對象。
1 public class Person { 2 private String name; 3 private int age; 4 5 public void setName(String name){ 6 this.name=name; 7 } 8 public void setAge(int age){ 9 this.age=age;10 }11 public String getName(){12 return name;13 }14 public int getAge(){15 return age;16 }17 18 19 public Person(){20 21 }22 public Person(String name,int age){23 setName(name);24 setAge(age);25 }26 27 public String toString(){28 return "Person:"+name+"..."+age;29 }30 }31 import java.util.*;32 public class ArrayListTest {33 public static void main(String[] args) {34 //創建一個集合,創建一個鍵盤輸入的Scanner35 ArrayList array = new ArrayList();36 Scanner sc = new Scanner(System.in);37 //接受鍵盤輸入38 while(true){39 String str = sc.nextLine().trim();40 //判斷輸入的是不是over 41 if("over".equals(str))42 break;43 //進行字符串的切割操作,空格的形式44 String[] s = str.split(" +");45 //姓名和成績存儲到ArrayList集合,成績轉成int46 array.add(new Student(s[0],Integer.parseInt(s[1])));47 }48 //創建迭代器,獲取集合中的元素49 Iterator it = array.iterator();50 while(it.hasNext()){51 System.out.println(it.next());52 }53 }54 }B、制作一個6位的不同字符的驗證碼,輸出到控制臺,用戶輸入,判斷是對還是錯。要求:6位不同的數子,字母和漢字。
import java.util.*;public class GetCode{ public static void main(String[] args){ Scanner sc=new Scanner(System.in); //定義數組,保存一些字符 char[] ch={'a','v','1','3','6','你','黑','我','為','的','啊'}; //創建一個字符串緩沖區 while(true){ StringBuilder sb=new StringBuilder(); //因為只需6個字符,所以sb的長度為6就停止添加字符 while(sb.length()<6){ int num=new Random().nextInt(ch.length); if(sb.toString().contains(ch[num]+"")) continue; sb.append(ch[num]); } System.out.println(sb); //再比較字符串與輸入的是否相等。相等就跳出循環,不等就刷新驗證碼。 String code=sc.nextLine(); if(sb.toString().equals(code)){ System.out.println("驗證碼正確!"); break; }else{ System.out.println("驗證碼錯誤!"); } } }}3、去掉ArrayList中的重復元素要求ArrayList集合中對象重寫equals()方法。
/*方法中返回一個新集合替換老集合*/public static ArrayList method(ArrayList oldArray){//定義新集合,存儲去掉重復元素后的集合 ArrayList newArray=new ArrayList(); Iterator it=oldArray.iterator(); while(it.hasNext()){ Object obj=it.next(); if(!newArray.contains(obj)) newArray.add(obj); } return newArray; }contains()會調用equals();對象中重寫的equals():public boolean void equals(Object obj){ if(this==obj) return true; if(obj==null) return false; if(obj instanceof Person){ Person p=(Person)obj; return this.name.equals(p.name)&&this.age==p.age; }}Vector類沒有集合框架以前,存儲對象只能依賴Vector。Vector底層的數據結構也是可變數組,但是它線程安全,運行效率慢,而且每次數組擴容是100%。所以被ArrayList取代了。 LinkedList類1、特點: 底層數據結構是鏈表實現,以記錄對象地址的方式存儲 查詢慢,增刪快 線程不安全,執行效率高2、LinkedList類特有的方法 addFirst()將元素添加到鏈表的開頭 addLast()將元素添加到鏈表的結尾 Object getFirst()獲取鏈表的開頭 Object getLast()獲取鏈表的結尾 Object removeFirst()移除鏈表的開頭,返回被移除前的對象 Object removeLast()移除鏈表的結尾, 返回被移除前的對象JDK1.6開始,有n個新的方法,把以前的方法取代,不做掌握 offerFirst()-->addFist() 返回值不同add開頭的沒有返回值,offer開頭返回boolean offerLast()-->addLast() peekFirst()-->getFirst()get開頭沒有元素,出異常,peek開頭沒有元素返回null,沒異常 peekLast()-->getLast() pollFirst()-->removeFirst() pollLast()-->removeLast()
3、LinkedList模擬堆棧和隊列,體現的是思想的轉換:將jdk中的方法封裝起來,讓用戶調用我們自己的方法來執行程序,而不是 用jdk中的方法。
import java.util.*;class MyMethod{ private LinkedList link=null; public MyMethod(){ link=new LinkedList();} public void add(Object obj){ link.add(obj); } //先進先出 public Object get(){ return link.removeFirst(); } //先進后出 public Object get(int x){ return link.removeLast(); } public boolean isEmpty(){ return !link.isEmpty(); } }public class LinkedListOut{ public static void main(String[] args) { MyMethod my=new MyMethod(); my.add("2"); my.add("3"); my.add("4"); while(my.isEmpty()){ System.out.println(my.get(2)); } }}Set 接口1、Set集合派系的特點: 不允許存儲重復元素 沒有下標 無序的集合,存儲的和取出的順序不一樣2、Set接口中的方法和Collection接口中的一致
HashSet類1、HashSet類除有和Set接口一樣的特點外,自身的特點是: 底層數據結構:哈希表,存儲的是對象的哈希值 HashSet本身沒有功能,功能來自于HashMap。HashSet調用HashMap的功能。2、HashSet的存儲原理: 存儲對象時,先調用對象的hashcode(),獲取該對象的哈希值(十進制數)。HashSet看 存儲過這個哈希值沒。如果沒有就將這個哈希值存到自己的哈希表中;如果有,就再 調用對象的equals()。如果相等就不存到HashSet集合中,不等就掛載到HashSet中原 有的哈希值下面。3、HashSet集合取出重復的元素,保證對象的唯一性 需重寫hashCode()和equals():
public int hashCode(){ //利用name變量 age變量 return name.hashCode()+age*13; } //同名的,和同年齡的對象,返回真 public boolean equals(Object obj){ if( this == obj) return true; if(obj == null) return false; if(obj instanceof Person){ Person p = (Person)obj; return this.name.equals(p.name) && this.age == p.age; } return false; }4、hashCode和equals的問題 如果兩個對象具有相同的哈希值,兩個對象進行equals比較,不一定返回真; 如果兩個對象進行equals比較,返回真,兩個對象具有相同的哈希值嗎,必須相同。
LinkedHashSet類---HashSet的子類LinkedListSet獨有的特點: 有序的,基于哈希表的鏈表,線程不安全,執行效率高
TreeSet類1、TreeSet獨有的特點: 底層結構是二叉樹; 對存儲的對象自然排序; 線程不安全,執行效率高。2、將自定義的對象Person存儲到TreeSet集合,出現了類型轉換異常 ClassCastException :原因,Person不能被轉成java.lang.Comparable TreeSet中,需要對Person進行排序,可是你的Person對象,不具備自然順序。3、TreeSet集合中使對象具備自然順序: 自定義的類需實現Comparable接口,重寫compareTo()方法; 或者,自定義比較器類,實現接口Comparator,重寫Compare(Object o1,Object o2)。
1 方法一: 2 //主要比較姓名,如果姓名一樣,比較年齡。也可以主要比較年齡 3 public int compareTo(Object obj){ 4 //this 后進來的, obj先進來的對象 5 Person p = (Person)obj; 6 int num = this.name.compareTo(p.name); 7 return num == 0 ? this.age - p.age : num; 8 } 9 方法二:10 /*11 * 自定義比較器,對于TreeSet集合中存儲的Person對象進行排序12 */13 Set set=new TreeSet(new Comparator());14 public class MyComparator implements java.util.Comparator{15 //重寫compare方法,做什么事情,比較Person對象的年齡和姓名16 // ts.add(new Person("lisi",20));17 // ts.add(new Person("zisi",21));18 public int compare(Object o1, Object o2){19 //o1 和 o2 比較一下,年齡,主要條件,年齡不同,不需要比較姓名20 Person p1 = (Person)o1;21 Person p2 = (Person)o2;22 //Person的變量,只能用get方法獲取23 int num = p1.getAge() - p2.getAge();24 return num == 0? p1.getName().compareTo(p2.getName()) : num;25 }26 27 }注:兩個方法都是大于0,就存后面;等于0,就不存;小于0,存前面。
泛型1、格式: 集合類<數據類型> 變量 = new 集合類<數據類型>(); 數據類型,指定了這個集合,只能存儲這個類型的對象。 如: ArrayList<E> boolean add(E e) E:看成是一個變量 ArrayList<String> 所有的E都變成了String 注意:存儲基本數據類型,泛型必須寫對應的包裝類2、泛型的好處: 泛型的出現,將安全問題,由運行時期,提前到了編譯時期 減少了代碼,使用泛型避免類型的強制轉換3、自定義的泛型,保證數據安全 泛型類,聲明類的時候,加上泛型 泛型方法, 在方法上定義泛型,和類無關,需聲明; public<T> void method(T t){} public static<T> void method(){}注意: 靜態的方法的泛型不要和類上的一樣。因為 靜態的成員是優先于對象存在,用類名調用時無法指定 泛型的類型。 方法中的泛型是局部的泛型,不影響類名的泛型。 泛型接口,在接口名后面加上 通常定義實現類,實現接口的時候,不指定泛型,等待new實現類對象 的時候指定。class MyComparator <T> implements Comparator<T>(){}4、泛型的通配符和限定 上限限定 ? extends E 傳遞E類型,E的任意子類類型 下限限定 ? super E 傳遞E類型,E的任意父類類型 弊端:使用通配符后,不能強轉。
Map接口1、Map接口的特點: 一個鍵最多只能映射一個值 不允許出現重復的鍵2、Map接口的方法: V put(K,V) 將鍵值對存儲到集合。返回值,存儲了重復的鍵,返回被覆蓋之前的值 V get(K) 根據鍵獲取值,傳遞一個鍵,返回鍵映射的值,沒有這個鍵,返回null Set<K> keySet()鍵存儲到Set集合 Set<Map.Entry<K,V>> entrySet()2014/8/15映射關系對象保存到Set集合 V remove(K)移除指定的鍵對應的值,返回被移除前的值,沒有移除成功,返回null boolean containsKey(K)判斷集合中,有沒有這個鍵,有返回true boolean containsValue(V)判斷集合中個,有沒有這個值,有返回true Collection values()將集合中的所有值,保存到Collection集合3、獲取Map集合中鍵值對的方式? 第一種,利用Map中的一個方法keySet(),Map集合中的鍵,存儲到Set集合 迭代Set集合,獲取出來的是所有的鍵 通過鍵獲取值,Map接口中的get方法
1 Map<String,Integer> map=new HaspMap<String,Integer>();2 Set<String> set=map.keySet();3 Iterator<String> it=set.iterator();4 while(it.hasNext()){5 String key=it.next();6 Integer value=map.get(key);7 System.out.println(key+"..."+value);8 }第二種利用Map集合中的鍵值對映射關系獲取Map接口中有一個方法entrySet(),獲取鍵值對的映射關系對象Entry,將這個對象Entry存儲到了Set集合迭代Set集合,獲取出來的Set集合中存儲的是映射關系對象Entry通過映射關系對象中的方法 getKey getValue
1 Map<String,Integer> map=new HasMap<String,Integer>();2 Set<Map.Entry<String,Integer>> set=map.entrySet();3 Iterator <Map.Entry<String,Integer>> it=map.iterator();4 while(it.hasNext()){5 Map.Entry<String,Integer> me=it.next();6 String key=me.getKey();7 Integer value=me.getValue();8 System.out.println(key+"..."+value);9 }HashMap類1、HashMap獨有的特點 底層結構是哈希表,允許存儲null值,null鍵 不同步,線程不安全,執行效率高2、保證存儲到的HashMap中的鍵唯一性。自定義對象保證唯一性,自定義對象需重寫hoseCode()和equals()。
LinkedHashMap類-------HashMap的子類
1、特點: 底層結構是基于哈希表的鏈表實現的 鍵怎么存,怎么取 不同步,線程不安全,執行效率高
TreeMap類1、TreeMap的特點: 底層數據結構是紅黑樹,記自然平衡二叉樹 對鍵進行自然的排序,要求作為鍵的對象,具備自然排序或者自定義比較器 不同步,線程不安全,執行效率高
2、TreeMap使用方式和TreeSet是一致的,保證對象的自然順序,或者定義比較器就可以了。在存儲的時候,Set使用add,Map使用put。
HashTable類
1、HashTable的特點: 底層數據結構式哈希表 線程安全,不允許存null值,null鍵 因為HashTable出了線程和null的區別,其他的和HashMap的一致,所以被HashMap取代了。但是HashTable的一個子類Properties至今 很活躍。
Properties類---HashTable的子類1、Properties的特點: 線程安全,與IO流配合使用。這個集合的泛型已經定好了,鍵值的泛型都是String。2、Properties的兩個特有的方法: setProperty(String key,String value) getProperty(String key)3、計算一個字符串中每個字符出現的次數:
1 import java.util.*; 2 public class TreeMapTest { 3 public static void main(String[] args) { 4 String s = "asrrfegrr4gw34g"; 5 //String s = "aa"; 6 //建立TreeMap集合,鍵就是單個字符,值出現次數 7 TreeMap<Character,Integer> tm = new TreeMap<Character, Integer>(); 8 //將字符串變成字符數組,操作單個字符 9 char[] ch = s.toCharArray();10 for(int x = 0 ; x < ch.length ; x++){11 //遍歷到每一個字符,字符當作鍵,到集合中獲取值12 Integer i = tm.get(ch[x]);13 if(i==null){14 //說明鍵,不存在的,字符沒有出現過,把字符當作鍵,值為1存儲到集合15 tm.put(ch[x], 1);16 }else{17 //說明鍵存在,將值++后存儲會集合18 19 tm.put(ch[x], ++i);20 }21 }22 System.out.println(tm);23 }24 }JDK1.5后的新特性1、增強for循環:只適合遍歷數組和集合 格式: for(數據類型 變量:集合或者數組){ 輸出(變量); }2、可變參數格式: 方法名(數據類型...變量名) 注意事項: 可變參數的數據類型唯一 多個參數,可變參數放最后 可變參數只能寫一個
Collections集合工具類<List專用>1、凡是工具類里面的成員都是靜態的2、集合工具類的方法: static sort(List list)可以排序List集合,升序 static sort(List list,Comparator com)傳遞List,比較器,按照比較器對集合升序排序 static Comparator reverSEOrder()返回一個比較器,逆轉了對象的自然順序(Comparable) static Comparator reverseOrder(傳遞比較器)返回比較器,逆轉了傳遞的比較器的順序 static int binarySerach(List list,Object key)集合的折半查找,如果找不到該元素,返回-插入點-1。插入點,就是將查找的元素,放在集合中個,保證集合有序,下標插入點 static reverse(List list)反轉集合 static fill(List list,Object o)替換集合中的所有對象 static shuffle(List list)隨機排列集合中的對象,洗牌 Collections工具類中有一組方法 synchronized開頭的,將線程不安全的集合,變成線程安全的集合
Arrays數組工具類數組工具類中的方法: static sort(數組) 數組進行升序排序,快排 static int binarySerach(數組,查找的元素)數組的折半查找 static String toString(數組)不是重寫Object,將數組變成字符串 static List asList(數組)數組轉集合,List集合,集合長度不可變 2Collection接口方法 T[] toArray(T[] a) 集合變數組
新聞熱點
疑難解答