initial psike of #KT-39 on collections (iterators required too), though hit #KT-1710
This commit is contained in:
@@ -177,22 +177,25 @@ public inline fun <T> java.lang.Iterable<T>.reverse() : List<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Copies all elements into the given collection */
|
/** Copies all elements into the given collection */
|
||||||
public inline fun <T, C: Collection<T>> java.lang.Iterable<T>.to(result: C) : C {
|
public inline fun <in T, C: Collection<in T>> java.lang.Iterable<T>.to(result: C) : C {
|
||||||
for (element in this) result.add(element)
|
for (element in this) result.add(element)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Copies all elements into a [[LinkedList]] */
|
/** Copies all elements into a [[LinkedList]] if its not already a [[LinkedList]] */
|
||||||
public inline fun <T> java.lang.Iterable<T>.toLinkedList() : LinkedList<T> = to(LinkedList<T>())
|
public inline fun <in T> java.lang.Iterable<T>.toLinkedList() : LinkedList<T> = if (this is LinkedList<T>) this else to(LinkedList<T>())
|
||||||
|
|
||||||
/** Copies all elements into a [[List]] */
|
/** Copies all elements into a [[List]] if its not already a [[List]] */
|
||||||
public inline fun <T> java.lang.Iterable<T>.toList() : List<T> = to(ArrayList<T>())
|
public inline fun <in T> java.lang.Iterable<T>.toList() : List<T> = if (this is List<T>) this else to(ArrayList<T>())
|
||||||
|
|
||||||
/** Copies all elements into a [[Set]] */
|
/** Copies all elements into a [[List]] if it is not already a [[Collection]] */
|
||||||
public inline fun <T> java.lang.Iterable<T>.toSet() : Set<T> = to(HashSet<T>())
|
public inline fun <in T> java.lang.Iterable<T>.toCollection() : Collection<T> = if (this is Collection<T>) this else to(ArrayList<T>())
|
||||||
|
|
||||||
/** Copies all elements into a [[SortedSet]] */
|
/** Copies all elements into a [[Set]] if its not already a [[Set]] */
|
||||||
public inline fun <T> java.lang.Iterable<T>.toSortedSet() : SortedSet<T> = to(TreeSet<T>())
|
public inline fun <in T> java.lang.Iterable<T>.toSet() : Set<T> = if (this is Set<T>) this else to(HashSet<T>())
|
||||||
|
|
||||||
|
/** Copies all elements into a [[SortedSet]] if its not already a [[SortedSet]] */
|
||||||
|
public inline fun <in T> java.lang.Iterable<T>.toSortedSet() : SortedSet<T> = if (this is SortedSet<T>) this else to(TreeSet<T>())
|
||||||
|
|
||||||
/**
|
/**
|
||||||
TODO figure out necessary variance/generics ninja stuff... :)
|
TODO figure out necessary variance/generics ninja stuff... :)
|
||||||
|
|||||||
@@ -39,12 +39,58 @@ public inline fun <T> java.util.Collection<T>.toArray() : Array<T> {
|
|||||||
return answer as Array<T>
|
return answer as Array<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
/** TODO these functions don't work when they generate the Array<T> versions when they are in JavaIterables */
|
/** Returns true if the collection is not empty */
|
||||||
|
public inline fun <T> java.util.Collection<T>.notEmpty() : Boolean = !this.isEmpty()
|
||||||
|
|
||||||
|
/** Returns the Collection if its not null otherwise it returns the empty list */
|
||||||
|
public inline fun <T> java.util.Collection<T>?.orEmpty() : Collection<T>
|
||||||
|
= if (this != null) this else Collections.EMPTY_LIST as Collection<T>
|
||||||
|
|
||||||
|
|
||||||
|
/** TODO these functions don't work when they generate the Array<T> versions when they are in JLIterables */
|
||||||
public inline fun <in T: java.lang.Comparable<T>> java.lang.Iterable<T>.toSortedList() : List<T> = toList().sort()
|
public inline fun <in T: java.lang.Comparable<T>> java.lang.Iterable<T>.toSortedList() : List<T> = toList().sort()
|
||||||
|
|
||||||
public inline fun <in T: java.lang.Comparable<T>> java.lang.Iterable<T>.toSortedList(comparator: java.util.Comparator<T>) : List<T> = toList().sort(comparator)
|
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
|
// List APIs
|
||||||
|
|
||||||
@@ -98,12 +144,3 @@ val <T> List<T>.tail : T?
|
|||||||
|
|
||||||
val <T> List<T>.last : T?
|
val <T> List<T>.last : T?
|
||||||
get() = this.tail
|
get() = this.tail
|
||||||
|
|
||||||
|
|
||||||
/** Returns true if the collection is not empty */
|
|
||||||
public inline fun <T> java.util.Collection<T>.notEmpty() : Boolean = !this.isEmpty()
|
|
||||||
|
|
||||||
/** Returns the Collection if its not null otherwise it returns the empty list */
|
|
||||||
public inline fun <T> java.util.Collection<T>?.orEmpty() : Collection<T>
|
|
||||||
= if (this != null) this else Collections.EMPTY_LIST as Collection<T>
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import kotlin.test.*
|
|||||||
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
import org.junit.Test
|
import org.junit.Test as test
|
||||||
|
|
||||||
class CollectionTest {
|
class CollectionTest {
|
||||||
|
|
||||||
Test fun all() {
|
test fun all() {
|
||||||
val data = arrayList("foo", "bar")
|
val data = arrayList("foo", "bar")
|
||||||
assertTrue {
|
assertTrue {
|
||||||
data.all{it.length == 3}
|
data.all{it.length == 3}
|
||||||
@@ -18,7 +18,7 @@ class CollectionTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Test fun any() {
|
test fun any() {
|
||||||
val data = arrayList("foo", "bar")
|
val data = arrayList("foo", "bar")
|
||||||
assertTrue {
|
assertTrue {
|
||||||
data.any{it.startsWith("f")}
|
data.any{it.startsWith("f")}
|
||||||
@@ -29,20 +29,20 @@ class CollectionTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Test fun appendString() {
|
test fun appendString() {
|
||||||
val data = arrayList("foo", "bar")
|
val data = arrayList("foo", "bar")
|
||||||
val buffer = StringBuilder()
|
val buffer = StringBuilder()
|
||||||
val text = data.appendString(buffer, "-", "{", "}")
|
val text = data.appendString(buffer, "-", "{", "}")
|
||||||
assertEquals("{foo-bar}", buffer.toString())
|
assertEquals("{foo-bar}", buffer.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
Test fun count() {
|
test fun count() {
|
||||||
val data = arrayList("foo", "bar")
|
val data = arrayList("foo", "bar")
|
||||||
assertEquals(1, data.count{it.startsWith("b")})
|
assertEquals(1, data.count{it.startsWith("b")})
|
||||||
assertEquals(2, data.count{it.size == 3})
|
assertEquals(2, data.count{it.size == 3})
|
||||||
}
|
}
|
||||||
|
|
||||||
Test fun filter() {
|
test fun filter() {
|
||||||
val data = arrayList("foo", "bar")
|
val data = arrayList("foo", "bar")
|
||||||
val foo = data.filter{it.startsWith("f")}
|
val foo = data.filter{it.startsWith("f")}
|
||||||
assertTrue {
|
assertTrue {
|
||||||
@@ -52,7 +52,7 @@ class CollectionTest {
|
|||||||
assertEquals(arrayList("foo"), foo)
|
assertEquals(arrayList("foo"), foo)
|
||||||
}
|
}
|
||||||
|
|
||||||
Test fun filterNot() {
|
test fun filterNot() {
|
||||||
val data = arrayList("foo", "bar")
|
val data = arrayList("foo", "bar")
|
||||||
val foo = data.filterNot{it.startsWith("b")}
|
val foo = data.filterNot{it.startsWith("b")}
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ class CollectionTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO would be nice to avoid the <String>
|
// TODO would be nice to avoid the <String>
|
||||||
Test fun filterIntoLinkedList() {
|
test fun filterIntoLinkedList() {
|
||||||
val data = arrayList("foo", "bar")
|
val data = arrayList("foo", "bar")
|
||||||
val foo = data.filterTo(linkedList<String>()){it.startsWith("f")}
|
val foo = data.filterTo(linkedList<String>()){it.startsWith("f")}
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ class CollectionTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO would be nice to avoid the <String>
|
// TODO would be nice to avoid the <String>
|
||||||
Test fun filterNotIntoLinkedList() {
|
test fun filterNotIntoLinkedList() {
|
||||||
val data = arrayList("foo", "bar")
|
val data = arrayList("foo", "bar")
|
||||||
val foo = data.filterNotTo(linkedList<String>()){it.startsWith("f")}
|
val foo = data.filterNotTo(linkedList<String>()){it.startsWith("f")}
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ class CollectionTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO would be nice to avoid the <String>
|
// TODO would be nice to avoid the <String>
|
||||||
Test fun filterNotNullIntoLinkedList() {
|
test fun filterNotNullIntoLinkedList() {
|
||||||
val data = arrayList(null, "foo", null, "bar")
|
val data = arrayList(null, "foo", null, "bar")
|
||||||
val foo = data.filterNotNullTo(linkedList<String>())
|
val foo = data.filterNotNullTo(linkedList<String>())
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ class CollectionTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Test fun filterNotNull() {
|
test fun filterNotNull() {
|
||||||
val data = arrayList(null, "foo", null, "bar")
|
val data = arrayList(null, "foo", null, "bar")
|
||||||
val foo = data.filterNotNull()
|
val foo = data.filterNotNull()
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ class CollectionTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Test fun filterIntoSet() {
|
test fun filterIntoSet() {
|
||||||
val data = arrayList("foo", "bar")
|
val data = arrayList("foo", "bar")
|
||||||
// TODO would be nice to avoid the <String>
|
// TODO would be nice to avoid the <String>
|
||||||
val foo = data.filterTo(hashSet<String>()){it.startsWith("f")}
|
val foo = data.filterTo(hashSet<String>()){it.startsWith("f")}
|
||||||
@@ -136,7 +136,7 @@ class CollectionTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Test fun filterIntoSortedSet() {
|
test fun filterIntoSortedSet() {
|
||||||
val data = arrayList("foo", "bar")
|
val data = arrayList("foo", "bar")
|
||||||
// TODO would be nice to avoid the <String>
|
// TODO would be nice to avoid the <String>
|
||||||
val sorted = data.filterTo(sortedSet<String>()){it.length == 3}
|
val sorted = data.filterTo(sortedSet<String>()){it.length == 3}
|
||||||
@@ -147,7 +147,7 @@ class CollectionTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Test fun find() {
|
test fun find() {
|
||||||
val data = arrayList("foo", "bar")
|
val data = arrayList("foo", "bar")
|
||||||
val x = data.find{it.startsWith("x")}
|
val x = data.find{it.startsWith("x")}
|
||||||
assertNull(x)
|
assertNull(x)
|
||||||
@@ -160,7 +160,7 @@ class CollectionTest {
|
|||||||
assertEquals("foo", f)
|
assertEquals("foo", f)
|
||||||
}
|
}
|
||||||
|
|
||||||
Test fun flatMap() {
|
test fun flatMap() {
|
||||||
val data = arrayList("", "foo", "bar", "x", "")
|
val data = arrayList("", "foo", "bar", "x", "")
|
||||||
val characters = data.flatMap<String,Character>{ it.toCharList() }
|
val characters = data.flatMap<String,Character>{ it.toCharList() }
|
||||||
println("Got list of characters ${characters}")
|
println("Got list of characters ${characters}")
|
||||||
@@ -169,7 +169,7 @@ class CollectionTest {
|
|||||||
assertEquals("foobarx", text)
|
assertEquals("foobarx", text)
|
||||||
}
|
}
|
||||||
|
|
||||||
Test fun forEach() {
|
test fun forEach() {
|
||||||
val data = arrayList("foo", "bar")
|
val data = arrayList("foo", "bar")
|
||||||
var count = 0
|
var count = 0
|
||||||
data.forEach{ count += it.length }
|
data.forEach{ count += it.length }
|
||||||
@@ -186,7 +186,7 @@ class CollectionTest {
|
|||||||
// numbers.map{it.toString()}.fold(""){it + it2}
|
// numbers.map{it.toString()}.fold(""){it + it2}
|
||||||
numbers.map<Int, String>{it.toString()}.fold(""){(it, it2) -> it + it2}
|
numbers.map<Int, String>{it.toString()}.fold(""){(it, it2) -> it + it2}
|
||||||
*/
|
*/
|
||||||
Test fun fold() {
|
test fun fold() {
|
||||||
// lets calculate the sum of some numbers
|
// lets calculate the sum of some numbers
|
||||||
expect(10) {
|
expect(10) {
|
||||||
val numbers = arrayList(1, 2, 3, 4)
|
val numbers = arrayList(1, 2, 3, 4)
|
||||||
@@ -210,7 +210,7 @@ class CollectionTest {
|
|||||||
// numbers.map{it.toString()}.foldRight(""){it + it2}
|
// numbers.map{it.toString()}.foldRight(""){it + it2}
|
||||||
numbers.map<Int, String>{it.toString()}.foldRight(""){(it, it2) -> it + it2}
|
numbers.map<Int, String>{it.toString()}.foldRight(""){(it, it2) -> it + it2}
|
||||||
*/
|
*/
|
||||||
Test fun foldRight() {
|
test fun foldRight() {
|
||||||
expect("4321") {
|
expect("4321") {
|
||||||
val numbers = arrayList(1, 2, 3, 4)
|
val numbers = arrayList(1, 2, 3, 4)
|
||||||
numbers.map<Int, String>{it.toString()}.foldRight(""){(it, it2) -> it + it2}
|
numbers.map<Int, String>{it.toString()}.foldRight(""){(it, it2) -> it + it2}
|
||||||
@@ -221,7 +221,7 @@ class CollectionTest {
|
|||||||
TODO inference engine should not need this type info?
|
TODO inference engine should not need this type info?
|
||||||
val byLength = words.groupBy<String, Int>{it.length}
|
val byLength = words.groupBy<String, Int>{it.length}
|
||||||
*/
|
*/
|
||||||
Test fun groupBy() {
|
test fun groupBy() {
|
||||||
val words = arrayList("a", "ab", "abc", "def", "abcd")
|
val words = arrayList("a", "ab", "abc", "def", "abcd")
|
||||||
val byLength = words.groupBy<String, Int>{it.length}
|
val byLength = words.groupBy<String, Int>{it.length}
|
||||||
assertEquals(4, byLength.size())
|
assertEquals(4, byLength.size())
|
||||||
@@ -232,7 +232,7 @@ class CollectionTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Test fun makeString() {
|
test fun makeString() {
|
||||||
val data = arrayList("foo", "bar")
|
val data = arrayList("foo", "bar")
|
||||||
val text = data.makeString("-", "<", ">")
|
val text = data.makeString("-", "<", ">")
|
||||||
assertEquals("<foo-bar>", text)
|
assertEquals("<foo-bar>", text)
|
||||||
@@ -243,7 +243,7 @@ class CollectionTest {
|
|||||||
we should be able to remove the explicit type <String,Int> on the map function
|
we should be able to remove the explicit type <String,Int> on the map function
|
||||||
http://youtrack.jetbrains.net/issue/KT-1145
|
http://youtrack.jetbrains.net/issue/KT-1145
|
||||||
*/
|
*/
|
||||||
Test fun map() {
|
test fun map() {
|
||||||
val data = arrayList("foo", "bar")
|
val data = arrayList("foo", "bar")
|
||||||
val lengths = data.map<String, Int>{ it.length }
|
val lengths = data.map<String, Int>{ it.length }
|
||||||
assertTrue {
|
assertTrue {
|
||||||
@@ -253,13 +253,31 @@ class CollectionTest {
|
|||||||
assertEquals(arrayList(3, 3), lengths)
|
assertEquals(arrayList(3, 3), lengths)
|
||||||
}
|
}
|
||||||
|
|
||||||
Test fun reverse() {
|
test fun plus() {
|
||||||
|
val list = arrayList("foo", "bar")
|
||||||
|
val list2 = list + "cheese"
|
||||||
|
assertEquals(arrayList("foo", "bar"), list)
|
||||||
|
assertEquals(arrayList("foo", "bar", "cheese"), list2)
|
||||||
|
}
|
||||||
|
|
||||||
|
test fun plusAssign() {
|
||||||
|
var list = arrayList("foo", "bar")
|
||||||
|
/*
|
||||||
|
TODO should we have plus and plus assign work differently for collections?
|
||||||
|
see KT-1710
|
||||||
|
|
||||||
|
list += "cheese"
|
||||||
|
assertEquals(arrayList("foo", "bar", "cheese"), list)
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
test fun reverse() {
|
||||||
val data = arrayList("foo", "bar")
|
val data = arrayList("foo", "bar")
|
||||||
val rev = data.reverse()
|
val rev = data.reverse()
|
||||||
assertEquals(arrayList("bar", "foo"), rev)
|
assertEquals(arrayList("bar", "foo"), rev)
|
||||||
}
|
}
|
||||||
|
|
||||||
Test fun sort() {
|
test fun sort() {
|
||||||
val coll: List<String> = arrayList("foo", "bar", "abc")
|
val coll: List<String> = arrayList("foo", "bar", "abc")
|
||||||
|
|
||||||
// TODO fixme
|
// TODO fixme
|
||||||
@@ -272,7 +290,7 @@ class CollectionTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Test fun toArray() {
|
test fun toArray() {
|
||||||
val data = arrayList("foo", "bar")
|
val data = arrayList("foo", "bar")
|
||||||
val arr = data.toArray()
|
val arr = data.toArray()
|
||||||
println("Got array ${arr}")
|
println("Got array ${arr}")
|
||||||
@@ -283,14 +301,14 @@ class CollectionTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Test fun simpleCount() {
|
test fun simpleCount() {
|
||||||
val data = arrayList("foo", "bar")
|
val data = arrayList("foo", "bar")
|
||||||
assertEquals(2, data.count())
|
assertEquals(2, data.count())
|
||||||
assertEquals(3, hashSet(12, 14, 15).count())
|
assertEquals(3, hashSet(12, 14, 15).count())
|
||||||
assertEquals(0, ArrayList<Double>().count())
|
assertEquals(0, ArrayList<Double>().count())
|
||||||
}
|
}
|
||||||
|
|
||||||
Test fun last() {
|
test fun last() {
|
||||||
val data = arrayList("foo", "bar")
|
val data = arrayList("foo", "bar")
|
||||||
assertEquals("bar", data.last())
|
assertEquals("bar", data.last())
|
||||||
assertEquals(25, arrayList(15, 19, 20, 25).last())
|
assertEquals(25, arrayList(15, 19, 20, 25).last())
|
||||||
@@ -300,13 +318,13 @@ class CollectionTest {
|
|||||||
// assertEquals(19, TreeSet(arrayList(90, 47, 19)).first())
|
// assertEquals(19, TreeSet(arrayList(90, 47, 19)).first())
|
||||||
|
|
||||||
|
|
||||||
Test fun lastException() {
|
test fun lastException() {
|
||||||
fails { arrayList<Int>().last() }
|
fails { arrayList<Int>().last() }
|
||||||
fails { linkedList<String>().last() }
|
fails { linkedList<String>().last() }
|
||||||
fails { hashSet<Char>().last() }
|
fails { hashSet<Char>().last() }
|
||||||
}
|
}
|
||||||
|
|
||||||
Test fun subscript() {
|
test fun subscript() {
|
||||||
val list = arrayList("foo", "bar")
|
val list = arrayList("foo", "bar")
|
||||||
assertEquals("foo", list[0])
|
assertEquals("foo", list[0])
|
||||||
assertEquals("bar", list[1])
|
assertEquals("bar", list[1])
|
||||||
@@ -329,7 +347,7 @@ class CollectionTest {
|
|||||||
assertEquals(arrayList("new", "thing", "works"), list)
|
assertEquals(arrayList("new", "thing", "works"), list)
|
||||||
}
|
}
|
||||||
|
|
||||||
Test fun indices() {
|
test fun indices() {
|
||||||
val data = arrayList("foo", "bar")
|
val data = arrayList("foo", "bar")
|
||||||
val indices = data.indices
|
val indices = data.indices
|
||||||
assertEquals(0, indices.start)
|
assertEquals(0, indices.start)
|
||||||
@@ -338,7 +356,7 @@ class CollectionTest {
|
|||||||
assertFalse(indices.isReversed)
|
assertFalse(indices.isReversed)
|
||||||
}
|
}
|
||||||
|
|
||||||
Test fun contains() {
|
test fun contains() {
|
||||||
val data = arrayList("foo", "bar")
|
val data = arrayList("foo", "bar")
|
||||||
assertTrue(data.contains("foo"))
|
assertTrue(data.contains("foo"))
|
||||||
assertTrue(data.contains("bar"))
|
assertTrue(data.contains("bar"))
|
||||||
|
|||||||
Reference in New Issue
Block a user