----------- android培訓、java培訓、java學習型技術博客、期待與您交流! ------------
1 什麼叫集合
通常情況下,把具有相同性質的一類東西,匯聚成一個整體,就可以稱爲集合。
2 集合與數組的區別
從存儲的數據類型來看:
可以定義基本類型的數組,用來存儲基本類型數據。也可以定義引用類型的數組,存儲引用類型的數據;
集合只能存儲引用類型,而不能存儲基本類型。
從長度來看:
數組一旦定義後,其長度就不能改變;
集合的長度會自動變化。
3 集合的功能
集合可以存取元素!這是對容器的基本功能。
集合還有很多對數據的操作方法,例如查看當前集合中是否包含某個元素、移除指定的元素等功能。
4 集合共性抽取
無論是什麼集合,它們都是集合。所以可以把集合的共性向上抽取,而形成一個體系。在Java集合中的根就是Collection。
當我們學習了Collection的使用,那麼就掌握了所有集合的基本操作。(學頂層,用底層)
6 常見的數據結構
棧、隊列、數組、鏈表
(1)、後進先出,最上面的元素我們叫棧頂元素!出棧(彈棧),就是把棧頂元素從棧中移除,並返回。壓棧,就是把一個新元素放到棧頂位置
(2)、先進先出,沒底的管道。
(3)、數組的索引速度非常的快,但是添加和刪除元素,那麼就需要copy數組
(4)、鏈表元素在內存中是親戚關係,鏈表頭元素知道下一個元素的地址,下一個元素又知道下下元素的地址,最後一個元素,即鏈表尾,它的下一個元素師null。
7 Collection接口
Collection接口有2個子接口,分別是list接口、Set接口。而他們分別的實現類是:List接口有ArrayList類、Vector類、LinkedList類,Set接口中有HashSet類、TreeSet類。
Collection實例:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionDemo {
/**
* @param args
*/
public static void main(String[] args) {
//創建一個Collection接口的實現類ArrayList
Collection cl = new ArrayList();
//向集合cl添加元素
cl.add("Java");
cl.add("Html");
cl.add("php");
//迭代集合cl
Iterator it = cl.iterator();
//判斷cl集合是否有元素可以迭代
while (it.hasNext()) {
//返回下一個迭代的字符串
String ot = (String) it.next();
//打印返回的字符
System.out.println(ot);
}
}
}
結果爲:Java
Html
php
8 ListIterator與Iterator的區別
ListIterator是Itreator的子接口,它實現了Iterator的所有方法。ListItreator只能爲list接口服務。ListItreator有一個特有的功能向前遍歷boolean hasPrevious():判斷是否前一個元素;Object previous():返回前一個元素;int previousIndex():獲取前一個元素的下標。還有一個ListIterator listIterator(int index),返回指定位置的列表迭代器
ListIterator實例:
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class CollectionDemo {
/**
* @param args
*/
public static void main(String[] args) {
// 創建一個Collection接口的實現類ArrayList
List cl = new ArrayList();
// 向集合cl添加元素
cl.add("Java");
cl.add("Html");
cl.add("php");
// 迭代集合cl
ListIterator it = cl.listIterator();
// 判斷cl集合是否有元素可以迭代
while (it.hasNext()) {
// 返回下一個迭代的字符串
String ot = (String) it.next();
}
// 逆向遍歷,如果有元素就返回true
while (it.hasPrevious()) {
// 逆向字符串
String ot = (String) it.previous();
// 打印字符串
System.out.println(ot);
}
}
}
結果爲:php
Html
Java
9 list接口
list是Collection的子接口!List包子元素存入的順序!也可以包含重複元素,List可以添加、移除元素,而且List的長度可以改變。
Lsit接口的特點:
1.可以添加重複元素。
2.List集合石有序的
3.list元素有索引
ArrayList實例:
import java.util.ArrayList;
import java.util.List;
public class ListDemo {
/**
* @param args
*/
public static void main(String[] args) {
//創建一個ArrayList集合
List li = new ArrayList();
//向集合li添加元素
li.add("java");
li.add("mysql");
li.add("oracle");
li.add("android");
li.add("java");
li.add("java");
System.out.println(fun(li));
}
//定義一個去除list集合中重複元素
public static List fun(List list) {
//新建一個newlist集合
List newlist = new ArrayList();
//遍歷參數集合
for (Object object : list) {
//判斷新集合是否不包含object
if (!newlist.contains(object)) {
//不包含就添加元素
newlist.add(object);
}
}
//返回新的元素
return newlist;
}
}
10 Vector類:
它是在jdk1.0版本的時候出現的,在1.2版本出現了Iterator迭代器後,它的作用逐漸被替換了。Vector底層用的是數組結構,與ArrayList的作用相同!
Vector中的方法都是同步的,即Vector是線程安全的。
Vector特有的方法:
void addElement(Object):等同與add()
Object elementAt(int):等同與get()
Object removeElement(Object):等同與remove()
Enumeration elements():返回枚舉器,它是老版本的迭代器!
Vector對象方法的實例:
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
public class VectorDemo {
/**
* 適配器模式:
* 轉換器思想
* 把Iterator,轉換成Enumeration,並返回其方法
* 核心,是定義其類型屬性。
*
*/
public static void main(String[] args) {
// 創建一個ArrayList集合
List li = new ArrayList();
// 添加元素
li.add("ZhangSan");
li.add("Lisi");
li.add("WangWu");
// 迭代集合
Iterator it = li.iterator();
// 創建舊版本迭代對象,並傳入it對象
Enumeration em = new MyTransformer(it);
prin(em);
}
// 封裝一個遍歷方法,傳入參數爲接口對象
public static void prin(Enumeration em) {
// 判斷對象中是否有元素
while (em.hasMoreElements()) {
// 返回下一個字符串元素
String type = (String) em.nextElement();
// 打印字符串
System.out.println(type);
}
}
}
// 實現Enumeration接口
class MyTransformer implements Enumeration {
// 定義Iterator類型的屬性
private Iterator it;
// 在構造器加載的時候創建Iterator對象
public MyTransformer(Iterator it) {
this.it = it;
}
// 重寫Enumeration判斷元素存在的抽象方法
@Override
public boolean hasMoreElements() {
// 返回屬性類的判斷元素方法
return it.hasNext();
}
@Override
// 重寫Enumeration遍歷下一個元素的抽象方法
public Object nextElement() {
// 返回屬性類的遍歷下一個元素方法
return it.next();
}
}
結果:ZhangSan
Lisi
WangWu
11 LinkedList實現類
LinkedList是list實現類之一,它的數據結構是鏈表結構。特點是:增刪快,查詢慢,線程同步的,比較安全。
LinkedList特有方法:
void addFirst(Object)
void addLast(Object)
Object getFirst()
Object getLast()
Object removeFirst()
Object removeLast()
void push(Object o):壓棧,就是把元素添加到0下標位置,與addFirst一樣。
Object pop():彈棧,就是把0下標位置的元素返回並移除。
LinkedList實例:
import java.util.LinkedList;
public class LinkedListDemo {
/**
* LinkedList數據結果是鏈表結構:
*而它在內存中操作的是棧,它的特性是"後進先出"
*/
public static void main(String[] args) {
// 創建一個LinkedList集合
LinkedList li = new LinkedList();
// 壓棧,壓入元素
li.push("張三");
li.push("李四");
li.push("王五");
IQueue mi = new MyIQueue(li);
// 利用多態,調用MyIQueue對象的mpty方法,判斷集合是否不爲空
while (!mi.mpty()) {
//打印彈棧元素
System.out.println(mi.op());
}
}
}
// 定義一個接口,與三個方法
interface IQueue {
void ph(Object obj);
boolean mpty();
Object op();
}
// 實現接口
class MyIQueue implements IQueue {
// 定義一個LinkedList類型的屬性並初始化
private LinkedList lk = new LinkedList();;
// 定義一個能接受LinkedList類型的構造器
public MyIQueue(LinkedList lk) {
this.lk = lk;
}
@Override
// 實現接口的抽象方法
public void ph(Object obj) {
// 調用lk對象的push方法,讓參數壓棧
lk.push(obj);
}
@Override
// 實現接口的抽象方法
public boolean mpty() {
// 調用lk對象的isEmpty方法,判斷集合是否爲空
return lk.isEmpty();
}
@Override
// 實現接口的抽象方法
public Object op() {
// 調用lk對象的push方法,讓元素彈棧
return lk.pop();
}
}
結果爲:王五
李四
張三
12 泛型:
1.什麼是泛型?
具有一個多個類型參數的類就是泛型。它的表現格式:<>
2.泛型的好處
1.在運行期間的問題ClassCastException問題轉成編譯失。敗,體現在編譯時期,程序員就可以解決問題。
2.避免了強制轉換的麻煩。
3.泛型的運用
泛型時在編譯器使用的技術,到了運行時期,泛型就不存在了。這是因爲泛型的擦除,編譯器檢查了泛型的類型正確後,在生成的類文件是沒有泛型的。但當
類型已經確定該了是同一個類型的元素,所以在運行時,只要獲取到該元素的類型,就不需要轉型了。
4.泛型的使用
當類中的操作的引用數據類型不確定的時候,以前用的Object來擴展的,現在可以用泛型來表示。這樣避免強轉的麻煩,而且將運行問題轉移到到編譯時期。
泛型實例1:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class GenericDemo {
/**
* @param args
*/
public static void main(String[] args) {
List<String> li = new ArrayList<String>();
li.add("java");
// li.add(100);如果插入的元素師int型,就會出現添加類型錯誤,因爲已經定義了li集合對象是String類型的
li.add("C++");
li.add("php");
// 迭代器也必須指定String泛型,這樣避免了迭代出來的數據後,還得進行強轉。
Iterator<String> it = li.iterator();
while (it.hasNext()) {
// 此處在沒有定義泛型之前必須進行強轉,因爲iterator的next方法迭代出來的數據是不確定的類型
String string = it.next();
System.out.println(string);
}
}
}
結果爲:java
C++
php
泛型的限定:
上限:<? extends T> 只能使用T類型或者T類型的子類對象。
下限:<? super T> 只能使用T類型或者T的父類及接口實例對象
上限什麼時候用:往集合中添加元素時,既可以添加T類型對象,又可以添加E的子類型對象。爲什麼?因爲取的時候,T類型既可以接受T類對象,又可以接收T的子類對象。
下限什麼時候用:當從集合中獲取元素進行操作的時候,可以用當前元素的類型接受,也可以用當前元素的父類型接收。
泛型實例2:
import java.util.ArrayList;
import java.util.List;
public class GenericDemo1 {
/**
* @param args
*/
public static void main(String[] args) {
List<? extends Object> li = new ArrayList<String>();
/*
* 這樣添加是錯誤的,String雖然是Object的子類,但是Object的子類非常多,
* 你不確定它是哪個?既然不確定,又怎麼添加具體類型的對象呢?
*/
// li.add("abc");
List<? super String> lia = new ArrayList<Object>();
/*
* 這樣是可以的,下限。因爲"abc"是字符串對象,而lia的集合規定了,只能添加String類型或者它的父類對象 ,所以是可以的
*/
lia.add("123");
// 不可以在new的時候使用通配符。因爲創建的時候,必須明確它的類型
// ArrayList lib = new ArrayList<? extends Object>();
List<?> list1 = new ArrayList();
List<?> list2 = new ArrayList<String>();
List<? extends Object> pList = new ArrayList<Object>();
List<? super String> sList = new ArrayList<String>();
List<?> list3 = sList;
// list1.add("abc");error,因爲list不確定是什麼類型的集合。
list2.isEmpty();// 這個可以是因爲使用Object引用來指向isEmpty()方法的返回值了
// list3.add(123);// 它是不確定的類型集合,既然不確定就不能添加具體的對象,而默認的是Object的類型。
}
// 可以在定義的時候使用通配符。因爲你在給它傳入參數的時候,指定了它的一個範圍。
public static void fun(List<? extends Object> list, String str) {
// 只能對集合中的元素調用Object類中的方法,具體子類型的方法都不能用,因爲子類型不確定。
// 用Object的get方法引用指向了它的返回值
System.out.println(list.get(0));
}
}
總結:
1.可以使用List<? extends person>指向List<student>、List<person>、List<Employee>。只要元素類型爲Person,或其子類就是可以的。
2.可以使用List<? super student>指向List<student>、List<person>、List<Object>。只要元素類型爲Student或Student父類就是可以的。
3.注意:不能再new時使用通配符。
new ArrayLsit<? extends person>(),這是不可以的!
4.可以在定義引用時使用通配符:
ArrayList<? extends Person>list;
----------- android培訓、java培訓、java學習型技術博客、期待與您交流! ------------