java的知識點23——泛型Generics、Collection介面、List特點和常用方法、 ArrayList特點和底層實現
泛型Generics
一般通過“容器”來容納和管理資料。程式中的“容器”就是用來容納和管理資料。
陣列就是一種容器,可以在其中放置物件或基本型別資料。
陣列的優勢:是一種簡單的線性序列,可以快速地訪問陣列元素,效率高。如果從效率和型別檢查的角度講,陣列是最好的。
陣列的劣勢:不靈活。容量需要事先定義好,不能隨著需求的變化而擴容。比如:在一個使用者管理系統中,要把今天註冊的所有使用者取出來,那麼這樣的使用者有多少個?在寫程式時是無法確定的。因此,在這裡就不能使用陣列。
容器,也叫集合(Collection)
泛型:可以幫助我們建立型別安全的集合。在使用了泛型的集合中,遍歷時不必進行
泛型的本質就是“資料型別的引數化”。可以把“泛型”理解為資料型別的一個佔位符(形式引數),即告訴編譯器,在呼叫泛型時必須傳入實際型別。
未使用泛型時:
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介面的兩個子介面是List、Set介面。
注:由於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個:ArrayList、LinkedList和Vector
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);
}
}