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
|
||||
|
||||
import kotlin.support.AbstractIterator
|
||||
|
||||
import java.util.*
|
||||
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 */
|
||||
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