Wenn ich eine Liste [alice, bob, abigail, charlie]
habe, die einen Iterator enthält, und ich möchte ihn so schreiben, dass er über Elemente iteriert, die mit 'a' beginnen, kann ich dann meinen eigenen schreiben? Wie kann ich das machen ?
Wenn ich eine Liste [alice, bob, abigail, charlie]
habe, die einen Iterator enthält, und ich möchte ihn so schreiben, dass er über Elemente iteriert, die mit 'a' beginnen, kann ich dann meinen eigenen schreiben? Wie kann ich das machen ?
Antworten:
Sicher. Ein Iterator ist nur eine Implementierung der java.util.Iterator
Schnittstelle. Wenn Sie ein vorhandenes iterierbares Objekt (z. B. a LinkedList
) von verwenden java.util
, müssen Sie es entweder in Unterklassen unterteilen und seine iterator
Funktion überschreiben , damit Sie Ihr eigenes zurückgeben, oder Sie können einen Standarditerator in Ihre spezielle Iterator
Instanz einschließen (welche) hat den Vorteil einer breiteren Verwendung) usw.
Iterator
Instanz ..." gemeint (und danke). :-)
Die beste wiederverwendbare Option besteht darin, die Schnittstelle Iterable zu implementieren und den Methodeniterator () zu überschreiben.
Hier ist ein Beispiel für eine ArrayList-ähnliche Klasse, die die Schnittstelle implementiert, in der Sie die Methode Iterator () überschreiben.
import java.util.Iterator;
public class SOList<Type> implements Iterable<Type> {
private Type[] arrayList;
private int currentSize;
public SOList(Type[] newArray) {
this.arrayList = newArray;
this.currentSize = arrayList.length;
}
@Override
public Iterator<Type> iterator() {
Iterator<Type> it = new Iterator<Type>() {
private int currentIndex = 0;
@Override
public boolean hasNext() {
return currentIndex < currentSize && arrayList[currentIndex] != null;
}
@Override
public Type next() {
return arrayList[currentIndex++];
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
return it;
}
}
Diese Klasse implementiert die Iterable-Schnittstelle mithilfe von Generics . Wenn Sie Elemente im Array haben, können Sie eine Instanz eines Iterators abrufen. Dies ist beispielsweise die benötigte Instanz, die von der "foreach" -Schleife verwendet wird.
Sie können einfach eine anonyme Instanz des Iterators erstellen, ohne einen erweiterten Iterator zu erstellen, und den Wert von currentSize nutzen, um zu überprüfen, bis zu welcher Stelle Sie über das Array navigieren können (nehmen wir an, Sie haben ein Array mit einer Kapazität von 10 erstellt, aber Sie haben nur 2 Elemente bei 0 und 1). Die Instanz hat ihren Eigentümerzähler, wo sie sich befindet, und alles, was Sie tun müssen, ist mit hasNext () zu spielen, das überprüft, ob der aktuelle Wert nicht null ist, und mit next (), das die Instanz Ihres currentIndex zurückgibt. Unten finden Sie ein Beispiel für die Verwendung dieser API ...
public static void main(String[] args) {
// create an array of type Integer
Integer[] numbers = new Integer[]{1, 2, 3, 4, 5};
// create your list and hold the values.
SOList<Integer> stackOverflowList = new SOList<Integer>(numbers);
// Since our class SOList is an instance of Iterable, then we can use it on a foreach loop
for(Integer num : stackOverflowList) {
System.out.print(num);
}
// creating an array of Strings
String[] languages = new String[]{"C", "C++", "Java", "Python", "Scala"};
// create your list and hold the values using the same list implementation.
SOList<String> languagesList = new SOList<String>(languages);
System.out.println("");
// Since our class SOList is an instance of Iterable, then we can use it on a foreach loop
for(String lang : languagesList) {
System.out.println(lang);
}
}
// will print "12345
//C
//C++
//Java
//Python
//Scala
Wenn Sie möchten, können Sie auch mit der Iterator-Instanz darüber iterieren:
// navigating the iterator
while (allNumbers.hasNext()) {
Integer value = allNumbers.next();
if (allNumbers.hasNext()) {
System.out.print(value + ", ");
} else {
System.out.print(value);
}
}
// will print 1, 2, 3, 4, 5
Die foreach-Dokumentation befindet sich unter http://download.oracle.com/javase/1,5.0/docs/guide/language/foreach.html . Eine vollständigere Implementierung finden Sie in meinem persönlichen Google-Code .
Um die Auswirkungen dessen zu erhalten, was Sie benötigen, müssen Sie meines Erachtens ein Filterkonzept in den Iterator einfügen ... Da der Iterator von den nächsten Werten abhängt, ist es schwierig, true auf hasNext () und dann zurückzugeben Filtern Sie die next () - Implementierung mit einem Wert, der beispielsweise nicht mit einem Zeichen "a" beginnt. Ich denke, Sie müssen mit einem sekundären Interator herumspielen, der auf einer gefilterten Liste mit den Werten mit dem angegebenen Filter basiert.
for instance
Ist das ein Wortspiel?
Gutes Beispiel für Iterable zur Berechnung der Fakultät
FactorialIterable fi = new FactorialIterable(10);
Iterator<Integer> iterator = fi.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
Funktionscode für Java 1.8
new FactorialIterable(5).forEach(System.out::println);
Benutzerdefinierte iterierbare Klasse
public class FactorialIterable implements Iterable<Integer> {
private final FactorialIterator factorialIterator;
public FactorialIterable(Integer value) {
factorialIterator = new FactorialIterator(value);
}
@Override
public Iterator<Integer> iterator() {
return factorialIterator;
}
@Override
public void forEach(Consumer<? super Integer> action) {
Objects.requireNonNull(action);
Integer last = 0;
for (Integer t : this) {
last = t;
}
action.accept(last);
}
}
Benutzerdefinierte Iterator-Klasse
public class FactorialIterator implements Iterator<Integer> {
private final Integer mNumber;
private Integer mPosition;
private Integer mFactorial;
public FactorialIterator(Integer number) {
this.mNumber = number;
this.mPosition = 1;
this.mFactorial = 1;
}
@Override
public boolean hasNext() {
return mPosition <= mNumber;
}
@Override
public Integer next() {
if (!hasNext())
return 0;
mFactorial = mFactorial * mPosition;
mPosition++;
return mFactorial;
}
}
Dies ist der vollständige Code zum Schreiben eines Iterators, sodass er über Elemente iteriert, die mit 'a' beginnen:
import java.util.Iterator;
public class AppDemo {
public static void main(String args[]) {
Bag<String> bag1 = new Bag<>();
bag1.add("alice");
bag1.add("bob");
bag1.add("abigail");
bag1.add("charlie");
for (Iterator<String> it1 = bag1.iterator(); it1.hasNext();) {
String s = it1.next();
if (s != null)
System.out.println(s);
}
}
}
Benutzerdefinierte Iterator-Klasse
import java.util.ArrayList;
import java.util.Iterator;
public class Bag<T> {
private ArrayList<T> data;
public Bag() {
data = new ArrayList<>();
}
public void add(T e) {
data.add(e);
}
public Iterator<T> iterator() {
return new BagIterator();
}
public class BagIterator<T> implements Iterator<T> {
private int index;
private String str;
public BagIterator() {
index = 0;
}
@Override
public boolean hasNext() {
return index < data.size();
}
@Override
public T next() {
str = (String) data.get(index);
if (str.startsWith("a"))
return (T) data.get(index++);
index++;
return null;
}
}
}
Sie können Ihren eigenen Iterator implementieren. Ihr Iterator kann so konstruiert sein, dass er den von der Liste zurückgegebenen Iterator umschließt, oder Sie können einen Cursor behalten und die Methode get (int index) der Liste verwenden. Sie müssen nur der nächsten Methode Ihres Iterators UND der hasNext-Methode Logik hinzufügen, um Ihre Filterkriterien zu berücksichtigen. Sie müssen auch entscheiden, ob Ihr Iterator den Entfernungsvorgang unterstützt.
Hier ist die vollständige Antwort auf die Frage.
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
class ListIterator implements Iterator<String>{
List<String> list;
int pos = 0;
public ListIterator(List<String> list) {
this.list = list;
}
@Override
public boolean hasNext() {
while(pos < list.size()){
if (list.get(pos).startsWith("a"))
return true;
pos++;
}
return false;
}
@Override
public String next() {
if (hasNext())
return list.get(pos++);
throw new NoSuchElementException();
}
}
public class IteratorTest {
public static void main(String[] args) {
List<String> list = Arrays.asList("alice", "bob", "abigail", "charlie");
ListIterator itr = new ListIterator(list);
while(itr.hasNext())
System.out.println(itr.next()); // prints alice, abigail
}
}
ListIterator
ist der Iterator für das Array, der die Elemente zurückgibt, die mit 'a' beginnen. NoSuchElementException
Ausnahme zurückgegeben.