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 */
|
/** 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> {
|
inline fun <T> java.util.Iterator<T>.filter(predicate: (T)-> Boolean) : java.util.Iterator<T> {
|
||||||
return FilterIterator2(this, predicate)
|
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? {
|
override protected fun computeNext(): T? {
|
||||||
/*
|
|
||||||
|
|
||||||
TODO this block generates a compiler error:
|
|
||||||
http://youtrack.jetbrains.com/issue/KT-1646
|
|
||||||
|
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
val element = iter.next()
|
val element = iter.next()
|
||||||
if (fn(element)) {
|
if ((predicate)(element)) {
|
||||||
return element
|
return element
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
done()
|
done()
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user