Programing

Java로 자체 반복자를 작성할 수 있습니까?

lottogame 2020. 9. 6. 11:49
반응형

Java로 자체 반복자를 작성할 수 있습니까?


포함 된 목록이 [alice, bob, abigail, charlie]있고 'a'로 시작하는 요소를 반복하는 반복자를 작성하려면 직접 작성할 수 있습니까? 어떻게 할 수 있습니까?


확실한. 반복기는 java.util.Iterator인터페이스 의 구현 일뿐 입니다. 에서 기존의 반복 가능한 객체 (예 : a LinkedList)를 사용 java.util하는 경우 하위 클래스를 만들고 iterator함수를 재정 의하여 고유 한 값을 반환하거나 특수 Iterator인스턴스 에서 표준 반복기를 래핑하는 수단을 제공해야 합니다 ( 더 광범위하게 사용되는 이점이 있습니다) 등


재사용 가능한 가장 좋은 옵션은 Iterable 인터페이스를 구현하고 iterator () 메서드를 재정의하는 것입니다.

다음은 Iterator () 메서드를 재정의하는 인터페이스를 구현하는 클래스와 같은 ArrayList의 예입니다.

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

이 클래스는 Generics를 사용하여 Iterable 인터페이스를 구현합니다 . 배열에 요소가 있다는 점을 고려하면 예를 들어 "foreach"루프에서 사용하는 필수 인스턴스 인 반복기의 인스턴스를 가져올 수 있습니다.

Iterator를 확장하지 않고 반복자의 익명 인스턴스를 생성하고 currentSize의 값을 활용하여 배열을 탐색 할 수있는 위치까지 확인할 수 있습니다 (용량이 10 인 배열을 생성했다고 가정 해 보겠습니다. 0과 1의 요소). 인스턴스는 현재 위치에 대한 소유자 카운터를 가지며 현재 값이 null이 아닌지 확인하는 hasNext ()와 currentIndex의 인스턴스를 반환하는 next ()를 사용하여 재생하기 만하면됩니다. 다음은이 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

The foreach documentation is located at http://download.oracle.com/javase/1,5.0/docs/guide/language/foreach.html. You can take a look at a more complete implementation at my personal practice google code.

Now, to get the effects of what you need I think you need to plug a concept of a filter in the Iterator... Since the iterator depends on the next values, it would be hard to return true on hasNext(), and then filter the next() implementation with a value that does not start with a char "a" for instance. I think you need to play around with a secondary Interator based on a filtered list with the values with the given filter.


Good example for Iterable to compute factorial

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

shortly code for Java 1.8

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

custom Iterable class

public class FactorialIterable implements Iterable<Integer> {

    private final FactorialIteartor factorialIteartor;

    public FactorialIterable(Integer value) {
        factorialIteartor = new FactorialIteartor(value);
    }

    @Override
    public Iterator<Integer> iterator() {
        return factorialIteartor;
    }

    @Override
    public void forEach(Consumer<? super Integer> action) {
        Objects.requireNonNull(action);
        Integer last = 0;
        for (Integer t : this) {
            last = t;
        }
        action.accept(last);
    }

}

custom Iterator class

public class FactorialIteartor implements Iterator<Integer> {

    private final Integer mNumber;
    private Integer mPosition;
    private Integer mFactorial;


    public FactorialIteartor(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;
    }
}

This is the complete code to write an iterator such that it iterates over elements that begin with 'a':

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

Custom Iterator class

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

You can implement your own Iterator. Your iterator could be constructed to wrap the Iterator returned by the List, or you could keep a cursor and use the List's get(int index) method. You just have to add logic to your Iterator's next method AND the hasNext method to take into account your filtering criteria. You will also have to decide if your iterator will support the remove operation.

참고URL : https://stackoverflow.com/questions/5849154/can-we-write-our-own-iterator-in-java

반응형