Functional Android (II): Collection operations in Kotlin
Lambdas are a great powerful tool to simplify code, but also to do things that were not possible before. We talked about them in the [first part of the series](Unleash functional power on Android (I): Kotlin lambdas).
In the end, lambdas are the basis to implement lots of functional features, such as the ones we are talking today: Collection operations
This article is not Android specific, but it will boost Android Apps development in many different ways. Today I’ll be talking about the different types of collections Kotlin provides, as well as the available operations over them.
Collections
Although we can just use Java collections, Kotlin provides a good set of native interfaces you will want to use:
- Iterable: The parent class. Any classes that inherit from this interface represent a sequence of elements we can iterate over.
- MutableIterable: Iterables that support removing items during iteration.
- Collection: This class represents a generic collection of elements. We get access to functions that return the size of the collection, whether the collection is empty, contains an item or a set of items. All the methods for this kind of collections are only to request data, because collections are immutable.
- MutableCollection: a
Collection
that supports adding and removing elements. It provides extra functions such asadd
,remove
orclear
among others. - List: Probably the most used collection. It represents a generic ordered collection of elements. As it’s ordered, we can request an item by its position, using the
get
function. - MutableList: a
List
that supports adding and removing elements. - Set: an unordered collection of elements that doesn’t support duplicate elements.
- MutableSet: a
Set
that supports adding and removing elements. - Map: a collection of key-value pairs. The keys in a map are unique, which means we cannot have two pairs with the same key in a map.
- MutableMap: a
Map
that supports adding and removing elements.
Collection Operations
This is the set of functional operations we have available over the different collections. I want to show you a little definition and example. It is useful to know what the options are, because that way it’s easier to identify where these functions can be used. Please let me know if you miss any function from the standard library.
All this content and much more can be found in Kotlin for Android Developers book.
18.1 Aggregate operations
any
Returns true
if at least one element matches the given predicate.
val list = listOf(1, 2, 3, 4, 5, 6) assertTrue(list.any { it % 2 == 0 }) assertFalse(list.any { it > 10 })
all
Returns true
if all the elements match the given predicate.
Want to learn Kotlin?
Check my free guide to create your first project in 15 minutes!
assertTrue(list.all { it < 10 }) assertFalse(list.all { it % 2 == 0 })
count
Returns the number of elements matching the given predicate.
assertEquals(3, list.count { it % 2 == 0 })
fold
Accumulates the value starting with an initial value and applying an operation from the first to the last element in a collection.
assertEquals(25, list.fold(4) { total, next -> total + next })
foldRight
Same as fold
, but it goes from the last element to first.
assertEquals(25, list.foldRight(4) { total, next -> total + next })
forEach
Performs the given operation to each element.
list forEach { println(it) }
forEachIndexed
Same as forEach
, though we also get the index of the element.
list forEachIndexed { index, value -> println("position $index contains a $value") }
max
Returns the largest element or null
if there are no elements.
assertEquals(6, list.max())
maxBy
Returns the first element yielding the largest value of the given function or null
if there are no elements.
// The element whose negative is greater assertEquals(1, list.maxBy { -it })
min
Returns the smallest element or null
if there are no elements.
assertEquals(1, list.min())
minBy
Returns the first element yielding the smallest value of the given function or null
if there are no elements.
// The element whose negative is smaller assertEquals(6, list.minBy { -it })
none
Returns true
if no elements match the given predicate.
// No elements are divisible by 7 assertTrue(list.none { it % 7 == 0 })
reduce
Same as fold
, but it doesn’t use an initial value. It accumulates the value applying an operation from the first to the last element in a collection.
assertEquals(21, list.reduce { total, next -> total + next })
reduceRight
Same as reduce
, but it goes from the last element to first.
assertEquals(21, list.reduceRight { total, next -> total + next })
sumBy
Returns the sum of all values produced by the transform function from the elements in the collection.
assertEquals(3, list.sumBy { it % 2 })
18.2 Filtering operations
drop
Returns a list containing all elements except first n elements.
assertEquals(listOf(5, 6), list.drop(4))
dropWhile
Returns a list containing all elements except first elements that satisfy the given predicate.
assertEquals(listOf(3, 4, 5, 6), list.dropWhile { it < 3 })
dropLastWhile
Returns a list containing all elements except last elements that satisfy the given predicate.
assertEquals(listOf(1, 2, 3, 4), list.dropLastWhile { it > 4 })
filter
Returns a list containing all elements matching the given predicate.
assertEquals(listOf(2, 4, 6), list.filter { it % 2 == 0 })
filterNot
Returns a list containing all elements not matching the given predicate.
assertEquals(listOf(1, 3, 5), list.filterNot { it % 2 == 0 })
filterNotNull
Returns a list containing all elements that are not null
.
assertEquals(listOf(1, 2, 3, 4), listWithNull.filterNotNull())
slice
Returns a list containing elements at specified indices.
assertEquals(listOf(2, 4, 5), list.slice(listOf(1, 3, 4)))
take
Returns a list containing first n elements.
assertEquals(listOf(1, 2), list.take(2))
takeLast
Returns a list containing last n elements.
assertEquals(listOf(5, 6), list.takeLast(2))
takeWhile
Returns a list containing first elements satisfying the given predicate.
assertEquals(listOf(1, 2), list.takeWhile { it < 3 })
18.3 Mapping operations
flatMap
Iterates over the elements creating a new collection for each one, and finally flattens all the collections into a unique list containing all the elements.
assertEquals(listOf(1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7), list.flatMap { listOf(it, it + 1) })
groupBy
Returns a map of the elements in original collection grouped by the result of given function
assertEquals(mapOf("odd" to listOf(1, 3, 5), "even" to listOf(2, 4, 6)), list.groupBy { if (it % 2 == 0) "even" else "odd" })
map
Returns a list containing the results of applying the given transform function to each element of the original collection.
assertEquals(listOf(2, 4, 6, 8, 10, 12), list.map { it * 2 })
mapIndexed
Returns a list containing the results of applying the given transform function to each element and its index of the original collection.
assertEquals(listOf (0, 2, 6, 12, 20, 30), list.mapIndexed { index, it -> index * it })
mapNotNull
Returns a list containing the results of applying the given transform function to each non-null element of the original collection.
assertEquals(listOf(2, 4, 6, 8), listWithNull mapNotNull { it * 2 })
18.4 Elements operations
contains
Returns true
if the element is found in the collection.
assertTrue(list.contains(2))
elementAt
Returns an element at the given index or throws an IndexOutOfBoundsException
if the index is out of bounds of this collection.
assertEquals(2, list.elementAt(1))
elementAtOrElse
Returns an element at the given index or the result of calling the default function if the index is out of bounds of this collection.
assertEquals(20, list.elementAtOrElse(10, { 2 * it }))
elementAtOrNull
Returns an element at the given index or null
if the index is out of bounds of this collection.
assertNull(list.elementAtOrNull(10))
first
Returns the first element matching the given predicate
assertEquals(2, list.first { it % 2 == 0 })
firstOrNull
Returns the first element matching the given predicate, or null
if no element was found.
assertNull(list.firstOrNull { it % 7 == 0 })
indexOf
Returns the first index of element, or -1 if the collection does not contain element.
assertEquals(3, list.indexOf(4))
indexOfFirst
Returns index of the first element matching the given predicate, or -1 if the collection does not contain such element.
assertEquals(1, list.indexOfFirst { it % 2 == 0 })
indexOfLast
Returns index of the last element matching the given predicate, or -1 if the collection does not contain such element.
assertEquals(5, list.indexOfLast { it % 2 == 0 })
last
Returns the last element matching the given predicate.
assertEquals(6, list.last { it % 2 == 0 })
lastIndexOf
Returns last index of element, or -1 if the collection does not contain element.
val listRepeated = listOf(2, 2, 3, 4, 5, 5, 6) assertEquals(5, listRepeated.lastIndexOf(5))
lastOrNull
Returns the last element matching the given predicate, or null
if no such element was found.
val list = listOf(1, 2, 3, 4, 5, 6) assertNull(list.lastOrNull { it % 7 == 0 })
single
Returns the single element matching the given predicate, or throws exception if there is no or more than one matching element.
assertEquals(5, list.single { it % 5 == 0 })
singleOrNull
Returns the single element matching the given predicate, or null
if element was not found or more than one element was found.
assertNull(list.singleOrNull { it % 7 == 0 })
18.5 Generation operations
merge
Returns a list of values built from elements of both collections with same indexes using the provided transform function. The list has the length of shortest collection.
val list = listOf(1, 2, 3, 4, 5, 6) val listRepeated = listOf(2, 2, 3, 4, 5, 5, 6) assertEquals(listOf(3, 4, 6, 8, 10, 11), list.merge(listRepeated) { it1, it2 -> it1 + it2 })
partition
Splits original collection into pair of collections, where the first collection contains elements for which the predicate returned true
,
while the second collection contains elements for which the predicate returned false
.
assertEquals(Pair(listOf(2, 4, 6), listOf(1, 3, 5)), list.partition { it % 2 == 0 })
plus
Returns a list containing all elements of the original collection and then all elements of the given collection. Because of the name of the function, we can use the ‘+’ operator with it.
assertEquals(listOf(1, 2, 3, 4, 5, 6, 7, 8), list + listOf(7, 8))
zip
Returns a list of pairs built from the elements of both collections with the same indexes. The list has the length of the shortest collection.
assertEquals(listOf(Pair(1, 7), Pair(2, 8)), list.zip(listOf(7, 8)))
18.6 Ordering operations
reverse
Returns a list with elements in reversed order.
val unsortedList = listOf(3, 2, 7, 5) assertEquals(listOf(5, 7, 2, 3), unsortedList.reverse())
sort
Returns a sorted list of all elements.
assertEquals(listOf(2, 3, 5, 7), unsortedList.sort())
sortBy
Returns a list of all elements, sorted by the specified comparator.
assertEquals(listOf(3, 7, 2, 5), unsortedList.sortBy { it % 3 })
sortDescending
Returns a sorted list of all elements, in descending order.
assertEquals(listOf(7, 5, 3, 2), unsortedList.sortDescending())
sortDescendingBy
Returns a sorted list of all elements, in descending order by the results of the specified order function.
assertEquals(listOf(2, 5, 7, 3), unsortedList.sortDescendingBy { it % 3 })
I’m in love with Kotlin. I’ve been learning about it for a couple of years, applying it to Android and digesting all this knowledge so that you can learn it with no effort.
SharesLike this:
Loading...Related
相關推薦
Functional Android (II): Collection operations in Kotlin
Lambdas are a great powerful tool to simplify code, but also to do things that were not possible before. We talked about them in the [first part of t
Functional operations with collections in Kotlin (KAD 11)
I must admit that, for me, one of the most frustrating things when writing Java ccode is the list handling. Java 8 has some improvements in this resp
Kotlin for Android (II): Create a new project
After getting a light idea of, it´s time to configure Android Studio to help us develop Android apps using Kotlin. It requires some steps that only n
Operator overload in Kotlin: Add standard operations to any class (KAD 17)
In Kotlin, as in every language, we have predefined operators to perform certain operations. The most typical are the addition (+), subtraction (-),
API request in Android the easy way using Kotlin
Kotlin is a really powerful language aimed to write more code using less boilerplate. And this is specially true in Android. Apart from the language
Lambdas in Kotlin, and how they simplify Android development (KAD 07)
Lambdas are one of the most powerful tools in Kotlin, and in any other modern language, since it allows modelling functions in a much simpler way. Th
Kotlin Recipes for Android (II): RecyclerView and DiffUtil
As you may know, the Support Library 24 included a new really handy class called DiffUtil, which will let you get rid of the boring and error prone o
Extension functions in Kotlin: Extend the Android Framework (KAD 08)
Extension functions are a really cool feature that Kotlin provides, and that you’ll find yourself using a lot when writing Android Apps. We have to a
Property delegation in Kotlin: Assign values in Android without having the context (KAD 15)
As we’ve seen in previous articles, properties need a default value, they can’t be declared without assigning them a value. This is a problem, becaus
android手機安全衛士、Kotlin漫畫、支付寶動畫、沈浸狀態欄等源碼
文字 多源 href fragment 四種 cimage ++ 條件 支付 Android精選源碼 輕量級底部導航欄 android手機衛士源碼 android實現高仿今日頭條源碼 一個用Kotlin寫的簡單漫畫App源碼
[轉]Enabling CRUD Operations in ASP.NET Web API 1
storage next have get ini called each tail span 本文轉自:https://docs.microsoft.com/en-us/aspnet/web-api/overview/older-versions/creating-a-w
AndroidStudio Frameworks detected: Android framework is detected in the project Configure
ima gpo detect framework size div 打開 錯誤 onf 出現這個問題應該是文件沒有用正確的方式打開。 遇到這種情況,就要去檢查下載的這個包的結構。 我的這個文件明顯真正的是下面這個文件夾,如果把整個當做一個android文
Android studio 實現java與kotlin的相互轉換
其實就是互轉,下面用Android studio 示範 Kotlin 轉換Java檔案 Tools>Kotlin>Show Kotlin Bytecode Decompile Java轉換kotlin檔案(需要studio3.0)或者安裝了kotlin外掛。 選擇頁面的
Android Studio 3.2中Kotlin和Databinding同時使用問題
今天使用Androidstudio 3.2 編譯以前的專案,結果總是遇到 無法找到 符號DataBindingComponent 的問題,經過一系列搜尋,測試.最終發現網上的方法根本無效。 果斷刪除如下 kapt ‘com.android.databinding:compil
Found 2 versions of android-support-v4.jar in the dependency list,The type android.support.v4.app.Fr
1、 Found 2 versions of android-support-v4.jar in the dependency list, but not all the versions are identical (check is based on SHA-1 only at t
android studio 3.0 建立kotlin
android studio 3.0自帶kotlin外掛,則省去新增外掛步驟 1.在java工程下建立kotlin專案 在平常project建立新的module,在最後頁面上選擇語言為kotlin 創建出來的工程報錯: Plugin with id ‘kotlin-a
[Swift]LeetCode154. 尋找旋轉排序數組中的最小值 II | Find Minimum in Rotated Sorted Array II
log con while logs findmi href exit out lex Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand
Android Studio-“Android framework is detected in the project”
轉載自: https://blog.csdn.net/qq_32452623/article/details/75134928 問題描述 上午的時候專案一切正常,下午不知道操作了什麼,開啟專案就出現瞭如下的問題。 Frameworks detected: Android framewor
【譯】Easily Build Android APKs on Device in Termux
您是否曾想在Android上構建自己的Android應用程式? 你自己的應用程式,APK! 您可以通過網際網路分發的東西,可以在全球的Android智慧手機上使用。 您是否敢於嘗試花一些時間學習新的東西? 此原始碼儲存庫僅用於此目的。 原始碼是用可理解的人類語言編寫軟體的方
AndroidStudio Frameworks detected: Android framework is detected in the project Configure。
AndroidStudio Frameworks detected: Android framework is detected in the project Configure。 拷貝別人的androidStudio工程檔案,然後開啟後,出現讓comfigure,點選後有