#KT-39 Fixed with eager and lazy implementations

This commit is contained in:
James Strachan
2012-04-03 15:36:34 +01:00
parent 013ebf46db
commit f022b61794
6 changed files with 146 additions and 51 deletions
+28 -2
View File
@@ -1,7 +1,7 @@
package kotlin
import kotlin.support.AbstractIterator
import kotlin.support.FunctionIterator
import kotlin.support.*
import java.util.Collections
/**
* Returns an iterator which invokes the function to calculate the next value on each iteration until the function returns *null*
@@ -110,6 +110,32 @@ private class FlatMapIterator<T, R>(val iterator : java.util.Iterator<T>, val tr
}
}
/**
* Creates an [[Iterator]] which iterates over this iterator then the given element at the end
*
* @includeFunctionBody ../../test/iterators/IteratorsTest.kt plus
*/
public inline fun <in T> java.util.Iterator<T>.plus(element: T): java.util.Iterator<T> {
return CompositeIterator<T>(this, SingleIterator(element))
}
/**
* Creates an [[Iterator]] which iterates over this iterator then the following iterator
*
* @includeFunctionBody ../../test/iterators/IteratorsTest.kt plusCollection
*/
public inline fun <in T> java.util.Iterator<T>.plus(iterator: java.util.Iterator<T>): java.util.Iterator<T> {
return CompositeIterator<T>(this, iterator)
}
/**
* Creates an [[Iterator]] which iterates over this iterator then the following collection
*
* @includeFunctionBody ../../test/iterators/IteratorsTest.kt plusCollection
*/
public inline fun <in T> java.util.Iterator<T>.plus(collection: java.lang.Iterable<T>): java.util.Iterator<T> = plus(collection.iterator())
/**
* Returns an iterator containing all the non-*null* elements, lazily throwing an [[IllegalArgumentException]]
if there are any null elements
@@ -39,6 +39,29 @@ public inline fun <T> java.lang.Iterable<T?>?.filterNotNull() : List<T> = filter
*/
public inline fun <T, R> java.lang.Iterable<T>.flatMap(transform: (T)-> Collection<R>) : Collection<R> = flatMapTo(ArrayList<R>(), transform)
/**
* Creates a copy of this collection as a [[List]] with the element added at the end
*
* @includeFunctionBody ../../test/CollectionTest.kt plus
*/
public inline fun <in T> java.lang.Iterable<T>.plus(element: T): List<in T> {
val list = to(ArrayList<T>())
list.add(element)
return list
}
/**
* Creates a copy of this collection as a [[List]] with all the elements added at the end
*
* @includeFunctionBody ../../test/CollectionTest.kt plusCollection
*/
public inline fun <in T> java.lang.Iterable<T>.plus(elements: java.lang.Iterable<T>): List<T> {
val list = to(ArrayList<T>())
list.addAll(elements.toCollection())
return list
}
/**
* Returns a list containing all the non-*null* elements, throwing an [[IllegalArgumentException]] if there are any null elements
*
-39
View File
@@ -53,45 +53,6 @@ public inline fun <in T: java.lang.Comparable<T>> java.lang.Iterable<T>.toSorted
public inline fun <in T: java.lang.Comparable<T>> java.lang.Iterable<T>.toSortedList(comparator: java.util.Comparator<T>) : List<T> = toList().sort(comparator)
/**
* Creates a new [[List]] with the element added at the end
*
* @includeFunctionBody ../../test/CollectionTest.kt plus
*/
public inline fun <in T> java.util.Collection<T>.plus(element: T): List<in T> {
val list = to(ArrayList<T>())
list.add(element)
return list
}
/**
* Adds the element to this collection
*
* @includeFunctionBody ../../test/CollectionTest.kt plusAssign
*/
public inline fun <in T, C: java.util.Collection<in T>> C.plusAssign(element: T): C {
add(element)
return this
}
/**
* Creates a new [[List]] with the element added at the end
*/
/*
public inline fun <in T> java.util.Collection<T>.plus(elements: java.lang.Iterable<T>): List<T> = toList().plusAssign(elements)
*/
/**
* Adds all the elements to this collection
*/
/*
public inline fun <in T, C: Collection<in T>> C.plusAssign(elements: java.lang.Iterable<T>): C {
addAll(elements.toCollection())
return this
}
*/
// List APIs
public inline fun <in T: java.lang.Comparable<T>> List<T>.sort() : List<T> {
@@ -32,7 +32,9 @@ public abstract class AbstractIterator<T>: java.util.Iterator<T> {
return next.sure()
}
override fun remove() { throw UnsupportedOperationException() }
override fun remove() {
throw UnsupportedOperationException()
}
/** Returns the next element in the iteration without advancing the iteration */
fun peek(): T {
@@ -75,7 +77,7 @@ public abstract class AbstractIterator<T>: java.util.Iterator<T> {
}
/** An [[Iterator]] which invokes a function to calculate the next value in the iteration until the function returns *null* */
class FunctionIterator<T>(val nextFunction : () -> T?) : AbstractIterator<T>() {
class FunctionIterator<T>(val nextFunction: () -> T?): AbstractIterator<T>() {
override protected fun computeNext(): Unit {
val next = (nextFunction)()
@@ -86,3 +88,47 @@ class FunctionIterator<T>(val nextFunction : () -> T?) : AbstractIterator<T>() {
}
}
}
/** An [[Iterator]] which iterates over a number of iterators in sequence */
class CompositeIterator<T>(vararg iterators: java.util.Iterator<T>): AbstractIterator<T>() {
val iteratorsIter = iterators.iterator()
var currentIter: java.util.Iterator<T>? = null
override protected fun computeNext(): Unit {
while (true) {
if (currentIter == null) {
if (iteratorsIter.hasNext) {
currentIter = iteratorsIter.next()
} else {
done()
return
}
}
val iter = currentIter
if (iter != null) {
if (iter.hasNext()) {
setNext(iter.next())
return
} else {
currentIter = null
}
}
}
}
}
/** A singleton [[Iterator]] which invokes once over a value */
class SingleIterator<T>(val value: T): AbstractIterator<T>() {
var first = true
override protected fun computeNext(): Unit {
if (first) {
first = false
setNext(value)
} else {
done()
}
}
}
+21 -8
View File
@@ -258,17 +258,30 @@ class CollectionTest {
val list2 = list + "cheese"
assertEquals(arrayList("foo", "bar"), list)
assertEquals(arrayList("foo", "bar", "cheese"), list2)
// lets use a mutable variable
var list3 = arrayList("a", "b")
list3 += "c"
assertEquals(arrayList("a", "b", "c"), list3)
}
test fun plusAssign() {
var list = arrayList("foo", "bar")
/*
TODO should we have plus and plus assign work differently for collections?
see KT-1710
/*
TODO compiler fails on this one
list += "cheese"
assertEquals(arrayList("foo", "bar", "cheese"), list)
*/
val list = arrayList("foo", "bar") + arrayList("cheese", "wine")
*/
test fun plusCollection() {
val a = arrayList("foo", "bar")
val b = arrayList("cheese", "wine")
val list = a + b
assertEquals(arrayList("foo", "bar", "cheese", "wine"), list)
// lets use a mutable variable
var ml = a
ml += "beer"
ml += b
ml += "z"
assertEquals(arrayList("foo", "bar", "beer", "cheese", "wine", "z"), ml)
}
test fun requireNoNulls() {
@@ -52,6 +52,32 @@ class IteratorsTest {
assertEquals("13, 21, 34, 55, 89, ...", fibonacci().filter { it > 10 }.makeString(separator = ", ", limit = 5))
}
test fun plus() {
val iter = arrayList("foo", "bar").iterator()
val iter2 = iter + "cheese"
assertEquals(arrayList("foo", "bar", "cheese"), iter2.toList())
// lets use a mutable variable
var mi = arrayList("a", "b").iterator()
mi += "c"
assertEquals(arrayList("a", "b", "c"), mi.toList())
}
test fun plusCollection() {
val a = arrayList("foo", "bar")
val b = arrayList("cheese", "wine")
val iter = a.iterator() + b.iterator()
assertEquals(arrayList("foo", "bar", "cheese", "wine"), iter.toList())
// lets use a mutable variable
var ml = arrayList("a").iterator()
ml += a.iterator()
ml += "beer"
ml += b
ml += "z"
assertEquals(arrayList("a", "foo", "bar", "beer", "cheese", "wine", "z"), ml.toList())
}
test fun requireNoNulls() {
val iter = arrayList<String?>("foo", "bar").iterator()
val notNull = iter.requireNoNulls()