thanks to the heads up from Franck, I can work around KT-1646 - refactored previous Filter code to reuse the AbstractIterator base class and implemented filter/filterNot/filterIsInstance lazily
This commit is contained in:
@@ -1,49 +0,0 @@
|
||||
package kotlin
|
||||
|
||||
import java.util.*
|
||||
import java.lang.Iterable
|
||||
|
||||
/** Filters given iterator */
|
||||
inline fun <T> java.util.Iterator<T>.filter(f: (T)-> Boolean) : java.util.Iterator<T> = FilterIterator<T>(this, f)
|
||||
|
||||
/** Create iterator filtering given java.lang.Iterable */
|
||||
/*
|
||||
inline fun <T> java.lang.Iterable<T>.filter(f: (T)->Boolean) : java.util.Iterator<T> = (iterator() as java.util.Iterator<T>).filter(f)
|
||||
*/
|
||||
|
||||
private class FilterIterator<T>(val original: java.util.Iterator<T>, val filter: (T)-> Boolean) : java.util.Iterator<T> {
|
||||
var state = 0
|
||||
var nextElement: T? = null
|
||||
|
||||
override fun hasNext(): Boolean =
|
||||
when(state) {
|
||||
1 -> true // checked and next present
|
||||
2 -> false // checked and next not present
|
||||
else -> {
|
||||
while(original.hasNext()) {
|
||||
val candidate = original.next()
|
||||
if((filter)(candidate)) {
|
||||
nextElement = candidate
|
||||
state = 1
|
||||
true
|
||||
}
|
||||
}
|
||||
state = 2
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
override fun next(): T =
|
||||
if(state != 1)
|
||||
throw java.util.NoSuchElementException()
|
||||
else {
|
||||
val res = nextElement as T
|
||||
nextElement = null
|
||||
state = 0
|
||||
res
|
||||
}
|
||||
|
||||
override fun remove() {
|
||||
throw java.lang.UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
@@ -21,33 +21,19 @@ private class FilterIsIterator<T, R :T>(val iter: java.util.Iterator<T>, val kla
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO when we're past the compiler error
|
||||
// http://youtrack.jetbrains.com/issue/KT-1646
|
||||
//
|
||||
// we can use this code to replace the other
|
||||
// filter / FilterIterator class as it reuses the
|
||||
// core logic from AbstractIterator
|
||||
|
||||
/** Returns a new lazy iterator containing all elements in this iteration which match the given predicate */
|
||||
inline fun <T> java.util.Iterator<T>.filter2(predicate: (T)-> Boolean) : java.util.Iterator<T> {
|
||||
return FilterIterator2(this, predicate)
|
||||
inline fun <T> java.util.Iterator<T>.filter(predicate: (T)-> Boolean) : java.util.Iterator<T> {
|
||||
return FilterIterator(this, predicate)
|
||||
}
|
||||
|
||||
private class FilterIterator2<T>(val iter: java.util.Iterator<T>, val fn: (T)-> Boolean) : AbstractIterator<T>() {
|
||||
private class FilterIterator<T>(val iter: java.util.Iterator<T>, val predicate: (T)-> Boolean) : AbstractIterator<T>() {
|
||||
override protected fun computeNext(): T? {
|
||||
/*
|
||||
|
||||
TODO this block generates a compiler error:
|
||||
http://youtrack.jetbrains.com/issue/KT-1646
|
||||
|
||||
while (iter.hasNext()) {
|
||||
val element = iter.next()
|
||||
if (fn(element)) {
|
||||
if ((predicate)(element)) {
|
||||
return element
|
||||
}
|
||||
}
|
||||
*/
|
||||
done()
|
||||
return null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user