1 Introduction
When we use for
or while
loop to iterate over the elements of a collection, Iterator
it allows us to not worry about the index position, even let us not just through a collection, but also can change it. For example, if you want to delete the element cycle, the for
cycle is not necessarily always possible.
Combined with a custom iterator, we can iterate more complex objects, as well as forward and backward, and know how to make use of its advantages will become very clear.
This article will discuss in depth how to use Iterator
and Iterable
interface.
2. Iterator()
Iterator
Interface is used to set the iteration element List
( , Set
or Map
). It is used to retrieve elements one by one, and performs operations when required for each element.
The following method is used to traverse the set of operations performed:
.hasNext()
: If you have not reached the end of the collection is returnedtrue
, otherwisefalse
.next()
: Returns the next element in the collection.remove()
: The last element is removed from the collection iterator returned.forEachRemaining()
: In order to perform a given operation is set in each of the remaining element
First, because the iterator for a collection, let's do a simple contains several elements ArrayList
:
List<String> avengers = new ArrayList<>();
// Now lets add some Avengers to the list
avengers.add("Ant-Man");
avengers.add("Black Widow");
avengers.add("Captain America");
avengers.add("Doctor Strange");
We can use a simple loop to iterate this collection:
System.out.println("Simple loop example:\n");
for (int i = 0; i < avengers.size(); i++) {
System.out.println(avengers.get(i));
}
However, we would like to explore the iterator:
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());
}
If we want this ArrayList
to delete an element, what would happen? Let's try using a regular for
cycle:
System.out.println("Simple loop example:\n");
for (int i = 0; i < avengers.size(); i++) {
if (avengers.get(i).equals("Doctor Strange")) {
avengers.remove(i);
}
System.out.println(avengers.get(i));
}
We will receive a nasty IndexOutOfBoundsException
:
Simple loop example:
Ant-Man
Black Widow
Captain America
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
This change is significant in its size when iterating over collections, enhance for
circulation, too:
System.out.println("Simple loop example:\n");
for (String avenger : avengers) {
if (avenger.equals("Doctor Strange")) {
avengers.remove(avenger);
}
System.out.println(avenger);
}
Once again, we received another exception:
Simple loop example:
Ant-Man
Black Widow
Captain America
Doctor Strange
Exception in thread "main" java.util.ConcurrentModificationException
Then iterator comes in handy, it acts as a middleman, remove elements from the collection, while ensuring that traverse continue as planned:
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();
}
}
This is to ensure the safe way to remove elements while traversing the collection.
And confirm whether the element has been deleted:
// 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);
Output is as follows:
For Each Remaining Example:
Black Widow
Captain America
Doctor Strange
As you can see, the people have ants from 复仇者联盟
the list of deleted.
2.1. ListIterator ()
ListIterator
Inherited from the Iterator
interface. In only List
carried out on the use, you can two-way iterative, which means you can iterate from front to back or back to front. It also does not current element, because the cursor is always placed List
between the two elements, so we use .previous()
or .next()
access the elements.
Iterator
AndListIterator
What is the difference between?
First of all, Iterator
it can be used for any set of - List
, Map
, Queue
, Set
and the like.
ListIterator
Can only be applied List, by adding this limitation, ListIterator
in terms of the method can be more specific, and therefore, we have introduced many new ways that they can help us to modify it while traversing.
If you are working List
to achieve ( ArrayList
, LinkedList
etc.), then use the ListIterator
more desirable number.
Here's how you might use:
.add(E e)
: Add elements to the List..remove()
: Remove from the List.next()
or.previous()
the last element returned..set(E e)
: Use the specified element to cover the List.next()
or.previous()
the last element returned..hasNext()
: If you have not reached the end of List Returnstrue
otherwisefalse
..next()
: Returns the next element List..nextIndex()
: Returns the index of the next element..hasPrevious()
: If you have not yet reached the beginning of the List, then returnstrue
otherwisefalse
..previous()
: Returns the previous element of List..previousIndex()
: Returns the index of an element.
Again, let's use some elements constitute a ArrayList
:
ArrayList<String> defenders = new ArrayList<>();
defenders.add("Daredevil");
defenders.add("Luke Cage");
defenders.add("Jessica Jones");
defenders.add("Iron Fist");
Let us use ListIterator
to traverse the List and print its elements:
ListIterator listIterator = defenders.listIterator();
System.out.println("Original contents of our List:\n");
while (listIterator.hasNext())
System.out.print(listIterator.next() + System.lineSeparator());
Obviously, it works the Iterator
same. Output is as follows:
Original contents of our List:
Daredevil
Luke Cage
Jessica Jones
Iron Fist
Now, let's try to modify some elements:
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 of print now, then get the following results:
Modified contents of our List:
The Mighty Defender: Daredevil
The Mighty Defender: Luke Cage
The Mighty Defender: Jessica Jones
The Mighty Defender: Iron Fist
Now, let's go through the list backwards, just as we can ListIterator
do it:
System.out.println("Modified List backwards:\n");
while (defendersListIterator.hasPrevious()) {
System.out.println(defendersListIterator.previous());
}
Output is as follows:
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
The interface is functionally Iterator
identical. You may never need to use directly Spliterator
, but let's move on to some use cases.
However, you should be familiar with Java Streams and the Lambda Expressions in the Java .
Although we will list Spliterator
all the methods have, but Spliterator
all the work interface is beyond the scope of this article. Through an example we will discuss Spliterator
how to use the more efficient parallelized traverse we can decompose Stream
.
We deal Spliterator
method is used when:
.characteristics()
: As having returned to the Spliterator
int
Eigenvalues. These include:
ORDERED
DISTINCT
SORTED
SIZED
CONCURRENT
IMMUTABLE
NONNULL
SUBSIZED
.estimateSize()
: Return to traverse aslong
an estimate of the value of the number of elements encountered, if unable to return is returnedlong.MAX_VALUE
..forEachRemaining(E e)
: In order to set each of the remaining element to perform a given operation..getComparator()
: If theSpliterator
source is madeComparator
, it will return sortedComparator
..getExactSizeIfKnown()
: If the size is known then returns.estimateSize()
otherwise-1
..hasCharacteristics(int characteristics)
: If thisSpliterator
is.characteristics()
containing all the given characteristics is returnedtrue
..tryAdvance(E e)
: If there are remaining elements, to perform a given operation on its returntrue
, otherwisefalse
..trySplit()
: If thisSpliterator
can be partitioned, it returns aSpliterator
covering element, when returning from this method, this will not beSpliterator
covered.
As usual, let's start with a simple ArrayList
start:
List<String> mutants = new ArrayList<>();
mutants.add("Professor X");
mutants.add("Magneto");
mutants.add("Storm");
mutants.add("Jean Grey");
mutants.add("Wolverine");
mutants.add("Mystique");
Now, we need to Spliterator
be applied Stream
. Fortunately, due to the Collections framework, it is easy ArrayList
and Stream
convert between:
// Obtain a Stream to the mutants List.
Stream<String> mutantStream = mutants.stream();
// Getting Spliterator object on mutantStream.
Spliterator<String> mutantList = mutantStream.spliterator();
To demonstrate some of these methods, let us run them separately:
// .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) -> 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) -> System.out.println(n));
}
// Now, use the splitList1
System.out.println("\nOutput from splitList1:");
splitList1.forEachRemaining((n) -> System.out.println(n));
We will get the output:
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()
If for some reason, we want to create a custom Iterator
interfaces, how should we do? You must first know that this picture:
To create a custom Iterator
, we need to .hasNext()
, .next()
and .remove()
do a custom implementation.
In the Iterator
interface, there is a method, which returns an iterator set of elements, i.e. .iterator()
a method, there is a method to perform a method of operation of each element in the iterator, i.e. .dorEach()
methods.
For example, suppose we are Tony Stark, we need to write custom iterators to list each piece of Iron Man suits the current arsenal.
First, let's create a class suit to get and set data:
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;
}
}
Let's write custom 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() >= 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
}
}
The last class is the main method:
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);
}
}
}
Output is as follows:
mark: 22, codename: HOTROD
mark: 33, codename: SILVER CENTURION
mark: 34, codename: SOUTHPAW
mark: 48, codename: HULKBUSTER 2.0
5. Summary
In this paper, we discuss in detail how to use iterators in Java, even wrote a custom iterator to explore Iterable
all the new possibilities of the interface.
We also discuss how Java is parallelized Stream, the use of Spliterator
interface through the collection of internal optimization.
August welfare struck on time, public concern number backstage Re: July 003 can receive a translation of highlights oh go on welfare Re: 001, 002, you can receive!