集合與數(shù)組的區(qū)別:
1.數(shù)組是固定長度的;集合的長度是可變的。
2.數(shù)組可以存儲基本數(shù)據(jù)類型,也可以存儲引用數(shù)據(jù)類型;集合只能存儲引用數(shù)據(jù)類型。
3.數(shù)組存儲元素必須是同一個數(shù)據(jù)類型;集合存儲的對象可以是不同數(shù)據(jù)類型。
java集合主要有3種重要的類型:
●List:是一個有序集合,可以存放重復(fù)的數(shù)據(jù)。
●Set: 是一個無序集合,不允許存放重復(fù)的數(shù)據(jù)。
●Map: 是一個無序集合,集合中包含一個鍵對象和一個值對象, 鍵對象不允許重復(fù),值對象可以重復(fù)。
下面是集合繼承結(jié)構(gòu)圖-Collection部分,從圖中可以很清楚的知道Collection接口下的子接口與實現(xiàn)類的關(guān)系。
Collection集合的常用方法:
boolean add(Object o): 向集合中添加元素
boolean addAll(Collection c):把集合c中的元素添加到指定的集合中
void clear():清空集合
boolean isEmpty():判斷集合中是否有元素
Iterator iterator(): 獲取集合所依賴的迭代器對象
boolean contains(Object o): 判斷集合中是否包含某個元素
boolean remove(Object o): 刪除集合中某個元素
int size(): 獲取集合中元素的個數(shù)
Object[] toArray(): 將集合轉(zhuǎn)換成數(shù)組
1 import java.util.*; 2 3 public class CollectionDemo { 4 public static void main(String[] args) { 5 6 // 創(chuàng)建集合 7 Collection c = new ArrayList();// 多態(tài) 8 9 // 添加元素10 c.add(100); // 自動裝箱11 c.add("Java編程");12 13 Person p = new Person("Bill", 21);14 c.add(p);// Collection集合只能單個存儲元素,并且只能存儲引用類型15 16 // 獲取元素個數(shù)17 System.out.PRintln(c.isEmpty());// false 說明集合c不為空18 System.out.println("c集合的元素個數(shù)為:" + c.size());// 個數(shù)為319 20 // 將集合轉(zhuǎn)換成Object類型的數(shù)組21 Object[] obj = c.toArray();22 for (int i = 0; i < obj.length; i++) {23 24 // 輸出結(jié)果:100 Java編程 Person[name=Bill,age=21]25 System.out.println(obj[i]);26 }27 28 // 刪除指定元素29 c.remove(100); // 元素100已刪30 System.out.println("c集合的元素個數(shù)為:" + c.size());// 個數(shù)為231 32 // 清空33 c.clear();34 System.out.println(c.isEmpty());// true 說明集合c為空35 System.out.println("c集合的元素個數(shù)為:" + c.size());// 個數(shù)為036 37 }38 }39 40 class Person {41 String name;42 int age;43 44 Person(String name, int age) {45 this.name = name;46 this.age = age;47 }48 49 // 重寫Object中的toString方法50 public String toString() {51 return "Person[name=" + name + ",age=" + age + "]";52 }53 54 }View Code
Iterator iterator();獲取集合所依賴的迭代器對象
通過迭代器中的方法完成集合的迭代(遍歷)
這種方式是所有集合通用的遍歷方式
Itertor接口定義的三個方法:
boolean hasNext():如果仍有元素可以迭代,則返回 true。
Object next(): 返回迭代的下一個元素。
void remove(): 從迭代器指向的 collection 中移除迭代器返回的最后一個元素(可選操作)。
Iterator必須依附于Collection對象,若有一個Iterator對象,則必然有一個與之關(guān)聯(lián)的Collection對象。
當使用Iterator對集合元素進行迭代時,Iterator并不是把集合元素本身傳給迭代變量,而是把集合元素的值傳給迭代變量,因此當修改迭代變量的值時對集合元素本身沒有任何影響
注意:當使用Iterator迭代訪問Collection集合元素時,Collection集合里的元素不能被改變,只能通過Iterator的remove方法刪除上一次next方法返回的集合元素,否則將會引發(fā)java.util.CencurrentModificationException異常。
1 import java.util.*; 2 public class IteratorDemo { 3 4 public static void main(String[] args) { 5 6 // 創(chuàng)建一個集合 7 Collection books = new HashSet(); 8 books.add("三國演義"); 9 books.add("西游記");10 books.add("水滸傳");11 12 // 獲取books集合對應(yīng)的迭代器13 Iterator it = books.iterator();14 while (it.hasNext()) {15 // it.next()方法返回的是Object類型,需強制類型轉(zhuǎn)換16 String str = (String) it.next();17 System.out.println(str);18 19 if (str.equals("三國演義")) {20 // 從集合中刪除上一次next方法返回的元素21 it.remove();// 通過迭代器刪除22 23 // 不要使用集合自身所帶的remove方法,會引發(fā)異常24 // books.remove(str);25 }26 // 對str變量賦值,不會改變集合元素本身27 str = "紅樓夢";// 此處代碼對集合沒有任何影響28 }29 System.out.println(books);// [西游記, 水滸傳]30 }31 }View Code
boolean contains(Object o):判斷集合中是否包含某個元素存儲在集合中的元素應(yīng)該重寫equals方法
1 import java.util.*; 2 public class ContainsDemo { 3 4 public static void main(String[] args) { 5 6 // 創(chuàng)建集合 7 Collection c = new ArrayList(); 8 9 // 創(chuàng)建Integer類型對象10 Integer i1 = new Integer(100);11 12 // 添加元素13 c.add(i1);14 15 // 判斷集合中是否包含i116 System.out.println(c.contains(i1));// true17 18 // 創(chuàng)建另一個Integer類型對象19 Integer i2 = new Integer(100);20 // contains方法底層調(diào)用的是equals方法。Integer重寫了equals方法,i1就是i221 System.out.println(c.contains(i2));// true22 23 // 創(chuàng)建一個Student對象24 Student s1 = new Student(100, "Bill");25 // 添加到集合里26 c.add(s1);27 // 判斷集合c中是否包含s128 System.out.println(c.contains(s1));// true29 30 // 創(chuàng)建另一個Student對象31 Student s2 = new Student(100, "Bill");32 // 重寫equals方法之前,比較的是內(nèi)存33 // System.out.println(c.contains(s2));//false34 35 // 重寫equals方法之后,比較的是內(nèi)容36 System.out.println(c.contains(s2));// true37 }38 }39 40 class Student {41 int no;42 String name;43 44 Student(int no, String name) {45 this.no = no;46 this.name = name;47 }48 49 // 重寫equals方法50 // 要求:編號和姓名相同則表示同一個Student51 public boolean equals(Object o) {52 if (this == o) {53 return true;54 }55 if (o instanceof Student) {56 Student s = (Student) o;57 if (s.no == this.no && s.name == this.name) {58 return true;59 }60 }61 return false;62 }63 }View Code
List集合
ArrayList集合底層是數(shù)組。數(shù)組是有下標的. 所以ArrayList集合有很多自己的特性.
ArrayList集合底層默認初始化容量是 10. 擴大之后的容量是原容量的1.5倍.
Vector集合底層默認初始化容量也是10.擴大之后的容量是原容量的2倍.
如何優(yōu)化ArrayList和Vector?
盡量減少擴容操作,因為擴容需要數(shù)組拷貝。數(shù)組拷貝很耗內(nèi)存。一般推薦在創(chuàng)建集合的時候指定初始化容量。
1 import java.util.*; 2 public class ListDemo { 3 4 public static void main(String[] args) { 5 6 // 創(chuàng)建List集合 7 List li = new ArrayList(); 8 // List li = new LinkedList(); 9 10 // 添加元素11 li.add(100);12 li.add(200);13 li.add(400);14 15 // 在下標為2的位置上添加30016 li.add(2, 300);17 18 // 取得第一個元素19 System.out.println(li.get(0));// 10020 21 // 遍歷(List集合特有的遍歷方式)22 for (int i = 0; i < li.size(); i++) {23 Object o = li.get(i);24 System.out.println(o);25 }26 27 // 迭代器也可以28 Iterator it = li.iterator();29 while (it.hasNext()) {30 System.out.println(it.next());31 }32 }33 }View Code
Set集合:HashSet
1.HashSet底層實際上是一個HashMap,HashMap底層采用了哈希表數(shù)據(jù)結(jié)構(gòu)。
2.哈希表又叫做散列表,哈希表底層是一個數(shù)組,這個數(shù)組中每一個元素是一個單向鏈表。每個單向鏈表都有一個獨一無二的hash值,代表數(shù)組的下標。在某個單向鏈表中的每一個節(jié)點上的hash值是相等的。hash值實際上是key調(diào)用hashCode方法,在通過"hash function"轉(zhuǎn)換成的值。
3.如何向哈希表中添加元素:先調(diào)用被存儲的key的hashCode方法,經(jīng)過某個算法得出hash值,如果在這個哈希表中不存在這個 hash值,則直接加入元素。如果該hash值已經(jīng)存在,繼續(xù)調(diào)用key之間的equals方法,如果equals方法返回false,則將該元素添加。如果equals方法返回true,則放棄添加該元素。
4.HashSet其實是HashMap中的key部分。HashSet有什么特點,HashMap中的key 應(yīng)該具有相同的特點。
5.HashMap和HashSet初始化容量都是 16,默認加載因子是0.75,即當存儲容量達到75%時就擴容。
6.關(guān)于往Set集合中存儲的元素,該元素的hashCode和equals方法:
HashMap中有一個put方法,put(key,value) key是無序不可重復(fù)的.
結(jié)論:存儲在HashSet集合或者HashMap集合key部分的元素,需要同時重寫hashCode+equals
1 import java.util.*; 2 public class SetDemo { 3 4 public static void main(String[] args) { 5 6 // Set集合存儲元素是無序不可重復(fù)的,這里就不做測試了 7 8 //創(chuàng)建集合 9 Set s = new HashSet();10 11 //這里假設(shè)鍵值重復(fù)只為做測試,實際上是不可重復(fù)的12 Employee e1 = new Employee("1000","JACK");13 Employee e2 = new Employee("1000","JACK");14 Employee e3 = new Employee("1000","SCOTT");15 Employee e4 = new Employee("2001","SUN");16 Employee e5 = new Employee("3000","JIM");17 Employee e6 = new Employee("3001","COOK");18 19 System.out.println(e1.hashCode());//重寫hashCode方法后e1就是e220 System.out.println(e2.hashCode());21 22 //添加元素23 s.add(e1);24 s.add(e2);25 s.add(e3);26 s.add(e4);27 s.add(e5);28 s.add(e6);29 30 //查看集合元素個數(shù)31 System.out.println(s.size()); //532 33 }34 }35 36 //假設(shè)該公司員工編號是: 1000 - 999937 class Employee{38 39 //編號40 String no;41 42 //姓名43 String name;44 45 //Constructor46 Employee(String no,String name){47 this.no = no;48 this.name = name;49 }50 51 //重寫equals方法.52 //如果員工編號相同,并且名字相同,則是同一個對象53 public boolean equals(Object o){54 if(this==o){55 return true;56 }57 if(o instanceof Employee){58 Employee e = (Employee)o;59 if(e.no.equals(this.no) && e.name.equals(this.name)){60 return true;61 }62 }63 64 return false;65 }66 67 //重寫hashCode方法.68 public int hashCode(){69 //以員工編號分組.70 return no.hashCode();71 }72 }View Code
先對SortedSet做測試
1 import java.text.*; 2 import java.util.*; 3 4 public class SortedSetDemo01 { 5 6 public static void main(String[] args) throws Exception { 7 8 // 創(chuàng)建集合 9 SortedSet ss = new TreeSet();10 11 // 測試Integer類型12 ss.add(10); // 自動裝箱13 ss.add(20);14 ss.add(15);15 ss.add(30);16 ss.add(25);17 ss.add(9);18 19 // 遍歷20 Iterator it = ss.iterator();21 while (it.hasNext()) {22 Object element = it.next();23 System.out.println(element);//9 10 15 20 25 3024 }25 26 // 測試String類型27 SortedSet strs = new TreeSet();28 29 strs.add("JACK");30 strs.add("SUN");31 strs.add("KOOK");32 strs.add("LUCY");33 strs.add("KING");34 35 // 遍歷36 it = strs.iterator();37 while (it.hasNext()) {38 Object element = it.next();39 System.out.println(element);40 /*輸出:JACK41 KING42 KOOK43 LUCY44 SUN*/45 }46 47 // 測試日期Date類型48 String st1 = "2008-08-08";49 String st2 = "2009-08-08";50 String st3 = "2008-09-08";51 String st4 = "2008-08-09";52 String st5 = "2012-08-08";53 54 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");55 56 Date t1 = sdf.parse(st1);57 Date t2 = sdf.parse(st2);58 Date t3 = sdf.parse(st3);59 Date t4 = sdf.parse(st4);60 Date t5 = sdf.parse(st5);61 62 // 添加63 SortedSet times = new TreeSet();64 65 times.add(t5);66 times.add(t2);67 times.add(t3);68 times.add(t4);69 times.add(t1);70 71 // 遍歷72 it = times.iterator();73 while (it.hasNext()) {74 Object element = it.next();75 if (element instanceof Date) {76 Date d = (Date) element;77 78 System.out.println(sdf.format(d));79 /*輸出:2008-08-0880 2008-08-0981 2008-09-0882 2009-08-0883 2012-08-08*/84 }85 }86 }87 }View Code
SortedSet集合存儲元素為什么可以自動排序? 因為被存儲的元素實現(xiàn)了Comparable接口, SUN編寫TreeSet集合在添加元素的時候,會調(diào)用compareTo方法完成比較.
1 import java.util.*; 2 3 public class SortedSetDemo02 { 4 5 public static void main(String[] args) { 6 7 SortedSet users = new TreeSet(); 8 9 User u1 = new User(15);10 User u2 = new User(16);11 User u3 = new User(25);12 User u4 = new User(13);13 User u5 = new User(11);14 15 // 添加元素16 users.add(u1);17 users.add(u2);18 users.add(u3);19 users.add(u4);20 users.add(u5);21 22 // 遍歷23 Iterator it = users.iterator();24 while (it.hasNext()) {25 //輸出:User[age=11] User[age=13] User[age=15] User[age=16] User[age=25]26 System.out.println(it.next());27 }28 }29 30 }31 32 // 這是第一種方式.33 class User implements Comparable {34 35 int age;36 37 User(int age) {38 this.age = age;39 }40 41 public String toString() {42 return "User[age=" + age + "]";43 }44 45 // 實現(xiàn)java.lang.Comparable;接口中的compareTo方法46 // 該方法程序員負責(zé)實現(xiàn),SUN提供的程序已經(jīng)調(diào)用了該方法.47 // 需求:按照User的age排序48 public int compareTo(Object o) {49 // 編寫一個比較規(guī)則.50 int age1 = this.age;51 int age2 = ((User) o).age;52 return age1 - age2;53 }54 }View Code
讓SortedSet集合做到排序還有另一種方式:java.util.Comparator;
單獨編寫一個比較器.
1 import java.util.*; 2 3 public class SortedSetDemo03 { 4 5 public static void main(String[] args) { 6 7 // 創(chuàng)建TreeSet集合的時候提供一個比較器. 8 SortedSet products = new TreeSet(new ProductComparator()); 9 10 // 匿名內(nèi)部類:不推薦使用,因為比較器無法得到重復(fù)利用。11 /*12 * SortedSet products = new TreeSet(new Comparator() { // 需求:按照商品價格排序13 * public int compare(Object o1, Object o2) {14 * 15 * double price1 = ((Product) o1).price; double price2 = ((Product)16 * o2).price;17 * 18 * if (price1 == price2) { return 0; } else if (price1 > price2) {19 * return 1; } else { return -1; } } });20 */21 22 Product p1 = new Product(3.4);23 Product p2 = new Product(4.0);24 Product p3 = new Product(3.0);25 Product p4 = new Product(2.0);26 Product p5 = new Product(5.0);27 28 // 添加元素29 products.add(p1);30 products.add(p2);31 products.add(p3);32 products.add(p4);33 products.add(p5);34 35 // 遍歷36 Iterator it = products.iterator();37 while (it.hasNext()) {38 //輸出2.0 3.0 3.4 4.0 5.039 System.out.println(it.next());40 41 }42 }43 44 }45 46 class Product {47 48 double price;49 50 Product(double price) {51 this.price = price;52 }53 54 public String toString() {55 return price + "";56 }57 58 }59 60 // 第二種方法單獨編寫一個比較器61 62 class ProductComparator implements Comparator {63 64 // 需求:按照商品價格排序65 public int compare(Object o1, Object o2) {66 67 double price1 = ((Product) o1).price;68 double price2 = ((Product) o2).price;69 70 if (price1 == price2) {71 return 0;72 } else if (price1 > price2) {73 return 1;74 } else {75 return -1;76 }77 }78 79 }View Code
下面是集合繼承結(jié)構(gòu)圖-Map部分,從圖中可以清楚的知道Map接口下子接口與實現(xiàn)類的關(guān)系。
關(guān)于Map集合中常用的方法
void clear(); 清空Mapboolean isEmpty();判斷該集合是否為空int size(); 獲取Map中鍵值對的個數(shù)。 Object put(Object key, Object value); 向集合中添加鍵值對Object get(Object key);通過key獲取value boolean containsKey(Object key); 判斷Map中是否包含這樣的keyboolean containsValue(Object value); 判斷Map中是否包含這樣的value Object remove(Object key); 通過key將鍵值對刪除.Collection values(); 獲取Map集合中所有的valueSet keySet(); 獲取Map中所有的keySet entrySet();返回此映射中包含的映射關(guān)系的 Set 視圖。
注意:存儲在Map集合key部分的元素需要同時重寫hashCode+equals方法.
1 import java.util.*; 2 3 public class MapDemo01{ 4 5 public static void main(String[] args){ 6 7 //1.創(chuàng)建Map集合 8 Map persons = new HashMap(); //HashMap的默認初始化容量是16,默認加載因子是0.75 9 10 //2.存儲鍵值對11 persons.put("10000","JACK");12 persons.put("10011","JACK");13 persons.put("10002","SUN");14 persons.put("10003","COOK");15 persons.put("10004","KING");16 persons.put("10000","LUCY");17 18 //3.判斷鍵值對的個數(shù)19 //Map中的key是無序不可重復(fù)的.和HashSet相同.20 System.out.println(persons.size());//521 22 //4.判斷集合中是否包含這樣的key23 System.out.println(persons.containsKey("10000")); //true24 25 //5.判斷集合中是否包含這樣的value26 //注意:Map中如果key重復(fù)了,value采用的是“覆蓋”。27 System.out.println(persons.containsValue("LUCY")); //true28 29 //6.通過key獲取value30 String k = "10002";31 Object v = persons.get(k);32 System.out.println(v); //SUN33 34 //7.通過key刪除鍵值對35 persons.remove("10002");36 System.out.println(persons.size()); //437 38 //8.獲取所有的value39 Collection values = persons.values();40 Iterator it = values.iterator();41 while(it.hasNext()){42 System.out.println(it.next()); 43 /*LUCY44 JACK45 COOK46 KING*/47 }48 49 //9.獲取所有的key50 //以下程序演示如何遍歷Map集合.51 Set keys = persons.keySet();52 53 Iterator it2 = keys.iterator();54 55 while(it2.hasNext()){56 Object id = it2.next();57 Object name = persons.get(id);58 System.out.println(id+"-->"+name);59 /*10000-->LUCY60 10011-->JACK61 10003-->COOK62 10004-->KING*/63 64 }65 66 //10.entrySet67 //將Map轉(zhuǎn)換成Set集合.68 /*69 Set entrySet = persons.entrySet();70 Iterator it3 = entrySet.iterator();71 while(it3.hasNext()){72 System.out.println(it3.next());73 }74 */75 76 }77 }View Code
使用集合的技巧:
看到Array就是數(shù)組結(jié)構(gòu),有角標,查詢速度很快。
看到link就是鏈表結(jié)構(gòu):增刪速度快,而且有特有方法。addFirst; addLast; removeFirst(); removeLast(); getFirst();getLast();
看到hash就是哈希表,就要想要哈希值,就要想到唯一性,就要想到存入到該結(jié)構(gòu)的中的元素必須覆蓋hashCode,equals方法。
看到tree就是二叉樹,就要想到排序,就想要用到比較。
比較的兩種方式:
一個是Comparable:覆蓋compareTo方法;
一個是Comparator:覆蓋compare方法。
LinkedHashSet,LinkedHashMap:這兩個集合可以保證哈希表有存入順序和取出順序一致,保證哈希表有序。
這是我在自學(xué)到j(luò)ava集合時通過看視頻所整理出來的一部分內(nèi)容,馬馬虎虎。在此感謝授課老師將視頻分享,讓在黑暗中摸索的我看到了一絲光明。把自己學(xué)到的一些知識分享出來是快樂的,這樣也能鞭策自己,磨礪自己。所謂當局者迷,旁觀者清,在此還望各位前輩不吝賜教,指出不足之處,這樣我也才能更好的認清自己。下面附上我所看視頻的下載地址:http://pan.baidu.com/s/1i342Y6x
新聞熱點
疑難解答