泛型
數組直接定義了存儲的類型,防止出現其他類型的元素,集合能不能也像數組一樣,直接規定我們集合的存儲類型,針對這種情況
引進一種技術:泛型
<數據類型> --- 引用數據類型
泛型:將明確的集合類型的工作推遲到了創建對象或者調用方法的時候,屬於一種參數化類型,可以作爲參數傳遞.
泛型的好處:
1)將運行時期異常提前到了編譯時期
2)優化了設計,解決了黃色警告線問題
3)避免了強制類型轉換
爲什麼引出泛型?
1. 泛型的引出可以提供程序的安全性!
解決了java.lang.ClassCastException:類轉換異常
2.在早期的時候,使用Object類型代表任意類型,向上轉型沒有問題,
使用向下轉型的時候,可能會出現問題(需要的類型有問題),這個時候就需要引入泛型操作
在API文檔上,接口,類,方法上有<E> ,都是泛型
public class ObjectTool<T> {
//將泛型定義在接口上
public interface Inter<T> {
//接口中變量是常量: public static final int num ;
public abstract void show() ; //抽象方法
//泛型的應用:在接口中,類中,方法上應用,在集合中應用最多!
//接口中泛型,子實現類的第一種情況,就是已經知道是什麼類型了
//第二種情況,就是不知道具體的類型是什麼
泛型高級(通配符)
<?> :代表任意類型Object類型,或者任意的Java類
<? extends E>:向下限定,E的子類或者E這個類型
<? super E>:向上限定,E及其他的父類
ArrayList集合
ArrayList是List接口中常用的一個子實現類
遍歷功能:
1)一個是Collection的iterator()
2)size()和get(int index)普通for循環
public class ArrayListDemo1 {
public static void main(String[] args) {
ArrayList<String> l=new ArrayList();
l.add("hello");
l.add("world");
l.add("java");
Iterator<String> it=l.iterator();
while(it.hasNext()) {
String s=it.next();
System.out.println(s);
}
}
}
Vector集合
Vector集合的特點:
底層是一種可增長對象數組,查詢快,增刪慢
線程安全,同步,執行效率高
特有功能:
public void addElement(Object obj)------->add(Object obj)
public Enumeration elements():返回此向量的枚舉--->相當於:public Iterator iterator()
boolean hasMoreElements() --->boolean hasNext() ;
Object nextElement() --->Object next() ;
import java.util.Enumeration;
import java.util.Vector;
public class VectorDemo1 {
public static void main(String[] args) {
Vector v=new Vector() ;
v.addElement("hello");
v.addElement("world");
v.add("javaee");
Enumeration<String> e=v.elements();
while(e.hasMoreElements()) {
String s=e.nextElement();
System.out.println(s);
}
}
}
LinkedList集合
LinkedList集合的特點:
底層是一種鏈表實現,查詢慢,增刪快
線程不安全的,不同步,執行效率高
特有功能:
添加功能
addFirst(Object e):將指定的元素插入到列表的開頭
addLast(object e):將指定的元素添加到列表末尾
獲取功能:
getFirst():獲取列表第一個元素
getLast():獲取列表第二個元素
刪除功能
public Object removeFirst()移除並返回此列表的第一個元素。
public Object removeLast()
模擬棧結構的特點,先進後出
import java.util.Iterator;
import java.util.LinkedList;
class Mystack{
private LinkedList list;
public Mystack() {
list=new LinkedList<>();
}
public void add(Object obj) {
list.addFirst(obj);
}
public Object get() {
return list.removeFirst();
}
public boolean isEmpty() {
return list.isEmpty();
}
}
public class MystackDemo1 {
public static void main(String[] args) {
Mystack m=new Mystack();
m.add("hello");
m.add("world");
m.add("java");
while(!m.isEmpty()) {
System.out.println(m.get());
}
}
}
需求:給集合中添加重複的元素(字符串類型),將重複的元素從集合去除掉!
思路:
1)創建一箇舊集合,添加重複元素
2)創建一個新集合
3)遍歷舊集合中的元素獲取到每一個元素
在舊集合中判斷新集合中是否包含舊集合中的元素
包含,不搭理
不包含,添加到新集合中
4)遍歷新集合
import java.util.ArrayList;
import java.util.Iterator;
//去重集合中重複的元素
//假設:現在的需求:不允許新建一個集合去完成,怎麼辦?
public class ArrayListTest2 {
public static void main(String[] args) {
//創建ArrayList集合對象
ArrayList array = new ArrayList() ;
//添加元素
array.add("hello") ;
array.add("world") ;
array.add("java") ;
array.add("javaee") ;
array.add("hello") ;
array.add("world") ;
array.add("hello") ;
array.add("javaee") ;
//System.out.println(array);
//引入選擇排序,
//用0索引對應的元素依次和後面索引對應的元素進行比較
//如果前面的元素和後面的元素重複了,把後面元的幹掉
// 依次1索引....
for(int x = 0 ; x < array.size()-1 ; x ++) {
for(int y = x +1 ; y < array.size() ; y ++) {
//判斷,前面的索引對應的元素和後面索引對應的元素進行比較,如果相等就幹掉後面重複的
if(array.get(x).equals(array.get(y))) {
array.remove(y) ;
y-- ;
}
}
}
//遍歷集合
Iterator it = array.iterator() ;
while(it.hasNext()) {
String s = (String) it.next() ;
System.out.println(s);
}
}
}
需求:使用集合ArrayList存儲自定義對象(Student),去除重複的對象(成員變量的值一樣,看成一個人)
問題:按照存儲字符串(新建集合的思想)的形式來去存儲自定義對象,發現自定義對象並沒有去重,爲什麼?
因爲contains方法底層依賴於equals方法
equals方法默認比較的是地址值,如果想讓equals()方法比較他們的內容是否相同,需要重寫equals(),也就意味着存儲自定義類必須重寫equals()方法,這樣才能比較的是這些對象的內容是否相同
可變參數
可變參數:當一個方法的參數個數不確定的時候,要使用可變參數
格式: 修飾符 返回值類型 方法名(數據類型...變量名){...}
注意:
1)變量名:看成一個數組
2)使用的時候數據類型 ...
注意:根據具體的需求去完成,一般情況,知道有這個特性就可以了
增強for循環
ArrayList集合存儲自定義對象並遍歷,有幾種方式?
1.Iterator iterator() ;
2.listIterator listiterator();(可以不寫)
3.普通for循環:size()/get(int index)
4.增強for循環
public class 增強for {
public static void main(String[] args) {
String [] str= {"hello","world","java"};
for(String s:str) {
System.out.print(s+" ");
}
}
}
asList方法
針對數組操作的工具類:Arrays,提供了一個方法:
public static <T> List<T> asList(T... a) :將數組轉換成固定大小的集合
注意:如果使用此方法,那麼集合的長度不可變
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class AsListDemo1 {
public static void main(String[] args) {
String[] s= {"hello","world","javaee"};
List<String> l=Arrays.asList(s);
Iterator<String> it=l.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
Jdk5以後的新特性
增強for,靜態導入,可變參數,泛型,自動拆裝箱...
增強for循環的格式
for(數據大類型 變量名 : 數組或者集合對象名){
輸出變量即可!
}
增強for的出現時替代迭代器的,所以在遍歷集合或者遍歷數組就可以使用增強for去完成
增強for循環的弊端:如果集合的對象是null,如果再次對集合操作,就會出現異常
解決辦法:對集合進行判斷
靜態導入:Jdk5一個新特性
特點:
1)前提是該方法必須是靜態的
2)導入到的一個方法的級別
靜態導入的格式:
import static 包名.類名.方法名;
錯誤:import static java.util.ArrayList.add; 方法必須是靜態方法
之前導包:java.util.Scanner; 導入到類的級別
import static java.lang.Math.abs; 導入到方法的級別
集合的嵌套遍歷
有一個Java基礎班,裏面有很多學生,把一個班級集合:ArrayList<Student>
不止一個Java基礎班,這個時候就定義大集合:ArrayList<ArrayList<Student>>
有三個基礎班,分別遍歷每一個班裏面學生信息:(name,age)
步驟:
第一步:將每個班的學生先添加到小集合
第二部:將每個小集合添加到大集合
遍歷:
採用增強for嵌套遍歷
集合接收隨機數:
需求: 求10個1~20之間的隨機數,要求數據不能重複
分析:
可以使用數組,數組的長度固定,不夠好,使用集合去做
創建一個隨機數類對象
Random
獲取指定的隨機數的範圍:
int nextInt() ; 獲取的int類型的範圍
int nextInt(int n) ;獲取1~n之間的數據 ,[0,n)
創建一個ArrayList集合對象,元素類型:Integer類型
定義統計遍歷:count 是從0開始
判斷如果統計遍歷小於10
先計算出1-20之間的隨機數,還需要判斷集合中是否包含這些元素
如果不包含,添加,count++
包含,重複,不搭理了....
大於10,不搭理
遍歷即可
import java.util.ArrayList; import java.util.Random; public class 集合添加隨機數 { public static void main(String[] args) { Random r=new Random(); ArrayList<Integer> l=new ArrayList(); int n=0; while(n<10) { int num=r.nextInt(20)+1; if(!l.contains(null)) { l.add(num); n++; } } for(int i:l) { System.out.println(i); } } }