1. 程式人生 > >java的知識點23——泛型Generics、Collection介面、List特點和常用方法、 ArrayList特點和底層實現

java的知識點23——泛型Generics、Collection介面、List特點和常用方法、 ArrayList特點和底層實現

泛型Generics

一般通過“容器”來容納和管理資料。程式中的“容器”就是用來容納和管理資料。

陣列就是一種容器,可以在其中放置物件基本型別資料

陣列的優勢:是一種簡單的線性序列,可以快速地訪問陣列元素,效率高。如果從效率型別檢查的角度講,陣列是最好的。

陣列的劣勢不靈活容量需要事先定義好,不能隨著需求的變化而擴容。比如:在一個使用者管理系統中,要把今天註冊的所有使用者取出來,那麼這樣的使用者有多少個?在寫程式時是無法確定的。因此,在這裡就不能使用陣列。

容器,也叫集合(Collection)

泛型:可以幫助我們建立型別安全的集合在使用了泛型的集合中,遍歷時不必進行

強制型別轉換。JDK提供了支援泛型的編譯器,將執行時的型別檢查提前到了編譯時執行,提高了程式碼可讀性和安全性。

泛型的本質就是“資料型別的引數化”。可以把“泛型”理解為資料型別的一個佔位符(形式引數),即告訴編譯器,在呼叫泛型時必須傳入實際型別。

未使用泛型時:

package cn.dym11;
//測試泛型
public class TestGeneric {
	public static void main(String[] args) {
		MyCollection mc=new MyCollection();
		mc.set("代止兮", 0);
		mc.set(8888, 1);
		Integer a=(Integer) mc.get(1);
		String b=(String) mc.get(0);
	}
}
class MyCollection {
	Object [] objs=new Object[5];
	public void set(Object obj,int index) {
		objs[index]=obj;
	}
	public Object get(int index) {
		return objs[index];
	}
}

使用泛型:

package cn.dym11;
//測試泛型
public class TestGeneric {
	public static void main(String[] args) {
		MyCollection<String> mc=new MyCollection<String>();
		mc.set("代止兮", 0);
		String b=mc.get(0);
	}
}
class MyCollection <E> {
	Object [] objs=new Object[5];
	public void set(E e,int index) {
		objs[index]=e;
	}
	public E get(int index) {
		return (E) objs[index];
	}
}

自定義泛型、容器中使用泛型

類的宣告處增加泛型列表,如:<T,E,V>

public class Test {
    public static void main(String[] args) {
        // 以下程式碼中List、Set、Map、Iterator都是與容器相關的介面;
        List<String> list = new ArrayList<String>();
        Set<Man> mans = new HashSet<Man>();
        Map<Integer, Man> maps = new HashMap<Integer, Man>();
        Iterator<Man> iterator = mans.iterator();
    }
}

Collection、List、Set、Map、Iterator介面都定義了泛型。


Collection介面

Collection 表示一組物件,它是集中、收集的意思。Collection介面的兩個子介面是ListSet介面。

注:由於List、Set是Collection的子介面,意味著所有List、Set的實現類都有上面的方法。

package cn.dym11;

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

//測試Collection介面中的方法
public class TestList {
	public static void main(String[] args) {
		Collection<String> c=new ArrayList<>();
		System.out.println(c.size());
		System.out.println(c.isEmpty());
		
		c.add("代止兮");
		c.add("蒼凌");
		System.out.println(c);
		System.out.println(c.size());
		
		System.out.println(c.contains("蒼凌"));
		
		Object[] objs=c.toArray();
		System.out.println(objs);
		
		c.remove("蒼凌");
		System.out.println(c);
		
		c.clear();
		System.out.println(c.size());
	}
	
}

package cn.dym11;

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

//測試Collection介面中的方法
public class TestList {
	public static void main(String[] args) {
		test02();
	}
	public static void test02() {
		
		List<String> list01=new ArrayList <>();
		list01.add("aa");
		list01.add("bb");
		list01.add("cc");
		
		List<String> list02=new ArrayList <>();
		list02.add("aa");
		list02.add("dd");
		list02.add("ee");
		
		System.out.println("list01:"+list01);  //list01:[aa, bb, cc]
		
		// list01.addAll(list02);
		// System.out.println("list01:"+list01);  //list01:[aa, bb, cc, aa, dd, ee]
		
		// list01.removeAll(list02);
		// System.out.println("list01:"+list01);  //list01:[bb, cc]
		
		list01.retainAll(list02);
		System.out.println("list01:"+list01); // list01:[aa]
		
		System.out.println(list01.containsAll(list02));
	}
}


List特點和常用方法

List是有序、可重複的容器 

有序:List中每個元素都有索引標記。

可重複:List允許加入重複的元素。更確切地講,List通常允許滿足 e1.equals(e2) 的元素重複加入容器。

List介面常用的實現類有3個:ArrayListLinkedListVector

List中操作索引的常用方法

package cn.dym11;

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

public class TsetList01 {
    public static void main(String[] args) {
    	test01();
    }
    public static void test01(){
    	List<String> list=new ArrayList<>();
    	list.add("A");
    	list.add("B");
    	list.add("C");
    	list.add("D");
    	
    	System.out.println(list);
    	
    	list.add(2,"代止兮");
    	System.out.println(list);
    	
    	list.remove(2);
    	System.out.println(list);
    	
    	list.set(2, "代止兮");
    	System.out.println(list);
    	
    	System.out.println(list.get(2));
    	
    	list.add("C");
    	list.add("B");
    	list.add("A");
    	System.out.println(list);
    	System.out.println(list.indexOf("B"));  //找到,返回索引位置
    	System.out.println(list.indexOf("d"));  //找不到,返回-1
    	System.out.println(list.lastIndexOf("B"));
    }
}


 ArrayList特點和底層實現

ArrayList底層是用陣列實現的儲存。   特點:查詢效率高,增刪效率低,執行緒不安全。

ArrayList底層使用Object陣列來儲存元素資料

陣列長度是有限的,而ArrayList是可以存放任意數量的物件,長度不受限制,那麼它是怎麼實現的呢?本質上就是通過定義新的更大的陣列,將舊陣列中的內容拷貝到新陣列,來實現擴容。

自定義實現一個ArrayList,體會底層原理

第一個版本:

package cn.dym11;

// 自定義實現一個ArrayList,體會底層原理

public class SxtArrayList {
    private Object[] elementData;
    private int size;
    
    private static final int DEFAULT_CAPACITY=10;
    
    public SxtArrayList() {
    	elementData=new Object[DEFAULT_CAPACITY];
    }
    
    public SxtArrayList(int capacity) {
    	elementData=new Object[capacity];
    }
    
    public void add(Object obj) {
    	elementData[size++]=obj;
    }
    
    public String toString() {
    	StringBuilder sb=new StringBuilder();
    	// [a,b,c]
    	sb.append("[");
//    	for(Object obj:elementData) {
//    		sb.append(obj);
//    	}
//    	sb.append("]");
    	
    	for(int i=0;i<size;i++) {
    		sb.append(elementData[i]+",");
    	}
    	sb.setCharAt(sb.length()-1, ']');
    	
    	return sb.toString();
    }
    
    public static void main(String[] args) {
    	SxtArrayList s1=new SxtArrayList(20);
    	s1.add("aa");
    	s1.add("bb");
    	
    	System.out.println(s1);
    }
}

//增加泛型
//增加陣列擴容

package cn.dym11;

// 自定義實現一個ArrayList,體會底層原理
//增加泛型
//增加陣列擴容
public class SxtArrayList02<E> {
    private Object[] elementData;
    private int size;
    
    private static final int DEFAULT_CAPACITY=10;
    
    public SxtArrayList02() {
    	elementData=new Object[DEFAULT_CAPACITY];
    }
    
    public SxtArrayList02(int capacity) {
    	elementData=new Object[capacity];
    }
    
    public void add(E element) {
    	// 什麼時候擴容??
    	if(size==elementData.length) {
    		//怎麼擴容?? //擴容操作
    		Object[] newArray=new Object[elementData.length+(elementData.length>>1)];
    		System.arraycopy(elementData, 0, newArray, 0,elementData.length );
    		elementData=newArray;
    	}	
    	elementData[size++]=element;
    }
    
    public String toString() {
    	StringBuilder sb=new StringBuilder();
    	// [a,b,c]
    	sb.append("[");
//    	for(Object obj:elementData) {
//    		sb.append(obj);
//    	}
//    	sb.append("]");
    	
    	for(int i=0;i<size;i++) {
    		sb.append(elementData[i]+",");
    	}
    	sb.setCharAt(sb.length()-1, ']');
    	
    	return sb.toString();
    }
    
    public static void main(String[] args) {
    	SxtArrayList02 s1=new SxtArrayList02(20);
    	for(int i=0;i<40;i++) {
    		s1.add("dym"+i);
    	}
    	
    	System.out.println(s1);
    }
}