क्या हम जावा में अपना इटरेटर लिख सकते हैं?


104

अगर मेरे पास एक सूची है [alice, bob, abigail, charlie]और मैं एक पुनरावृत्ति लिखना चाहता हूं, तो यह ऐसे तत्वों पर निर्भर करता है जो 'a' से शुरू होते हैं, क्या मैं अपना स्वयं का लिख ​​सकता हूं? मैं उसे कैसे कर सकता हूँ ?


4
आप ऐसा कर सकते हैं। आपको Iterator इंटरफ़ेस लागू करना होगा।
gd1

यकीन है, यह सिर्फ एक सामान्य इंटरफ़ेस है। JDO इम्पैक्ट के लिए java.util को सम्‍मिलित करना। इसमें बहुत सारे कस्टम पुनरावृत्तियाँ शामिल हैं।
'16

जवाबों:


48

ज़रूर। एक पुनरावृत्ति java.util.Iteratorइंटरफ़ेस का सिर्फ एक कार्यान्वयन है । यदि आप एक मौजूदा iterable वस्तु (जैसे कि, एक प्रयोग कर रहे हैं LinkedList) से java.util, आप इसे किसी उपवर्ग करने की जरूरत है और उसके पर वरीयता दी जाएगी iteratorसमारोह ताकि आप अपने खुद के लौटने के लिए, या अपने विशेष में एक मानक इटरेटर लपेटकर का एक साधन प्रदान Iteratorउदाहरण (जो अधिक व्यापक रूप से इस्तेमाल होने का लाभ), आदि।


8
अच्छा जवाब .... +1 हालांकि आप लिंक्डलिस्ट को उप-करने के लिए मजबूर नहीं हैं। आप एक CustomIterator लिख सकते हैं कि यह नए CustomIterator (somelist) के साथ त्वरित है, क्योंकि इंटरफेस बिल्डरों के साथ कुछ भी नहीं बताते हैं।
जीडी

1
@ गियाकोमो: इसका मतलब है कि मैं "... या अपने विशेष Iteratorउदाहरण में एक मानक पुनरावृत्ति लपेटने का साधन प्रदान करता हूं ..." (और धन्यवाद)। :-)
टीजे क्राउडर

196

सबसे अच्छा पुन: प्रयोज्य विकल्प इंटरफ़ेस को लागू करने के लिए है और विधि पुनरावृत्ति () को ओवरराइड करता है।

यहाँ एक ArrayList का उदाहरण है जैसे कि इंटरफ़ेस को लागू करने वाला वर्ग, जिसमें आप विधि Iterator () को ओवरराइड करते हैं।

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;
    }
}

यह वर्ग जेनरिक का उपयोग करके Iterable इंटरफ़ेस को लागू करता है । आपके पास सरणी के तत्वों को ध्यान में रखते हुए, आप एक Iterator का एक उदाहरण प्राप्त करने में सक्षम होंगे, जो कि उदाहरण के लिए "foreach" लूप द्वारा उपयोग किया जाने वाला आवश्यक उदाहरण है।

आप केवल इटरेटर को बनाए बिना इटरेटर का एक अनाम उदाहरण बना सकते हैं और वर्तमान के मूल्य का लाभ उठाकर यह सत्यापित कर सकते हैं कि आप ऐरे पर कहां नेविगेट कर सकते हैं (मान लीजिए कि आपने 10 की क्षमता वाला ऐरे बनाया है, लेकिन आपके पास केवल 2 हैं तत्व 0 और 1 पर)। उदाहरण के पास इसका स्वामी काउंटर होगा जहां यह है और आपको बस इतना करना है कि hasNext () के साथ खेलना है, जो सत्यापित करता है कि वर्तमान मान शून्य नहीं है, और अगला (), जो आपके currentIndex का उदाहरण लौटाएगा। नीचे इस 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

यदि आप चाहें, तो आप Iterator उदाहरण का उपयोग करके उस पर पुनरावृति कर सकते हैं:

// 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 प्रलेखन http://download.oracle.com/javase/1,5.0/docs/guide/language/foreach.html पर स्थित है । आप मेरे व्यक्तिगत अभ्यास Google कोड पर अधिक संपूर्ण कार्यान्वयन पर एक नज़र डाल सकते हैं ।

अब, आपको जो मेरी आवश्यकता है, उसके प्रभावों को प्राप्त करने के लिए आपको Iterator में एक फिल्टर की अवधारणा को प्लग करने की आवश्यकता है ... चूंकि इटिटर अगले मानों पर निर्भर करता है, इसलिए hasNext () पर सही लौटना मुश्किल होगा अगले मूल्य को फ़िल्टर करें () ऐसे मूल्य के साथ कार्यान्वयन जो उदाहरण के लिए "a" के साथ शुरू नहीं होता है। मुझे लगता है कि आपको दिए गए फ़िल्टर के साथ मानों के साथ फ़िल्टर्ड सूची के आधार पर एक माध्यमिक इंटररेटर के साथ खेलना होगा।


14
for instance, यह एक सजा है?
n611x007 12

4
30 अन्य लोगों ने यह नहीं सोचा कि यह एक दंड है :)
मार्सेलो डे सेल्स डे

2
हमारे द्वारा कार्यान्वित विधियों से असमर्थित ऑपरेशन अपवाद को फेंकना एक अच्छा अभ्यास है। मुझे लगता है कि हटाने () विधि से असमर्थित ऑपरेशन अपवाद को फेंकना एक अच्छा विचार है!
दर्शन

2
क्षमा करें @ दर्शन, लेकिन यह समाधान "कैसे लिखने वालों को लिखने के लिए" के संबंध में है ... यदि ध्यान "पूरी तरह से लिखित कोड लिखने के लिए" था, तो यह होगा!
मार्सेलो डे सेल्स

स्पष्ट नहीं है कि क्यों 'arrayList [currentIndex]! = null' चेक हैशनेट () के अंदर आवश्यक है। क्या कोई समझा सकता है।
भूषण कर्मकार

12

तथ्यात्मक गणना करने के लिए Iterable के लिए अच्छा उदाहरण

FactorialIterable fi = new FactorialIterable(10);
Iterator<Integer> iterator = fi.iterator();
while (iterator.hasNext()){
     System.out.println(iterator.next());
}

जावा 1.8 का लघु कोड

new FactorialIterable(5).forEach(System.out::println);

कस्टम Iterable वर्ग

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);
    }

}

कस्टम Iterator वर्ग

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;
    }
}

8

यह लिखने का पूरा कोड है कि यह 'ए' से शुरू होने वाले तत्वों पर आधारित है।

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); 
        }
    }
}

कस्टम Iterator वर्ग

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; 
        }
    } 
}

5

आप अपने स्वयं के Iterator को लागू कर सकते हैं। आपके पुनरावृत्ति का निर्माण सूची द्वारा लौटे Iterator को लपेटने के लिए किया जा सकता है, या आप एक कर्सर रख सकते हैं और सूची के प्राप्त (इंट इंडेक्स) विधि का उपयोग कर सकते हैं। आपको अपने फ़िल्टरिंग मानदंडों को ध्यान में रखने के लिए बस अपने Iterator की अगली विधि और hasNext विधि में तर्क जोड़ना होगा। आपको यह भी तय करना होगा कि आपका पुनरावृत्ति हटाने के ऑपरेशन का समर्थन करेगा या नहीं।


1

यहां सवाल का पूरा जवाब है।

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 उस एरे के लिए पुनरावृत्त है जो 'ए' से शुरू होने वाले तत्वों को लौटाता है।
  • एक Iterable इंटरफ़ेस को लागू करने की कोई आवश्यकता नहीं है। लेकिन वह एक संभावना है।
  • इसे उदारतापूर्वक लागू करने की आवश्यकता नहीं है।
  • यह hasNext () और अगले () के अनुबंध को पूरी तरह से संतुष्ट करता है। यानी अगर हैनक्स्ट () कहता है कि अभी भी तत्व हैं, तो अगले () उन तत्वों को वापस कर देंगे। और अगर hasext () कोई और तत्व नहीं कहता है, तो यह एक वैध NoSuchElementExceptionअपवाद देता है।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.