added a helper method to filter a subset of an iterator by sub type
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
package kotlin.util
|
package kotlin.util
|
||||||
|
|
||||||
|
import kotlin.support.AbstractIterator
|
||||||
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.Iterator
|
import java.util.Iterator
|
||||||
|
|
||||||
@@ -24,3 +26,21 @@ inline fun <T> java.util.Iterator<T>.toLinkedHashSet() = to(LinkedHashSet<T>())
|
|||||||
|
|
||||||
/** Add iterated elements to java.util.TreeSet */
|
/** Add iterated elements to java.util.TreeSet */
|
||||||
inline fun <T> java.util.Iterator<T>.toTreeSet() = to(TreeSet<T>())
|
inline fun <T> java.util.Iterator<T>.toTreeSet() = to(TreeSet<T>())
|
||||||
|
|
||||||
|
/** Filters the iterator for all elements of a certain kind */
|
||||||
|
inline fun <T, R: T> java.util.Iterator<T>.filterIs(): Iterator<R> {
|
||||||
|
val iter = this
|
||||||
|
return object : AbstractIterator<R>() {
|
||||||
|
|
||||||
|
override fun computeNext(): R? {
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
val next = iter.next()
|
||||||
|
if (next is R) {
|
||||||
|
return next as R
|
||||||
|
}
|
||||||
|
}
|
||||||
|
done()
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package kotlin.support
|
||||||
|
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
// TODO should we use enums?
|
||||||
|
private val Ready = 0
|
||||||
|
private val NotReady = 1
|
||||||
|
private val Done = 2
|
||||||
|
private val Failed = 3
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A base class to simplify implementing iterators so that implementations only have to implement [[#computeNext()]]
|
||||||
|
* to implement the iterator, calling [[done()]] when the iteration is complete.
|
||||||
|
*/
|
||||||
|
abstract class AbstractIterator<T>: Iterator<T> {
|
||||||
|
var state = NotReady
|
||||||
|
var next: T? = null
|
||||||
|
|
||||||
|
override fun hasNext(): Boolean {
|
||||||
|
require(state != Failed)
|
||||||
|
return when (state) {
|
||||||
|
Done -> false
|
||||||
|
Ready -> true
|
||||||
|
else -> tryToComputeNext()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun next(): T {
|
||||||
|
if (!hasNext()) {
|
||||||
|
throw NoSuchElementException();
|
||||||
|
} else {
|
||||||
|
state = NotReady
|
||||||
|
return next.sure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove() {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the next element in the iteration without advancing the iteration
|
||||||
|
*/
|
||||||
|
fun peek(): T {
|
||||||
|
if (!hasNext()) {
|
||||||
|
throw NoSuchElementException();
|
||||||
|
}
|
||||||
|
return next.sure();
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun tryToComputeNext(): Boolean {
|
||||||
|
state = Failed
|
||||||
|
next = computeNext();
|
||||||
|
return if (state != Done) {
|
||||||
|
state = Ready
|
||||||
|
true
|
||||||
|
} else false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the next element in the iterator, calling endOfData() when
|
||||||
|
* there are no more elements
|
||||||
|
*/
|
||||||
|
abstract protected fun computeNext(): T?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the state to done so that the iteration terminates
|
||||||
|
*/
|
||||||
|
protected fun done() {
|
||||||
|
state = Done
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user