1. 程式人生 > >javaSE_day10_集合_迭代器_增強for_泛型_List介面_ArrayList_LinkedList_Vector_Set_HashSet_Map__可變引數

javaSE_day10_集合_迭代器_增強for_泛型_List介面_ArrayList_LinkedList_Vector_Set_HashSet_Map__可變引數

1.介紹

集合是一種容器,可以用來儲存多個數據

2.集合和陣列的區別

陣列的長度是固定的,集合的長度是可變的

集合中儲存的元素必須是引用資料型別

3.集合繼承關係

Collection介面為最頂層集合介面了

      Collecton介面常用的子介面有:List介面、Set介面

      List介面常用的子類有:ArrayList類、LinkedList類

     Set介面常用的子類有:HashSet類、LinkedHashSet類

 

4.迭代器

java中提供了很多個集合,它們在儲存元素時,採用的儲存方式不同。 我們要取出這些集合中的元素,可通過一種通用的獲取方式來完成

Collection集合元素的通用獲取方式:在取元素之前先要判斷集合中有沒有元素,如果有,就把這個元素取出來,繼續在判斷,如果還有就再取出出來。一直把集合中的所有元素全部取出。這種取出方式專業術語稱為迭代。

介面 Iterator : 兩個抽象方法:

boolean hasNext() 判斷集合中還有沒有可以被取出的元素,如果有返回true

next() 取出集合中的下一個元素

package com.day10;

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

public class Test01 {
	public static void main(String[] args) {
		Collection<String> coll=new ArrayList<String>();
		coll.add("www.");
		coll.add("baidu");
		coll.add(".com");
		Iterator<String> it = coll.iterator();
		while (it.hasNext()) {
			String str=it.next();
			System.out.println(str);
		}
	}

}

5.增強for

格式:

     for( 資料型別  變數名 : 陣列或者集合 ){

      輸出(變數);

       }

例:for (String string : coll) {
            System.out.println(string);
        }

 好處: 程式碼少了,方便對容器遍歷

弊端: 沒有索引,不能操作容器裡面的元素

6.泛型(新的安全機制,保證程式的安全性)

 泛型: 指明瞭集合中儲存資料的型別  <資料型別>

 泛型的通配,匹配所有的資料型別 ?

7.List介面

特點:有序,可重複元素,索引

實現子類:ArrayList    LinkedList

常用的方法

增加元素方法:

      add(Object e):向集合末尾處,新增指定的元素

      add(int index, Object e):向集合指定索引處,新增指定的元素,原有元素依次後移

刪除元素刪除:

     remove(Object e):將指定元素物件,從集合中刪除,返回值為被刪除的元素

     remove(int index):將指定索引處的元素,從集合中刪除,返回值為被刪除的元素

替換元素方法:

      set(int index, Object e):將指定索引處的元素,替換成指定的元素,返回值為替換前的元素

查詢元素方法:

       get(int index):獲取指定索引處的元素,並返回該元素

 

​​​​​​8.Iterator的併發修改異常

在迭代過程中,使用了集合的方法對元素進行操作。導致迭代器並不知道集合中的變化,容易引發資料的不確定性。

出現的異常:java.util.ConcurrentModificationException

併發修改異常解決辦法:在迭代時,不要修改集合的長度,也就是不要使用add方法。

​​​​​​9.List集合儲存資料的結構:堆疊,佇列,陣列,連結串列

堆疊:特點是先進後出,壓棧就是存元素,彈棧就是取元素

佇列:特點是先進先出

陣列:查詢元素快,增刪元素慢

連結串列:多個節點之間,通過地址進行連線,查詢元素慢,增刪元素快

10.ArrayList集合資料儲存的結構是陣列結構。元素增刪慢,查詢快,由於日常開發中使用最多的功能為查詢資料、遍歷資料,所以ArrayList是最常用的集合

11.LinkedList集合

資料儲存的結構是連結串列結構。方便元素新增、刪除的集合。實際開發中對一個集合元素的新增與刪除經常涉及到首尾操作

LinkedList主要方法

例:

	LinkedList<String> link = new LinkedList<String>();
		//新增元素
		link.addFirst("abc1");
		link.addFirst("abc2");
		link.addFirst("abc3");
		//獲取元素
		System.out.println(link.getFirst());
		System.out.println(link.getLast());
		//刪除元素
		System.out.println(link.removeFirst());
		System.out.println(link.removeLast());
		
		while(!link.isEmpty()){ //判斷集合是否為空
			System.out.println(link.pop()); //彈出集合中的棧頂元素

 

​​​​​​12.Vector集合

Vector集合資料儲存的結構是陣列結構,Vector中提供了一個獨特的取出方式,就是列舉Enumeration

Vector常見的方法:

Enumeration列舉常見的方法:

Vector集合對ArrayList集合使用的對比

​​​​​​13.Set介面

List中是可以存放重複元素的,Set所儲存的元素就是不重複的

素的equals方法,來判斷是否為重複元素

集合取出的元素的方式採用:迭代器和增強for

set的實現類:HashSet和LikedHashSet

14.HashSet

底層資料結構是雜湊表

 

15.List與Set知識點總結

List與Set集合的區別?

List:

  它是一個有序的集合(元素存與取的順序相同)

  它可以儲存重複的元素

  Set:

  它是一個無序的集合(元素存與取的順序可能不同)

  它不能儲存重複的元素

List集合中的特有方法:

void add(int index, Object element) 將指定的元素,新增到該集合中的指定位置上

Object get(int index)返回集合中指定位置的元素。

Object remove(int index) 移除列表中指定位置的元素, 返回的是被移除的元素

Object set(int index, Object element)用指定元素替換集合中指定位置的元素,返回值的更新前的元素

 

ArrayList:

底層資料結構是陣列,查詢快,增刪慢

 

LinkedList:

底層資料結構是連結串列,查詢慢,增刪快

 

HashSet:

元素唯一,不能重複

底層結構是 雜湊表結構

元素的存與取的順序不能保證一致

 

如何保證元素的唯一的?

重寫hashCode() 與 equals()方法

 

LinkedHashSet:

元素唯一不能重複

底層結構是 雜湊表結構 + 連結串列結構

元素的存與取的順序一致

16.Map介面

Map介面和Collection介面的不同:

Map介面下的集合與Collection介面下的集合,它們儲存資料的形式不同

Collection中的集合,元素是孤立存在的,向集合中儲存元素採用一個個元素的方式儲存。

Map中的集合,元素是成對存在的。每個元素由鍵與值兩部分組成,通過鍵可以找對所對應的值。

Collection中的集合稱為單列集合,Map中的集合稱為雙列集合。

需要注意的是,Map中的集合不能包含重複的鍵,值可以重複;每個鍵只能對應一個值。

 

Map介面中常用子類的集合為HashMap集合、LinkedHashMap集合

HashMap<K,V>:儲存資料採用的雜湊表結構,元素的存取順序不能保證一致

LinkedHashMap<K,V>:HashMap下有個子類LinkedHashMap,儲存資料採用的雜湊表結構+連結串列結構

注意:Map介面中的集合都有兩個泛型變數<K,V>,在使用時,要為兩個泛型變數賦予資料型別。兩個泛型變數<K,V>的資料型別可以相同,也可以不同

Map的常用方法:

public class MapDemo {
	public static void main(String[] args) {
		//建立Map物件
		Map<String, String> map = new HashMap<String,String>();
		//給map中新增元素
		map.put("星期一", "Monday");
		map.put("星期日", "Sunday");
		System.out.println(map); // {星期日=Sunday, 星期一=Monday}

		//當給Map中新增元素,會返回key對應的原來的value值,若key沒有對應的值,返回null
		System.out.println(map.put("星期一", "Mon")); // Monday
		System.out.println(map); // {星期日=Sunday, 星期一=Mon}

		//根據指定的key獲取對應的value
		String en = map.get("星期日");
		System.out.println(en); // Sunday
		
		//根據key刪除元素,會返回key對應的value值
		String value = map.remove("星期日");
		System.out.println(value); // Sunday
		System.out.println(map); // {星期一=Mon}

  Map集合遍歷:通過鍵找值;遍歷鍵值對方式

Map集合遍歷鍵找值:

keySet()方法

例:

public class MapDemo {
	public static void main(String[] args) {
		//建立Map物件
		Map<String, String> map = new HashMap<String,String>();
		//給map中新增元素
		map.put("鄧超", "孫儷");
		map.put("李晨", "范冰冰");
        map.put("劉德華", "柳巖");
		//獲取Map中的所有key
		Set<String> keySet = map.keySet();
		//遍歷存放所有key的Set集合
		Iterator<String> it =keySet.iterator();
		while(it.hasNext()){
			//得到每一個key
			String key = it.next();
			//通過key獲取對應的value
			String value = map.get(key);
			System.out.println(key+"="+value);
		}
	}
}

 Map集合遍歷鍵值對方式

即通過集合中每個鍵值對(Entry)物件,獲取鍵值對(Entry)物件中的鍵與值

public class MapDemo {
	public static void main(String[] args) {
		//建立Map物件
		Map<String, String> map = new HashMap<String,String>();
		//給map中新增元素
		map.put("鄧超", "孫儷");
		map.put("李晨", "范冰冰");
        map.put("劉德華", "柳巖");
		//獲取Map中的所有key與value的對應關係
		Set<Map.Entry<String,String>> entrySet = map.entrySet();
		//遍歷Set集合
		Iterator<Map.Entry<String,String>> it =entrySet.iterator();
		while(it.hasNext()){
			//得到每一對對應關係
			Map.Entry<String,String> entry = it.next();
			//通過每一對對應關係獲取對應的key
			String key = entry.getKey();
			//通過每一對對應關係獲取對應的value
			String value = entry.getValue();
			System.out.println(key+"="+value);
		}
	}
}

注意:Map集合不能直接使用迭代器或者foreach進行遍歷。但是轉成Set之後就可以使用了。

 

HashMap儲存自定義型別鍵值

例:Person類

package com.day10;

public class Person {
	private String name;
	private int age;
	
	public Person() {}

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	//重寫物件的hashCode和equals方法,保證物件傳入的值的唯一性
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

}

Test類:

public class HashMapTest {
	public static void main(String[] args) {
		//1,建立hashmap集合物件。
		Map<Person,String> map = new HashMap<Person,String>();
		
		//2,新增元素。
		map.put(new Person("lisi",28), "上海");
		map.put(new Person("wangwu",22), "北京");
		map.put(new Person("zhaoliu",24), "成都");
		map.put(new Person("zhouqi",25), "廣州");
		map.put(new Person("wangwu",22), "南京");
		
		//3,取出元素。鍵找值方式
		Set<Person> keySet = map.keySet();
		for(Person key : keySet){
			String value = map.get(key);
			System.out.println(key.toString()+"....."+value);
		}
		
		//取出元素。鍵值對方式
		Set<Map.Entry<Person, String>> entrySet = map.entrySet();
		for (Map.Entry<Person, String> entry : entrySet) {
			Person key = entry.getKey();
			Person value = entry.getValue();
			System.out.println(key.toString()+"....."+value);
		}
	}
}

注意:

當給HashMap中存放自定義物件時,如果自定義物件作為key存在,這時要保證物件唯一,必須複寫物件的hashCode和equals方法(如果忘記,請回顧HashSet存放自定義物件)。

如果要保證map中存放的key和取出的順序一致,可以使用LinkedHashMap集合來存放。

可變引數:

前提:引數的資料型別確定,但引數個數不確定

語法格式:資料型別...變數名

demo:

public class Test03 {
	public static void main(String[] args) {
		System.out.println(getSum(11,12,13,18));
	}

	private static int getSum(int...a) {
		int sum=0;
		for (int i : a) {
			sum+=i;
		}
		return sum;	
	}
}

注意:一個方法中,只能有一個可變引數

         可變引數必須寫在引數列表的最後一位

Map知識點總結

Map集合:

    map集合中的元素都是成對出現,成對儲存的

   map集合中的元素都是以一對鍵和值的形式組成存在的,稱為鍵值對,理解為夫妻對

   map集合中的鍵不能重複儲存,值可以重複

   map集合中的每一個鍵 對應著一個值

方法:

V put(K key, V value)  把指定的鍵與指定的值新增到Map集合中

V remove(Object key) 把指定的鍵 所對應的鍵值對元素 在Map集合中刪除,返回被刪除元素的值

Set<Map.Entry<K,V>> entrySet() 獲取到Map集合中所有的鍵值對物件的集合(Set集合)

V get(Object key) 根據指定的鍵,在Map集合中獲取對應的值

Set<K> keySet() 獲取Map集合中所有的鍵,儲存到Set集合中

 

Map集合遍歷的兩種方式

方式1:根據鍵找值的方式

//a, 獲取到Map集合中所有的鍵,返回對應的Set集合

//b, 遍歷鍵的集合,獲取到每一個鍵

//c, 通過鍵,找到對應的值

 

//獲取到Map集合中所有的鍵,返回對應的Set集合

Set<String> keys = map.keySet();

//遍歷鍵的集合,獲取到每一個鍵

for (String key : keys) {

//通過鍵,找到對應的值

Student s = map.get(key);

System.out.println( key + "..." + s.getName() + "..." + s.getAge() );

}

 

方式2:根據鍵值對物件找鍵和值的方式

//a, 獲取Map集合中所有的鍵值對元素,返回對應的Set集合

//b, 遍歷鍵值對元素集合,獲取到每一個鍵值對元素物件

//c, 通過鍵值對元素物件,獲取對應的鍵,和對應的值

 

//獲取Map集合中所有的鍵值對元素,返回對應的Set集合

Set< Map.Entry<String, Student>> entrySet = map.entrySet();

//遍歷鍵值對元素集合,獲取到每一個鍵值對元素物件

for (Map.Entry<String, Student> entry : entrySet) {

//通過鍵值對元素物件,獲取對應的鍵,和對應的值

//找鍵

String key = entry.getKey();

//找值

Student s = entry.getValue();

//列印

System.out.println( key+"..."+s.getName()+"..."+s.getAge() );

}

 

HashMap:

特點:

  是Map集合的子集合

  底層採用雜湊表結構

  HashMap集合中的key不能重複,通過重寫hashCode() 與 equals()方法來保證鍵的唯一。

  不能保證元素存與取的順序完全一致

LinkedHashMap:

特點:

是HashMap集合的子集合

底層採用雜湊表+連結串列結構

LinkedHashMap集合中的key不能重複,通過重寫hashCode() 與 equals()方法來保證鍵的唯一。

 

Collections中的方法:

public static <T> void sort(List<T> list) 排序

public static void shuffle(List<?> list) 集合中的元素儲存位置隨機打亂