您好,登錄后才能下訂單哦!
------- android培訓、java培訓、期待與您交流! ----------
1、集合類
為什么出現集合類?
面向對象語言對事物的體現都是以對象的形式,所以為了方便對多個對象的操作,就對對象進行存儲,集合就是存儲對象最常用的一 種方式。
數組和集合類同是容器,有何不同?
數組雖然也可以存儲對象,但長度是固定的;集合長度是可變的。數組中可以存儲基本數據類型,集合只能存儲對象。
集合類的特點
集合只用于存儲對象,集合長度是可變的,集合可以存儲不同類型的對象。
2、集合框架的構成及分類
3、Collection接口:
常用方法:
1,添加:
add(object):添加一個元素
addAll(Collection) :添加一個集合中的所有元素。
2,刪除:
clear():將集合中的元素全刪除,清空集合。
remove(obj) :刪除集合中指定的對象。注意:刪除成功,集合的長度會改變。 removeAll(collection) :刪除部分元素。部分元素和傳入Collection一致。
3,判斷:
boolean contains(obj) :集合中是否包含指定元素。
boolean containsAll(Collection) :集合中是否包含指定的多個元素。 boolean isEmpty():集合中是否有元素。
4,獲取:
int size():集合中有幾個元素。
5,取交集:
boolean retainAll(Collection) :對當前集合中保留和指定集合中的相同的元素。如果兩個集合元素相同,返回flase;如果retainAll修改了當前集合,返回true。
6,獲取集合中所有元素:
Iterator iterator():迭代器
7,將集合變成數組:
toArray();
4、List接口:元素是有序的,元素可以重復。因為該集合體系有索引。
常用子類:
ArrayList:底層的數據結構使用的是數組結構。特點:查詢速度很快。但是增刪稍慢。線程不同步。
練習:
import java.util.*; import java.lang.*; /* 將自定義對象作為元素存到ArrayList集合中,并去除重復元素。 比如:存人對象。同姓名同年齡,視為同一個人。為重復元素。 思路: 1,對人描述,將數據封裝進人對象。 2,定義容器,將人存入。 3,取出。 List判斷元素是否相同,依據的是元素的equals方法。 */ class Person { private String name; private int age; Person(String name,int age) { this.name = name; this.age = age; } public boolean equals(Object obj) { if (!(obj instanceof Person)) throw new RuntimeException("類型不匹配"); Person p = (Person)obj; System.out.println(this.name+"===="+p.name); return this.name.equals(p.name) && this.age == p.age; } public String getName() { return name; } public int getAge() { return age; } } class ArrayListTest2 { public static void sop(Object obj) { System.out.println(obj); } public static void main(String[] args) { ArrayList al = new ArrayList(); al.add(new Person("zhangsan",34)); al.add(new Person("zhangsan",34)); al.add(new Person("lisi",32)); al.add(new Person("wangwu",24)); al.add(new Person("wangwu",24)); al.add(new Person("zhaoliu",23)); al = singleElement(al); for (Iterator it = al.iterator();it.hasNext() ; ) { Person p = (Person)it.next(); sop(p.getName()+","+p.getAge()); } } public static ArrayList singleElement(ArrayList al) { //定義一個臨時容器。 ArrayList newAl = new ArrayList(); Iterator it = al.iterator(); while (it.hasNext()) { Object obj = it.next(); if (!newAl.contains(obj))//調用底層方法調用的是equals方法。所以需要復寫equals方法。 newAl.add(obj); } return newAl; } }
LinkedList:底層使用的是鏈表數據結構。特點:增刪速度很快,查詢稍慢。不同步。
相關練習:
/* 使用LinkedList模擬一個堆棧或者隊列數據結構。 堆棧:先進后出。如同一個杯子。 隊列:先進先出。First in First out FIFO 如同一個水管。 */ import java.util.*; class DuiLie { private LinkedList link; DuiLie() { link = new LinkedList(); } public void myAdd(Object obj) { link.addFirst(obj); } public void myget() { return link.removeLast(); } public boolean isNull() { return link.isEmpty(); } }
Vector:底層是數組數據結構。線程同步。被ArrayList替代了。
相關練習:
import java.util.*; /* 枚舉就是Vector特有的取出方式。 發現枚舉和迭代器很像。 其實枚舉和迭代時一樣的。 為什么要設置枚舉? 因為枚舉的名稱以及方法的名稱都過長。 所以都被迭代器取代了。 枚舉郁郁而終。 */ class VectorDemo { public static void main(String[] args) { Vector v = new Vector(); v.add("java01"); v.add("java02"); v.add("java03"); v.add("java04"); Enumeration en = v.elements(); while (en.hasMoreElements()) { System.out.println(en.nextElement()); } } }
特有方法:
增:
add(index,element);在
addAll(index,Collection):
刪:
remove(index);
改:
set(index,element);
查:
get(index);
subList(form,to);
listIterator();
List集合特有的迭代器。ListIterator是Iterator的子接口。在迭代時,不可以通過集合對象的方法操作集合中的元素。因為會發生ConcurrentModificationException異常。所以,在迭代器時,只能用迭代器的方法操作元素,可是Iterator方法時有限的。只能對元素進行判斷,取出,刪除的操作。如果要其他操作如添加,修改等,就需要使用其子接口,ListIterator。該接口只能通過List集合的ListIterator方法獲取。
5、Set:元素是無序的,元素不可以重復。
|--HashSet:底層數據結構是哈希表。線程非同步的。
HashSet是如何保證元素的唯一性的呢?
是通過元素的兩個方法,hashCode和equals來完成。
如果元素的HashCode值相同,才會判斷equals是否為true。
如果元素的hashCode值不同,不會調用equals。
注意:對于判斷元素是否存在,以及刪除等操作,依賴的方法是元素的hashCode和equals方法。
練習:
/* 往HashSet集合中存入自定義對象。 姓名和年齡視為同一人。重復元素。 */ import java.util.*; class HashSetTest { public static void sop(Object obj) { System.out.println(obj); } public static void main(String[] args) { HashSet hs = new HashSet(); hs.add(new Person("a1",11)); hs.add(new Person("a1",11)); hs.add(new Person("a2",13)); hs.add(new Person("a3",15)); //hs.add(new Person("a4",17)); sop("a1"+hs.contains(new Person("a2",13))); sop("a1"+hs.remove(new Person("a3",15))); for (Iterator it = hs.iterator();it.hasNext() ; ) { Person p = (Person)it.next(); sop(p.getName()+","+p.getAge()); } } } class Person { private String name; private int age; Person(String name,int age) { this.name = name; this.age = age; } public int hashCode() { return name.hashCode()+age; } public boolean equals(Object obj) { if (!(obj instanceof Person)) throw new RuntimeException("數據異常"); Person p = (Person)obj; return this.name.equals(p.name) && this.age == p.age; } public String getName() { return name; } public int getAge() { return age; } }
|--TreeSet:可以對Set集合中的元素進行排序。
記住:排序時,當注意條件相同時,一定要判斷一下次要條件。
因為底層數據結構是二叉樹,保證元素唯一性的依據:compareTo方法return 0;
TreeSet排序的第一種方式:讓元素自身具備比較性。元素需要實現Comparable接口,覆蓋compareTo方法。
TreeSet的第二種排序方式。當元素自身不具備比較性時,或者具備的比較性不是所需要的。這時就需要讓集合自身具備比較性。在集合初始化時,就具備比較性。
練習:
/* 練習:按照字符串長度排序。 字符串本身具備比較性,但是它的比較方式不是所需要的。 */ import java.util.*; class TreeSetTest { public static void main(String[] args) { TreeSet ts = new TreeSet(new StrLenCompare()); /*匿名內部類。 TreeSet ts = new TreeSet(new Comparator(){ public int compare(Object o1,Object o2) { if (!(o1 instanceof String && o2 instanceof String)) throw new RuntimeException("類型不匹配"); String s1 = (String)o1; String s2 = (String)o2; int num = new Integer(s1.length()).compareTo(new Integer(s2.length())); if (num==0) return s1.compareTo(s2); return num; } }); */ ts.add("abcd"); ts.add("cc"); ts.add("cba"); ts.add("aaa"); ts.add("z"); ts.add("hahaha"); for (Iterator it=ts.iterator();it.hasNext() ; ) { System.out.println(it.next()); } } } class StrLenCompare implements Comparator { public int compare(Object o1,Object o2) { if (!(o1 instanceof String && o2 instanceof String)) throw new RuntimeException("類型不匹配"); String s1 = (String)o1; String s2 = (String)o2; int num = new Integer(s1.length()).compareTo(new Integer(s2.length())); if (num==0) return s1.compareTo(s2); return num; } }
5、Map集合:
Map集合:該集合存儲鍵值對。是一對一對往里村,要保證鍵的唯一性。
1,添加。
V put(K key, V value)
void putAll(Map<? extends K,? extends V> m)
2,刪除。
void clear();
V remove(Object key)
3,判斷。
boolean containsKey(Object key)
boolean containsValue(Object value)
boolean isEmpty()
4,獲取。
V get(Object key)
int size()
Collection<V> values()
5、 重點:
Set<Map.Entry<K,V>> entrySet()
Set<K> keySet()
常用Map子類:
|--Hashtable:底層是哈希表數據結構,不可以存入null鍵null值。該集合時線程同步的。JDK1.0,效率低
|--hashMap:底層是哈希表數據結構。允許使用null鍵null值,該集合是不同步的。JDK1.2 效率高。
|--TreeMap:底層是二叉樹數據結構,線程不同步。可以用于給map集合中的鍵進行排序。
Map和Set很像。
其實Set底層就是使用了Map集合。
map集合的兩種取出方式。
1,Set<Map.Entry<k,v>>entrySet:將map集合中的映射關系存入到了set集合中,而這個關系的數據類型就是Map.Entry。
2,Set<K> keySet:將map中所有的鍵存入到Set集合,因為Set集合具備迭代器。所以可以迭代方式取出所有的鍵,在根據get方法。獲取每一個鍵對應的值。Map集合的取出原理:將map集合轉成set集合,在通過迭代器取出。
例子:
import java.util.*; class MapDemo2 { public static void main(String[] args) { Map<String,String> map = new HashMap<String,String>(); map.put("02","zhangsan02"); map.put("05","zhangsan05"); map.put("03","zhangsan03"); map.put("01","zhangsan01"); //將Map集合中的映射關系取出。存入到Set集合中。 Set<Map.Entry<String,String>> entrySet = map.entrySet(); for (Iterator<Map.Entry<String,String>> it = entrySet.iterator();it.hasNext() ; ) { Map.Entry<String,String> me = it.next(); String key = me.getKey(); String value = me.getValue(); System.out.println("key:"+key+"=value:"+value); } /* //先獲取map集合的所有鍵的set集合,keySet(); Set<String> keySet = map.keySet(); //有了Set集合,就可以獲取其迭代器。 Iterator<String> it = keySet.iterator(); while (it.hasNext()) { String key = it.next(); //有了鍵就可以通過map集合的get方法獲取其對應的值。 String value = map.get(key); System.out.println("key:"+key+"=value:"+value); } */ } } /* Map.Entry 其實Entry也是一個接口,它是Map接口中的一個內部接口。 */ interface Map { public static interface Entry { public abstract object getKey(); public abstract object getValue(); } }
6、常用工具類
Collections:它的出現給集合操作提供了更多的功能。這個類不需要創建對象,內部提供的都是靜態方法。
靜態方法:
Collections.sort(list);//list集合進行元素的自然順序排序。
Collections.sort(list,new ComparatorByLen());///按指定的比較器方法排序。
class ComparatorByLen implements Comparator<String>{
public int compare(String s1,String s2){
int temp = s1.length()-s2.length();
return temp==0?s1.compareTo(s2):temp;
}
}
Collections.max(list); //返回list中字典順序最大的元素。
int index = Collections.binarySearch(list,"zz");//二分查找,返回角標。
Collections.reverseOrder();//逆向反轉排序。
Collections.shuffle(list);//隨機對list中的元素進行位置的置換。
將非同步集合轉成同步集合的方法:
Collections中的 XXX synchronizedXXX(XXX);
List synchronizedList(list);
Map synchronizedMap(map);
原理:定義一個類,將集合所有的方法加同一把鎖后返回。
Collection 和 Collections的區別:
Collections是個java.util下的類,是針對集合類的一個工具類,提供一系列靜態方法,實現對集合的查找、排序、替換、線程安全化(將非同步的集合轉換成同步的)等操作。
Collection是個java.util下的接口,它是各種集合結構的父接口,繼承于它的接口主要有Set和List,提供了關于集合的一些操作,如插入、刪除、判斷一個元素是否其成員、遍歷等。
-------------------------------------------------------
Arrays:用于操作數組對象的工具類,里面都是靜態方法。
asList方法:將數組轉換成list集合。
String[] arr = {"abc","kk","qq"}
List<String> list = Arrays.asList(arr);//將arr數組轉成list集合。
將數組轉換成集合,有什么好處呢?用aslist方法,將數組變成集合;
可以通過list集合中的方法來操作數組中的元素:isEmpty()、contains、indexOf、set;
注意(局限性):數組是固定長度,不可以使用集合對象增加或者刪除等,會改變數組長度的功能方法。比如add、remove、clear。(會報不支持操作異常UnsupportedOperationException);
如果數組中存儲的引用數據類型,直接作為集合的元素可以直接用集合方法操作。
如果數組中存儲的是基本數據類型,asList會將數組實體作為集合元素存在。
集合變數組:用的是Collection接口中的方法:toArray();
如果給toArray傳遞的指定類型的數據長度小于了集合的size,那么toArray方法,會自定再創建一個該類型的數據,長度為集合的size。
如果傳遞的指定的類型的數組的長度大于了集合的size,那么toArray方法,就不會創建新數組,直接使用該數組即可,并將集合中的元素存儲到數組中,其他為存儲元素的位置默認值null。
所以,在傳遞指定類型數組時,最好的方式就是指定的長度和size相等的數組。
將集合變成數組后有什么好處?限定了對集合中的元素進行增刪操作,只要獲取這些元素即可。
--------------------------------------------------------------------
System類:
描述系統一些信息。
獲取系統屬性信息:Properties getProgerties();
out:標準輸出:默認是控制臺。
in:標準輸入,默認是鍵盤。
import java.util.*;
class SystemDemo
{
public static void main(String[] args)
{
Properties prop =System.getProperties();
//因為Properties是Hashtable子類,也就是Map集合的一個子類對象。
//那么可以通過map的方法取出該集合中的元素。
//該集合中存儲的都是字符串,沒有泛型定義。
//如何在系統中自定義一些特有信息呢?
System.setProperty("mykey","myvalue");
//獲取指定屬性信息。
String value = System.getProperty("os.name");
System.out.println("value="+value);
//可不可以在jvm啟動時,動態加載一些屬性信息呢?
//-D<name>=<value>
String v =System.getProperty("hah");
System.out.println("v="+v);
/*
for(Object obj:prop.keySet())
{
String value =(String)prop.get(obj);
System.out.println(obj+"="+value);
}
*/
}
}
-----------------------------------------------------------------------
Runtim對象
該類并沒有提供構造函數。
說明不可以new對象。那么會直接想到該類的方法都是靜態的。
發現該類中還有非靜態方法。
說明該類肯定會提供了方法獲取本類對象,而且該方法是靜態的。并且返回值類型是本類類型。
由這個特點可以看出該類使用了單例設計模式完成。
該方法是static Runtime getRuntime();
*/
class RuntimeDemo
{
public static void main(String[] args) throws Exception
{
Runtime r = Runtime.getRuntime();
Process p = r.exec("notepad.exe SystemDemo.java");//\為轉義字符,所以應寫為\\
//p.destroy();
}
}
------------------------------------------------------------------------
Date對象
可以對時間的進行操作的對象。
import java.util.*;
import java.text.*;
class DateDemo
{
public static void main(String[] args)
{
Date d = new Date();
System.out.println(d);
//將模式封裝到SimpleDateFormat對象中。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 E kk:mm:ss");
//調用format方法,讓模式格式化指定Date對象。
System.out.println(sdf.format(d));
}
}
-----------------------------------------------------
Calendar對象
import java.util.*;
import java.text.*;
class CalendarDemo
{
public static void main(String[] args)
{
Calendar c = Calendar.getInstance();
String[] month = {"一月","二月","三月","四月"
,"五月","六月","七月","八月"
,"九月","十月","十一月","十二月"};
String[] week ={"","星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
int index = c.get(Calendar.MONTH);
int index1= c.get(Calendar.DAY_OF_WEEK);
sop(c.get(Calendar.YEAR)+"年");
//sop(c.get((Calendar.MONTH)+1)+"月");
sop(month[index]);
sop(c.get(Calendar.DAY_OF_MONTH)+"日");
sop((c.get(Calendar.DAY_OF_WEEK)));
sop(week[index1]);
/*
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
sdf.format(d)
System.out.println(d);
*/
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
------------------------------------------------------------------------
泛型(Generic)
泛型:JDK1.5版本以后出現的新特性。用于解決安全問題。是一個安全機制。
好處:
1,將運行時期出現的問題ClassCastException,轉移到了編譯時期。
方便于程序員解決問題,讓運行時期問題減少,安全。
2,避免了強制轉換的麻煩。
泛型格式:通過<>來定義要操作的引用數據類型。
在使用java提供的對象時,什么時候寫泛型呢?
通常在集合框架中很常見。
只要見到<>就要定義泛型。
其實<>就是用了接受類型的。
當使用集合時,將集合中要存儲的數據類型作為參數傳遞到<>即可。
class GenericDemo { public static void main(String[] args) { ArrayList<String> al = new ArrayList<String>(); al.add("abc01"); al.add("abc02"); al.add("abc0991"); al.add("abc014"); //al.add(4); for (Iterator<String> it=al.iterator();it.hasNext() ; ) { String s = it.next(); System.out.println(s+":"+s.length()); } } }
泛型的使用
1、泛型類
在類聲明時通過一個標識符表示類中某個字段的類型或者某個方法的返回值或參數的類型,這樣在類聲明或實例化的時候只要指定自己需要的類型就ok。
聲明帶泛型的類:
class 類名<泛型類型1,泛型類型2……>{
泛型類型 變量名;
泛型類型 方法名(){}
返回值類型 方法名(泛型類型 變量名){}
}
使用帶泛型的類:
類名<具體類> 對象名 = new 類名<具體類>();
類型參數規范:推薦使用規范-常見的泛型,泛型只保存在源文件中,class文件中不存在;也就是說在編譯階段就會丟失,基本數據類型不能作為泛型類型;
K鍵,比如映射的鍵 key的類型
V值,比如Map的值 value類型
E元素,比如Set<E> Element表示元素,元素的類型
T 泛型,Type的意思
泛型好處:限定添加類型和消除強轉轉換的麻煩!
練習例子
需求:設計一個表示點的類Point,該類有兩個字段,一個是橫坐標x,一個縱坐標y,要求坐標有3種表達形式(Integer,Double,String):
如果不使用泛型的話可以新建多個類,但是內部方法體只有參數類型不一樣,所以用泛型的話更加簡單,給定一個占位符,并不明確表示到底是什么類型,在實際運用的時候才確定類型!!
很好的例子!
package generic;
class Point<T>{
private T t1;
private T t2;
public T getT1() {
return t1;
}
public void setT1(T t1) {
this.t1 = t1;
}
public T getT2() {
return t2;
}
public void setT2(T t2) {
this.t2 = t2;
}
}
public class GenericDemo {
public static void main(String[] args) {
//String 類型的
Point<String> p = new Point<String>();
p.setT1("2");
p.setT2("3");
System.out.println(p.getT1());
System.out.println(p.getT2());
//Integer 類型的
Point<Integer> p2 = new Point<Integer>();
p2.setT1(23);
p2.setT2(24);
System.out.println(p2.getT1());
System.out.println(p2.getT2());
//Double 類型的
Point<Double> p3 = new Point<Double>();
p3.setT1(23.00);
p3.setT2(24.00);
System.out.println(p3.getT1());
System.out.println(p3.getT2());
-----------------------------------------------------------------------------------------------------------------------------------------------
Set<String> s = new HashSet<String>();//創建一個容器對象,應該在創建的時候就明確是裝什么的
s.add("a");
//s.add(1);//此時就加不進去了,因為已經限制了容器內參數類型!
//此時就能保證集合里元素類型一致,
Set<Integer> treeSet = new TreeSet<Integer>();
//規定key只能是String,value是Date
Map<String,Date> map = new HashMap<String,Date>();
// V put(K key, V value)
Date v = map.put("", new Date());//和上面定義的類型一樣
//V get(Object key)
Date val = map.get("");
}
}
運行結果
2
3
23
24
23.0
24.0
這樣的話借助泛型一個類就可以表達多個不同類型的參數!
要求
消除強制類型的轉換,如,使用Comparable比較時每次都需要類型強轉;
1、沒有加上泛型,最初的需要強制類型轉換
package generic;
import java.util.Set;
import java.util.TreeSet;
class Person implements Comparable{//需要進行排序的類要實現Comparable
private Integer age;
public Person(Integer age) {
super();
this.age = age;
}
@Override
public int compareTo(Object o) {
Person p = (Person)o;//強制類型轉換
return this.age.compareTo(p.age);
}
public String toString(){
return this.age.toString();
}
}
public class GenericDemo2 {
public static void main(String[] args) {
Set set = new TreeSet();
set.add(new Person(15));
set.add(new Person(12));
set.add(new Person(19));
set.add(new Person(53));
set.add(new Person(62));
System.out.println(set);
}
}
第二步:加上泛型,不再需要強轉(因為類型已經固定了)!
package generic;
import java.util.Set;
import java.util.TreeSet;
class Person implements Comparable<Person>{//
private Integer age;
public Person(Integer age) {
super();
this.age = age;
}
@Override
public int compareTo(Person o) {
return this.age.compareTo(o.age);//排序
}
public String toString(){
return this.age.toString();
}
}
public class GenericDemo2 {
public static void main(String[] args) {
Set<Person> set = new TreeSet<Person>();
set.add(new Person(15));
set.add(new Person(12));
set.add(new Person(19));
set.add(new Person(53));
set.add(new Person(62));
System.out.println(set);
}
}
2、聲明多個泛型類型和通配符
若一個類中多個字段需要不同的泛型聲明,則在聲明類的時候指定多個泛型類型即可;
格式:
public interface IDAO<PK, T> {
PK add(T t);
void remove(PK id);
void update(PK id, T t);
T get(PK id);
}
在進行引用傳遞的時候泛型類型必須匹配才可以傳遞,否則編譯不通過;
使用 ? ,表示未知類型的泛型對象:
List<?> 表示未知元素的List集合;
這種帶通配符的List僅表示各種泛型List的父類,并不能把元素添加入集合中;
List<?> list = new ArrayList<>(); list.add(1);//ERROR
public void show(List<?> list){}
//表示可接受任意類型的List集合
3、泛型的上限與下限
設置泛型對象的上限使用extends,表示參數類型只能是該類型或該類型的子類:
聲明對象:類名<? extends 類> 對象名
定義類:類名<泛型標簽 extends 類>{}
設置泛型對象的下限使用super,表示參數類型只能是該類型或該類型的父類:
聲明對象:類名<? super 類> 對象名稱
定義類:類名<泛型標簽 extends類>{}
public static void show(List<? extends Number> l){
}
public static void show(List<? super String> l){
}
public static void show(List<? extends Number> l){}
public static void show(List<? super String> l){}
泛型的上限
public static void main(String[] args) {
Person<Integer> p1 = new Person<>();
p1.setVal(99);
Person<Double> p2 = new Person<>();
p2.setVal(3.14);
Person<String> p3 = new Person<>();
p3.setVal("007");
show(p1);//√
show(p2);//√
show(p3);//×
}
public static void show(Person<? extends Number> p){//此處限定了Person的參數類型只能是Number或者是其子類,而String并不屬于Number。
System.out.println(p.getVal());
}
泛型的下限
public static void main(String[] args) {
Person<Integer> p1 = new Person<>();
p1.setVal(99);//Integer
Person<Double> p2 = new Person<>();
p2.setVal(3.14);//Double
Person<String> p3 = new Person<>();
p3.setVal("007");//String
Person<Object> p4 = new Person<>();
p4.setVal(new Object());//Object
show(p1);//×
show(p2);//×
show(p3);//√
show(p4);//√
}
public static void show(Person<? super String> p){
System.out.println(p.getVal());
}
很好的例子!
package generic;
import java.util.ArrayList;
import java.util.List;
public class GenericDemo3 {
public static void main(String[] args) {
//因為show方法是用List<?>通配符接收的,所以可以是任意類型!
List<String> l1 = new ArrayList<>();//new ArrayList<String>()
show(l1);
List<Double> l2 = new ArrayList<>();
show(l2);
List<Number> l3 = new ArrayList<>();
show(l3);
List<Object> l4 = new ArrayList<>();
show(l4);
//使用up方法的話接收類型為Number或者其子類
//up(l1);//錯誤,因為up方法接收類型為Number或者其子類,l1(String)不符合!
up(l2);
up(l3);
//使用down方法的話接收類型為Number或者其父類
//down(l2);error
down(l3);
down(l4);
}
public static void down(List<? super Number> l){
for (Object object : l) {
System.out.println(object);
}
}
public static void up(List<? extends Number> l){
for (Object object : l) {
System.out.println(object);
}
}
public static void show(List<?> l){
for (Object object : l) {
System.out.println(object);
}
}
}
4、泛型接口和方法
java5后,可以聲明泛型接口,聲明方式和聲明泛型類是一樣的。
public interface IDAO<T>{}
泛型接口子類有兩種方式:
直接在子類后申明泛型;
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。