1.はじめに
私たちが使用している場合for
やwhile
、コレクションの要素を反復処理するループを、Iterator
それは私たちも私たちだけではなく、コレクションを通じて、それを変更することができますが、また聞かせて、インデックス位置を心配しないですることができます。あなたは要素のサイクルを削除したい場合たとえば、for
周期は必ずしも常に可能ではありません。
カスタムイテレータと組み合わせることで、我々としても、前方と後方、より複雑なオブジェクトを反復処理し、非常に明確になるだろうその利点を活用する方法を知ることができます。
この記事では、どのように使用する深さに説明しますIterator
とIterable
インタフェース。
2.イテレータ()
Iterator
インタフェースは、反復要素を設定するために使用されているList
(Set
又はMap
)。要素を一つずつ取得するために使用され、各構成要素に必要なときに動作を行います。
以下の方法が実行されるオペレーションのセットを横断するために使用されます。
.hasNext()
:あなたは達していない場合は、コレクションの末尾が返されるtrue
それ以外の場合は、false
.next()
:コレクション内の次の要素を返します.remove()
:最後の要素が返されたコレクションの反復子から削除されます.forEachRemaining()
:指定された操作を実行するために、残りの要素のそれぞれに設定されています
まず、コレクションのイテレータので、のは簡単にはいくつかの要素が含まれてやらせます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");
私たちは、このコレクションを反復処理するために、単純なループを使用することができます。
System.out.println("Simple loop example:\n");
for (int i = 0; i < 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 < 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
継承されますIterator
インターフェイス。のみでのList
使用に行って、あなたが戻って前に戻ったりするために正面から繰り返すことができることを意味、双方向反復することができます。カーソルが常に置かれているので、それはまた、現在の要素ないList
二つの要素の間、私たちが使う.previous()
か.next()
の要素にアクセスします。
Iterator
そして、ListIterator
の違いは何ですか?
まず第一に、Iterator
それがために使用することができるの任意のセット - 、List
、、Map
などが挙げられます。Queue
Set
ListIterator
唯一、この制限を追加することで、リストを適用することができListIterator
、より特異的であることができる方法の面で、そのため、私たちは横断しながら、彼らはそれを修正するために私たちを助けることができる多くの新しい方法を導入しました。
あなたが作業している場合はList
(達成するためにArrayList
、LinkedList
など)、そして使用ListIterator
がより望ましい数を。
ここでは、使用する可能性があります方法は次のとおりです。
.add(E e)
:リストに要素を追加します。.remove()
:リストから削除する.next()
か、.previous()
最後の要素が返されます。.set(E e)
:リストをカバーするために、指定された要素を使用して、.next()
または.previous()
最後の要素を返します。.hasNext()
:あなたがリストの終わりに達していない場合は返しtrue
そうfalse
。.next()
:次の要素のリストを返します。.nextIndex()
:次の要素のインデックスを返します。.hasPrevious()
:あなたはまだリストの先頭に達していない場合は、返されtrue
そうfalse
。.previous()
:リストの前の要素を返します。.previousIndex()
:要素のインデックスを返します。
ここでも、の構成要素をいくつか使ってみましょうArrayList
:
ArrayList<String> defenders = new ArrayList<>();
defenders.add("Daredevil");
defenders.add("Luke Cage");
defenders.add("Jessica Jones");
defenders.add("Iron Fist");
私たちが使用してみましょうListIterator
リストを横断し、その要素を印刷するには:
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);
}
印刷一覧今、その後、次のような結果が得られます。
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ストリームと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<>();
mutants.add("Professor X");
mutants.add("Magneto");
mutants.add("Storm");
mutants.add("Jean Grey");
mutants.add("Wolverine");
mutants.add("Mystique");
今、私たちはする必要がSpliterator
適用されますStream
。幸い、コレクションフレームワークのために、それは簡単であるArrayList
とStream
の間で変換します。
// 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) -> 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));
私たちは、出力が得られます。
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.反復処理可能()
何らかの理由で、私たちは、カスタム作成する場合Iterator
のインターフェイスを、私たちはどのようにすればよいですか?あなたは最初に、この絵を知っている必要があります。
カスタムを作成するためにIterator
、私たちのようにする必要があり.hasNext()
、.next()
および.remove()
カスタム実装を行います。
Iterator
インターフェース要素のイテレータセット、即ち返すメソッド、ある.iterator()
方法、すなわちイテレータの各要素の動作の方法を実行するための方法であって、ある.dorEach()
方法。
例えば、我々はトニー・スタークあるとし、我々は、アイアンマン、現在の武器庫に合っの各部分をリストするカスタムイテレータを記述する必要があります。
まずは、データを取得および設定するために、クラスのスーツを作成してみましょう:
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() >= 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
5.まとめ
本論文では、私たちも、探求するカスタムイテレータを書いて、Javaでイテレータを使用する方法を詳細に議論するIterable
インタフェースのすべての新たな可能性を。
我々はまた、Javaがストリームの使用並列化する方法を話し合うSpliterator
内部の最適化のコレクションをインタフェースを。
8月の福祉は時間に打たれ、国民の関心番号舞台裏日時:7月003は、オハイオ州のハイライトの翻訳受け取ることができる福祉の日時に行く:001、002、あなたが受け取ることができます!