Java基礎(chǔ)——jdk1.5新特性及集合與數(shù)組的轉(zhuǎn)換

jdk1.5的新特性

泛型是一種泛泛的類型,泛指某一種類型竟秫,是在創(chuàng)建對(duì)象或者調(diào)用方法或者實(shí)現(xiàn)接口才明確的類型娃惯。

泛型好處提高安全性(將運(yùn)行期的類型轉(zhuǎn)換錯(cuò)誤提前到編譯期),省去強(qiáng)轉(zhuǎn)的麻煩肥败。

泛型使用注意事項(xiàng)

  1. <>中放的必須是引用數(shù)據(jù)類型趾浅;
  2. 前后的泛型必須一致,或者后面的泛型可以省略不寫(1.7的新特性菱形泛型) (建議后面的也寫全);
  3. 在創(chuàng)建對(duì)象或者調(diào)用方法或者實(shí)現(xiàn)接口明確泛型的時(shí)候馒稍,盡量不要明確成Object皿哨,因?yàn)檫@樣做沒(méi)有意義(泛型的由來(lái)就是由Object的轉(zhuǎn)型的問(wèn)題得到的);
  4. 泛型是JDK1.5出現(xiàn)的纽谒。

代碼演示:

public static void demo1() {
    ArrayList list = new ArrayList();
    list.add(110);//添加一個(gè)Integer類型的 110证膨,在沒(méi)有使用泛型的時(shí)候 list可以添加任意的引用類型  
    list.add(true); //添加一個(gè)Boolean類型的 true
    list.add(new Person("張三", 23)); //添加一個(gè)Person
    Iterator it = list.iterator();
    while(it.hasNext()) {
        System.out.println(it.next());  //將集合里面的元素打印出來(lái)
    }
}

public static void demo2() {
    ArrayList list = new ArrayList();
    list.add(110);          
    list.add(true);             
    list.add(new Person("張三", 23)); 
    Iterator it = list.iterator();
    while(it.hasNext()) {
        //如果我想使用Person的特有功能 需要強(qiáng)制轉(zhuǎn)換成Person類型
        Person p = (Person)it.next();//編譯不報(bào)錯(cuò), 運(yùn)行的時(shí)候立刻報(bào)錯(cuò)鼓黔,因?yàn)榇鎯?chǔ)的 110 和 true 并不是Person類型 單卻強(qiáng)制轉(zhuǎn)換成Person類型 會(huì)報(bào)出類型轉(zhuǎn)換錯(cuò)誤          
        System.out.println(p.getName() + "..." + p.getAge());
    }
}

//ArrayList存儲(chǔ)字符串并遍歷泛型版
public static void demo3() {
    ArrayList<Person> list = new ArrayList<>();     //<Person>規(guī)定 list對(duì)象里面必須存儲(chǔ)Person類型的元素央勒,存儲(chǔ)其他類型的編譯就會(huì)報(bào)錯(cuò)
    list.add(new Person("張三", 23));
    list.add(new Person("李四", 24));
    list.add(new Person("王五", 25));
    list.add(new Person("趙六", 26));

    Iterator<Person> it = list.iterator();          //獲取的迭代器也是Person類型的泛型
    while(it.hasNext()) {
        Person p = it.next();               //it.next()獲取到的元素 就不再是Object了,泛型里面規(guī)定的類型 it.next()就獲取什么樣類型的元素澳化,所以就不用強(qiáng)制類型轉(zhuǎn)換了
        System.out.println(p.getName() + "..." + p.getAge());
    }
}


public static void main(String[] args) {
    //ArrayList<int> list = new ArrayList<int>();       //編譯報(bào)錯(cuò) <>中放的必須是引用數(shù)據(jù)類型 
    //ArrayList<Object> list = new ArrayList<Person>(); //編譯報(bào)錯(cuò) 集合的泛型要保證前后的數(shù)據(jù)類型一致
    ArrayList<Object> list = new ArrayList<>();//泛型最好不要定義成Object,沒(méi)有意義崔步,1.7版本的新特性,菱形泛型,后面的<>可以不用填寫
    list.add("aaa");
    list.add(true);
}
泛型類: public class 類名<泛型類型1,泛型類型2,....>{}
public class Worker<QQ> {
    public void show(QQ qq){
        System.out.println(qq);
    }
}
public class Worker<QQ,MM,DD,RR> {  //可以寫一個(gè)泛型 也可以寫多個(gè)
    public void show(QQ qq){
        System.out.println(qq);
    }
}
泛型非靜態(tài)方法: public <泛型類型> 返回類型 方法名(泛型類型 變量名){}

代碼演示:

public class Demo1_Generic {
    public static void main(String[] args) {
        /*Tool t = new Tool();
        t.show("abc");      //調(diào)用show(String s)方法 傳入一個(gè)"abc"
        t.show(100);*/      //調(diào)用show(Integer i)方法 傳入一個(gè)100
        //如果想繼續(xù)接著調(diào)用一個(gè)show(Student s)方法缎谷, 就需要繼續(xù)修改Tool類刷晋,再繼續(xù)編寫一個(gè)show(Student s)方法 才能調(diào)用
        //如果想繼續(xù)接著調(diào)用一個(gè)show(Animal a)方法, 就需要繼續(xù)修改Tool類,再繼續(xù)編寫一個(gè)show(Animal a)方法 才能調(diào)用
        //如果想繼續(xù)接著調(diào)用一個(gè)show(Worker w)方法眼虱, 就需要繼續(xù)修改Tool類喻奥,再繼續(xù)編寫一個(gè)show(Worker w)方法 才能調(diào)用
        //這樣修改  將無(wú)窮無(wú)盡,所以用下面的泛型類改進(jìn)代碼

        /*Tool1<String> t = new Tool1<>();  //想調(diào)用show方法 傳入一個(gè)"abc" 那么就創(chuàng)建一個(gè)泛型為String的對(duì)象
        t.show("abc");
        
        Tool1<Integer> t1 = new Tool1<>();  //想調(diào)用show方法 傳入一個(gè)100 那么就創(chuàng)建一個(gè)泛型為Integer的對(duì)象
        t1.show(100);

        Tool1<Student> t2 = new Tool1<>();  //想調(diào)用show方法 傳入一個(gè)Student 那么就創(chuàng)建一個(gè)泛型為Student的對(duì)象
        t2.show(new Student());*/       
        //如果想接著調(diào)用show方法 傳入一個(gè)Animal 就又要?jiǎng)?chuàng)建一個(gè)泛型為Animal的對(duì)象 捏悬,每次都要?jiǎng)?chuàng)建一個(gè)新的對(duì)象 浪費(fèi)空間 所以用下面的泛型方法改進(jìn)

        Tool2 t = new Tool2();  
        t.show("abc");  //調(diào)用show方法的時(shí)候就明確了QQ是String類型
        t.show(100);//調(diào)用show方法的時(shí)候就明確了QQ是Integer類型
        t.show(new Student());//調(diào)用show方法的時(shí)候就明確了QQ是Student類型
        //想傳什么樣的類型都可以 而且代碼非常的簡(jiǎn)單
    }
}
public class Tool {
    public void show(String s) {
        System.out.println(s);
    }
    public void show(Integer i) {
        System.out.println(i);
    }
}

public class Tool1<QQ> {
    public void show(QQ qq){
        System.out.println(qq);
    }
}
public class Tool2 {
    public <QQ>void show(QQ s){
        System.out.println(s);
    }
}
泛型靜態(tài)方法: public static <泛型類型> 返回類型 方法名(泛型類型 變量名){}
public class Tools<Q> { 
    /*public static void show(Q q) {        //編譯報(bào)錯(cuò)撞蚕,因?yàn)殪o態(tài)的 優(yōu)先于對(duì)象而存在
            System.out.println(q);
    }*/
    public static<W> void print(W w) {      //靜態(tài)方法必須聲明自己的泛型
        System.out.println(w);
    }
}
泛型接口:public interface 接口名<泛型類型>

子類在實(shí)現(xiàn)父接口的時(shí)候可以明確泛型,也可以直接沿用父類的泛型

代碼演示:

interface Inter<T> {
    public void show(T t);
}

class Demo implements Inter<String> {       //子類在實(shí)現(xiàn)父接口的時(shí)候 可以明確泛型 明確成了String類型
    @Override
    public void show(String t) {
        System.out.println(t);
    }
}

class Demo<T> implements Inter<T> {     //也可以直接沿用父類的泛型 T
    @Override
    public void show(T t) {
        System.out.println(t);
    }
}
泛型-通配符:

A:泛型通配符<?>任意類型

List<?> list = new ArrayList<Integer>(); //當(dāng)右邊的泛型是不確定時(shí),左邊可以指定為?
B:<? extends E >明確泛型的時(shí)候明確成E或者E的兒子
代碼演示:

public static void main(String[] args) {
    ArrayList<Person> list1 = new ArrayList<>();
    list1.add(new Person("張三", 23));
    list1.add(new Person("李四", 24));
    list1.add(new Person("王五", 25));

    ArrayList<Student> list2 = new ArrayList<>();
    list2.add(new Student("趙六", 26));
    list2.add(new Student("周七", 27));

    //boolean addAll(Collection<? extends E> c)
    list1.addAll(list2);        //Student 是Person的兒子 所以 可以添加成功
    System.out.println(list1);
}

C:<? super E >明確泛型的時(shí)候明確成 E或者E的父類

增強(qiáng)for循環(huán)

為了簡(jiǎn)化數(shù)組或者集合的遍歷而出現(xiàn)的(JDK1.5出現(xiàn)的)

for(集合或者數(shù)組里面元素的數(shù)據(jù)類型 變量名 : 數(shù)組或者集合){
    直接使用變量名就ok过牙;
}

代碼演示:

public static void demo1() {
    int[] arr = {11,22,33,44,55};
    for (int i : arr) {     //增強(qiáng)for循環(huán)可以遍歷數(shù)組
        //增強(qiáng)for循環(huán)在遍歷數(shù)組或者集合的時(shí)候甥厦,優(yōu)點(diǎn):代碼的書寫確實(shí)簡(jiǎn)單了,但缺點(diǎn)是遍歷時(shí)候沒(méi)有索引寇钉,如果想用索引的時(shí)候刀疙,就請(qǐng)用普通for循環(huán)
        System.out.println(i);
    }

    ArrayList<String> list = new ArrayList<>();
    list.add("a");
    list.add("b");
    list.add("c");
    list.add("d");

    for (String string : list) {    //增強(qiáng)for循環(huán)可以遍歷集合
        System.out.println(string);
    }
}

遍歷過(guò)程中能否刪除元素總結(jié):
1)普通for循環(huán)在遍歷的時(shí)候(只能遍歷List體系的集合),可以刪除扫倡,但是在刪除過(guò)程中索引會(huì)改變谦秧, size也會(huì)發(fā)生改變,所以容易出現(xiàn)漏刪的情況撵溃。

解決:索引--疚鲤,代碼片段如下:

ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("b");
list.add("c");
list.add("d");
for(int i = 0; i < list.size(); i++) {
    if("b".equals(list.get(i))) {
        list.remove(i--);   //通過(guò)索引刪除元素
    }
}

2)迭代器在遍歷集合的時(shí)候 Iterator(可以遍歷任何單列集合),不可以通過(guò)集合操作元素缘挑,否則會(huì)報(bào)并發(fā)修改異常集歇。只能通過(guò)迭代器自身來(lái)對(duì)元素進(jìn)行操作,如果是刪除:可以用Iterator 也可以用ListIterator 因?yàn)樗麄兝锩娑加衦emove()语淘;如果是添加:只能使用ListIterator诲宇,因?yàn)橹挥蠰istIterator里面有add()
代碼片段如下:

ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("b");
list.add("c");
list.add("d");
Iterator<String> it = list.iterator();
while(it.hasNext()) {
    if("b".equals(it.next())) {
        //list.remove("b"); //不能用集合的刪除方法,因?yàn)榈^(guò)程中如果集合修改會(huì)出現(xiàn)并發(fā)修改異常
        it.remove();        //讓迭代器自己來(lái)刪除元素
    }
}

3)增強(qiáng)for循環(huán)遍歷集合的時(shí)候(可以遍歷任何單列集合),由于底層就是調(diào)用的迭代器惶翻,所以不能刪除姑蓝,只能遍歷。代碼片段如下:

ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("b");
list.add("c");
list.add("d");
for (String string : list) {
    if("b".equals(string)) {
        list.remove("b");   //運(yùn)行報(bào)錯(cuò)维贺,并發(fā)修改異常它掂,增強(qiáng)for循環(huán)底層用的是迭代器 所以不能在迭代器過(guò)程中讓集合來(lái)刪除元素巴帮,如果用迭代器自己來(lái)刪除 溯泣,哪有迭代器來(lái)讓你使用呢?榕茧,在底層呢 你又看不到
    }
}
System.out.println(list);

可變參數(shù)
格式:修飾符 返回值類型 方法名(數(shù)據(jù)類型 ... 變量名){}
注意:

  1. 可變參數(shù)是JDK1.5后出現(xiàn)的新特性
  2. 可變參數(shù)其實(shí)是一個(gè)數(shù)組垃沦,所以調(diào)用帶有可變參數(shù)的方法的時(shí)候,可以傳入一個(gè)相同類型的數(shù)組
  3. 有多個(gè)參數(shù)的時(shí)候用押,可變參數(shù)放到最后

代碼演示:

public class Demo3_ChangeableArgs {
    public static void main(String[] args) {
        int[] arr = {11,22,33,44,55};
        print();            //調(diào)用的時(shí)候 可以不傳入?yún)?shù)
        print(arr);         //調(diào)用的時(shí)候 可以傳入一個(gè)數(shù)組肢簿,因?yàn)榭勺儏?shù)的底層就是使用的數(shù)組
        print(11,22,55);        //調(diào)用的時(shí)候 可以傳入多個(gè)參數(shù)        
    }

    public static void print(int ... arr) { //可變參數(shù)其實(shí)是一個(gè)數(shù)組
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
    public static void show(String s , int ... arr) {   //有多個(gè)參數(shù)的時(shí)候,可變參數(shù)放到最后

    }
    /*
        public static void method(int ... arr , String s) { //編譯報(bào)錯(cuò) 有多個(gè)參數(shù)的時(shí)候,可變參數(shù)放到最后

        }*/
}

//可變參數(shù)的應(yīng)用
public class Demo4_ChangeableArgs {
    public static void main(String[] args) {    
        //求兩個(gè)數(shù)的最大值,我需要定義一個(gè),含兩個(gè)參數(shù)的方法max(int a , int b)
        int big = max(5,6);
        //假如現(xiàn)在需求變了池充,我想求三個(gè)數(shù)的最大值,那么我需要定義一個(gè)含三個(gè)參數(shù)的方法 max(int a , int b , int c)
        int big1 = max(5,6,10);

        //假如現(xiàn)在需求又變了桩引,我想求四個(gè)數(shù)的最大值,難道我就再繼續(xù)定義一個(gè)含有四個(gè)參數(shù)的方法 max(int a , int b , int c , int d)嗎收夸? 這樣太麻煩了坑匠, 解決方案就是 用可變參數(shù)
        int big2 = max(11,432,7,87,23);
    }

    //求兩個(gè)數(shù)的最大值
    public static int max(int a , int b) {
        return a>b?a:b;
    }

    //求三個(gè)數(shù)的最大值
    public static int max(int a , int b , int c) {
        return a>b ? (a>c?a:c) : (b>c?b:c);
    }

    //求任意個(gè)數(shù)的最大值
    public static void max(int ... arr) {   //可變參數(shù)其實(shí)是一個(gè)數(shù)組
        int a = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if(arr[i]> a){
                a = arr[i]
            }
        }
        return a;
    }
}

集合和數(shù)組之間的轉(zhuǎn)換

Arrays工具類的asList(T ... t):將數(shù)組轉(zhuǎn)成集合(該方法用的可變參數(shù))
注意:

1)返回一個(gè)長(zhǎng)度固定的集合,可以改和查,不能增和刪,也就是改變其長(zhǎng)度的操作都不可以做卧惜。

2)將數(shù)組轉(zhuǎn)換成集合,數(shù)組必須是引用數(shù)據(jù)類型厘灼。

Collection中toArray(T[] a)泛型版的集合轉(zhuǎn)數(shù)組:

T[] 明確成什么樣的數(shù)組 toArray(T[] a)方法就返回什么類型的數(shù)組

注意:當(dāng)集合轉(zhuǎn)換數(shù)組時(shí),數(shù)組長(zhǎng)度如果是小于等于集合的size時(shí),轉(zhuǎn)換后的數(shù)組長(zhǎng)度等于集合的size;如果數(shù)組的長(zhǎng)度大于了size,分配的數(shù)組長(zhǎng)度就和你指定的長(zhǎng)度一樣咽瓷。

好了今天就先說(shuō)到這了设凹,想了解更多學(xué)習(xí)知識(shí),請(qǐng)關(guān)注微信公眾號(hào)“阿Q說(shuō)”茅姜,獲取更多學(xué)習(xí)資料吧闪朱!你也可以后臺(tái)留言說(shuō)出你的疑惑,阿Q將會(huì)在后期的文章中為你解答匈睁。每天學(xué)習(xí)一點(diǎn)點(diǎn)监透,每天進(jìn)步一點(diǎn)點(diǎn)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末航唆,一起剝皮案震驚了整個(gè)濱河市胀蛮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌糯钙,老刑警劉巖粪狼,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異任岸,居然都是意外死亡再榄,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門享潜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)困鸥,“玉大人,你說(shuō)我怎么就攤上這事剑按〖簿停” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵艺蝴,是天一觀的道長(zhǎng)猬腰。 經(jīng)常有香客問(wèn)我,道長(zhǎng)猜敢,這世上最難降的妖魔是什么姑荷? 我笑而不...
    開(kāi)封第一講書人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任盒延,我火速辦了婚禮,結(jié)果婚禮上鼠冕,老公的妹妹穿的比我還像新娘添寺。我一直安慰自己,他們只是感情好懈费,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布畦贸。 她就那樣靜靜地躺著,像睡著了一般楞捂。 火紅的嫁衣襯著肌膚如雪薄坏。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 52,475評(píng)論 1 312
  • 那天寨闹,我揣著相機(jī)與錄音胶坠,去河邊找鬼。 笑死繁堡,一個(gè)胖子當(dāng)著我的面吹牛沈善,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播椭蹄,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼闻牡,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了绳矩?” 一聲冷哼從身側(cè)響起罩润,我...
    開(kāi)封第一講書人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎翼馆,沒(méi)想到半個(gè)月后割以,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡应媚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年严沥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片中姜。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡消玄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出丢胚,到底是詐尸還是另有隱情翩瓜,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布嗜桌,位于F島的核電站奥溺,受9級(jí)特大地震影響辞色,放射性物質(zhì)發(fā)生泄漏骨宠。R本人自食惡果不足惜浮定,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望层亿。 院中可真熱鬧桦卒,春花似錦、人聲如沸匿又。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)碌更。三九已至裕偿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間痛单,已是汗流浹背嘿棘。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留旭绒,地道東北人鸟妙。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像挥吵,于是被迫代替她去往敵國(guó)和親重父。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容