1. 程式人生 > >Functional Android (II): Collection operations in Kotlin

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

. Kotlin provides an awesome set of operations that wouldn’t be possible (or really verbose) when using a language which doesn’t support lambdas.

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 as add, remove or clear 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.

Kotlin for Android Developers

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.

Shares

Like this:

Like Loading...

相關推薦

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,點選後有