Java超級接口List有哪些用法

這篇文章主要介紹“Java超級接口List有哪些用法”,在日常操作中,相信很多人在Java超級接口List有哪些用法問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java超級接口List有哪些用法”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

十載的阜陽網(wǎng)站建設(shè)經(jīng)驗(yàn),針對設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。網(wǎng)絡(luò)營銷推廣的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整阜陽建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)從事“阜陽網(wǎng)站設(shè)計(jì)”,“阜陽網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

ListCollection三大直接子接口之一,其中的數(shù)據(jù)可以通過位置檢索,用戶可以在指定位置插入數(shù)據(jù)。List的數(shù)據(jù)可以為空,可以重復(fù)。以下是其文檔注釋,只看前兩段:

An ordered collection (also known as a sequence). The user of this interface has precise control over where in the list each element is inserted. The user can access elements by their integer index (position in the list), and search for elements in the list.

Unlike sets, lists typically allow duplicate elements. More formally, lists typically allow pairs of elements <tt>e1</tt> and e2such that e1.equals(e2), and they typically allow multiple null elements if they allow null elements at all. It is not inconceivable that someone might wish to implement a list that prohibits duplicates, by throwing runtime exceptions when the user attempts to insert them, but we expect this usage to be rare.

List特有方法

我們關(guān)注其不同于Collection的方法,主要有以下這些:

//在指定位置,將指定的集合插入到當(dāng)前的集合中
boolean addAll(int index, Collection<? extends E> c);

//這是一個(gè)默認(rèn)實(shí)現(xiàn)的方法,會(huì)通過Iterator的方式對每個(gè)元素進(jìn)行指定的操作
default void replaceAll(UnaryOperator<E> operator) {
    Objects.requireNonNull(operator);
    final ListIterator<E> li = this.listIterator();
    while (li.hasNext()) {
        li.set(operator.apply(li.next()));
    }
}

//排序,依據(jù)指定的規(guī)則對當(dāng)前集合進(jìn)行排序,可以看到,排序是通過Arrays這個(gè)工具類完成的。
default void sort(Comparator<? super E> c) {
    Object[] a = this.toArray();
    Arrays.sort(a, (Comparator) c);
    ListIterator<E> i = this.listIterator();
    for (Object e : a) {
        i.next();
        i.set((E) e);
    }
}

//獲取指定位置的元素
E get(int index);

//修改指定位置元素的值
E set(int index, E element);

//將指定元素添加到指定的位置
void add(int index, E element);

//將指定位置的元素移除
E remove(int index);

//返回一個(gè)元素在集合中首次出現(xiàn)的位置
int indexOf(Object o);

//返回一個(gè)元素在集合中最后一次出現(xiàn)的位置
int lastIndexOf(Object o);

//ListIterator繼承于Iterator,主要增加了向前遍歷的功能
ListIterator<E> listIterator();

//從指定位置開始,返回一個(gè)ListIterator
ListIterator<E> listIterator(int index);

//返回一個(gè)子集合[fromIndex, toIndex),非結(jié)構(gòu)性的修改返回值會(huì)反映到原表,反之亦然。
//如果原表進(jìn)行了結(jié)構(gòu)修改,則返回的子列表可能發(fā)生不可預(yù)料的事情
List<E> subList(int fromIndex, int toIndex);

通過以上對接口的分析可以發(fā)現(xiàn),Collection主要提供一些通用的方法,而List則針對線性表的結(jié)構(gòu),提供了對位置以及子表的操作。

超級實(shí)現(xiàn)類:AbstractList

有了分析AbstractCollection的經(jīng)驗(yàn),我們分析AbstractList就更容易了。首先也看下其文檔中強(qiáng)調(diào)的部分:

To implement an unmodifiable list, the programmer needs only to extend this class and provide implementations for the get(int) and size() methods.

To implement a modifiable list, the programmer must additionally override the set(int, E) method (which otherwise throws an UnsupportedOperationException). If the list is variable-size the programmer must additionally override the add(int, E) and remove(int) methods.

大致意思是說,要實(shí)現(xiàn)一個(gè)不可修改的集合,只需要復(fù)寫getsize就可以了。要實(shí)現(xiàn)一個(gè)可以修改的集合,還需要復(fù)寫set方法,如果要?jiǎng)討B(tài)調(diào)整大小,就必須再實(shí)現(xiàn)addremove方法。

然后看下其源碼實(shí)現(xiàn)了哪些功能吧:

//在AbstractCollection中,add方法默認(rèn)會(huì)拋出異常,
//而在這里是調(diào)用了add(int index, E e)方法,但這個(gè)方法也是沒有實(shí)現(xiàn)的。
//這里默認(rèn)會(huì)把元素添加到末尾。
public boolean add(E e) {
    add(size(), e);
    return true;
}

//同上,這個(gè)只需要進(jìn)行一次遍歷即可
public boolean addAll(int index, Collection<? extends E> c) {
    //...   
}

接下來,還有幾個(gè)方法和IteratorListIterator息息相關(guān),在AbstractList中有具體的實(shí)現(xiàn),我們先看看它是如何把集合轉(zhuǎn)變成Iterator對象并支持foreach循環(huán)的吧。

我們追蹤源碼發(fā)現(xiàn),在iterator()方法中直接返回了一個(gè)Itr對象

public Iterator<E> iterator() {
    return new Itr();
}

這樣我們就明白了,它是實(shí)現(xiàn)了一個(gè)內(nèi)部類,這個(gè)內(nèi)部類實(shí)現(xiàn)了Iterator接口,合理的處理hasNext、nextremove方法。這個(gè)源碼就不粘貼啦,其中僅僅在remove時(shí)考慮了一下多線程問題,有興趣的可以自己去看看。

另外一個(gè)就是ListIterator,

public ListIterator<E> listIterator() {
    return listIterator(0);
}

可以看到,listIterator方法依賴于listIterator(int index)方法。有了上邊的經(jīng)驗(yàn),我們可以推測,它也是通過一個(gè)內(nèi)部類完成的。

public ListIterator<E> listIterator(final int index) {
    rangeCheckForAdd(index);

    return new ListItr(index);
}

事實(shí)證明,和我們想的一樣,AbstractList內(nèi)部還定義了一個(gè)ListItr,實(shí)現(xiàn)了ListIterator接口,其實(shí)現(xiàn)也很簡單,就不粘貼源碼啦。

接下來我們看看,利用這兩個(gè)實(shí)現(xiàn)類,AbstractList都做了哪些事情。

//尋找一個(gè)元素首次出現(xiàn)的位置,只需要從前往后遍歷,找到那個(gè)元素并返回其位置即可。
public int indexOf(Object o) {
    ListIterator<E> it = listIterator();
    if (o==null) {
        while (it.hasNext())
            if (it.next()==null)
                return it.previousIndex();
    } else {
        while (it.hasNext())
            if (o.equals(it.next()))
                return it.previousIndex();
    }
    return -1;
}

//同理,尋找一個(gè)元素最后一次出現(xiàn)的位置,只需要從列表最后一位向前遍歷即可。
//看到listIterator(int index)方法是可以傳遞參數(shù)的,這個(gè)我想我們都可以照著寫出來了。
public int lastIndexOf(Object o) {
    //...
}

//這個(gè)方法是把從fromIndex到toIndex之間的元素從集合中刪除。
//clear()方法也是調(diào)用這個(gè)實(shí)現(xiàn)的(我認(rèn)為clear實(shí)現(xiàn)意義并不大,因?yàn)樵谄渖霞堿bstractCollection中已經(jīng)有了具體實(shí)現(xiàn))。
protected void removeRange(int fromIndex, int toIndex) {
    ListIterator<E> it = listIterator(fromIndex);
    for (int i=0, n=toIndex-fromIndex; i<n; i++) {
        it.next();
        it.remove();
    }
}

接下來還有兩塊內(nèi)容比較重要,一個(gè)是關(guān)于SubList的,一個(gè)是關(guān)于equalshashcode的。

我們先看看SubList相關(guān)的內(nèi)容。SubList并不是新建了一個(gè)集合,只是持有了當(dāng)前集合的引用,然后控制一下用戶可以操作的范圍,所以在接口定義時(shí)就說明了其更改會(huì)直接反應(yīng)到原集合中。SubList定義在AbstractList內(nèi)部,并且是AbstractList的子類。在AbstractList的基礎(chǔ)上增加了對可選范圍的控制。

equalshashcode的實(shí)現(xiàn),也關(guān)乎我們的使用。在AbstractList中,這兩個(gè)方法不僅與其實(shí)例有關(guān),也和其內(nèi)部包含的元素有關(guān),所以在定義數(shù)據(jù)元素時(shí),也應(yīng)該復(fù)寫這兩個(gè)方法,以保證程序的正確運(yùn)行。這里看下其源碼加深一下印象吧。

public boolean equals(Object o) {
    if (o == this)
        return true;
    if (!(o instanceof List))
        return false;

    ListIterator<E> e1 = listIterator();
    ListIterator<?> e2 = ((List<?>) o).listIterator();
    while (e1.hasNext() && e2.hasNext()) {
        E o1 = e1.next();
        Object o2 = e2.next();
        //這里用到了數(shù)據(jù)元素的equals方法
        if (!(o1==null ? o2==null : o1.equals(o2)))
            return false;
    }
    return !(e1.hasNext() || e2.hasNext());
}
public int hashCode() {
    int hashCode = 1;
    for (E e : this)
        //這里用到了數(shù)據(jù)元素的hashCode方法
        hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
    return hashCode;
}

到此,關(guān)于“Java超級接口List有哪些用法”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

網(wǎng)站標(biāo)題:Java超級接口List有哪些用法
分享路徑:http://www.muchs.cn/article4/phdooe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈外貿(mào)建站、網(wǎng)站策劃、搜索引擎優(yōu)化定制開發(fā)、服務(wù)器托管

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)