Kotlin extension functions
Successor of Ktoolz.
Collection of Kotlin extension functions and utilities. This library does not have any dependency.
Katlib is available on the Maven Central. Then to import Katlib to Gradle project use:
implementation("dev.forst", "katlib", "2.2.7")
Or with Groovy DSL
implementation 'dev.forst:katlib:2.2.7'
To import Katlib to Maven project use:
<dependency>
<groupId>dev.forst</groupId>
<artifactId>katlib</artifactId>
<version>2.2.7</version>
</dependency>
Available online - katlib.forst.dev
Feel free to submit PR with your favourite extension functions and other cool utilities!
The library contains a lot of useful (as well as useless) extensions and functions that were gathered during my (and my colleges) Kotlin
career. Please see tests folder for all possible functions and how to use them. Full documentation can
be found here.
Please note that some functions seems like duplicates of the standard library - usually it is not like that as they provide similar
functionality on different interface. For example there’s List.random
but not Iterable.random
- random on Iterable
is then implemented
in this library. Some functions are also essentially type aliases (for example equalsIgnoreCase
) for standard library as I was having hard
time finding correct name.
However, in some cases there might be duplicates, as development of this library started in 2018 and a lot of functions came to standard
library in Kotlin 1.4. - so if you find some duplicates, let me know or create PR that deprecates them in the code.
Following functions are the most popular ones.
Iterable<E>.random
- returns the random element from the iterableIterable<T>.reduction
- reduce producing list allowing you to set initial value, useful for cumulative sumsIterable<List<Int>>.sumByIndexes
- sums all Lists of integers into single one by indexesIterable<List<Double>>.sumDoublesByIndexes
- same as previous but with doublesIterable<T>.mapToSet
- creates set from iterable, transforms with given functionIterable<T>.dominantValueBy
- returns the most frequently occurring value of the given functionIterable<T1>.cartesianProduct
- cartesian product between all the elements from two iterablesIterable<T?>.forEachNotNull
- performs action on each element that is not nullIterable<Iterable<T>?>.union
- creates union of all iterablesIterable<Iterable<T>?>.intersect
- creates intersect of all iterablesIterable<T?>.filterNotNullBy
- returns list with only not null results using selectorIterable<T>.singleOrEmpty
- returns single element or null if it wasn’t found, throws exception if there are multiple elementsIterable<Pair<T, V>>.splitPairCollection
- returns pair of two lists with left and right valuesIterable<T>.setDifferenceBy
- returns difference between two iterablesIterable<Pair<K, V>>.assoc
- returns map from key value pairs but logs case when key is replaced by same key with different valueIterable<Triple<A, B, C>>.flattenToLists
- returns three lists constructed from triplesIterable<T>.toNavigableSet
- creates NavigableSetIterable<T>.isEmpty
- determines whether the iterable is empty or notIterable<Iterable<T>>.cartesianProduct
- cartesian product between all the elements from nested iterablesIterable<Iterable<T>>.lazyCartesianProduct
- cartesian product between all the elements from nested iterables as sequenceIterable<A>.zip(b: Iterable<B>, c: Iterable<C>, transform: (a: A, b: B, c: C) -> V)
- zip with three collections instead of twoIterable<T>.sumByFloat(selector: (T) -> Float)
- sums iterable by float selector, because sumOf
from stdlib does not haveIterable<T>.withEach(action: T.() -> Unit)
- performs the given action with each element as a receiverIterable<T>.withEachIndexed(action: T.(index: Int) -> Unit)
- performs the given action with each element as a receiver, providing sequential index with the elementMap<T, Double>.getWeightedRandom
- randomly selects item with respect to the current weight distributionMap<K, V>.mergeReduce
- two maps together using the given reduce functionMap<K, V1>.join
- joins two maps together using the given join functionMap<K1, Map<K2, V>>.swapKeys(): Map<K2, Map<K1, V>>
- swaps keys in two-dimensional mapsswapKeys
implementations for up to three-dimensional maps, justMap<Pair<K1, K2>, V>.toTwoLevelMap(): Map<K1, Map<K2, V>>
- creates two-dimensional map from the map of pairsMap<Triple<K1, K2, K3>, V>.toThreeLevelMap(): Map<K1, Map<K2, Map<K3, V>>>
- creates three-dimensional map from the map of triplesMap<K1, Map<K2, V>>.getSecondLevelValues(): Set<V>
- collects all the values from the bottom level into setMap<K1, Map<K2, Map<K3, V>>>.getThirdLevelValues(): Set<V>
- collects all the values from the bottom level into setIterable<Map<K, V>>.merge(): Map<K, List<V>>
- for each key, merges all the values into one common listSortedSet.min
- returns minimum of the set or null if emptySortedSet.max
- returns maximum of the set or nullmapLeft/Right/Pair
- applies given block to left/right/all iterable element/s of the pair
val pair = Pair(listOf(1, 2, 3), 0)
assertEquals(Pair(listOf(11, 12, 13), 0), pair.mapLeft { it + 10 })
letLeft/Right/Pair
- applies given block to left/right/all element/s of the pair
val pair = Pair(10, 20)
assertEquals(Pair("10", 20), pair.letLeft { it.toString() })
getDateRangeTo
- returns list of dates between two LocalDate
getDaysInInterval
- returns number of days between two LocalDate
(inclusive)getDayDifference
- returns number of days between two LocalDate
(exclusive)getWeekOfYear
- returns week of year for given LocalDate
and optionaly Locale
To use these, one must include dependency on Jackson
implementation("com.fasterxml.jackson.core", "jackson-databind", jacksonVersion)
implementation("com.fasterxml.jackson.module", "jackson-module-kotlin", jacksonVersion)
jacksonMapper
- creates jackson mapper with some reasonable settingsparseJson
- parses JSON from the string/bytes, returns either instance of null, can log exception if some occurs
val obj: MyDataClass? = parseJson<MyDataClass>(myJson)
createJson
- creates JSON from given objectcreatePrettyJson
- creates JSON with pretty printcreateJsonBytes
- creates JSON in bytes from given objectprettyPrintJson
- returns pretty printed JSON value as stringwhenTrue
and whenFalse
- useful extensions mainly used for logging when the oneliners are used.
fun someFunctionIndicatingSuccess(): Boolean =
someComputationReturningBoolean()
.whenFalse {
logger.warning { "someComputationReturningBoolean returned false! Computation probably failed" }
}
startsWithLetter
- returns true fi string starts with latin letter a-z or A-ZrestrictLengthWithEllipsis
- shortens the string to given max length, appends ellipsis
assertEquals("ABCD…", "ABCDEFHG".restrictLengthWithEllipsis(5, "..."))
toUuid
- converts string to UUIDdurationToInMilli
- returns absolute difference between two Instant
values in millisecondshashWithSha256
- produces SHA-256
of given string/file/bytescomputeMd5
- computes MD5 from given byte array, returns base64 encoded dataOptional<T>.orNull(): T?
- from optional to Kotlin optionalT.whenNull
- executes block when this
is null, useful for logging
fun someFunction(): String? =
produceOptionalString()
.whenNull { logger.warn { "produceOptionalString returned null value!" } }
T.asList
- from `this creates one element listClosedRange<T>.intersects
- intersection between rangesT.with
- bundles two objects to listvalidate
- executes invalid block if validating block returns false, useful for validation
validate(
{ someText.startsWith("something") && someText.endsWith("else") },
{ throw IllegalStateException() }
)
Pair<A?, B?>.propagateNull(): Pair<A, B>?
- if left or right is null, returns null, otherwise pairT.applyIf
- applies given block only if should apply block returns true
byteBuffer.applyIf(shouldReadInt) { getInt() }
isUuid
- returns true if given string is UUIDisUrl
- returns true if give string is URL (with some limitations, see docs)getEnv
- shortcut for System.getenv
newLine
- shortcut for System.lineSeparator
ByteArray.toUuid
- Read ByteArray as two longs and combine the to UUIDTemporalProvider
- Interface providing access to current time via now
method, very useful when mockingbuildArray(builderAction: MutableList<E>.() -> Unit): Array<E>
- builds a new Array by populating a MutableList using the given builderAction and returning an Array with the same elementsArray<out T>.map(transform: (T) -> R): Array<R>
- Returns an array containing the results of applying the given transform function to each element in the original arrayArray<out T>.mapIndexed(transform: (index: Int, T) -> R): Array<R>
- returns an array containing the results of applying the given transform function to each element and its index in the original arrayArray<out T>.filter(predicate: (T) -> Boolean): Array<T>
- returns an array containing only elements matching the given predicateArray<out T>.filterNot(predicate: (T) -> Boolean): Array<T>
- returns an array containing all elements not matching the given predicateArray<out T>.filterIndexed(predicate: (index: Int, T) -> Boolean): Array<T>
- returns an array containing only elements matching the given predicateArray<*>.filterIsInstance(): Array<R>
- returns an array containing all elements that are instances of specified type parameter RArray<out T?>.filterNotNull(): Array<T>
- returns an array containing all elements that are not null
Array<out T>.minus(element: T): Array<T>
- returns an array containing all elements of the original collection without the first occurrence of the given elementArray<out T>.minus(elements: Array<out T>): Array<T>
- returns an array containing all elements of the original collection except the elements contained in the given elements arrayprompt(promptText: String, exceptionHandler: (e: Exception) -> String? = { null }, transform: (input: String) -> R): R
- prompts user and applies transform to input, invokes exceptionHandler if transform threw an Exception, and repeats prompt