Java中如何使用Iterator和Iterable接口

技术Java中如何使用Iterator和Iterable接口这篇文章主要介绍“Java中如何使用Iterator和Iterable接口”,在日常操作中,相信很多人在Java中如何使用Iterator和Iterable接口

本文主要介绍“如何在Java中使用迭代器和Iterable接口”。在日常操作中,相信很多人对于如何在Java中使用Iterator和Iterable接口有疑问。边肖查阅了各种资料,整理出简单易用的操作方法,希望能帮助大家解答“Java中如何使用Iterator和Iterable接口”的疑惑!接下来,请和边肖一起学习!

1. 简介

当我们使用for或while循环遍历集合的元素时,Iterator让我们不用担心索引位置,甚至让我们不仅遍历一个集合,还可以改变它。例如,如果您想要删除循环中的元素,那么For循环可能并不总是可行的。

结合自定义迭代器,我们可以迭代更复杂的对象并向前和向后移动,知道如何利用它的优势将变得非常清楚。

2. Iterator()

迭代器接口用于迭代集合中的元素(列表、集合或映射)。它用于逐个检索元素,并在必要时对每个元素执行操作。

以下方法用于遍历集合和执行操作:hasNext():如果尚未到达集合的末尾,则返回true,否则返回false。next():返回集合中的下一个元素。remove():从集合中移除迭代器返回的最后一个元素。forEachRemaining():对集合中的每个剩余元素按顺序执行给定的操作。

首先,由于迭代器用于集合,让我们用几个元素做一个简单的数组列表:

liststringvengers=NewArraylistlt;gt。();

//nowlettsaddsomevenuerstogetlist

复仇者联盟(蚁人);

复仇者联盟. add(' black WiNDOW ');

复仇者联盟. add(' CaptainAmeriCa ');

复仇者联盟. add(' DoctorStream ');我们可以使用一个简单的循环遍历这个集合:

system . out . println(' simpleloopexample : \ n ');

for(inti=0;ilt复仇者联盟. size();I){ 0

System.out.println(复仇者联盟. get(I));

}但是,我们想探索迭代器:

system . out . println(' \ niteratoresample : \ n ');

//first wemakeananiteratorbycall

//the . iterator()methodonthecollection

迭代器字符串复仇者迭代器=复仇者.迭代器();

//Andnowweuse.hasNext()和. Next()来处理它

while(复仇者畸形者. hasnext()){ 0

System.out.println(复仇者畸胎. next());

}如果我们想从这个数组列表中删除一个元素,会发生什么?让我们尝试使用正则for循环:

system . out . println(' simpleloopexample : \ n ');

for(int

nbsp;i = 0; i < 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接口”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/99776.html

(0)

相关推荐

  • 抖音点赞在线自助平台网站,抖音点赞自助购买平台?

    技术抖音点赞在线自助平台网站,抖音点赞自助购买平台?抖音刷赞自助网站,抖音点赞自助购买平台操作流程,一些大牌厂商也已经入驻,发展前景非常可观,在带来欢乐的同时也成为营销的重要平台,这样一个,又有趣,又能挣钱,路子又正,用

    测评 2021年10月26日
  • Java集合框架之如何使用List ArrayList LinkedList

    技术Java集合框架之如何使用List ArrayList LinkedList这篇文章主要讲解了“Java集合框架之如何使用List ArrayList LinkedList”,文中的讲解内容简单清晰,易于学习与理解,

    攻略 2021年10月25日
  • cad怎样测量面积,cad怎么计算图形面积

    技术cad怎样测量面积,cad怎么计算图形面积cad计算图形面积的方法如下cad怎样测量面积:1、打开cad图形,在菜单栏,点击“工具”,如下图所示。2、调出工具选项,用鼠标指着“查询Q”,激活查询命令,如下图所示。3、

    生活 2021年11月1日
  • 音频测试相关测试指标

    技术音频测试相关测试指标 音频测试相关测试指标音频测试常用的测试指标主要有电平(Level)、频率响应(FR,FrequenceResponse)、总谐波失真(THD+N)、信噪比(SNR,Signal

    礼包 2021年12月24日
  • python列表怎样实现for循环(pythonfor循环最多遍历几次)

    技术Python怎么在一个for循环中遍历两个列表Python怎么在一个for循环中遍历两个列表,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。我在看学习

    攻略 2021年12月22日
  • 霹雳的意思是什么,霹雳有什么诗号让人印象深刻

    技术霹雳的意思是什么,霹雳有什么诗号让人印象深刻一直以来《霹雳布袋戏》就深受大家的喜爱是因为它深入人心的角色,精彩的剧情。里面快意恩仇,肝胆相照,智冠群伦的智者,刀狂剑痴,心中唯有剑的柳生剑影,美丽的月神,视钱如命的杀手

    生活 2021年10月19日