成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

(Thinking in Java)第11章 持有對(duì)象

v1 / 1845人閱讀

摘要:迭代器解決了這個(gè)問題。刪除后于是我們可以寫一個(gè)方法,接受一個(gè)類型,然后讓他調(diào)用方法,這就不需要考慮這個(gè)是個(gè)還是了,也就是說,可以將遍歷容器的操作與序列底層的結(jié)構(gòu)分離,迭代器統(tǒng)一了對(duì)容器類的訪問方式。十二和兩種遍歷的方法,與迭代器方法。

一、泛型和類型安全的容器
package tij.hoding;

import java.util.ArrayList;

public class Test {
    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
        ArrayList apples=new ArrayList();
        for(int i=0;i<2;i++){
            apples.add(new Apple());
        }
        apples.add(new Orange());
        for(int i=0;i

在運(yùn)行期的類型轉(zhuǎn)換時(shí)會(huì)出現(xiàn)問題,因?yàn)槭褂胓et方法的時(shí)候取出來的其實(shí)object類型,之前程序中放進(jìn)去了一個(gè)orange卻要將他轉(zhuǎn)成一個(gè)apple。
因此需要使用類型參數(shù)來指定這個(gè)容器實(shí)例可以保存的類型,通過使用類型參數(shù),就可以在編譯期放置將錯(cuò)誤的類型放在容器中,上面的代碼改成下面類型

package tij.hoding;

import java.util.ArrayList;

public class Test {
    public static void main(String[] args) {
        ArrayList apples=new ArrayList<>();
        for(int i=0;i<2;i++){
            apples.add(new Apple());
        }
        for(int i=0;i

同樣,可以將容器的類型參數(shù)的指定類型以及其子類類型的實(shí)例變量放進(jìn)這個(gè)容器中,例子略

二、基本概念

Java容器類可以劃分為兩個(gè)不同的概念

Collection
一個(gè)存儲(chǔ)獨(dú)立元素的序列,不同序列有不同的規(guī)則:List必須按照插入順序保存元素;Set不能有重復(fù)元素;Queue按照排隊(duì)規(guī)則確定對(duì)象產(chǎn)生的順序。

Map
一組成對(duì)的簡直對(duì)對(duì)象

然而大多數(shù)情況在編寫代碼的時(shí)候都是與接口打交道,唯一需要精確指定使用的容器類型的地方就是創(chuàng)建的時(shí)候,如下

List apples=new ArrayList();

就是說多數(shù)情況我們是面向接口編程的,但也并不都是這樣,比如如果我們要使用LinkedList里的特有的功能,就不能用這種方法了。

三、添加一組元素

Collections和Arrays類中提供了很多與序列相關(guān)的方法,有啥自己去找API看去就行了。
注明

package tij.hoding;

import java.util.Arrays;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        List snow1=Arrays.asList(new Crusty(),new Slush(),new Powder(),new Light());
        List snow2=Arrays.asList(new Light(),new Heavy());
    }
}
class Snow{}
class Powder extends Snow{}
class Light extends Powder{}
class Heavy extends Powder{}
class Crusty extends Snow{}
class Slush extends Snow{}

書上說snow2是創(chuàng)建不了的,我用的是JDK1.8發(fā)現(xiàn)是可以創(chuàng)建的。

四、容器的打印

沒啥說的,數(shù)組的打印可以用Arrays.toString方法

五、List

List接口在Collection基礎(chǔ)上添加了大量方法

基本的ArrayList,訪問快,中間插入和移除較慢

LinkedList,進(jìn)行中間的插入刪除代價(jià)低
方法找API看

六、迭代器

對(duì)于List,add方法是插入元素的方法,get方法是去除元素的方法,但是這是有弊端的,如果使用容器,如果需要對(duì)元素進(jìn)行操作,就必須要針對(duì)容器的確切類型進(jìn)行編程,舉個(gè)例子,如果要從一個(gè)List里取出元素,我們寫了一些方法,但如果希望將這些方法再運(yùn)用到同是Collection類的set類上,就不行了,因?yàn)閟et根本沒有g(shù)et方法。迭代器解決了這個(gè)問題。

package tij.hoding;

import java.util.ArrayList;
import java.util.Iterator;

public class Test {
    public static void main(String[] args) {
        ArrayList str_list = new ArrayList();
        for (int i = 0; i < 10; i++)
            str_list.add("123134");
        Iterator it = str_list.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
        it = str_list.iterator();
        for (int i = 0; i < 5; i++) {
            it.next();
            it.remove();
        }
        System.out.println("----刪除后");
        it = str_list.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
    }
}

于是我們可以寫一個(gè)方法,接受一個(gè)collection類型,然后讓他調(diào)用iterator()方法,這就不需要考慮這個(gè)collection是個(gè)list還是set了,也就是說,可以將遍歷容器的操作與序列底層的結(jié)構(gòu)分離,迭代器統(tǒng)一了對(duì)容器類的訪問方式。

1.ListIterator

這是個(gè)List專用的迭代器,他可以雙向移動(dòng),可以生成索引,可以使用set方法對(duì)元素進(jìn)行替換,而且在創(chuàng)建的時(shí)候還可以指從哪開始迭代,具體看API

七、LinkedList

LinkedList里有很多功能類似的方法,比如peek、element、getFirst,這是因?yàn)槌R詌inkedList為基礎(chǔ)制作堆棧等數(shù)據(jù)結(jié)構(gòu),在這種數(shù)據(jù)結(jié)構(gòu)中使用push啊pop啊更合適,雖然我覺得有一些= =額= =恩。。。。

八、Stack

沒啥好說的,就是用Linkedlist實(shí)現(xiàn),LIFO

九、Set

Set保證集合內(nèi)元素的唯一性,同時(shí)Set也有不同的類型:HashSet使用了散列函數(shù);TreeSet將元素存儲(chǔ)在紅黑樹數(shù)據(jù)結(jié)構(gòu)中,可以完成元素按比較方法的排序;LinkedHashSet也使用了散列,但它通過使用鏈表維護(hù)了元素插入順序

十、Map

存儲(chǔ)映射關(guān)系的數(shù)據(jù)結(jié)構(gòu)

十一、Queue

FIFO的容器
看API挺簡單的

1.PriorityQueue

優(yōu)先級(jí)隊(duì)列聲明下一個(gè)彈出的元素是最需要的元素(優(yōu)先級(jí)最高)。當(dāng)用PriorityQueue上調(diào)用offer方法插入一個(gè)對(duì)象時(shí),這個(gè)對(duì)象會(huì)在隊(duì)列中被排序,可以使用對(duì)象的自然排序也可以提供自己的Comparator來修改排序規(guī)則。PriorityQueue可以確保調(diào)用各種方法時(shí),根據(jù)優(yōu)先級(jí)進(jìn)行操作。

package tij.hoding;

import java.util.Arrays;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Random;

public class Test {
    public static void main(String[] args) {
        PriorityQueue priorityQueue = new PriorityQueue();
        Random rand = new Random(47);
        for (int i = 0; i < 10; i++) {
            priorityQueue.offer(rand.nextInt(i + 10));
        }
        printQ(priorityQueue);
        List ints = Arrays.asList(25, 22, 20, 18, 14, 9, 3, 1, 1, 2, 3,
                9, 14, 18, 21, 23, 25);
        priorityQueue = new PriorityQueue(ints);
        printQ(priorityQueue);
    }
    @SuppressWarnings("rawtypes")
    static void printQ(Queue queue) {
        while (queue.peek() != null) {
            System.out.print(queue.remove() + " ");
        }
        System.out.println();
    }
}
十二、Collection和Iterator

兩種遍歷的方法,foreach與迭代器方法。
同時(shí)有一種默認(rèn)的AbstractCollection,繼承他可以較為簡單的將自己的類變成Collection類型而不用實(shí)現(xiàn)原Collection全部的方法

十三、Foreach與迭代器

因?yàn)橛辛说?,所以有了Foreach功能,這個(gè)功能真的很強(qiáng)大

package tij.hoding;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;

public class Test {

    public static void main(String[] args) {
        Collection cs = new LinkedList();
        Collections.addAll(cs, "Take the long way home".split(" "));
        for (String s : cs) {
            System.out.print(s + " ");
        }
    }
}

而這是因?yàn)镴ava se5引入了Iterable幾口,實(shí)現(xiàn)了Iterable接口的類都可應(yīng)用于Foreach之中。比如下面

package tij.hoding;

import java.util.Iterator;

public class Test {

    public static void main(String[] args) {
        for (String s : new IterableClass()) {
            System.out.print(s + " ");
        }
    }
}
class IterableClass implements Iterable {
    protected String[] words = "And that is how we know the Earth to be banana-shaped"
            .split(" ");

    @Override
    public Iterator iterator() {
        return new Iterator() {
            private int index = 0;
            @Override
            public boolean hasNext() {
                return index < words.length;
            }
            @Override
            public String next() {
                return words[index++];
            }
        };
    }

}

首先要搞懂Foreach語句中for(element:container)里的container要是iterable類型的才可以,foreach在遍歷時(shí),首先調(diào)用container的iterator方法得到這個(gè)iterator,然后就是在調(diào)用這個(gè)iterator的的hasNext和next方法

1.適配器方法慣用法

假如現(xiàn)在有一個(gè)類記錄了一串兒單詞,希望能運(yùn)用Foreach方法將他遍歷,只要讓他實(shí)現(xiàn)Iterable接口實(shí)現(xiàn)Iterator功能就可以了,但是現(xiàn)在希望他既能順向遍歷,又能逆向遍歷,這就不好辦了,因?yàn)槟阒荒苤貙慖terator一次啊。
一種解決方案就是所謂的適配機(jī)器方法,當(dāng)你有一個(gè)接口并需要另一個(gè)接口的時(shí)候,編寫適配器就可以解決問題。

package tij.hoding;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;

public class Test {

    public static void main(String[] args) {
        ReversibleArrayList ral = new ReversibleArrayList(
                Arrays.asList("To be or not to be".split(" ")));
        for (String s : ral) {
            System.out.print(s + " ");
        }
        System.out.println();
        for (String s : ral.reversed()) {
            System.out.print(s + " ");
        }
    }
}

@SuppressWarnings("serial")
class ReversibleArrayList extends ArrayList {
    public ReversibleArrayList(Collection c) {
        super(c);
    }
    public Iterable reversed() {
        return new Iterable() {
            @Override
            public Iterator iterator() {
                return reversed_iterator();
            }

            private Iterator reversed_iterator() {
                return new Iterator() {
                    int current = size() - 1;
                    public boolean hasNext() {
                        return current > -1;
                    }
                    public T next() {
                        return get(current--);
                    }
                };
            }
        };
    }
}

其實(shí)這個(gè)程序我看了半天才看懂,首先要搞懂Foreach語句中for(element:container)里的container要是iterable類型的才可以,foreach在遍歷時(shí),首先調(diào)用container的iterator方法得到這個(gè)iterator,然后就是在調(diào)用這個(gè)iterator的的hasNext和next方法。然后再順序遍歷的時(shí)候,傳入的是ral,然后調(diào)用ral自身的iterator本身的hasNext和next方法,就是順序遍歷了;在逆向遍歷的時(shí)候,傳入的是一個(gè)新的iterable,得到的也是一個(gè)新的iterator,然后調(diào)用的就是這個(gè)新的iteratoriterator的兩個(gè)方法。
另外我想了一下next方法里的get方法是誰的,然后用了內(nèi)部類訪問外部的方法也能調(diào)用

ReversibleArrayList.this.get()

于是我們就可以弄很多很多不同的遍歷規(guī)則了,比如隨機(jī)遍歷啊

package tij.hoding;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

public class Test {

    public static void main(String[] args) {
        ReversibleArrayList ral = new ReversibleArrayList(
                Arrays.asList("To be or not to be".split(" ")));
        for (String s : ral) {
            System.out.print(s + " ");
        }
        System.out.println();
        for (String s : ral.reversed()) {
            System.out.print(s + " ");
        }
        System.out.println();
        for (String s : ral.randomized()) {
            System.out.print(s + " ");
        }
    }
}

@SuppressWarnings("serial")
class ReversibleArrayList extends ArrayList {
    public ReversibleArrayList(Collection c) {
        super(c);
    }
    public Iterable reversed() {
        return new Iterable() {
            @Override
            public Iterator iterator() {
                return reversed_iterator();
            }

            private Iterator reversed_iterator() {
                return new Iterator() {
                    int current = size() - 1;
                    public boolean hasNext() {
                        return current > -1;
                    }
                    public T next() {
                        return ReversibleArrayList.this.get(current--);
                    }
                };
            }
        };
    }
    public Iterable randomized(){
        return new Iterable(){
            @Override
            public Iterator iterator() {
                List shuffle= ReversibleArrayList.this;
                Collections.shuffle(shuffle,new Random(47));
                return shuffle.iterator();
            }
        };
    }
}

可以注意到在隨機(jī)遍歷的時(shí)候,實(shí)際返回了一個(gè)新的序列的iterator這是為了不打亂原始的序列的順序
附一張簡單的容器分類

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/67583.html

相關(guān)文章

  • Thinking in Java10 內(nèi)部類

    摘要:內(nèi)部類中也可以取得這個(gè)外部類對(duì)象引用。創(chuàng)建成員內(nèi)部類對(duì)象的時(shí)候需要外部類對(duì)象。另外在方法中的內(nèi)部類不能加等權(quán)限修飾符,只能加和修飾符??梢栽诮涌趦?nèi)部定義內(nèi)部類,而且他們即使沒有修飾,也會(huì)自動(dòng)變成的。 Thinking in Java撈干貨,寫筆記 一、成員內(nèi)部類 1.最基本使用 public class Demo { class Contents{ privat...

    Brenner 評(píng)論0 收藏0
  • Thinking in Java13 字符串

    摘要:四上的操作看五格式化輸出運(yùn)用和語言很相似和是等價(jià)的喲類格式化說明符轉(zhuǎn)換六正則表達(dá)式網(wǎng)上教程學(xué)七掃描輸入新增了類。 一、不可變String String類型的對(duì)象是不可變的,所有的改變實(shí)際上都是創(chuàng)建了一個(gè)新的String對(duì)象,另外當(dāng)String作為傳入?yún)?shù)的時(shí)候,其實(shí)實(shí)際上傳入的是這個(gè)引用的一個(gè)拷貝,這個(gè)方法結(jié)束了之后這個(gè)傳入的引用也就消失了,原來的那個(gè)String不會(huì)受到方法內(nèi)的影響而...

    feng409 評(píng)論0 收藏0
  • Thinking in Java 對(duì)象導(dǎo)論

    摘要:基類導(dǎo)出類導(dǎo)出類繼承了基類的特點(diǎn),基類和導(dǎo)出類具有相同的基礎(chǔ)接口,形成兩者差異的做法在導(dǎo)出類中添加新方法在導(dǎo)出類型中添加新的接口元素,擴(kuò)展了接口。覆蓋在導(dǎo)出類用創(chuàng)建方法的新定義,覆蓋基類中的方法定義純粹替代,只覆蓋。 一、抽象過程 建?;谟?jì)算機(jī)的結(jié)構(gòu) 解空間的解 匯編語言:對(duì)底層機(jī)器的輕微抽象 命令式語言:匯編語言的抽象 建?;诖鉀Q問題 問題空間的元素 面向?qū)ο? 二、每個(gè)...

    joyqi 評(píng)論0 收藏0
  • Thinking in Java14 類型信息

    摘要:通過運(yùn)行時(shí)類型信息,程序能夠使用基類的指針或引用來檢查這些指針或引用所指的對(duì)象的實(shí)際派生類型。編程應(yīng)該盡量面向接口編程,應(yīng)該對(duì)類型信息盡量的少了解二對(duì)象看書,書上寫得好靜態(tài)語句塊在這個(gè)類被加載的時(shí)候運(yùn)行。 一、為什么需要RTTI Run-Time Type Information。通過運(yùn)行時(shí)類型信息,程序能夠使用基類的指針或引用來檢查這些指針或引用所指的對(duì)象的實(shí)際派生類型。編程應(yīng)該盡量...

    tomorrowwu 評(píng)論0 收藏0
  • Thinking in Java20 注解

    摘要:而這可以通過注解辦到,在代碼中以指令語言的形式化方法來為代碼提供更多信息。有注解的說明這個(gè)成員變量是一個(gè)列名,然后根據(jù)注解信息來生成相應(yīng)的語句。也就是說把注解信息提取了出來。 注解是向代碼中添加信息的一種方法,并且在之后還可以使用這些數(shù)據(jù)就比如這個(gè)方法是用來剝香蕉的,但是我們看就是一串代碼,我們沒辦法在代碼里寫一段指令說我這個(gè)程序是用來剝香蕉的,當(dāng)然除了注釋。而這可以通過注解辦到,在代...

    劉玉平 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<