İçeren bir listem varsa [alice, bob, abigail, charlie]ve 'a' ile başlayan öğeleri yineleyen bir yineleyici yazmak istersem, kendi listemi yazabilir miyim? Bunu nasıl yapabilirim ?
İçeren bir listem varsa [alice, bob, abigail, charlie]ve 'a' ile başlayan öğeleri yineleyen bir yineleyici yazmak istersem, kendi listemi yazabilir miyim? Bunu nasıl yapabilirim ?
Yanıtlar:
Elbette. Yineleyici, java.util.Iteratorarayüzün yalnızca bir uygulamasıdır . Kaynaktan var olan bir yinelenebilir nesneyi (örneğin, a LinkedList) kullanıyorsanız java.util, ya kendi alt sınıfınızı iteratordöndürmek için ya da kendi özel Iteratorörneğinize standart bir yineleyici sarmak için bir yol sağlamanız gerekir ( daha geniş kullanım avantajına sahiptir) vb.
Iteratorörneğinize standart bir yineleyici sarmanın bir yolunu sunun ..." derken bunu kastettim (ve teşekkürler). :-)
Yeniden kullanılabilir en iyi seçenek, yinelenebilir arabirimi uygulamak ve yöntem iteratörünü () geçersiz kılmaktır.
Iterator () yöntemini geçersiz kıldığınız, arabirimi uygulayan ArrayList benzeri bir sınıf örneğini burada bulabilirsiniz.
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;
}
}
Bu sınıf, Generics kullanarak yinelenebilir arabirimi uygular . Dizinin elemanlarına sahip olduğunuzu düşünürsek, örneğin "foreach" döngüsü tarafından kullanılan gerekli olan bir Yineleyici örneğini elde edebileceksiniz.
Genişletici Yineleyici oluşturmadan yineleyicinin anonim bir örneğini oluşturabilir ve dizi üzerinde nereye gidebileceğinizi doğrulamak için currentSize değerinden yararlanabilirsiniz (diyelim ki 10 kapasiteli bir dizi oluşturdunuz, ancak yalnızca 2 0 ve 1'deki öğeler). Örnek, bulunduğu yerin sahip sayacına sahip olacak ve yapmanız gereken tek şey, geçerli değerin boş olup olmadığını doğrulayan hasNext () ile oynamak ve next (), bu da currentIndex'inizin örneğini döndürecektir. Aşağıda bu API'yi kullanmanın bir örneği var ...
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
İsterseniz, Iterator örneğini kullanarak da yineleyebilirsiniz:
// 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
Foreach belgeleri http://download.oracle.com/javase/1,5.0/docs/guide/language/foreach.html adresinde bulunmaktadır . Kişisel pratiğim google kodunda daha eksiksiz bir uygulamaya göz atabilirsiniz .
Şimdi, ihtiyacınız olanın etkilerini elde etmek için Yineleyiciye bir filtre kavramı eklemeniz gerektiğini düşünüyorum ... Yineleyici sonraki değerlere bağlı olduğundan, hasNext () 'de true döndürmek zor olacak ve sonra sonraki () gerçeklemeyi bir char "a" ile başlamayan bir değerle filtreleyin örneğin. Verilen filtreye sahip değerlere sahip filtrelenmiş bir listeye dayalı ikincil bir Interator ile oynamanız gerektiğini düşünüyorum.
for instance, bu bir kelime oyunu mu?
Faktöriyel hesaplamak için Yinelenebilir için iyi bir örnek
FactorialIterable fi = new FactorialIterable(10);
Iterator<Integer> iterator = fi.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
Java 1.8 için kısa kod
new FactorialIterable(5).forEach(System.out::println);
Özel Yinelenebilir sınıf
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);
}
}
Özel Yineleyici sınıfı
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;
}
}
Bu, 'a' ile başlayan öğeler üzerinde yinelenecek şekilde bir yineleyici yazmak için eksiksiz koddur:
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);
}
}
}
Özel Yineleyici sınıfı
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;
}
}
}
Kendi Yineleyicinizi uygulayabilirsiniz. Yineleyiciniz, List tarafından döndürülen Yineleyiciyi saracak şekilde yapılandırılabilir veya bir imleci tutup List'in get (int indeks) yöntemini kullanabilirsiniz. Filtreleme kriterlerinizi hesaba katmak için Yineleyicinizin sonraki yöntemine VE hasNext yöntemine mantık eklemeniz yeterlidir. Yineleyicinizin kaldırma işlemini destekleyip desteklemeyeceğine de karar vermeniz gerekecektir.
İşte sorunun tam cevabı.
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 'a' ile başlayan öğeleri döndüren dizinin yineleyicisidir. NoSuchElementExceptionistisna döndürür .