亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中如何使用Iterator和Iterable接口

發布時間:2021-11-17 19:48:45 來源:億速云 閱讀:220 作者:iii 欄目:大數據

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

1. 簡介

當我們使用 forwhile 循環來遍歷一個集合的元素,Iterator 允許我們不用擔心索引位置,甚至讓我們不僅僅是遍歷一個集合,同時還可以改變它。例如,你如果要刪除循環中的元素,那么 for 循環不見得總是可行的。

結合自定義的迭代器,我們可以迭代更為復雜的對象,以及向前和向后移動,并且知曉如何利用其優勢也將變得非常清楚。

2. Iterator()

Iterator 接口用于迭代集合中的元素(ListSetMap)。它用于逐個檢索元素,并在需要時針對每個元素執行操作。

下面是用于遍歷集合與執行操作的方法:

  • .hasNext():如果還沒有到達集合的末尾,則返回 true,否則返回 false

  • .next():返回集合中的下一個元素

  • .remove():從集合中移除迭代器返回的最后一個元素

  • .forEachRemaining():按順序為集合中剩下的每個元素執行給定的操作

首先,由于迭代器是用于集合的,讓我們做一個簡單的包含幾個元素的 ArrayList

List<string> avengers = new ArrayList&lt;&gt;();

// Now lets add some Avengers to the list
avengers.add("Ant-Man");
avengers.add("Black Widow");
avengers.add("Captain America");
avengers.add("Doctor Strange");

我們可以使用一個簡單循環來遍歷這個集合:

System.out.println("Simple loop example:\n");
for (int i = 0; i &lt; avengers.size(); i++) {
    System.out.println(avengers.get(i));
}

不過,我們想探索迭代器:

System.out.println("\nIterator Example:\n");

// First we make an Iterator by calling 
// the .iterator() method on the collection
Iterator<string> avengersIterator = avengers.iterator();

// And now we use .hasNext() and .next() to go through it
while (avengersIterator.hasNext()) {
    System.out.println(avengersIterator.next());
}

如果我們想從這個 ArrayList 中刪除一個元素,會發生什么?讓我們試著使用常規的 for 循環:

System.out.println("Simple loop example:\n");
for (int i = 0; i &lt; avengers.size(); i++) {
    if (avengers.get(i).equals("Doctor Strange")) {
        avengers.remove(i);
    }
    System.out.println(avengers.get(i));
}

我們會收到一個討厭的 IndexOutOfBoundsException

Simple loop example:

Ant-Man
Black Widow
Captain America
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3

這在遍歷集合時更改其大小是有意義的,增強 for 循環也一樣:

System.out.println("Simple loop example:\n");
for (String avenger : avengers) {
    if (avenger.equals("Doctor Strange")) {
        avengers.remove(avenger);
    }
    System.out.println(avenger);
}

我們再次收到了另一個異常:

Simple loop example:

Ant-Man
Black Widow
Captain America
Doctor Strange
Exception in thread "main" java.util.ConcurrentModificationException

這時迭代器就派上用場了,由它充當中間人,從集合中刪除元素,同時確保遍歷按計劃繼續:

Iterator<string> avengersIterator = avengers.iterator();
while (avengersIterator.hasNext()) {
    String avenger = avengersIterator.next();

    // First we must find the element we wish to remove
    if (avenger.equals("Ant-Man")) {
        // This will remove "Ant-Man" from the original
        // collection, in this case a List
        avengersIterator.remove();
    }
}

這是保證在遍歷集合時刪除元素的安全方法。

并確認該元素是否已被刪除:

// We can also use the helper method .forEachRemaining()
System.out.println("For Each Remaining Example:\n");
Iterator<string> avengersIteratorForEach = avengers.iterator();

// This will apply System.out::println to all elements in the collection
avengersIteratorForEach.forEachRemaining(System.out::println);

輸出如下:

For Each Remaining Example:

Black Widow
Captain America
Doctor Strange

正如你所看到的,蟻人已經從 復仇者聯盟 的名單中刪除了。

2.1. ListIterator()

ListIterator 繼承自 Iterator 接口。它只在 List 上進行使用,可以雙向迭代,這意味著你可以從前到后或從后到前進行迭代。它也沒有 current 元素,因為游標總是放在 List 的兩個元素之間,所以我們用 .previous().next() 來訪問元素。

> IteratorListIterator 之間有什么區別呢?

首先,Iterator 可以用于 任意集合 —— ListMapQueueSet 等。

ListIterator 只能應用于 List,通過添加這個限制,ListIterator 在方法方面可以更加具體,因此,我們引入了許多新方法,他們可以幫助我們在遍歷時對其進行修改。

如果你正在處理 List 實現(ArrayListLinkedList等),那么使用 ListIterator 更為可取一些。

下面是你可能會用到的方法:

  • .add(E e):向 List 中添加元素。

  • .remove():從 List 中刪除 .next().previous() 返回的最后一個元素。

  • .set(E e):使用指定元素來覆蓋 List .next().previous() 返回的最后一個元素。

  • .hasNext():如果還沒有到達 List 的末尾,則返回 true,否則返回 false

  • .next():返回 List 中的下一個元素。

  • .nextIndex():返回下一元素的下標。

  • .hasPrevious():如果還沒有到達 List 的開頭,則返回 true,否則返回 false

  • .previous():返回 List 的上一個元素。

  • .previousIndex():返回上一元素的下標。

再次,讓我們用一些元素構成一個 ArrayList

ArrayList<string> defenders = new ArrayList&lt;&gt;();

defenders.add("Daredevil");
defenders.add("Luke Cage");
defenders.add("Jessica Jones");
defenders.add("Iron Fist");

讓我們用 ListIterator 來遍歷 List 并打印其元素:

ListIterator listIterator = defenders.listIterator(); 
  
System.out.println("Original contents of our List:\n");
while (listIterator.hasNext()) 
    System.out.print(listIterator.next() + System.lineSeparator());

顯然,它的工作方式與 Iterator 相同。輸出如下:

Original contents of our List: 

Daredevil
Luke Cage
Jessica Jones
Iron Fist

現在,讓我們來嘗試修改一些元素:

System.out.println("Modified contents of our List:\n");

// Now let's make a ListIterator and modify the elements
ListIterator defendersListIterator = defenders.listIterator();

while (defendersListIterator.hasNext()) {
    Object element = defendersListIterator.next();
    defendersListIterator.set("The Mighty Defender: " + element);
}

現在打印 List 的話會得到如下結果:

Modified contents of our List:

The Mighty Defender: Daredevil
The Mighty Defender: Luke Cage
The Mighty Defender: Jessica Jones
The Mighty Defender: Iron Fist

現在,讓我們倒著遍歷列表,就像我們可以用 ListIterator 做的那樣:

System.out.println("Modified List backwards:\n");
while (defendersListIterator.hasPrevious()) {
    System.out.println(defendersListIterator.previous());
}

輸出如下:

Modified List backwards:

The Mighty Defender: Iron Fist
The Mighty Defender: Jessica Jones
The Mighty Defender: Luke Cage
The Mighty Defender: Daredevil

3. Spliterator()

Spliterator 接口在功能上與 Iterator 相同。你可能永遠不需要直接使用 Spliterator,但讓我們繼續討論一些用例。

但是,你應首先熟悉 Java Streams 和 Lambda Expressions in Java。

雖然我們將列出 Spliterator 擁有的所有方法,但是 Spliterator 接口的全部工作超出了本文的范疇。我們將通過一個例子討論 Spliterator 如何使用并行化更有效地遍歷我們可以分解的 Stream

我們在處理 Spliterator 時使用的方法是:

  • .characteristics()


    : 返回該 Spliterator 具有的作為

    int


    值的特征。 這些包括:

    • ORDERED

    • DISTINCT

    • SORTED

    • SIZED

    • CONCURRENT

    • IMMUTABLE

    • NONNULL

    • SUBSIZED

  • .estimateSize():返回遍歷作為 long 值遇到的元素數量的估計值,如果無法返回則返回 long.MAX_VALUE

  • .forEachRemaining(E e):按順序對集合中的每個剩余元素執行給定操作。

  • .getComparator():如果該 Spliterator 的源是由 Comparator 排序的,其將返回 Comparator

  • .getExactSizeIfKnown():如果大小已知則返回 .estimateSize(),否則返回 -1

  • .hasCharacteristics(int characteristics):如果這個 Spliterator.characteristics() 包含所有給定的特征,則返回 true

  • .tryAdvance(E e):如果存在剩余元素,則對其執行給定操作,返回 true,否則返回 false

  • .trySplit():如果這個 Spliterator 可以被分區,返回一個 Spliterator 覆蓋元素,當從這個方法返回時,它將不被這個 Spliterator 覆蓋。

像往常一樣,讓我們從一個簡單的 ArrayList 開始:

List<string> mutants = new ArrayList&lt;&gt;();

mutants.add("Professor X");
mutants.add("Magneto");
mutants.add("Storm");
mutants.add("Jean Grey");
mutants.add("Wolverine");
mutants.add("Mystique");

現在,我們需要將 Spliterator 應用于 Stream。值得慶幸的是,由于 Collections 框架,很容易在 ArrayListStream 之間進行轉換:

// Obtain a Stream to the mutants List.
Stream<string> mutantStream = mutants.stream();

// Getting Spliterator object on mutantStream.
Spliterator<string> mutantList = mutantStream.spliterator();

為了展示其中的一些方法,讓我們分別運行下它們:

// .estimateSize() method
System.out.println("Estimate size: " + mutantList.estimateSize());

// .getExactSizeIfKnown() method
System.out.println("\nExact size: " + mutantList.getExactSizeIfKnown());

System.out.println("\nContent of List:");
// .forEachRemaining() method
mutantList.forEachRemaining((n) -&gt; System.out.println(n));

// Obtaining another Stream to the mutant List.
Spliterator<string> splitList1 = mutantStream.spliterator();

// .trySplit() method
Spliterator<string> splitList2 = splitList1.trySplit();

// If splitList1 could be split, use splitList2 first.
if (splitList2 != null) {
    System.out.println("\nOutput from splitList2:");
    splitList2.forEachRemaining((n) -&gt; System.out.println(n));
}

// Now, use the splitList1
System.out.println("\nOutput from splitList1:");
splitList1.forEachRemaining((n) -&gt; System.out.println(n));

我們將得到輸出:

Estimate size: 6

Exact size: 6

Content of List: 
Professor X
Magneto
Storm
Jean Grey
Wolverine
Mystique

Output from splitList2: 
Professor X
Magneto
Storm

Output from splitList1: 
Jean Grey
Wolverine
Mystique

4. Iterable()

如果出于某種原因,我們想要創建一個自定義的 Iterator 接口,應該怎么辦?你首先要熟悉的是這張圖:

Java中如何使用Iterator和Iterable接口

要創建自定義 Iterator,我們需要為 .hasNext().next().remove() 做自定義實現。

Iterator 接口中,有一個方法,它返回一個集合中元素的迭代器,即 .iterator() 方法,還有一個方法為迭代器中的每個元素執行一個操作的方法,即 .dorEach() 方法。

例如,假設我們是 Tony Stark,我們需要寫個自定義迭代器來列出當前武器庫中的每件鋼鐵俠套裝。

首先,讓我們創建一個類來獲取和設置 suit 數據:

public class Suit {

    private String codename;
    private int mark;

    public Suit(String codename, int mark) {
        this.codename = codename;
        this.mark = mark;
    }

    public String getCodename() { return codename; }

    public int getMark() { return mark; }

    public void setCodename (String codename) {this.codename=codename;}

    public void setMark (int mark) {this.mark=mark;}

    public String toString() {
        return "mark: " + mark + ", codename: " + codename;
    }
}

接下來讓我們編寫自定義 Iterator:

// Our custom Iterator must implement the Iterable interface
public class Armoury implements Iterable<suit> {
    
    // Notice that we are using our own class as a data type
    private List<suit> list = null;

    public Armoury() {
        // Fill the List with data
        list = new LinkedList<suit>();
        list.add(new Suit("HOTROD", 22));
        list.add(new Suit("SILVER CENTURION", 33));
        list.add(new Suit("SOUTHPAW", 34));
        list.add(new Suit("HULKBUSTER 2.0", 48));
    }
    
    public Iterator<suit> iterator() {
        return new CustomIterator<suit>(list);
    }

    // Here we are writing our custom Iterator
    // Notice the generic class E since we do not need to specify an exact class
    public class CustomIterator<e> implements Iterator<e> {
    
        // We need an index to know if we have reached the end of the collection
        int indexPosition = 0;
        
        // We will iterate through the collection as a List
        List<e> internalList;
        public CustomIterator(List<e> internalList) {
            this.internalList = internalList;
        }

        // Since java indexes elements from 0, we need to check against indexPosition +1
        // to see if we have reached the end of the collection
        public boolean hasNext() {
            if (internalList.size() &gt;= indexPosition +1) {
                return true;
            }
            return false;
        }

        // This is our custom .next() method
        public E next() {
            E val = internalList.get(indexPosition);

            // If for example, we were to put here "indexPosition +=2" we would skip every 
            // second element in a collection. This is a simple example but we could
            // write very complex code here to filter precisely which elements are
            // returned. 
            // Something which would be much more tedious to do with a for or while loop
            indexPosition += 1;
            return val;
        }
        // In this example we do not need a .remove() method, but it can also be 
        // written if required
    }
}

最后是 main 方法類:

public class IronMan {

    public static void main(String[] args) {

        Armoury armoury = new Armoury();

        // Instead of manually writing .hasNext() and .next() methods to iterate through 
        // our collection we can simply use the advanced forloop
        for (Suit s : armoury) {
            System.out.println(s);
        }
    }
}

輸出如下:

mark: 22, codename: HOTROD
mark: 33, codename: SILVER CENTURION
mark: 34, codename: SOUTHPAW
mark: 48, codename: HULKBUSTER 2.0

到此,關于“Java中如何使用Iterator和Iterable接口”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

都兰县| 龙陵县| 阿城市| 周口市| 东源县| 万州区| 瓦房店市| 红桥区| 乾安县| 藁城市| 武陟县| 天气| 宁城县| 璧山县| 沧州市| 沾化县| 酉阳| 阿拉善右旗| 房产| 泗洪县| 湘阴县| 潼南县| 桃江县| 平和县| 松滋市| 巨野县| 建湖县| 南陵县| 永济市| 易门县| 石门县| 依安县| 苍南县| 贵定县| 洛阳市| 容城县| 博罗县| 库伦旗| 荣成市| 富川| 黑河市|