国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java? 教程(List接口)

hedzr / 3261人閱讀

List接口

List是一個(gè)有序的Collection(有時(shí)稱為序列),列表可能包含重復(fù)元素,除了從Collection繼承的操作之外,List接口還包括以下操作:

位置訪問(wèn) — 根據(jù)列表中的數(shù)字位置操縱元素,這包括getsetaddaddAllremove等方法。

搜索 — 搜索列表中的指定對(duì)象并返回其數(shù)字位置,搜索方法包括indexOflastIndexOf

迭代 — 擴(kuò)展Iterator語(yǔ)義以利用列表的順序性,listIterator方法提供此行為。

范圍視圖 — sublist方法對(duì)列表執(zhí)行任意范圍操作。

Java平臺(tái)包含兩個(gè)通用的List實(shí)現(xiàn),ArrayList,通常是性能更好的實(shí)現(xiàn),而LinkedList在某些情況下提供更好的性能。

集合操作

假設(shè)你已經(jīng)熟悉它們,那么從Collection繼承的操作都可以完成你期望它們做的事情,如果你不熟悉Collection,現(xiàn)在是閱讀Collection接口部分的好時(shí)機(jī),remove操作始終從列表中刪除指定元素的第一個(gè)匹配項(xiàng),addaddAll操作始終將新元素附加到列表的末尾,因此,以下語(yǔ)法將一個(gè)列表連接到另一個(gè)列表。

list1.addAll(list2);

這是這個(gè)語(yǔ)法的非破壞性形式,它產(chǎn)生第三個(gè)List,其中包含附加到第一個(gè)列表的第二個(gè)列表。

List list3 = new ArrayList(list1);
list3.addAll(list2);

請(qǐng)注意,此語(yǔ)法在其非破壞性形式中利用了ArrayList的標(biāo)準(zhǔn)轉(zhuǎn)換構(gòu)造函數(shù)。

這是一個(gè)將一些名稱聚合到List中的示例(JDK 8及更高版本):

List list = people.stream()
.map(Person::getName)
.collect(Collectors.toList());

與Set接口一樣,List強(qiáng)化了對(duì)equalshashCode方法的需求,因此可以比較兩個(gè)List對(duì)象的邏輯相等性,而不考慮它們的實(shí)現(xiàn)類,如果兩個(gè)List對(duì)象包含相同順序的相同元素,則它們是相等的。

位置訪問(wèn)和搜索操作

基礎(chǔ)的位置訪問(wèn)操作是getsetaddremovesetremove操作返回被覆蓋或刪除的舊值),其他操作(indexOflastIndexOf)返回列表中指定元素的第一個(gè)或最后一個(gè)索引。

addAll操作從指定位置開(kāi)始插入指定Collection的所有元素,元素按指定Collection的迭代器返回的順序插入,此調(diào)用是CollectionaddAll操作的位置訪問(wèn)模擬。

這是在List中交換兩個(gè)索引值的一個(gè)小方法。

public static  void swap(List a, int i, int j) {
    E tmp = a.get(i);
    a.set(i, a.get(j));
    a.set(j, tmp);
}

當(dāng)然,有一個(gè)很大的區(qū)別,這是一個(gè)多態(tài)算法:它交換任何List中的兩個(gè)元素,無(wú)論其實(shí)現(xiàn)類型如何,這是另一種使用前面swap方法的多態(tài)算法。

public static void shuffle(List list, Random rnd) {
    for (int i = list.size(); i > 1; i--)
        swap(list, i - 1, rnd.nextInt(i));
}

此算法包含在Java平臺(tái)的Collections類中,使用指定的隨機(jī)源隨機(jī)置換指定的列表,這有點(diǎn)微妙:它從底部向上運(yùn)行列表,反復(fù)將隨機(jī)選擇的元素交換到當(dāng)前位置。不像大多數(shù)天真的洗牌嘗試,這是公平的(假設(shè)一個(gè)公平的隨機(jī)源,所有排列都有相同的可能性)和快速(需要完全list.size()-1交換),以下程序使用此算法以隨機(jī)順序打印其參數(shù)列表中的單詞。

import java.util.*;

public class Shuffle {
    public static void main(String[] args) {
        List list = new ArrayList();
        for (String a : args)
            list.add(a);
        Collections.shuffle(list, new Random());
        System.out.println(list);
    }
}

事實(shí)上,這個(gè)程序可以更短、更快,Arrays類有一個(gè)名為asList的靜態(tài)工廠方法,它允許將數(shù)組視為List,此方法不會(huì)復(fù)制數(shù)組,List中的更改會(huì)寫(xiě)入數(shù)組,反之亦然。生成的List不是通用List實(shí)現(xiàn),因?yàn)樗鼪](méi)有實(shí)現(xiàn)(可選)addremove操作:數(shù)組不可調(diào)整大小。利用Arrays.asList并調(diào)用shuffle的庫(kù)版本(使用默認(rèn)的隨機(jī)源),你將得到以下微小程序,其行為與前一個(gè)程序相同。

import java.util.*;

public class Shuffle {
    public static void main(String[] args) {
        List list = Arrays.asList(args);
        Collections.shuffle(list);
        System.out.println(list);
    }
}
迭代器

正如你所期望的那樣,Listiterator操作返回的Iterator以適當(dāng)?shù)捻樞蚍祷亓斜淼脑兀?b>List還提供了一個(gè)更豐富的迭代器,稱為ListIterator,它允許你在任一方向遍歷列表、在迭代期間修改列表、并獲取迭代器的當(dāng)前位置。

ListIteratorIterator繼承的三個(gè)方法(hasNextnextremove)在兩個(gè)接口中完全相同,hasPreviousprevious操作和hasNextnext的很相似,前一個(gè)操作引用(隱式)游標(biāo)之前的元素,而后者引用游標(biāo)之后的元素,previous操作向后移動(dòng)光標(biāo),而next向前移動(dòng)光標(biāo)。

這是在列表中向后迭代的標(biāo)準(zhǔn)語(yǔ)法。

for (ListIterator it = list.listIterator(list.size()); it.hasPrevious(); ) {
    Type t = it.previous();
    ...
}

請(qǐng)注意前面的語(yǔ)法中listIterator的參數(shù),List接口有兩種形式的listIterator方法,不帶參數(shù)的形式返回位于列表開(kāi)頭的ListIterator,帶有int參數(shù)的形式返回一個(gè)位于指定索引處的ListIterator。索引引用初始調(diào)用next返回的元素,對(duì)previous的初始調(diào)用將返回索引為index-1的元素,在長(zhǎng)度為n的列表中,indexn+1個(gè)有效值,從0n(包括n)。

直觀地說(shuō),游標(biāo)總是在兩個(gè)元素之間 — 一個(gè)將通過(guò)調(diào)用previous返回,一個(gè)將通過(guò)調(diào)用next返回。n+1個(gè)有效索引值對(duì)應(yīng)于元素之間的n+1個(gè)間隙,從第一個(gè)元素之前的間隙到最后一個(gè)元素之后的間隙,下圖顯示了包含四個(gè)元素的列表中的五個(gè)可能的游標(biāo)位置。

對(duì)nextprevious的調(diào)用可以混合使用,但是必須小心一點(diǎn),對(duì)previous的第一次調(diào)用返回與對(duì)next的最后一次調(diào)用相同的元素,類似地,在對(duì)previous進(jìn)行一系列調(diào)用之后,對(duì)next的第一次調(diào)用與對(duì)previous的最后一次調(diào)用返回相同的元素。

nextIndex方法返回后續(xù)調(diào)用next返回的元素的索引,并且previousIndex返回后續(xù)調(diào)用previous返回的元素的索引,這些調(diào)用通常用于報(bào)告找到某些內(nèi)容的位置或記錄ListIterator的位置,以便可以創(chuàng)建具有相同位置的另一個(gè)ListIterator

同樣也不足為奇的是,nextIndex返回的數(shù)字總是大于previousIndex返回的數(shù)字,這意味著兩種邊界情況的行為:(1)當(dāng)光標(biāo)位于初始元素之前時(shí)對(duì)previousIndex的調(diào)用返回-1,當(dāng)光標(biāo)位于最后一個(gè)元素之后時(shí)調(diào)用nextIndex返回list.size()。為了使所有這些具體化,以下是List.indexOf的可能實(shí)現(xiàn)。

public int indexOf(E e) {
    for (ListIterator it = listIterator(); it.hasNext(); )
        if (e == null ? it.next() == null : e.equals(it.next()))
            return it.previousIndex();
    // Element not found
    return -1;
}

請(qǐng)注意,indexOf方法返回it.previousIndex(),即使它正在向前遍歷列表,原因是it.nextIndex()將返回我們要檢查的元素的索引,并且我們想要返回剛檢查的元素的索引。

Iterator接口提供remove操作以從Collection中刪除next返回的最后一個(gè)元素,對(duì)于ListIterator,此操作將刪除nextprevious返回的最后一個(gè)元素。ListIterator接口提供了兩個(gè)額外的操作來(lái)修改列表 — setaddset方法用指定的元素覆蓋nextprevious返回的最后一個(gè)元素,以下多態(tài)算法使用set將一個(gè)指定值的所有出現(xiàn)替換為另一個(gè)。

public static  void replace(List list, E val, E newVal) {
    for (ListIterator it = list.listIterator(); it.hasNext(); )
        if (val == null ? it.next() == null : val.equals(it.next()))
            it.set(newVal);
}

在這個(gè)例子中唯一的棘手是valit.next之間的相等性測(cè)試,你需要特殊情況下val值為null以防止NullPointerException

add方法在當(dāng)前光標(biāo)位置之前立即將新元素插入到列表中,此方法在以下多態(tài)算法中說(shuō)明,以使用指定列表中包含的值序列替換指定值的所有出現(xiàn)。

public static  
    void replace(List list, E val, List newVals) {
    for (ListIterator it = list.listIterator(); it.hasNext(); ){
        if (val == null ? it.next() == null : val.equals(it.next())) {
            it.remove();
            for (E e : newVals)
                it.add(e);
        }
    }
}
范圍視圖操作

范圍視圖操作subList(int fromIndex,int toIndex)返回此列表部分的List視圖,其索引范圍從fromIndex(包括)到toIndex(不包括),這個(gè)半開(kāi)放范圍反映了典型的for循環(huán)。

for (int i = fromIndex; i < toIndex; i++) {
    ...
}

正如術(shù)語(yǔ)視圖所暗示的那樣,返回的List由調(diào)用了subListList進(jìn)行備份,因此前者中的更改將反映在后者中。

此方法消除了對(duì)顯式范圍操作的需要(對(duì)于數(shù)組通常存在的排序),任何期望List的操作都可以通過(guò)傳遞subList視圖而不是整個(gè)List來(lái)用作范圍操作,例如,以下語(yǔ)句從List中刪除了一系列元素。

list.subList(fromIndex, toIndex).clear();

可以構(gòu)造類似的語(yǔ)句以搜索范圍中的元素。

int i = list.subList(fromIndex, toIndex).indexOf(o);
int j = list.subList(fromIndex, toIndex).lastIndexOf(o);

請(qǐng)注意,前面的語(yǔ)句返回subList中找到的元素的索引,而不是支持列表中的索引。

List上操作的任何多態(tài)算法(例如replaceshuffle示例)都與subList返回的List一起使用。

這是一個(gè)多態(tài)算法,其實(shí)現(xiàn)使用subList來(lái)處理來(lái)自牌組的牌,也就是說(shuō),它返回一個(gè)新的List(“hand”),它包含從指定List(“deck”)末尾獲取的指定數(shù)量的元素,手中返回的元素將從牌組中移除。

public static  List dealHand(List deck, int n) {
    int deckSize = deck.size();
    List handView = deck.subList(deckSize - n, deckSize);
    List hand = new ArrayList(handView);
    handView.clear();
    return hand;
}

請(qǐng)注意,此算法將牌從牌組末端移除,對(duì)于許多常見(jiàn)的List實(shí)現(xiàn),例如ArrayList,從列表末尾刪除元素的性能明顯優(yōu)于從頭開(kāi)始刪除元素的性能。

以下是一個(gè)程序,它將dealHand方法與Collections.shuffle結(jié)合使用,從正常的52張卡牌中生成牌局,該程序采用兩個(gè)命令行參數(shù):(1)手牌數(shù)(2)每手牌數(shù)。

import java.util.*;

public class Deal {
    public static void main(String[] args) {
        if (args.length < 2) {
            System.out.println("Usage: Deal hands cards");
            return;
        }
        int numHands = Integer.parseInt(args[0]);
        int cardsPerHand = Integer.parseInt(args[1]);
    
        // Make a normal 52-card deck.
        String[] suit = new String[] {
            "spades", "hearts", 
            "diamonds", "clubs" 
        };
        String[] rank = new String[] {
            "ace", "2", "3", "4",
            "5", "6", "7", "8", "9", "10", 
            "jack", "queen", "king" 
        };

        List deck = new ArrayList();
        for (int i = 0; i < suit.length; i++)
            for (int j = 0; j < rank.length; j++)
                deck.add(rank[j] + " of " + suit[i]);
    
        // Shuffle the deck.
        Collections.shuffle(deck);
    
        if (numHands * cardsPerHand > deck.size()) {
            System.out.println("Not enough cards.");
            return;
        }
    
        for (int i = 0; i < numHands; i++)
            System.out.println(dealHand(deck, cardsPerHand));
    }
  
    public static  List dealHand(List deck, int n) {
        int deckSize = deck.size();
        List handView = deck.subList(deckSize - n, deckSize);
        List hand = new ArrayList(handView);
        handView.clear();
        return hand;
    }
}

運(yùn)行程序會(huì)產(chǎn)生如下輸出。

% java Deal 4 5

[8 of hearts, jack of spades, 3 of spades, 4 of spades,
    king of diamonds]
[4 of diamonds, ace of clubs, 6 of clubs, jack of hearts,
    queen of hearts]
[7 of spades, 5 of spades, 2 of diamonds, queen of diamonds,
    9 of clubs]
[8 of spades, 6 of diamonds, ace of spades, 3 of hearts,
    ace of hearts]

盡管subList操作非常強(qiáng)大,但在使用它時(shí)必須小心,如果以通過(guò)返回的List之外的任何方式向支持List添加或刪除元素,則subList返回的List的語(yǔ)義將變?yōu)?b>undefined。因此,強(qiáng)烈建議你僅將subList返回的List用作臨時(shí)對(duì)象 — 在支持List上執(zhí)行一個(gè)或一系列范圍操作,使用subList實(shí)例的時(shí)間越長(zhǎng),通過(guò)直接修改支持List或通過(guò)另一個(gè)subList對(duì)象來(lái)破壞它的可能性就越大,請(qǐng)注意,修改子列表的子列表并繼續(xù)使用原始子列表(盡管不是并發(fā))是合法的。

List算法

Collections類中的大多數(shù)多態(tài)算法專門(mén)應(yīng)用于List,擁有所有這些算法可以很容易地操作列表,以下是這些算法的摘要,這些算法在“算法”部分中有更詳細(xì)的描述。

sort — 使用合并排序算法對(duì)List進(jìn)行排序,該算法提供快速、穩(wěn)定的排序(穩(wěn)定排序是不重新排序相同元素的排序)。

shuffle — 隨機(jī)置換List中的元素。

reverse — 反轉(zhuǎn)List中元素的順序。

rotate — 將List中的所有元素旋轉(zhuǎn)指定的距離。

swap — 交換列表中指定位置的元素。

replaceAll — 將所有出現(xiàn)的一個(gè)指定值替換為另一個(gè)。

fill — 用指定的值覆蓋List中的每個(gè)元素。

copy — 將源列表復(fù)制到目標(biāo)列表。

binarySearch — 使用二進(jìn)制搜索算法搜索有序List中的元素。

indexOfSubList — 返回一個(gè)List的第一個(gè)子列表的索引,該列表等于另一個(gè)。

lastIndexOfSubList — 返回一個(gè)List的最后一個(gè)子列表的索引,該列表等于另一個(gè)。

上一篇:Set接口 下一篇:Queue接口

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/73219.html

相關(guān)文章

  • Java? 教程(集合接口

    集合接口 核心集合接口封裝了不同類型的集合,如下圖所示,這些接口允許獨(dú)立于其表示的細(xì)節(jié)來(lái)操縱集合,核心集合接口是Java集合框架的基礎(chǔ),如下圖所示,核心集合接口形成層次結(jié)構(gòu)。 showImg(https://segmentfault.com/img/bVbntJW?w=402&h=146); Set是一種特殊的Collection,SortedSet是一種特殊的Set,依此類推,另請(qǐng)注意,層次結(jié)構(gòu)...

    elisa.yang 評(píng)論0 收藏0
  • Java? 教程(Queue接口

    Queue接口 Queue是在處理之前保存元素的集合,除了基本的Collection操作外,隊(duì)列還提供額外的插入、刪除和檢查操作,Queue接口如下。 public interface Queue extends Collection { E element(); boolean offer(E e); E peek(); E poll(); E remov...

    RayKr 評(píng)論0 收藏0
  • Java? 教程(默認(rèn)方法)

    默認(rèn)方法 接口部分描述了一個(gè)涉及計(jì)算機(jī)控制汽車(chē)制造商的例子,他們發(fā)布了行業(yè)標(biāo)準(zhǔn)接口,描述了可以調(diào)用哪些方法來(lái)操作他們的汽車(chē),如果那些計(jì)算機(jī)控制的汽車(chē)制造商為他們的汽車(chē)添加新的功能,如飛行,該怎么辦?這些制造商需要指定新的方法,以使其他公司(如電子制導(dǎo)儀器制造商)能夠使其軟件適應(yīng)飛行汽車(chē),這些汽車(chē)制造商將在哪里聲明這些與飛行有關(guān)的新方法?如果他們將它們添加到原始接口,那么實(shí)現(xiàn)了這些接口的程序員將不得...

    zhisheng 評(píng)論0 收藏0
  • Java? 教程(泛型、繼承和子類型)

    泛型、繼承和子類型 如你所知,只要類型兼容,就可以將一種類型的對(duì)象分配給另一種類型的對(duì)象,例如,你可以將Integer分配給Object,因?yàn)镺bject是Integer的超類型之一: Object someObject = new Object(); Integer someInteger = new Integer(10); someObject = someInteger; // OK ...

    AaronYuan 評(píng)論0 收藏0
  • Java? 教程(為什么要使用泛型?)

    泛型 在任何重要的軟件項(xiàng)目中,bug都是不可避免的,仔細(xì)的規(guī)劃、編程和測(cè)試可以幫助減少它們的普遍性,但是它們總會(huì)在某個(gè)地方以某種方式潛入你的代碼,隨著新功能的引入以及你的代碼庫(kù)在規(guī)模和復(fù)雜性方面的增長(zhǎng),這一點(diǎn)變得尤為明顯。 幸運(yùn)的是,一些錯(cuò)誤比其他錯(cuò)誤更容易被發(fā)現(xiàn),例如,編譯時(shí)錯(cuò)誤可以在早期檢測(cè)到,你可以使用編譯器的錯(cuò)誤消息來(lái)確定問(wèn)題所在并立即修復(fù)它。但是,運(yùn)行時(shí)錯(cuò)誤可能會(huì)更成問(wèn)題,它們并不總是立...

    MudOnTire 評(píng)論0 收藏0

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

0條評(píng)論

hedzr

|高級(jí)講師

TA的文章

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