Java中的迭代器

Java游标是迭代器,用于逐个迭代、遍历或检索集合或流对象的元素。有 Java中的三个游标 .

null
  1. 迭代器
  2. 列举
  3. 列表迭代器

注: SplitIterator也可以被视为游标,因为它只是一种迭代器。

图片[1]-Java中的迭代器-yiteyi-C++库

1.迭代器

Java中的迭代器用于 收集框架 逐个检索元素。这是一个 普遍的 迭代器,因为我们可以将其应用于任何集合对象。通过使用迭代器,我们可以执行读取和删除操作。它是枚举的改进版本,具有删除元素的附加功能。

每当我们想要枚举集合框架实现的所有接口中的元素时,都必须使用迭代器,比如Set、List、Queue、Deque和Map接口的所有实现类。迭代器是 只有 光标可用于整个集合框架。 迭代器对象可以通过调用 迭代器() 方法出现在集合接口中。

语法:

Iterator itr = c.iterator();

注: 这里“c”是任何集合对象。itr是迭代器接口类型,指的是“c”。

Java中迭代器接口的实现方法

迭代器接口定义 方法如下:

1.hasNext(): 如果迭代包含更多元素,则返回true。

public boolean hasNext();

2.下一步: 返回迭代中的下一个元素。它抛出 非接触性异常 如果没有更多元素存在。

public Object next();

3.移除(): 删除迭代中的下一个元素。每次调用next()时只能调用一次此方法。

public void remove();

注: 删除() 方法可以引发两个异常,如下所示:

  • 不支持操作异常 : 如果此迭代器不支持删除操作
  • 非法国家例外 : 如果尚未调用下一个方法,或者在上次调用下一个方法之后已经调用了remove方法。

Java迭代器在内部是如何工作的?

在本节中,我们将尝试了解Java迭代器及其方法如何在内部工作。让我们以下面的LinkedList对象来理解此功能。

List<String> cities = new LinkedList<>(); cities.add("G-1"); cities.add("G-2"); cities.add("G-3"); . . . cities.add("G-n");

现在,让我们在List对象上创建一个迭代器对象,如下所示:

Iterator<String> citiesIterator = cities.iterator();

“CitiesTeartor”迭代器看起来像——

图片[2]-Java中的迭代器-yiteyi-C++库

这里迭代器的光标指向列表的第一个元素之前。

现在,我们将运行以下代码片段。

citiesIterator.hasNext();citiesIterator.next();

图片[3]-Java中的迭代器-yiteyi-C++库

当我们运行上面的代码片段时,迭代器的光标指向列表中的第一个元素,如上图所示。

现在,我们将运行以下代码片段。

citiesIterator.hasNext();citiesIterator.next();

图片[4]-Java中的迭代器-yiteyi-C++库

当我们运行上面的代码片段时,迭代器的光标指向列表中的第二个元素,如上图所示。执行此过程以将迭代器的光标移到列表的结束元素。

图片[5]-Java中的迭代器-yiteyi-C++库

在读取最后一个元素后,如果我们运行下面的代码片段,它将返回一个“false”值。

citiesIterator.hasNext();

图片[6]-Java中的迭代器-yiteyi-C++库

当迭代器的光标指向列表的最后一个元素之后时,hasNext()方法返回一个假值。

注: 在观察了所有这些图之后,我们可以说Java迭代器只支持正向迭代,如下图所示。所以它也被称为单向光标。

图片[7]-Java中的迭代器-yiteyi-C++库

例子:

JAVA

// Java program to Demonstrate Iterator
// Importing ArrayList and Iterator classes
// from java.util package
import java.util.ArrayList;
import java.util.Iterator;
// Main class
public class Test {
// Main driver method
public static void main(String[] args)
{
// Creating an ArrayList class object
// Declaring object of integer type
ArrayList<Integer> al = new ArrayList<Integer>();
// Iterating over the List
for ( int i = 0 ; i < 10 ; i++)
al.add(i);
// Printing the elements in the List
System.out.println(al);
// At the beginning itr(cursor) will point to
// index just before the first element in al
Iterator itr = al.iterator();
// Checking the next element  where
// condition holds true till there is single element
// in the List using hasnext() method
while (itr.hasNext()) {
//  Moving cursor to next element
int i = (Integer)itr.next();
// Getting even elements one by one
System.out.print(i + " " );
// Removing odd elements
if (i % 2 != 0 )
itr.remove();
}
// Command for next line
System.out.println();
// Printing the elements inside the object
System.out.println(al);
}
}


输出

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]0 1 2 3 4 5 6 7 8 9 [0, 2, 4, 6, 8]

拆分迭代器

与其他迭代器一样,拆分器用于遍历源的元素。源可以是源 收集 ,IO通道或发电机功能。它包含在JDK 8中,除了支持顺序遍历之外,还支持高效的并行遍历(并行编程)。Java Spliterator接口是一个内部迭代器,它将流分解为更小的部分。这些较小的零件可以并行处理。

注: 在现实编程中,我们可能永远不需要直接使用拆分器。在正常操作下,它的行为与Java迭代器完全相同。

Java迭代器的优点

  • 我们可以将其用于任何收集类。
  • 它支持读取和删除操作。
  • 它是集合API的通用游标。
  • 方法名简单易用。

此外,迭代器还有一些限制,如下所示:

Java迭代器的局限性

  • 在CRUD操作中,它不支持创建和更新操作。
  • 它只支持单向迭代器的正向迭代。
  • 与Spliterator相比,它不支持并行迭代元素,这意味着它只支持顺序迭代。
  • 与Spliterator相比,它不支持迭代大量数据的更好性能。

2.列举

它是一个用于获取遗留集合(向量、哈希表)元素的接口。枚举是JDK 1.0中出现的第一个迭代器,REST包含在JDK 1.2中,具有更多功能。枚举还用于指定到 顺序输入流 .我们可以通过调用 元素() 任何向量对象上的向量类方法

// Here "v" is an Vector class object. e is of// type Enumeration interface and refers to "v"Enumeration e = v.elements();

枚举接口中的方法,即:

1.公共布尔hasMoreElements(): 此方法测试此枚举是否包含更多元素。

2.公共对象nextElement(): 此方法返回此枚举的下一个元素。如果没有更多元素存在,则抛出NoTouchElementException

JAVA

// Java program to demonstrate Enumeration
// Importing Enumeration and Vector classes
// from java.util package
import java.util.Enumeration;
import java.util.Vector;
// Main class
public class Test
{
// Main driver method
public static void main(String[] args)
{
// Creating a vector object
Vector v = new Vector();
// Iterating over vector object
for ( int i = 0 ; i < 10 ; i++)
v.addElement(i);
// Printing elements in vector object
System.out.println(v);
// At beginning e(cursor) will point to
// index just before the first element in v
Enumeration e = v.elements();
// Checking the next element availability where
// condition holds true till there is a single element
// remaining in the List
while (e.hasMoreElements())
{
// Moving cursor to next element
int i = (Integer)e.nextElement();
// Print above elements in object
System.out.print(i + " " );
}
}
}


输出:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]0 1 2 3 4 5 6 7 8 9 

枚举的某些限制如下:

  • 枚举是为 遗产 仅限类(向量、哈希表)。因此,它不是一个通用迭代器。
  • 无法使用枚举执行删除操作。
  • 只能进行正向迭代。

Java枚举和迭代器的相似之处

  • 两者都是Java游标。
  • 两者都用于逐个迭代对象元素的集合。
  • 两者都支持读取或检索操作。
  • 两者都是单向Java游标,这意味着只支持正向迭代。

Java枚举和迭代器的区别

下表描述了Java枚举和迭代器之间的差异:

列举 迭代器
在Java1.0中引入 在Java1.2中引入
遗留接口 不是遗留接口
它仅用于迭代遗留集合类。 我们可以将其用于任何收集类。
它只支持读取操作。 它支持读取和删除操作。
它不是通用光标。 它是一个通用光标。
冗长的方法名称。 简单易用的方法名。

3.列表迭代器

它只适用于列表集合实现的类,如ArrayList、LinkedList等。它提供双向迭代。当我们想要枚举列表的元素时,必须使用ListIterator。这个游标比迭代器有更多的功能(方法)。ListIterator对象可以通过调用 listIterator() 方法出现在列表界面中。

ListIterator ltr = l.listIterator();

注: 这里“l”是任何列表对象,ltr是类型。ListIterator接口,并引用“l”。ListIterator接口扩展了Iterator接口。因此,Iterator接口的所有三种方法都可用于ListIterator。此外,还有 更多方法。

1.前进方向

1.1 hasNext(): 如果迭代包含更多元素,则返回true

public boolean hasNext();

1.2下一步(): 与迭代器的next()方法相同。返回迭代中的下一个元素。

public Object next();

1.3 nextIndex(): 如果列表迭代器位于列表末尾,则返回下一个元素索引或列表大小。

public int nextIndex();

2.反向

2.1 hasPrevious(): 如果在向后遍历时迭代有更多元素,则返回true。

public boolean hasPrevious();

2.2上一个() 返回迭代中的上一个元素,可以抛出 非接触性异常 如果没有更多元素存在。

public Object previous();

2.3以前的索引(): 返回上一个元素索引,如果列表迭代器位于列表的开头,则返回-1,

public int previousIndex();

3.其他方法

3.1移除(): 与迭代器的remove()方法相同。删除迭代中的下一个元素。

public void remove();

3.2设置(对象obj): 用指定的元素替换next()或previous()返回的最后一个元素。

public void set(Object obj); 

3.3添加(对象obj): 将指定的元素插入列表中next()将返回的元素之前的位置

public void add(Object obj);

显然,这三种方法 列表迭代器 从迭代器继承( hasNext() , 下一个() 删除() )在两个接口中执行完全相同的操作。这个 hasPrevious() 之前的操作与 hasNext() 下一个() 前者指的是(隐式)光标前的元素,而后者指的是光标后的元素。前一个操作将光标向后移动,而下一个操作将光标向前移动。

ListIterator没有当前元素;其光标位置始终位于调用返回的元素之间 上一篇() 以及调用将返回的元素 下一步()。

1.集合() 方法可以抛出4个异常。

  • 不支持操作异常: 如果此列表迭代器不支持set操作
  • ClassCastException: 如果指定元素的类阻止将其添加到此列表中
  • IllegalArgumentException: 如果指定元素的某些方面阻止将其添加到此列表中
  • 非法州例外: 如果未调用next或previous,或者在上次调用next或previous之后调用了remove或add

2.添加() 方法可以引发3个异常。

  • 不支持操作异常: 如果此列表迭代器不支持add方法
  • ClassCastException: 如果指定元素的类阻止将其添加到此列表中
  • IllegalArgumentException: 如果此元素的某些方面阻止将其添加到此列表中

例子:

JAVA

// Java program to demonstrate ListIterator
// Importing ArrayList and List iterator classes
// from java.util package
import java.util.ArrayList;
import java.util.ListIterator;
// Main class
public class Test {
// Main driver method
public static void main(String[] args)
{
// Creating an object of ArrayList class
ArrayList al = new ArrayList();
// Iterating over Arraylist object
for ( int i = 0 ; i < 10 ; i++)
// Adding elements to the Arraylist object
al.add(i);
// Print and display all elements inside object
// created above
System.out.println(al);
// At beginning ltr(cursor) will point to
// index just before the first element in al
ListIterator ltr = al.listIterator();
// Checking the next element availability
while (ltr.hasNext()) {
//  Moving cursor to next element
int i = (Integer)ltr.next();
// Getting even elements one by one
System.out.print(i + " " );
// Changing even numbers to odd and
// adding modified number again in
// iterator
if (i % 2 == 0 ) {
// Change to odd
i++;
// Set method to change value
ltr.set(i);
// To add
ltr.add(i);
}
}
// Print and display statements
System.out.println();
System.out.println(al);
}
}


输出:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]0 1 2 3 4 5 6 7 8 9 [1, 1, 1, 3, 3, 3, 5, 5, 5, 7, 7, 7, 9, 9, 9]

注: 同样,ListIterator也有一定的局限性 . 它是最强大的迭代器,但它只适用于列表实现的类,因此它不是通用迭代器。

要点

  1. 请注意,最初,任何迭代器引用都会指向集合中第一个元素的索引之前的索引。
  2. 我们不创建枚举、迭代器、列表迭代器的对象,因为它们是接口。我们使用elements()、iterator()、listIterator()等方法来创建对象。这些方法具有匿名性 内部阶级 它扩展了各自的接口并返回这个类对象。

注: 这个 $ 引用类名中的符号证明使用了内部类的概念,并且创建了这些类对象。

这可以通过以下代码进行验证。有关内部类的更多信息,请参阅

JAVA

// Java program to demonstrate iterators references
// Importing required classes from java.util package
import java.util.Enumeration;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Vector;
// Main class
public class GFG {
// Main driver method
public static void main(String[] args)
{
// Creating an object of Vector class
Vector v = new Vector();
// Creating three iterators
Enumeration e = v.elements();
Iterator itr = v.iterator();
ListIterator ltr = v.listIterator();
// Print class names of iterators
// using getClass() and getName() methods
System.out.println(e.getClass().getName());
System.out.println(itr.getClass().getName());
System.out.println(ltr.getClass().getName());
}
}


输出

java.util.Vector$1java.util.Vector$Itrjava.util.Vector$ListItr

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享