15

Diving Deeper Into Kotlin Standard Library Functions

 2 years ago
source link: https://blog.kiprosh.com/kotlin-standard-library-functions/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Published on 18 May 2021 in android

Diving Deeper Into Kotlin Standard Library Functions

When we search for "Android Development in Kotlin," we come across many articles about Getting Rid of NullPointerException, Smart Type Casts, Complete Interoperability With Java, etc.; however, there are a handful of articles that list down advance and handy Kotlin functions. These functions make development simpler & more manageable. Kotlin offers a very concise and intuitive syntax; hence it helps to avoid the boilerplate code. Kotlin's standard library has become powerful with advanced in-built methods.
Therefore I thought to pen down the most useful, commonly required, and less talked Kotlin standard library functions. Let's dig deeper and find the hidden properties of Kotlin.

Kotlin is more concise. Rough estimates indicate approximately a 40% cut in the number of lines of code.
- Kotlin Document

Pair & Triple:
Have you ever thought that a function could return more than two values without using the map, model, or data class? No, not at all! But, with the help of `Pair` and `Triple` classes, this isn't a pain anymore. We can have a method that can return up to three elements:

fun getThreeElements(): Triple<String, Double, String> { return Triple("Learn Kotlin", 200.00, "Educational") } val data = getThreeElements() print(data.first) //Output: Learn Kotlin print(data.second) //Output: 200.00 print(data.third) //Output: Educational

fun getTwoElements(): Pair<String, Double> { return Pair("Learn Java", 300.00) } val twoElements = getTwoElements() print(twoElements.first) //Output: Learn Java print(twoElements.second) //Output: 300.00

Destructuring Declarations:
Destructuring declaration is the easiest way to create variables & initialize all of them in a single line of code:

val(id, name, age) = Person(101, "Harry Potter", 15) //Output: id = 101, name = Harry Potter, age = 15

val (x, y, z) = arrayOf(1.3, 2.4, 3.8) //Output: x= 1.3, y= 2.4, z= 3.8

val map = mutableMapOf(1 to "Harry", 2 to "Hermione", 3 to "Ron") for((key, value) in map) print("Id: $key, Name: $value ,") //Output: Id: 1, Name: Harry, Id: 2, Name: Hermione, Id: 3, Name: Ron

String:
Daily we deal with many functionalities where it's required to manipulate the strings. Earlier to avail various String functions in Android, we had no option other than integrating the Apache Common library, as Android's TextUtils class doesn't provide many functionalities. However, Kotlin offers a variety of functions that helps to tweak and trick the output as per the requirement. Let's take a look at a few of Kotlin's in-built useful methods that save us from writing lengthy logics to achieve a requirement:

"Ja49va1K7otl54in7".partition { "123456789".contains(it)} //Output: (4917547, JavaKotlin)

"L7ea3rn 1Kotl8in 12".filter { it.isDigit() } //Output: 731812

"L7ea3rn 1Kotl8in 12F".findLast { it.isDigit() } //Output:2 //Similar methods: findAnyOf(), findLastAnyOf()

"Learn Kotlin".all { it.isLowerCase() } //Output: false

"Learn Kotlin".any { it.isLowerCase() } //Output: true

"Learn Kotlin".dropLastWhile{it.isLowerCase()} //Output; Learn K //Similar methods: dropWhile{}, drop(), dropLast()

"Learn Kotlin".associateWith { it.toUpperCase() } //Output: {L=L, e=E, a=A, r=R, n=N, = , K=K, o=O, t=T, l=L, i=I} //Similar methods: associate{}, associateBy{}, associateByTo(), associateWithTo()

"Line One\n Line Two \n Line Three".lines() //Output: [Line One, Line Two , Line Three]

"Learn Kotlin".replaceAfter(' ', "Java") //Output: Learn Java //Similar methods: replace(), replaceAfterLast(), replaceBefore(), replaceBeforeLast(), replaceFirst(), replaceIndentByMargin(), replaceRange(), replaceFirst() "Learn Kotlin".substringAfter("a") //Output: rn Kotlin //Similar methods: substring(), substringAfterLast(), substringBefore(), substringBeforeLast()

"Android_App_Java".commonPrefixWith("Android_App_Kotlin") //Output: Android_App_ //Similar methods: commonSuffixWith()

"Learn Kotlin".removeSurrounding("L", "lin") //Output: earn Kot //Similar methods: removePrefix(), removeSuffix(), removeRange()

"\t".isBlank() //Output: true //Similar methods: ifBlank{}, isNotBlank(), isNotBlank(), isNullOrBlank()

"\t".isEmpty() //Output: false //Similar methods: ifEmpty{}, isNotEmpty(), isNullOrEmpty(), orEmpty()

"Learning\tKotlin".trim('L','B', 'n') //Output: earning Kotli //Similar methods: trimIndent(), trimMargin(), trimStart(), trimEnd(), trimStart('L'), trimEnd('n')

"Learning Kotlin".padStart(20, '.') //Output: .....Learning Kotlin //Similar method: padEnd() "learning kotlin".capitalize() //Output: Learning kotlin //Similar method: decapitalize()

Ranges:
Range is a very cool feature in Kotlin that helps create a list of a sequence by specifying the start & end of the range. It also provides functionality to define range interval & find an item's existence, e.g., find whether the current date lies in the range or not:

val start = Date.valueOf("2020-01-01") val end = Date.valueOf("2025-12-31") print(Date.valueOf("2022-05-11") in start..end}) //Output: true

for (i in 8 downTo 1) print(i) //Output: 87654321

for (i in 8 downTo 1 step 2) print(i) //Output: 8642

Collections:
A traditional way of dealing with collections used to be iterating over collections, and this looping requires a lot of boilerplate. Java Stream APIs provide the flexibility to filter the collection elements with less code, but Android has limitations. Below Android 24, we need to be dependent on third-party libraries or desugaring support.
The collections in Kotlin have surprised us with a vast set of functions. Kotlin has both mutable & immutable types of collections. Mutable collections can be modified, whereas immutable collections are read-only. In the below code snippet, I have grouped and listed some useful methods offered in the Kotlin language.

1. Get common, distinct, combine or flatten elements of the list:

mutableListOf(1, 2, 3).union(mutableListOf(2, 3, 4, 5)) //Output: [1, 2, 3, 4, 5] mutableListOf(1, 2, 3).intersect(mutableListOf(2, 3, 4, 5)) //Output: [2, 3]

mutableListOf(1, 2, 3).subtract(mutableListOf(2, 3, 4, 5)) //Output: [1]

mutableListOf(1, 2, 3).retainAll(mutableListOf(2, 3, 4, 5)) //Output: true, [2, 3]

mutableListOf(listOf(1, 2), listOf(2, 4), listOf(5, 6)).flatten() //Output: [1, 2, 2, 4, 5, 6] //Similar method: flatMap()

2. Get a particular element from list/map:

data class Person(val id: Int, val name: String) listOf(Person(null, 33), Person(null, 40),Person("Monica",33)).firstNotNullOfOrNull {it.name} //Output: Monica

listOf(1, 2, 3, 4).getOrElse(10){100} //Output: 100, //Similar methods: getOrNull(), get()

mutableMapOf(1 to 'a', 2 to 'b').getOrPut(3){'c'} //Output: c

listOf(1, 2, 3, 4, 100).component5() //Output: 100 //Similar methods: component1(), component2(), component3(), component4(), component5()

listOf(1, 2).singleOrNull() //Output: null //Similar methods: single()

listOf(1, 2, 3, 4, 5).first() //Output: 1

listOf(1, 2, 3, 4, 5).last() //Output: 5

listOf(1, 2, 3, 4, 5).findLast { it%2 == 0 } //Output: 4 //Similar methods: find{}

listOf(1, 2, 3, 4, 5).elementAtOrElse(9) { "Doesn't Exist" } //Output: Doesn't Exist //Similar methods: elementAt(), elementAtOrNull()

listOf(10, 20, 30, 40, 50).binarySearch(50)) //Output: 4 // Similar method: binarySearchBy()

(1..6).toMutableList().takeLastWhile { it >= 4 } //Output: [4, 5, 6] //Similar methods: take(), takeLast(), takeWhile{}, takeIf{}, takeUnless{}

(1..6).toMutableList().slice(2..4) //Output: [3, 4, 5] //Similar method: sliceArray()

3. Modify list data into chunks or group arrays:

listOf(1, 2, 3, 4, 5).zip(listOf(6, 7, 8, 9)) //Output: [(1, 6), (2, 7), (3, 8), (4, 9)]

listOf(1, 2, 3, 4, 5).zipWithNext() //Output: [(1, 2), (2, 3), (3, 4), (4, 5)]

listOf(1 to 2, 3 to 4, 5 to 6).unzip() //Output: ([1, 3, 5], [2, 4, 6])

listOf(1, 2, 3, 4, 5, 6, 7, 8, 9).chunked(4) //Output: [[1, 2, 3, 4], [5, 6, 7, 8], [9]]

listOf(1, 2, 3, 4, 5, 6, 7, 8, 9).windowed(4, 2, true) //Output: [[1, 2, 3, 4], [3, 4, 5, 6], [5, 6, 7, 8], [7, 8, 9], [9]]

listOf(1, 2, 3, 4, 5, 6, 7, 8, 9).partition { it % 2 == 0 } //Output: ([2, 4, 6, 8], [1, 3, 5, 7, 9]) data class Person(val name: String, val age: Int) listOf(Person("Joey", 33), Person("Ross", 40),Person("Monica",33)).groupBy { it.age } //Output: {33=[Person(name=Joey, age=33), Person(name=Monica, age=33)], 40=[Person(name=Ross, age=40)]}

4. Modify & print list data:

data class Person(val name: String, val age: Int) val characters = listOf(Person("Joey", 33), Person("Ross", 40), Person("Monica",33), Person("Ema",12)) characters.joinToString(separator = ", ", prefix = "Including ", postfix = " 2 more are invited.", limit = 2, truncated = "etc") { it.name } //Output: Including Joey, Ross, etc 2 more are invited. //Similar method: joinTo()

(1..6).toMutableList().plusAssign(9) //Output: [1, 2, 3, 4, 5, 6, 9] //Similar methods: plus(), plusElement(), add(), addAll(), put(), putAll()

(1..6).toMutableList().minusAssign(2) //Output: [1, 3, 4, 5, 6] //Similar methods: minus(), minusElement()

(1..6).toMutableList().dropWhile { it <= 2} //Output: [3, 4, 5, 6] //Similar methods: drop(), dropLast(), dropLastWhile{}

(1..6).toMutableList().removeAll((1..3).toList()) //Output: [4, 5, 6] //Similar methods: remove(), removeIf{}, removeAt(), removeFirstOrNull(), removeFirst(), removeLastOrNull(), removeLast()

mutableListOf('a','A','b','C','C').distinctBy { it.toUpperCase() } //Output: [a, b, C] //Similar methods: distinct()

arrayOf(arrayOf(3, 7, 9, 4), arrayOf("a", "b"), intArrayOf(2, 4, 8)).contentDeepToString() //Output: [[3, 7, 9, 4], [a, b], [2, 4, 8]] //Similar method: contentToString()

5. Copy the array elements:

intArrayOf(1, 2, 3, 4).copyInto(intArrayOf(40, 50, 60, 70, 80, 90)).contentToString() //Output: [1, 2, 3, 4, 80, 90].

intArrayOf(1, 2, 3, 4).copyOfRange(1,3).contentToString() //Output: [2, 3]

intArrayOf(1, 2, 3, 4).copyOf(6).contentToString() //Output: [1, 2, 3, 4, 0, 0]

6. Sort, shuffle & filter the list:

mutableListOf("Blue", "Purple", "Red").sortedByDescending { it.length } //Output: [Purple, Blue, Red] //Similar methods: sorted(), sortedBy{}, sortedWith(), sortedArray(), sortedArrayDescending(), sortedArrayWith(), //sortBy(), sortByDescending(), sortDescending(), sortWith(),

mutableListOf("Blue", "Purple", "Red").shuffled() //Output: [Blue, Red, Purple]

mutableListOf(4, 5, 4, 2).sorted().reversed() //Output: [4, 5, 4, 2]

mutableListOf(0, 9, 8, 3).filterIndexed { index, it -> index == it } //Output:[0, 3] //Similar methods: filter{}, filterNot{}, filterNotNull(), filterNot(), filterNotTo()

7. Apart from commonly used aggregate functions like average(), sum(), sumOf{}, count(), Kotlin provides reduce() & fold() that sequentially apply the mentioned operation to the collection elements & returns the accumulated result:

val result = listOf(5, 2, 10, 4).reduce { sum, element -> sum + element * 2 } // (5)+(2*2)+(10*2)+(4*2) print(result) //Output: 37 //Similar methods: reduceOrNull(), reduceIndexed(), reduceIndexedOrNull(), reduceRight(), reduceRightIndexed(), reduceRightIndexedOrNull(), reduceRightOrNull()

val result = listOf(5, 2, 10, 4).fold(2) { sum, element -> sum + element * 2 } // (2)+(5*2)+(2*2)+(10*2)+(4*2) print(result) // 44 //Similar methods: foldIndexed(), foldRight(), foldRightIndexed()

listOf("a", "b", "c", "d").runningFold("z") { acc, string -> acc + string } //Output: [z, za, zab, zabc, zabcd] //Similar method: runningFoldIndexed()

listOf("a", "b", "c", "d").scan("z") { acc, string -> acc + string } //Output: [z, za, zab, zabc, zabcd] //Similar method: scanIndexed()

Tip for the Android versions prior SDK 24:
Although Java 8 & higher versions provide advanced in-built methods, however for compatibility with lower Android versions we need to rely on backport dependencies or third-party libraries like Java 8+ API Desugaring Support, Lightweight-Stream-API or Stream, Apache Common APIs, etc.

I hope this article helped you.
I have attempted to provide a one-line description of each method to make it easy to learn & explore. This blog scratches the surface of Kotlin's standard library functions. Stay tuned for more updates.
Thank you!

Reference:
Kotlin Documentation
Use Java 8+ features and APIs

Kavita Patil

Kavita Patil

Android developer


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK