Gabungkan iterator di Groovy

Diberikan tiga iterator

it1, it2, it3

bagaimana saya bisa mengembalikan satu iterator yang mengulangi it1, lalu it2 dan terakhir it3?

Katakanlah

def it1 = [1, 2].iterator()
def it2 = [3, 4].iterator()
def it3 = [5, 6].iterator()

Saya ingin memiliki iterator yang akan kembali

1
2
3
4
5
6

person Theodor    schedule 30.10.2013    source sumber
comment
IIRC tidak ada yang bawaan, Jambu dan Koleksi Commons keduanya memiliki kelas utilitas untuk melakukan hal ini, atau Anda dapat menulis sendiri dalam 10 baris kode.   -  person Dave Newton    schedule 30.10.2013


Jawaban (1)


Tidak ada iterator yang saya ketahui di Groovy, tetapi Anda dapat menulisnya sendiri:

class SequentialIterator<T> implements Iterator<T> {
    List iterators
    int index = 0
    boolean done = false
    T next

    SequentialIterator( Iterator<T> ...iterators ) {
        this.iterators = iterators
        loadNext()
    }

    private void loadNext() {
        while( index < iterators.size() ) {
            if( iterators[ index ].hasNext() ) {
                next = iterators[ index ].next()
                break
            }
            else {
                index++
            }
        }
        if( index >= iterators.size() ) {
            done = true
        }
    }

    void remove() {
        throw UnsupportedOperationException()
    }

    boolean hasNext() {
        !done
    }

    T next() {
        if( done ) {
            throw new NoSuchElementException()
        }
        T ret = next
        loadNext()
        ret
    }
}

def it1 = [1, 2].iterator()
def it2 = [3, 4].iterator()
def it3 = [5, 6].iterator()

assert new SequentialIterator( it1, it2, it3 ).collect() == [ 1, 2, 3, 4, 5, 6 ]

Atau, jika Anda merasa serakah (dan membutuhkan semua data yang dimuat pada saat yang sama), Anda dapat mengumpulkan nilai dari iterator secara bergantian:

[ it1, it2, it3 ].collectMany { it.collect() }

Atau seperti kata Dave Newton, Anda dapat menggunakan Guava:

@Grab( 'com.google.guava:guava:15.0' )
import com.google.common.collect.Iterators

def it1 = [1, 2].iterator()
def it2 = [3, 4].iterator()
def it3 = [5, 6].iterator()

assert Iterators.concat( it1, it2, it3 ).collect() == [ 1, 2, 3, 4, 5, 6 ]

Atau koleksi milik bersama;

@Grab( 'commons-collections:commons-collections:3.2.1' )
import org.apache.commons.collections.iterators.IteratorChain

def it1 = [1, 2].iterator()
def it2 = [3, 4].iterator()
def it3 = [5, 6].iterator()

assert new IteratorChain( [ it1, it2, it3 ] ).collect() == [ 1, 2, 3, 4, 5, 6 ]
person tim_yates    schedule 30.10.2013