集合複習,深入理解


集合深入理解

集合:用於存儲對象,長度可變,可存儲不同類型元素

 

框架結構:

Collection:

                   Set:無序,元素不可重複

                             常見子類:

                         | ——HashSet       底層數據結構是哈希表

                                    1, 通過hashCode和equals方法判斷對象是否相等

                                     2,如果元素hashCode值不同,不會調用equals方法

                                     3,HashCode值相同纔會接着調用equals方法去判斷

                         |——TreeSet    底層數據結構是二叉樹

  可以對Set集合元素進行排序

                   List:有序,元素可重複,因爲該集合有索引

                          |—— ArrayList:底層是數組結構,查詢速度快。線程不同步,效率高。初始長度10

                                               可變長度原理:通過不斷new數組,長度是50%延長,將原數組copy到新數組,再接着添加新元素

                          |——  LinkedList:底層是鏈表,增刪數度快,查詢慢

                          |——  Vector:底層是數組結構。線程同步。延長100%

Java1.6新加入了Deque來代替Vector下的Stack類

 

 

Map     以鍵值對的形式存值

       |——               HashTable        底層是哈希表結構,不可存入null鍵null值,線程同步

       |——               HashMap                   底層是哈希表結構,允許使用null值和null鍵,不同步,效率高

       |——               TreeMap           二叉樹,紅黑樹,不同步,根據鍵 排序

 

 

Collections

                   工具類,不提供構造函數,不能創建對象,提供static方法對集合進行操作

         如:排序,synchronizedListList()方法,將普通集合包裝成線程安全的

 

Set和Map的關係:

         Map的所有鍵key集中在一起就是一個Set集合,Map集合中有一個keySet()方法,就是返回key所組成的Set集合

         如果將value值看作key的一個附屬屬性的話,key-value組合起來,也是形成一個Set集合,Map.Entry是一個內部接口

         Set集合如果存入的數據是Map.Entry形式,可以擴展成Map集合

 

 

注意:雖然說集合中存儲的是java對象,但是實際上集合中存儲的還是對對象的引用

 

如下:

import java.util.ArrayList;
import java.util.List;

class Apple {
	private double weight;

	public Apple(double weight) {
		this.weight = weight;
	}
}

public class ListTest {

	public static void main(String[] args) {
		Apple a = new Apple(1.1);
		Apple a2 = new Apple(2.2);

		List<Apple> list = new ArrayList<Apple>();
		list.add(a);
		list.add(a2);
		// 輸出true說明集合中的變量和a引用指向同一個對象
		System.out.println(list.get(0) == a);
	}
}

HashMap和HashSet

向hashSet集合中裝東西時,重寫equals方法和hashCode方法非常重要

         如下:

import java.util.HashSet;

class Stuff {
	private String id;
	private int age;

	public Stuff(String id, int age) {
		this.id = id;
		this.age = age;
	}

	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj.getClass() == Stuff.class) {
			Stuff s = (Stuff) obj;
			return s.id.equals(id);
		}
		return false;
	}

	public int hashCode() {
		// id唯一,根據返回id屬性的哈希值
		return id.hashCode();
	}

	public String toString() {
		return "id:" + id + ",age:" + age;
	}
}

public class HashSetTest {

	public static void main(String[] args) {
		HashSet<Stuff> hs = new HashSet<Stuff>();
		hs.add(new Stuff("ks123", 22));
		// 根據自己寫的hashCode方法,此處會判斷第二個對象和第一個對象一樣,所以不能重複添加
		hs.add(new Stuff("ks123", 23));
		System.out.println(hs);
	}
}

Map和List

   Map集合中的value集中起來就是一個list集合,通過map.values()方法可得到所有value數據

Values()源代碼  

	public Collection<V> values(){
//	獲取values實例變量
	Collection<v> vs = values;
//	如果vs == null,將返回new Values()對象
	return (vs!=null?vs:new Values());
}

可以看出,返回的並不是list集合對象

 

ArrayLsit和LinkedList

ArrayList的性能總體上來說還是高於LinkedList

在查詢元素時,因爲ArrayList是數組結構,有索引,比較好找

在刪除和增加元素時,ArrayList需要對元素整體移動,所以LinkedList更優

 

迭代器Iterator接口

Java要求各種集合都提供一個iterator()方法,該方法返回一個Iterator用於遍歷集合中的元素,至於返回的Iterator到底是哪種實現類,程序並不關心,這就是”迭代器模式”;

如:Iterator和Enumeration兩個接口都是迭代器模式的代表作,他們就是“迭代器接口”。

迭代器模式就是指:系統爲遍歷多種數據列表,集合,容器提供一個標準的“迭代器接口”,這些數據列表,集合,容器就可面向相同的“迭代器接口”編程,通過相同的迭代器接口訪問不同的數據列表,集合,容器裏的數據。不同的數據列表,集合,容器如何實現這個“迭代器接口”,則交給個數據列表,集合,容器自己完成

 

迭代時刪除指定元素

         由於Iterator迭代器只負責迭代,自己並沒有保留集合元素,所以通常迭代時不應該刪除集合元素,但是java允許通過Iterator的remove()方法刪除剛剛迭代的元素。

 

實際上在某些特殊情況下,可以在使用Iterator迭代集合時直接刪除集合中某個元素

如下:在迭代倒數第二個元素時,可以刪除該元素,但是刪除其他元素就會拋異常

import java.util.ArrayList;
import java.util.Iterator;

public class ArrayListRemove {

	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<String>();
		list.add("itheima");
		list.add("cloud");
		list.add("thythm");
		list.add("zhangsan");
		for (Iterator<String> it = list.iterator(); it.hasNext();) {
			String ele = it.next();
			System.out.println(ele);
			if ("thythm".equals(ele)) {
				// 直接刪除集合中的倒數第二個元素
				list.remove(ele);
			}
		}
	}
}

對於TreeSet,HashSet等Set集合而言,當使用Iterator遍歷他們時,如果正在遍歷最後一個集合元素,那麼使用Set集合的remove()方法刪除集合的任何元素不會引起異常

實際上此時的刪除動作已經在遍歷操作的範圍外了

發佈了49 篇原創文章 · 獲贊 12 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章