Java游标是迭代器,用于逐个迭代、遍历或检索集合或流对象的元素。有 Java中的三个游标 .
- 迭代器
- 列举
- 列表迭代器
注: SplitIterator也可以被视为游标,因为它只是一种迭代器。
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”迭代器看起来像——
这里迭代器的光标指向列表的第一个元素之前。
现在,我们将运行以下代码片段。
citiesIterator.hasNext();citiesIterator.next();
当我们运行上面的代码片段时,迭代器的光标指向列表中的第一个元素,如上图所示。
现在,我们将运行以下代码片段。
citiesIterator.hasNext();citiesIterator.next();
当我们运行上面的代码片段时,迭代器的光标指向列表中的第二个元素,如上图所示。执行此过程以将迭代器的光标移到列表的结束元素。
在读取最后一个元素后,如果我们运行下面的代码片段,它将返回一个“false”值。
citiesIterator.hasNext();
当迭代器的光标指向列表的最后一个元素之后时,hasNext()方法返回一个假值。
注: 在观察了所有这些图之后,我们可以说Java迭代器只支持正向迭代,如下图所示。所以它也被称为单向光标。
例子:
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也有一定的局限性 . 它是最强大的迭代器,但它只适用于列表实现的类,因此它不是通用迭代器。
要点
- 请注意,最初,任何迭代器引用都会指向集合中第一个元素的索引之前的索引。
- 我们不创建枚举、迭代器、列表迭代器的对象,因为它们是接口。我们使用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