1. 程式人生 > >java集合Collection介紹和iterator方法

java集合Collection介紹和iterator方法

集合類的繼承關係和基本方法

陣列和集合

陣列的長度是固定,改變陣列長度的方式是建立新的陣列,將舊陣列複製到新的數組裡.

集合類能儲存任意長度的物件,集合的長度可以隨著元素的增加而增加,隨元素減少而減少

陣列和集合區別

陣列既可以儲存基本資料型別(儲存值),又可以儲存引用資料型別(可以不同種物件,儲存地址值),陣列長度是固定的,不能自動增長

集合只能儲存引用資料型別(可以不同種物件,地址值),如果儲存基本資料型別時,會自動裝箱變成相應的包裝類,集合的長度的是可變的,可以根據元素的增加而自動增長

集合是一個介面,它的繼承子類和實現類主要有:(圖片只繪製了主要框架,具體繼承和實現的類沒標出)

 

集合是介面,沒有構造方法,集合的初始化可以採用多型的形式,集合引用指向子類物件

集合介面的主要方法:

boolean add(E e)向集合中新增一個元素,如果E是集合類,就會把集合e當作元素新增到原集合中

boolean addAll(Collection c)向集合中新增一個集合的元素,添加了c中的每個元素
boolean remove(Object o)從集合中移除指定元素,

boolean removeAll(Collection c)從集合中移除所有(即存在於原集合又存在於集合c中的)元素
void clear()清空集合
boolean contains(Object o)集合中是否包含某個元素(比較的是該元素與整個集合的所有元素的地址,如果元素的類沒有重寫equals方法,則返回不正確的值,所以呼叫該方法要確保已經重寫equals方法)

boolean containsAll(Collection c)集合中是否包含了指定集合的所有元素,
boolean isEmpty() 集合是否不包含元素
int size() 返回集合中元素的個數

Object toArrays()返回一個Object型別陣列

Iterator<E> iterator()返回一個迭代器物件,這個後面說.

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

public class CollectionTest02 {
	public static void main(String[] args) {
		Collection c1 = new ArrayList();
		Collection c2 = new ArrayList();
		c1.add("a");// 向集合中新增元素
		c1.add("b");
		c1.add("c");
		c1.add("d");
		c1.add("e");
		c1.add("f");
		c2.add("a");
		c2.add("b");
		c2.add("c");
		c2.add("d");
		c2.add("d");
		c2.add("h");
		System.out.println(c1);// c1=["a","b","c","d","e","f"]
		System.out.println(c2);// c2=["a","b","c","d","h"]
		// contain
		System.out.println(c1.contains("a"));// true
		// containsAll
		System.out.println(c1.containsAll(c2));// false
		// remove
		c1.remove("a");// c1=["b","c","d","e","f"]
		// remove集合中不存在的元素值時,返回false
		System.out.println(c1.remove("g"));// false
		System.out.println(c1);
		// removeAll
		c1.removeAll(c2);// c1=[e,f]
		System.out.println(c1);
		// clear
		c2.clear();// c2=[]
		System.out.println(c2.isEmpty());// true
		System.out.println(c1.size());// 2
		// c2重新新增一些元素
		c2.add("c");
		c2.add("d");
		c2.add("d");
		c2.add("h");
		c1.add(c2);
		System.out.println(c1);
		c1.addAll(c2);
		System.out.println(c1);
	}
}
out:
a, b, c, d, e, f]
[a, b, c, d, d, h]
true
false
false
[b, c, d, e, f]
[e, f]
true
2
[e, f, [c, d, d, h]]
[e, f, [c, d, d, h], c, d, d, h]

新增自己定義的物件時

對於列印對物件,Collection介面的子類AbstractedCollection中重寫了toString方法,所以列印集合物件不會列印集合物件的地址,而是每個物件元素,但是如果集合中的元素沒有重寫toString方法,那麼打印出來的物件元素還是每個元素的地址,所以,集合中的元素要重寫toString方法,有些類已經重寫了,比如String類

equals方法,同樣對於集合中的元素,如果該元素(是一個物件)沒有重寫equals方法,那麼在集合中的操作是操作該物件引用的堆記憶體地址,remove方法刪除不了該物件,contains方法返回的值也不正確,所以要重寫equals方法

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

import students.Student;

public class CollectionTest03 {
	public static void main(String[] args) {
		Collection c1 = new ArrayList();
		c1.add(new Student(12, "張"));
		c1.add(new Student(13, "李"));
		c1.add(new Student(14, "趙"));
		c1.add(new Student(15, "劉"));
		// 如果沒有重寫equals方法,刪除的只是s1的地址,s1的地址不在集合中,所以還是原來的集合
		// contains比較的也是地址,那麼返回false
		// 重寫equals方法後,才會比較引用的內容,remove和contains方法才生效
		Student s1 = new Student(13, "李");
		System.out.println(c1.contains(s1));
		c1.remove(s1);
		System.out.println(c1);
		// toArray方法,返回Object型別陣列
		Object[] objs = c1.toArray();
		for (int i = 0; i < objs.length; i++) {
			System.out.println(objs[i]);
		}
		// 清除c1集合的全部元素
		c1.clear();
		System.out.println(c1.isEmpty());

	}
}
out:
true
[Student [age=12, name=張], Student [age=14, name=趙], Student [age=15, name=劉]]
Student [age=12, name=張]
Student [age=14, name=趙]
Student [age=15, name=劉]
true

注:ArrayList和其父類AbstractList都實現了List<>介面,效果上沒什麼特別用途,僅僅是為了讓人閱讀原始碼時知道子類實現了該核心介面。就像很多人都知道 ArrayList實現了List介面就夠了,而不需要知道它繼承AbstractList的相關細節。

Iterator<E> iterator()  獲取Iterator介面例項

iterator是集合中的一個重寫的方法,Collection繼承了Iterable,Iterable介面中定義了返回Iterator例項的方法iterator,iterator例項可以遍歷集合

jdk11    Iterable中iterator方法的定義:

Iterator<E> iterator();//只提供一個抽象方法,需要子類實現

Collection的子類下面ArrayList中實現的原始碼為:

public Iterator<E> iterator() {
        return new Itr();
    }
 private class ListItr extends Itr implements ListIterator<E> {
        ListItr(int index) {
            super();
            cursor = index;
        }

        public boolean hasPrevious() {
            return cursor != 0;
        }

        public int nextIndex() {
            return cursor;
        }

        public int previousIndex() {
            return cursor - 1;
        }

        @SuppressWarnings("unchecked")
        public E previous() {
            checkForComodification();
            int i = cursor - 1;
            if (i < 0)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i;
            return (E) elementData[lastRet = i];
        }

        public void set(E e) {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.set(lastRet, e);
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        public void add(E e) {
            checkForComodification();

            try {
                int i = cursor;
                ArrayList.this.add(i, e);
                cursor = i + 1;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
    }

Iterator和Iterable在集合中的應用

Iterable是Collection的父介面,Iterator是單獨的介面,但是Iterable中有一個方法可以返回Iterator介面的例項

然後在Collection的子類中也有實現Iterator介面及其子介面的內部類,呼叫對應的方法可以返回Iterator物件

總結:所有的Collection子類會實現Iteratable介面以實現foreach功能,Iteratable介面的實現又依賴於實現了Iterator的內部類(參照LinkedListlistIterator()descendingIterator()的JDK原始碼)。有的容器類會有多個實現Iterator介面的內部類,通過返回不同的迭代器實現不同的迭代方式。

 

大致的Iterator,Iterable和Collection關係如下圖,但是Collection子類中有多個都定義了實現Iterator介面及其子介面的內部類,

 

 

 

Iterator介面的方法

boolean hasNext() 定義一個指標,返回當前指標指向的索引處是否還有元素,如果有就返回true,此方法不會移動指標

E next()該方法返回當前指標下的元素,同時將指標後移,當該指標移動到最後面時,再呼叫hasNext返回的就是false,再呼叫next方法會報出異常java.util.NoSuchElementException

 利用iterator方法獲取Iterator例項來遍歷Collection例子

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

import students.Student;

public class IteratorTest {
	public static void main(String[] args) {
		ArrayList c1 = new ArrayList();
		c1.add(new Student(12, "張"));
		c1.add(new Student(13, "李"));
		c1.add(new Student(14, "趙"));
		c1.add(new Student(15, "劉"));
		//for迴圈遍歷集合物件,列印物件
		for (Iterator iterator = c1.iterator(); iterator.hasNext();) {
			System.out.println(iterator.next());
		}
		Iterator it = c1.iterator();
		// while迴圈直接列印物件
		while (it.hasNext()) {
			System.out.println(it.next());
		}
		// while迴圈獲取元素後,向下轉型,呼叫元素的get方法獲取物件屬性
		while (it.hasNext()) {
			Student s = (Student) it.next();
			System.out.println(s.getName() + " " + s.getAge());
		}

	}
}
out:
Student [age=12, name=張]
Student [age=13, name=李]
Student [age=14, name=趙]
Student [age=15, name=劉]
Student [age=12, name=張]
Student [age=13, name=李]
Student [age=14, name=趙]
Student [age=15, name=劉]

 

參考:https://www.aliyun.com/jiaocheng/773540.html

        http://www.monkey1024.com/javase/528

https://www.jianshu.com/p/cf82ab7e51ef

  Chinese (Simplified)English

 

Chinese (Simplified)English

 

 

 

 

 

 

 

 

 

Text-to-speech function is limited to 200 characters

 

 

 

Options : History : Feedback : Donate Close