Read on for an introduction to the most important functions for predicates: all, any, none, isEmpty, isNotEmpty, ifEmpty, contains, containsAll, and their variants.
Predicate functions
all, any, none
//sampleStart inline fun <T> Iterable<T>.all(predicate: (T) -> Boolean): Boolean inline fun <T> Iterable<T>.any(predicate: (T) -> Boolean): Boolean //sampleEnd
The all method accepts a predicate and returns true if every element satisfies the predicate, and false otherwise. The some method has the same input, but returns true if at least one element satisfies the predicate, and false otherwise.
Example
//sampleStart fun main() { val list = listOf(1, 2, 3, 4) list.all { it % 2 == 0 }.also(::println) // false list.any { it % 2 == 0 }.also(::println) // true } //sampleEnd
There are also variations of any and none that take no arguments, and return true if the collection has at least one element and no elements, respectively.
Example
//sampleStart fun main() { val list = listOf(1) list.any().also(::println) // true list.none().also(::println) // false emptyList<Int>().none().also(::println) // true } //sampleEnd
isEmpty, isNotEmpty, ifEmpty
//sampleStart fun isEmpty(): Boolean inline fun <T> Collection<T>.isNotEmpty(): Boolean inline fun <C : Collection<*>, R> C.ifEmpty( defaultValue: () -> R ): R where C : R //sampleEnd
The isEmpty method is not an extension, but defined directly on the Collection interface. Predictably, it returns true if the collection contains no elements. For List, none is an alias for isEmpty. The opposite of isEmpty is isNotEmpty. There is also isNullOrEmpty, which is defined on a nullable receiver:
//sampleStart inline fun <T> Collection<T>?.isNullOrEmpty(): Boolean //sampleEnd
Of interest is the ifEmpty method, which allows us to substitute a different Collection if the receiver is empty. Notice that the type of the return value is always the type of what is returned by defaultValue, which can be a super-type of the receiver.
Example
//sampleStart fun main() { val list1 = emptyList<Int>() // List<Int> val list2 = listOf(1, 2, 3) // List<Int> list1.ifEmpty { listOf(4, 5.2, 3) }.also(::println) // List<Number> { 4, 5.2, 3 } list2.ifEmpty { listOf(4, 5.2, 3) }.also(::println) // List<Number> { 1, 2, 3 } } //sampleEnd
contains, containsAll
//sampleStart operator fun <T> Iterable<T>.contains(element: T): Boolean inline fun <T> Collection<T>.containsAll( elements: Collection<T> ): Boolean //sampleEnd
We already know contains from the chapter on operators. It can be invoked using the in keyword. The containsAll expands on this functionality by returning true only if the receiver contains all the elements of the argument, and false otherwise. Naturally, it is not an operator.
Example
//sampleStart fun main() { val list = listOf(1, 2, 3) list.contains(2).also(::println) // true println(2 in list) // true // listOf(1, 2) in list // Won't compile. Equivalent to list.contains(listOf(1, 2)) list.containsAll(listOf(1, 2)).also(::println) // true } //sampleEnd