remove kotlin code from repo
This commit is contained in:
parent
02a3978fae
commit
c4a3db7acc
|
@ -1,11 +0,0 @@
|
|||
## Core Kotlin Advanced
|
||||
|
||||
This module contains articles about advanced topics in Kotlin.
|
||||
|
||||
### Relevant articles:
|
||||
- [Building DSLs in Kotlin](https://www.baeldung.com/kotlin-dsl)
|
||||
- [Regular Expressions in Kotlin](https://www.baeldung.com/kotlin-regular-expressions)
|
||||
- [Idiomatic Logging in Kotlin](https://www.baeldung.com/kotlin-logging)
|
||||
- [Mapping of Data Objects in Kotlin](https://www.baeldung.com/kotlin-data-objects)
|
||||
- [Reflection with Kotlin](https://www.baeldung.com/kotlin-reflection)
|
||||
- [Kotlin Contracts](https://www.baeldung.com/kotlin-contracts)
|
|
@ -1,41 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-kotlin-advanced</artifactId>
|
||||
<name>core-kotlin-advanced</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-kotlin-modules</groupId>
|
||||
<artifactId>core-kotlin-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-test</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<kotlin.version>1.3.30</kotlin.version>
|
||||
<assertj.version>3.10.0</assertj.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -1,23 +0,0 @@
|
|||
package com.baeldung.contract
|
||||
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
|
||||
@ExperimentalContracts
|
||||
inline fun <R> myRun(block: () -> R): R {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return block()
|
||||
}
|
||||
|
||||
@ExperimentalContracts
|
||||
fun callsInPlace() {
|
||||
val i: Int
|
||||
myRun {
|
||||
i = 1 // Without contract initialization is forbidden due to possible re-assignment
|
||||
}
|
||||
println(i) // Without contract variable might be uninitialized
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
package com.baeldung.contract
|
||||
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
|
||||
data class Request(val arg: String)
|
||||
|
||||
class Service {
|
||||
|
||||
@ExperimentalContracts
|
||||
fun process(request: Request?) {
|
||||
validate(request)
|
||||
println(request.arg)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ExperimentalContracts
|
||||
private fun validate(request: Request?) {
|
||||
contract {
|
||||
returns() implies (request != null)
|
||||
}
|
||||
if (request == null) {
|
||||
throw IllegalArgumentException("Undefined request")
|
||||
}
|
||||
}
|
||||
|
||||
data class MyEvent(val message: String)
|
||||
|
||||
@ExperimentalContracts
|
||||
fun processEvent(event: Any?) {
|
||||
if (isInterested(event)) {
|
||||
println(event.message) // Compiler makes smart cast here with the help of contract
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalContracts
|
||||
fun isInterested(event: Any?): Boolean {
|
||||
contract {
|
||||
returns(true) implies (event is MyEvent)
|
||||
}
|
||||
return event is MyEvent
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package com.baeldung.datamapping
|
||||
|
||||
data class User(
|
||||
val firstName: String,
|
||||
val lastName: String,
|
||||
val street: String,
|
||||
val houseNumber: String,
|
||||
val phone: String,
|
||||
val age: Int,
|
||||
val password: String)
|
|
@ -1,22 +0,0 @@
|
|||
package com.baeldung.datamapping
|
||||
|
||||
import kotlin.reflect.full.memberProperties
|
||||
|
||||
fun User.toUserView() = UserView(
|
||||
name = "$firstName $lastName",
|
||||
address = "$street $houseNumber",
|
||||
telephone = phone,
|
||||
age = age
|
||||
)
|
||||
|
||||
fun User.toUserViewReflection() = with(::UserView) {
|
||||
val propertiesByName = User::class.memberProperties.associateBy { it.name }
|
||||
callBy(parameters.associate { parameter ->
|
||||
parameter to when (parameter.name) {
|
||||
UserView::name.name -> "$firstName $lastName"
|
||||
UserView::address.name -> "$street $houseNumber"
|
||||
UserView::telephone.name -> phone
|
||||
else -> propertiesByName[parameter.name]?.get(this@toUserViewReflection)
|
||||
}
|
||||
})
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package com.baeldung.datamapping
|
||||
|
||||
data class UserView(
|
||||
val name: String,
|
||||
val address: String,
|
||||
val telephone: String,
|
||||
val age: Int
|
||||
)
|
|
@ -1,114 +0,0 @@
|
|||
package com.baeldung.dsl
|
||||
|
||||
abstract class Condition {
|
||||
|
||||
fun and(initializer: Condition.() -> Unit) {
|
||||
addCondition(And().apply(initializer))
|
||||
}
|
||||
|
||||
fun or(initializer: Condition.() -> Unit) {
|
||||
addCondition(Or().apply(initializer))
|
||||
}
|
||||
|
||||
infix fun String.eq(value: Any?) {
|
||||
addCondition(Eq(this, value))
|
||||
}
|
||||
|
||||
protected abstract fun addCondition(condition: Condition)
|
||||
}
|
||||
|
||||
open class CompositeCondition(private val sqlOperator: String) : Condition() {
|
||||
private val conditions = mutableListOf<Condition>()
|
||||
|
||||
override fun addCondition(condition: Condition) {
|
||||
conditions += condition
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return if (conditions.size == 1) {
|
||||
conditions.first().toString()
|
||||
} else {
|
||||
conditions.joinToString(prefix = "(", postfix = ")", separator = " $sqlOperator ") {
|
||||
"$it"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class And : CompositeCondition("and")
|
||||
|
||||
class Or : CompositeCondition("or")
|
||||
|
||||
class Eq(private val column: String, private val value: Any?) : Condition() {
|
||||
|
||||
init {
|
||||
if (value != null && value !is Number && value !is String) {
|
||||
throw IllegalArgumentException("Only <null>, numbers and strings values can be used in the 'where' clause")
|
||||
}
|
||||
}
|
||||
|
||||
override fun addCondition(condition: Condition) {
|
||||
throw IllegalStateException("Can't add a nested condition to the sql 'eq'")
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return when (value) {
|
||||
null -> "$column is null"
|
||||
is String -> "$column = '$value'"
|
||||
else -> "$column = $value"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SqlSelectBuilder {
|
||||
|
||||
private val columns = mutableListOf<String>()
|
||||
private lateinit var table: String
|
||||
private var condition: Condition? = null
|
||||
|
||||
fun select(vararg columns: String) {
|
||||
if (columns.isEmpty()) {
|
||||
throw IllegalArgumentException("At least one column should be defined")
|
||||
}
|
||||
if (this.columns.isNotEmpty()) {
|
||||
throw IllegalStateException("Detected an attempt to re-define columns to fetch. Current columns list: "
|
||||
+ "${this.columns}, new columns list: $columns")
|
||||
}
|
||||
this.columns.addAll(columns)
|
||||
}
|
||||
|
||||
fun from(table: String) {
|
||||
this.table = table
|
||||
}
|
||||
|
||||
fun where(initializer: Condition.() -> Unit) {
|
||||
condition = And().apply(initializer)
|
||||
}
|
||||
|
||||
fun build(): String {
|
||||
if (!::table.isInitialized) {
|
||||
throw IllegalStateException("Failed to build an sql select - target table is undefined")
|
||||
}
|
||||
return toString()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
val columnsToFetch =
|
||||
if (columns.isEmpty()) {
|
||||
"*"
|
||||
} else {
|
||||
columns.joinToString(", ")
|
||||
}
|
||||
val conditionString =
|
||||
if (condition == null) {
|
||||
""
|
||||
} else {
|
||||
" where $condition"
|
||||
}
|
||||
return "select $columnsToFetch from $table$conditionString"
|
||||
}
|
||||
}
|
||||
|
||||
fun query(initializer: SqlSelectBuilder.() -> Unit): SqlSelectBuilder {
|
||||
return SqlSelectBuilder().apply(initializer)
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
package com.baeldung.logging
|
||||
|
||||
import org.slf4j.Logger
|
||||
|
||||
open class LoggerAsExtensionOnAny {
|
||||
val logger = logger()
|
||||
|
||||
fun log(s: String) {
|
||||
logger().info(s)
|
||||
logger.info(s)
|
||||
}
|
||||
}
|
||||
|
||||
class ExtensionSubclass : LoggerAsExtensionOnAny()
|
||||
|
||||
fun <T : Any> T.logger(): Logger = getLogger(getClassForLogging(javaClass))
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
LoggerAsExtensionOnAny().log("test")
|
||||
ExtensionSubclass().log("sub")
|
||||
"foo".logger().info("foo")
|
||||
1.logger().info("uh-oh!")
|
||||
SomeOtherClass().logger()
|
||||
}
|
||||
|
||||
class SomeOtherClass {
|
||||
fun logger(): String {
|
||||
return "foo"
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
package com.baeldung.logging
|
||||
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
interface Logging
|
||||
|
||||
inline fun <reified T : Logging> T.logger(): Logger =
|
||||
//Wrong logger name!
|
||||
//LoggerFactory.getLogger(javaClass.name + " w/interface")
|
||||
LoggerFactory.getLogger(getClassForLogging(T::class.java).name + " w/interface")
|
||||
|
||||
open class LoggerAsExtensionOnMarkerInterface : Logging {
|
||||
companion object : Logging {
|
||||
val logger = logger()
|
||||
}
|
||||
|
||||
fun log(s: String) {
|
||||
logger().info(s)
|
||||
logger.info(s)
|
||||
}
|
||||
}
|
||||
|
||||
class MarkerExtensionSubclass : LoggerAsExtensionOnMarkerInterface()
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
LoggerAsExtensionOnMarkerInterface().log("test")
|
||||
MarkerExtensionSubclass().log("sub")
|
||||
"foo".logger().info("foo")
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package com.baeldung.logging
|
||||
|
||||
open class LoggerAsProperty {
|
||||
private val logger = getLogger(javaClass)
|
||||
|
||||
fun log(s: String) {
|
||||
logger.info(s)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class PropertySubclass : LoggerAsProperty()
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
LoggerAsProperty().log("test")
|
||||
PropertySubclass().log("sub")
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
package com.baeldung.logging
|
||||
|
||||
import org.slf4j.Logger
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
open class LoggerAsPropertyDelegate {
|
||||
private val lazyLogger by lazyLogger()
|
||||
protected val logger by LoggerDelegate()
|
||||
private val logger2 = logger
|
||||
|
||||
companion object {
|
||||
private val lazyLoggerComp by lazyLogger()
|
||||
private val loggerComp by LoggerDelegate()
|
||||
}
|
||||
|
||||
open fun log(s: String) {
|
||||
logger.info(s)
|
||||
logger2.info(s)
|
||||
lazyLogger.info(s)
|
||||
loggerComp.info(s)
|
||||
lazyLoggerComp.info(s)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DelegateSubclass : LoggerAsPropertyDelegate() {
|
||||
override fun log(s: String) {
|
||||
logger.info("-- in sub")
|
||||
super.log(s)
|
||||
}
|
||||
}
|
||||
|
||||
fun lazyLogger(forClass: Class<*>): Lazy<Logger> =
|
||||
lazy { getLogger(getClassForLogging(forClass)) }
|
||||
|
||||
fun <T : Any> T.lazyLogger(): Lazy<Logger> = lazyLogger(javaClass)
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
LoggerAsPropertyDelegate().log("test")
|
||||
DelegateSubclass().log("sub")
|
||||
}
|
||||
|
||||
class LoggerDelegate<in R : Any> : ReadOnlyProperty<R, Logger> {
|
||||
override fun getValue(thisRef: R, property: KProperty<*>) =
|
||||
getLogger(getClassForLogging(thisRef.javaClass))
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
package com.baeldung.logging
|
||||
|
||||
open class LoggerInCompanionObject {
|
||||
companion object {
|
||||
private val loggerWithExplicitClass = getLogger(LoggerInCompanionObject::class.java)
|
||||
@Suppress("JAVA_CLASS_ON_COMPANION")
|
||||
private val loggerWithWrongClass = getLogger(javaClass)
|
||||
@Suppress("JAVA_CLASS_ON_COMPANION")
|
||||
private val logger = getLogger(javaClass.enclosingClass)
|
||||
}
|
||||
|
||||
fun log(s: String) {
|
||||
loggerWithExplicitClass.info(s)
|
||||
loggerWithWrongClass.info(s)
|
||||
logger.info(s)
|
||||
}
|
||||
|
||||
class Inner {
|
||||
companion object {
|
||||
private val loggerWithExplicitClass = getLogger(Inner::class.java)
|
||||
@Suppress("JAVA_CLASS_ON_COMPANION")
|
||||
@JvmStatic
|
||||
private val loggerWithWrongClass = getLogger(javaClass)
|
||||
@Suppress("JAVA_CLASS_ON_COMPANION")
|
||||
@JvmStatic
|
||||
private val logger = getLogger(javaClass.enclosingClass)
|
||||
}
|
||||
|
||||
fun log(s: String) {
|
||||
loggerWithExplicitClass.info(s)
|
||||
loggerWithWrongClass.info(s)
|
||||
logger.info(s)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class CompanionSubclass : LoggerInCompanionObject()
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
LoggerInCompanionObject().log("test")
|
||||
LoggerInCompanionObject.Inner().log("test")
|
||||
CompanionSubclass().log("sub")
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package com.baeldung.logging
|
||||
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import kotlin.reflect.full.companionObject
|
||||
|
||||
fun getLogger(forClass: Class<*>): Logger = LoggerFactory.getLogger(forClass)
|
||||
|
||||
fun <T : Any> getClassForLogging(javaClass: Class<T>): Class<*> {
|
||||
return javaClass.enclosingClass?.takeIf {
|
||||
it.kotlin.companionObject?.java == javaClass
|
||||
} ?: javaClass
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
package com.baeldung.datamapping
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertAll
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class UserTest {
|
||||
|
||||
@Test
|
||||
fun `maps User to UserResponse using extension function`() {
|
||||
val p = buildUser()
|
||||
val view = p.toUserView()
|
||||
assertUserView(view)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `maps User to UserResponse using reflection`() {
|
||||
val p = buildUser()
|
||||
val view = p.toUserViewReflection()
|
||||
assertUserView(view)
|
||||
}
|
||||
|
||||
private fun buildUser(): User {
|
||||
return User(
|
||||
"Java",
|
||||
"Duke",
|
||||
"Javastreet",
|
||||
"42",
|
||||
"1234567",
|
||||
30,
|
||||
"s3cr37"
|
||||
)
|
||||
}
|
||||
|
||||
private fun assertUserView(pr: UserView) {
|
||||
assertAll(
|
||||
{ assertEquals("Java Duke", pr.name) },
|
||||
{ assertEquals("Javastreet 42", pr.address) },
|
||||
{ assertEquals("1234567", pr.telephone) },
|
||||
{ assertEquals(30, pr.age) }
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
package com.baeldung.dsl
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.Test
|
||||
|
||||
class SqlDslTest {
|
||||
|
||||
@Test
|
||||
fun `when no columns are specified then star is used`() {
|
||||
doTest("select * from table1") {
|
||||
from ("table1")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when no condition is specified then correct query is built`() {
|
||||
doTest("select column1, column2 from table1") {
|
||||
select("column1", "column2")
|
||||
from ("table1")
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = Exception::class)
|
||||
fun `when no table is specified then an exception is thrown`() {
|
||||
query {
|
||||
select("column1")
|
||||
}.build()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when a list of conditions is specified then it's respected`() {
|
||||
doTest("select * from table1 where (column3 = 4 and column4 is null)") {
|
||||
from ("table1")
|
||||
where {
|
||||
"column3" eq 4
|
||||
"column4" eq null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when 'or' conditions are specified then they are respected`() {
|
||||
doTest("select * from table1 where (column3 = 4 or column4 is null)") {
|
||||
from ("table1")
|
||||
where {
|
||||
or {
|
||||
"column3" eq 4
|
||||
"column4" eq null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when either 'and' or 'or' conditions are specified then they are respected`() {
|
||||
doTest("select * from table1 where ((column3 = 4 or column4 is null) and column5 = 42)") {
|
||||
from ("table1")
|
||||
where {
|
||||
and {
|
||||
or {
|
||||
"column3" eq 4
|
||||
"column4" eq null
|
||||
}
|
||||
"column5" eq 42
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun doTest(expected: String, sql: SqlSelectBuilder.() -> Unit) {
|
||||
assertThat(query(sql).build()).isEqualTo(expected)
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
package com.baeldung.reflection
|
||||
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
@Ignore
|
||||
class JavaReflectionTest {
|
||||
private val LOG = LoggerFactory.getLogger(KClassTest::class.java)
|
||||
|
||||
@Test
|
||||
fun listJavaClassMethods() {
|
||||
Exception::class.java.methods
|
||||
.forEach { method -> LOG.info("Method: {}", method) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun listKotlinClassMethods() {
|
||||
JavaReflectionTest::class.java.methods
|
||||
.forEach { method -> LOG.info("Method: {}", method) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun listKotlinDataClassMethods() {
|
||||
data class ExampleDataClass(val name: String, var enabled: Boolean)
|
||||
|
||||
ExampleDataClass::class.java.methods
|
||||
.forEach { method -> LOG.info("Method: {}", method) }
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
package com.baeldung.reflection
|
||||
|
||||
import org.junit.Assert
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.math.BigDecimal
|
||||
import kotlin.reflect.full.*
|
||||
|
||||
class KClassTest {
|
||||
private val LOG = LoggerFactory.getLogger(KClassTest::class.java)
|
||||
|
||||
@Test
|
||||
fun testKClassDetails() {
|
||||
val stringClass = String::class
|
||||
Assert.assertEquals("kotlin.String", stringClass.qualifiedName)
|
||||
Assert.assertFalse(stringClass.isData)
|
||||
Assert.assertFalse(stringClass.isCompanion)
|
||||
Assert.assertFalse(stringClass.isAbstract)
|
||||
Assert.assertTrue(stringClass.isFinal)
|
||||
Assert.assertFalse(stringClass.isSealed)
|
||||
|
||||
val listClass = List::class
|
||||
Assert.assertEquals("kotlin.collections.List", listClass.qualifiedName)
|
||||
Assert.assertFalse(listClass.isData)
|
||||
Assert.assertFalse(listClass.isCompanion)
|
||||
Assert.assertTrue(listClass.isAbstract)
|
||||
Assert.assertFalse(listClass.isFinal)
|
||||
Assert.assertFalse(listClass.isSealed)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetRelated() {
|
||||
LOG.info("Companion Object: {}", TestSubject::class.companionObject)
|
||||
LOG.info("Companion Object Instance: {}", TestSubject::class.companionObjectInstance)
|
||||
LOG.info("Object Instance: {}", TestObject::class.objectInstance)
|
||||
|
||||
Assert.assertSame(TestObject, TestObject::class.objectInstance)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNewInstance() {
|
||||
val listClass = ArrayList::class
|
||||
|
||||
val list = listClass.createInstance()
|
||||
Assert.assertTrue(list is ArrayList)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
fun testMembers() {
|
||||
val bigDecimalClass = BigDecimal::class
|
||||
|
||||
LOG.info("Constructors: {}", bigDecimalClass.constructors)
|
||||
LOG.info("Functions: {}", bigDecimalClass.functions)
|
||||
LOG.info("Properties: {}", bigDecimalClass.memberProperties)
|
||||
LOG.info("Extension Functions: {}", bigDecimalClass.memberExtensionFunctions)
|
||||
}
|
||||
}
|
||||
|
||||
class TestSubject {
|
||||
companion object {
|
||||
val name = "TestSubject"
|
||||
}
|
||||
}
|
||||
|
||||
object TestObject {
|
||||
val answer = 42
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
package com.baeldung.reflection
|
||||
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.nio.charset.Charset
|
||||
import kotlin.reflect.KMutableProperty
|
||||
import kotlin.reflect.full.starProjectedType
|
||||
|
||||
class KMethodTest {
|
||||
|
||||
@Test
|
||||
fun testCallMethod() {
|
||||
val str = "Hello"
|
||||
val lengthMethod = str::length
|
||||
|
||||
Assert.assertEquals(5, lengthMethod())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testReturnType() {
|
||||
val str = "Hello"
|
||||
val method = str::byteInputStream
|
||||
|
||||
Assert.assertEquals(ByteArrayInputStream::class.starProjectedType, method.returnType)
|
||||
Assert.assertFalse(method.returnType.isMarkedNullable)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testParams() {
|
||||
val str = "Hello"
|
||||
val method = str::byteInputStream
|
||||
|
||||
method.isSuspend
|
||||
Assert.assertEquals(1, method.parameters.size)
|
||||
Assert.assertTrue(method.parameters[0].isOptional)
|
||||
Assert.assertFalse(method.parameters[0].isVararg)
|
||||
Assert.assertEquals(Charset::class.starProjectedType, method.parameters[0].type)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMethodDetails() {
|
||||
val codePoints = String::codePoints
|
||||
Assert.assertEquals("codePoints", codePoints.name)
|
||||
Assert.assertFalse(codePoints.isSuspend)
|
||||
Assert.assertFalse(codePoints.isExternal)
|
||||
Assert.assertFalse(codePoints.isInline)
|
||||
Assert.assertFalse(codePoints.isOperator)
|
||||
|
||||
val byteInputStream = String::byteInputStream
|
||||
Assert.assertEquals("byteInputStream", byteInputStream.name)
|
||||
Assert.assertFalse(byteInputStream.isSuspend)
|
||||
Assert.assertFalse(byteInputStream.isExternal)
|
||||
Assert.assertTrue(byteInputStream.isInline)
|
||||
Assert.assertFalse(byteInputStream.isOperator)
|
||||
}
|
||||
|
||||
val readOnlyProperty: Int = 42
|
||||
lateinit var mutableProperty: String
|
||||
|
||||
@Test
|
||||
fun testPropertyDetails() {
|
||||
val roProperty = this::readOnlyProperty
|
||||
Assert.assertEquals("readOnlyProperty", roProperty.name)
|
||||
Assert.assertFalse(roProperty.isLateinit)
|
||||
Assert.assertFalse(roProperty.isConst)
|
||||
Assert.assertFalse(roProperty is KMutableProperty<*>)
|
||||
|
||||
val mProperty = this::mutableProperty
|
||||
Assert.assertEquals("mutableProperty", mProperty.name)
|
||||
Assert.assertTrue(mProperty.isLateinit)
|
||||
Assert.assertFalse(mProperty.isConst)
|
||||
Assert.assertTrue(mProperty is KMutableProperty<*>)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testProperty() {
|
||||
val prop = this::mutableProperty
|
||||
|
||||
Assert.assertEquals(String::class.starProjectedType, prop.getter.returnType)
|
||||
|
||||
prop.set("Hello")
|
||||
Assert.assertEquals("Hello", prop.get())
|
||||
|
||||
prop.setter("World")
|
||||
Assert.assertEquals("World", prop.getter())
|
||||
}
|
||||
}
|
|
@ -1,123 +0,0 @@
|
|||
package com.baeldung.regex
|
||||
|
||||
import org.junit.Test
|
||||
import kotlin.test.*
|
||||
|
||||
class RegexTest {
|
||||
|
||||
@Test
|
||||
fun whenRegexIsInstantiated_thenIsEqualToToRegexMethod() {
|
||||
val pattern = """a([bc]+)d?\\"""
|
||||
|
||||
assertEquals(Regex.fromLiteral(pattern).pattern, pattern)
|
||||
assertEquals(pattern, Regex(pattern).pattern)
|
||||
assertEquals(pattern, pattern.toRegex().pattern)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenRegexMatches_thenResultIsTrue() {
|
||||
val regex = """a([bc]+)d?""".toRegex()
|
||||
|
||||
assertTrue(regex.containsMatchIn("xabcdy"))
|
||||
assertTrue(regex.matches("abcd"))
|
||||
assertFalse(regex matches "xabcdy")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenCompletelyMatchingRegex_whenMatchResult_thenDestructuring() {
|
||||
val regex = """a([bc]+)d?""".toRegex()
|
||||
|
||||
assertNull(regex.matchEntire("xabcdy"))
|
||||
|
||||
val matchResult = regex.matchEntire("abbccbbd")
|
||||
|
||||
assertNotNull(matchResult)
|
||||
assertEquals(matchResult!!.value, matchResult.groupValues[0])
|
||||
assertEquals(matchResult.destructured.toList(), matchResult.groupValues.drop(1))
|
||||
assertEquals("bbccbb", matchResult.destructured.component1())
|
||||
assertNull(matchResult.next())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenPartiallyMatchingRegex_whenMatchResult_thenGroups() {
|
||||
val regex = """a([bc]+)d?""".toRegex()
|
||||
var matchResult = regex.find("abcb abbd")
|
||||
|
||||
assertNotNull(matchResult)
|
||||
assertEquals(matchResult!!.value, matchResult.groupValues[0])
|
||||
assertEquals("abcb", matchResult.value)
|
||||
assertEquals(IntRange(0, 3), matchResult.range)
|
||||
assertEquals(listOf("abcb", "bcb"), matchResult.groupValues)
|
||||
assertEquals(matchResult.destructured.toList(), matchResult.groupValues.drop(1))
|
||||
|
||||
matchResult = matchResult.next()
|
||||
|
||||
assertNotNull(matchResult)
|
||||
assertEquals("abbd", matchResult!!.value)
|
||||
assertEquals("bb", matchResult.groupValues[1])
|
||||
|
||||
matchResult = matchResult.next()
|
||||
|
||||
assertNull(matchResult)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenPartiallyMatchingRegex_whenMatchResult_thenDestructuring() {
|
||||
val regex = """([\w\s]+) is (\d+) years old""".toRegex()
|
||||
val matchResult = regex.find("Mickey Mouse is 95 years old")
|
||||
val (name, age) = matchResult!!.destructured
|
||||
|
||||
assertEquals("Mickey Mouse", name)
|
||||
assertEquals("95", age)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenNonMatchingRegex_whenFindCalled_thenNull() {
|
||||
val regex = """a([bc]+)d?""".toRegex()
|
||||
val matchResult = regex.find("foo")
|
||||
|
||||
assertNull(matchResult)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenNonMatchingRegex_whenFindAllCalled_thenEmptySet() {
|
||||
val regex = """a([bc]+)d?""".toRegex()
|
||||
val matchResults = regex.findAll("foo")
|
||||
|
||||
assertNotNull(matchResults)
|
||||
assertTrue(matchResults.none())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenReplace_thenReplacement() {
|
||||
val regex = """(red|green|blue)""".toRegex()
|
||||
val beautiful = "Roses are red, Violets are blue"
|
||||
val grim = regex.replace(beautiful, "dark")
|
||||
val shiny = regex.replaceFirst(beautiful, "rainbow")
|
||||
|
||||
assertEquals("Roses are dark, Violets are dark", grim)
|
||||
assertEquals("Roses are rainbow, Violets are blue", shiny)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenComplexReplace_thenReplacement() {
|
||||
val regex = """(red|green|blue)""".toRegex()
|
||||
val beautiful = "Roses are red, Violets are blue"
|
||||
val reallyBeautiful = regex.replace(beautiful) {
|
||||
matchResult -> matchResult.value.toUpperCase() + "!"
|
||||
}
|
||||
|
||||
assertEquals("Roses are RED!, Violets are BLUE!", reallyBeautiful)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenSplit_thenList() {
|
||||
val regex = """\W+""".toRegex()
|
||||
val beautiful = "Roses are red, Violets are blue"
|
||||
|
||||
assertEquals(listOf("Roses", "are", "red", "Violets", "are", "blue"), regex.split(beautiful))
|
||||
assertEquals(listOf("Roses", "are", "red", "Violets are blue"), regex.split(beautiful, 4))
|
||||
assertEquals(regex.toPattern().split(beautiful).asList(), regex.split(beautiful))
|
||||
}
|
||||
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
## Core Kotlin Annotations
|
||||
|
||||
This module contains articles about core Kotlin annotations.
|
||||
|
||||
### Relevant articles:
|
||||
- [Kotlin Annotations](https://www.baeldung.com/kotlin-annotations)
|
||||
- [Guide to Kotlin @JvmField](https://www.baeldung.com/kotlin-jvm-field-annotation)
|
||||
- [Guide to JVM Platform Annotations in Kotlin](https://www.baeldung.com/kotlin-jvm-annotations)
|
|
@ -1,41 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-kotlin-annotations</artifactId>
|
||||
<name>core-kotlin-annotations</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-kotlin-modules</groupId>
|
||||
<artifactId>core-kotlin-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-test</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<kotlin.version>1.3.30</kotlin.version>
|
||||
<assertj.version>3.10.0</assertj.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -1,7 +0,0 @@
|
|||
package com.baeldung.annotations
|
||||
|
||||
@Target(AnnotationTarget.FIELD)
|
||||
annotation class Positive
|
||||
|
||||
@Target(AnnotationTarget.FIELD)
|
||||
annotation class AllowedNames(val names: Array<String>)
|
|
@ -1,3 +0,0 @@
|
|||
package com.baeldung.annotations
|
||||
|
||||
class Item(@Positive val amount: Float, @AllowedNames(["Alice", "Bob"]) val name: String)
|
|
@ -1,7 +0,0 @@
|
|||
package com.baeldung.annotations
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val item = Item(amount = 1.0f, name = "Bob")
|
||||
val validator = Validator()
|
||||
println("Is instance valid? ${validator.isValid(item)}")
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
package com.baeldung.annotations
|
||||
|
||||
/**
|
||||
* Naive annotation-based validator.
|
||||
* @author A.Shcherbakov
|
||||
*/
|
||||
class Validator() {
|
||||
|
||||
/**
|
||||
* Return true if every item's property annotated with @Positive is positive and if
|
||||
* every item's property annotated with @AllowedNames has a value specified in that annotation.
|
||||
*/
|
||||
fun isValid(item: Item): Boolean {
|
||||
val fields = item::class.java.declaredFields
|
||||
for (field in fields) {
|
||||
field.isAccessible = true
|
||||
for (annotation in field.annotations) {
|
||||
val value = field.get(item)
|
||||
if (field.isAnnotationPresent(Positive::class.java)) {
|
||||
val amount = value as Float
|
||||
if (amount < 0) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if (field.isAnnotationPresent(AllowedNames::class.java)) {
|
||||
val allowedNames = field.getAnnotation(AllowedNames::class.java)?.names
|
||||
val name = value as String
|
||||
allowedNames?.let {
|
||||
if (!it.contains(name)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
package com.baeldung.jvmannotations
|
||||
|
||||
import java.util.*
|
||||
|
||||
interface Document {
|
||||
|
||||
@JvmDefault
|
||||
fun getTypeDefault() = "document"
|
||||
|
||||
fun getType() = "document"
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
package com.baeldung.jvmannotations;
|
||||
|
||||
public class HtmlDocument implements Document {
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "HTML";
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
@file:JvmName("MessageHelper")
|
||||
@file:JvmMultifileClass //used
|
||||
package com.baeldung.jvmannotations
|
||||
|
||||
import java.util.*
|
||||
|
||||
@JvmName("getMyUsername")
|
||||
fun getMyName() : String {
|
||||
return "myUserId"
|
||||
}
|
||||
|
||||
object MessageBroker {
|
||||
@JvmStatic
|
||||
var totalMessagesSent = 0
|
||||
|
||||
const val maxMessageLength = 0
|
||||
|
||||
@JvmStatic
|
||||
fun clearAllMessages() {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
@Throws(Exception::class)
|
||||
fun findMessages(sender : String, type : String = "text", maxResults : Int = 10) : List<Message> {
|
||||
if(sender.isEmpty()) {
|
||||
throw Exception()
|
||||
}
|
||||
return ArrayList()
|
||||
}
|
||||
}
|
||||
|
||||
class Message {
|
||||
|
||||
// this would cause a compilation error since sender is immutable
|
||||
// @set:JvmName("setSender")
|
||||
val sender = "myself"
|
||||
|
||||
// this works as name is overridden
|
||||
@JvmName("getSenderName")
|
||||
fun getSender() : String = "from:$sender"
|
||||
|
||||
@get:JvmName("getReceiverName")
|
||||
@set:JvmName("setReceiverName")
|
||||
var receiver : String = ""
|
||||
|
||||
@get:JvmName("getContent")
|
||||
@set:JvmName("setContent")
|
||||
var text = ""
|
||||
|
||||
// generates a warning
|
||||
@get:JvmName("getId")
|
||||
private val id = 0
|
||||
|
||||
@get:JvmName("hasAttachment")
|
||||
var hasAttachment = true
|
||||
|
||||
var isEncrypted = true
|
||||
|
||||
fun setReceivers(receiverNames : List<String>) {
|
||||
}
|
||||
|
||||
@JvmName("setReceiverIds")
|
||||
fun setReceivers(receiverNames : List<Int>) {
|
||||
}
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
@file:JvmMultifileClass
|
||||
@file:JvmName("MessageHelper") //applies to all top level functions / variables / constants
|
||||
package com.baeldung.jvmannotations
|
||||
|
||||
fun convert(message: Message) {
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
package com.baeldung.jvmannotations
|
||||
|
||||
import java.util.*
|
||||
class TextDocument : Document {
|
||||
override fun getType() = "text"
|
||||
|
||||
fun transformList(list : List<Number>) : List<Number> {
|
||||
return list.filter { n -> n.toInt() > 1 }
|
||||
}
|
||||
|
||||
fun transformListInverseWildcards(list : List<@JvmSuppressWildcards Number>) : List<@JvmWildcard Number> {
|
||||
return list.filter { n -> n.toInt() > 1 }
|
||||
}
|
||||
|
||||
var list : List<@JvmWildcard Any> = ArrayList()
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
package com.baeldung.jvmannotations
|
||||
|
||||
import java.util.*
|
||||
|
||||
class XmlDocument(d : Document) : Document by d
|
|
@ -1,12 +0,0 @@
|
|||
package com.baeldung.jvmfield
|
||||
|
||||
class JvmSample(text:String) {
|
||||
@JvmField
|
||||
val sampleText:String = text
|
||||
}
|
||||
|
||||
class CompanionSample {
|
||||
companion object {
|
||||
@JvmField val MAX_LIMIT = 20
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
package com.baeldung.annotations
|
||||
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.assertFalse
|
||||
|
||||
class ValidationTest {
|
||||
|
||||
@Test
|
||||
fun whenAmountIsOneAndNameIsAlice_thenTrue() {
|
||||
assertTrue(Validator().isValid(Item(1f, "Alice")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenAmountIsOneAndNameIsBob_thenTrue() {
|
||||
assertTrue(Validator().isValid(Item(1f, "Bob")))
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun whenAmountIsMinusOneAndNameIsAlice_thenFalse() {
|
||||
assertFalse(Validator().isValid(Item(-1f, "Alice")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenAmountIsMinusOneAndNameIsBob_thenFalse() {
|
||||
assertFalse(Validator().isValid(Item(-1f, "Bob")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenAmountIsOneAndNameIsTom_thenFalse() {
|
||||
assertFalse(Validator().isValid(Item(1f, "Tom")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenAmountIsMinusOneAndNameIsTom_thenFalse() {
|
||||
assertFalse(Validator().isValid(Item(-1f, "Tom")))
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
package com.baeldung.range
|
||||
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
import com.baeldung.jvmannotations.*;
|
||||
|
||||
class DocumentTest {
|
||||
|
||||
@Test
|
||||
fun testDefaultMethod() {
|
||||
|
||||
val myDocument = TextDocument()
|
||||
val myTextDocument = XmlDocument(myDocument)
|
||||
|
||||
assertEquals("text", myDocument.getType())
|
||||
assertEquals("text", myTextDocument.getType())
|
||||
assertEquals("document", myTextDocument.getTypeDefault())
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package com.baeldung.jvmfield
|
||||
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class JvmSampleTest {
|
||||
|
||||
var sample = ""
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
sample = JvmSample("Hello!").sampleText
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenField_whenCheckValue_thenMatchesValue() {
|
||||
assertTrue(sample == "Hello!")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenStaticVariable_whenCheckValue_thenMatchesValue() {
|
||||
// Sample when is treated as a static variable
|
||||
assertTrue(CompanionSample.MAX_LIMIT == 20)
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
## Core Kotlin Collections
|
||||
|
||||
This module contains articles about core Kotlin collections.
|
||||
|
||||
## Relevant articles:
|
||||
|
||||
- [Aggregate Operations in Kotlin](https://www.baeldung.com/kotlin/aggregate-operations)
|
|
@ -1,47 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-kotlin-collections-2</artifactId>
|
||||
<name>core-kotlin-collections-2</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-kotlin-modules</groupId>
|
||||
<artifactId>core-kotlin-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-math3</artifactId>
|
||||
<version>${commons-math3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-test</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<kotlin.version>1.3.30</kotlin.version>
|
||||
<commons-math3.version>3.6.1</commons-math3.version>
|
||||
<assertj.version>3.10.0</assertj.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -1,107 +0,0 @@
|
|||
package com.baeldung.aggregate
|
||||
|
||||
class AggregateOperations {
|
||||
private val numbers = listOf(1, 15, 3, 8)
|
||||
|
||||
fun countList(): Int {
|
||||
return numbers.count()
|
||||
}
|
||||
|
||||
fun sumList(): Int {
|
||||
return numbers.sum()
|
||||
}
|
||||
|
||||
fun averageList(): Double {
|
||||
return numbers.average()
|
||||
}
|
||||
|
||||
fun maximumInList(): Int? {
|
||||
return numbers.max()
|
||||
}
|
||||
|
||||
fun minimumInList(): Int? {
|
||||
return numbers.min()
|
||||
}
|
||||
|
||||
fun maximumByList(): Int? {
|
||||
return numbers.maxBy { it % 5 }
|
||||
}
|
||||
|
||||
fun minimumByList(): Int? {
|
||||
return numbers.minBy { it % 5 }
|
||||
}
|
||||
|
||||
fun maximumWithList(): String? {
|
||||
val strings = listOf("Berlin", "Kolkata", "Prague", "Barcelona")
|
||||
return strings.maxWith(compareBy { it.length % 4 })
|
||||
}
|
||||
|
||||
fun minimumWithList(): String? {
|
||||
val strings = listOf("Berlin", "Kolkata", "Prague", "Barcelona")
|
||||
return strings.minWith(compareBy { it.length % 4 })
|
||||
}
|
||||
|
||||
fun sumByList(): Int {
|
||||
return numbers.sumBy { it * 5 }
|
||||
}
|
||||
|
||||
fun sumByDoubleList(): Double {
|
||||
return numbers.sumByDouble { it.toDouble() / 8 }
|
||||
}
|
||||
|
||||
fun foldList(): Int {
|
||||
return numbers.fold(100) { total, it ->
|
||||
println("total = $total, it = $it")
|
||||
total - it
|
||||
} // ((((100 - 1)-15)-3)-8) = 73
|
||||
}
|
||||
|
||||
fun foldRightList(): Int {
|
||||
return numbers.foldRight(100) { it, total ->
|
||||
println("total = $total, it = $it")
|
||||
total - it
|
||||
} // ((((100-8)-3)-15)-1) = 73
|
||||
}
|
||||
|
||||
fun foldIndexedList(): Int {
|
||||
return numbers.foldIndexed(100) { index, total, it ->
|
||||
println("total = $total, it = $it, index = $index")
|
||||
if (index.minus(2) >= 0) total - it else total
|
||||
} // ((100 - 3)-8) = 89
|
||||
}
|
||||
|
||||
fun foldRightIndexedList(): Int {
|
||||
return numbers.foldRightIndexed(100) { index, it, total ->
|
||||
println("total = $total, it = $it, index = $index")
|
||||
if (index.minus(2) >= 0) total - it else total
|
||||
} // ((100 - 8)-3) = 89
|
||||
}
|
||||
|
||||
fun reduceList(): Int {
|
||||
return numbers.reduce { total, it ->
|
||||
println("total = $total, it = $it")
|
||||
total - it
|
||||
} // (((1 - 15)-3)-8) = -25
|
||||
}
|
||||
|
||||
fun reduceRightList(): Int {
|
||||
return numbers.reduceRight() { it, total ->
|
||||
println("total = $total, it = $it")
|
||||
total - it
|
||||
} // ((8-3)-15)-1) = -11
|
||||
}
|
||||
|
||||
fun reduceIndexedList(): Int {
|
||||
return numbers.reduceIndexed { index, total, it ->
|
||||
println("total = $total, it = $it, index = $index")
|
||||
if (index.minus(2) >= 0) total - it else total
|
||||
} // ((1-3)-8) = -10
|
||||
}
|
||||
|
||||
fun reduceRightIndexedList(): Int {
|
||||
return numbers.reduceRightIndexed { index, it, total ->
|
||||
println("total = $total, it = $it, index = $index")
|
||||
if (index.minus(2) >= 0) total - it else total
|
||||
} // ((8-3) = 5
|
||||
}
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
package com.baeldung.aggregate
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class AggregateOperationsUnitTest {
|
||||
|
||||
private val classUnderTest: AggregateOperations = AggregateOperations()
|
||||
|
||||
@Test
|
||||
fun whenCountOfList_thenReturnsValue() {
|
||||
assertEquals(4, classUnderTest.countList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenSumOfList_thenReturnsTotalValue() {
|
||||
assertEquals(27, classUnderTest.sumList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenAverageOfList_thenReturnsValue() {
|
||||
assertEquals(6.75, classUnderTest.averageList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenMaximumOfList_thenReturnsMaximumValue() {
|
||||
assertEquals(15, classUnderTest.maximumInList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenMinimumOfList_thenReturnsMinimumValue() {
|
||||
assertEquals(1, classUnderTest.minimumInList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenMaxByList_thenReturnsLargestValue() {
|
||||
assertEquals(3, classUnderTest.maximumByList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenMinByList_thenReturnsSmallestValue() {
|
||||
assertEquals(15, classUnderTest.minimumByList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenMaxWithList_thenReturnsLargestValue(){
|
||||
assertEquals("Kolkata", classUnderTest.maximumWithList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenMinWithList_thenReturnsSmallestValue(){
|
||||
assertEquals("Barcelona", classUnderTest.minimumWithList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenSumByList_thenReturnsIntegerValue(){
|
||||
assertEquals(135, classUnderTest.sumByList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenSumByDoubleList_thenReturnsDoubleValue(){
|
||||
assertEquals(3.375, classUnderTest.sumByDoubleList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenFoldList_thenReturnsValue(){
|
||||
assertEquals(73, classUnderTest.foldList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenFoldRightList_thenReturnsValue(){
|
||||
assertEquals(73, classUnderTest.foldRightList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenFoldIndexedList_thenReturnsValue(){
|
||||
assertEquals(89, classUnderTest.foldIndexedList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenFoldRightIndexedList_thenReturnsValue(){
|
||||
assertEquals(89, classUnderTest.foldRightIndexedList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenReduceList_thenReturnsValue(){
|
||||
assertEquals(-25, classUnderTest.reduceList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenReduceRightList_thenReturnsValue(){
|
||||
assertEquals(-11, classUnderTest.reduceRightList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenReduceIndexedList_thenReturnsValue(){
|
||||
assertEquals(-10, classUnderTest.reduceIndexedList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenReduceRightIndexedList_thenReturnsValue(){
|
||||
assertEquals(5, classUnderTest.reduceRightIndexedList())
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
## Core Kotlin Collections
|
||||
|
||||
This module contains articles about core Kotlin collections.
|
||||
|
||||
### Relevant articles:
|
||||
|
||||
- [Split a List Into Parts in Kotlin](https://www.baeldung.com/kotlin-split-list-into-parts)
|
||||
- [Finding an Element in a List Using Kotlin](https://www.baeldung.com/kotlin-finding-element-in-list)
|
||||
- [Overview of Kotlin Collections API](https://www.baeldung.com/kotlin-collections-api)
|
||||
- [Converting a List to Map in Kotlin](https://www.baeldung.com/kotlin-list-to-map)
|
||||
- [Filtering Kotlin Collections](https://www.baeldung.com/kotlin-filter-collection)
|
||||
- [Collection Transformations in Kotlin](https://www.baeldung.com/kotlin-collection-transformations)
|
||||
- [Difference between fold and reduce in Kotlin](https://www.baeldung.com/kotlin/fold-vs-reduce)
|
||||
- [Guide to Sorting in Kotlin](https://www.baeldung.com/kotlin-sort)
|
||||
- [Working With Lists in Kotlin](https://www.baeldung.com/kotlin/lists)
|
||||
- [Iterating Collections by Index in Kotlin](https://www.baeldung.com/kotlin/iterating-collections-by-index)
|
|
@ -1,47 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-kotlin-collections</artifactId>
|
||||
<name>core-kotlin-collections</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-kotlin-modules</groupId>
|
||||
<artifactId>core-kotlin-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-math3</artifactId>
|
||||
<version>${commons-math3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-test</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<kotlin.version>1.3.30</kotlin.version>
|
||||
<commons-math3.version>3.6.1</commons-math3.version>
|
||||
<assertj.version>3.10.0</assertj.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -1,33 +0,0 @@
|
|||
package com.baeldung.index
|
||||
|
||||
fun main() {
|
||||
|
||||
// Index only
|
||||
val colors = listOf("Red", "Green", "Blue")
|
||||
for (i in colors.indices) {
|
||||
println(colors[i])
|
||||
}
|
||||
|
||||
val colorArray = arrayOf("Red", "Green", "Blue")
|
||||
for (i in colorArray.indices) {
|
||||
println(colorArray[i])
|
||||
}
|
||||
|
||||
(0 until colors.size).forEach { println(colors[it]) }
|
||||
for (i in 0 until colors.size) {
|
||||
println(colors[i])
|
||||
}
|
||||
|
||||
// Index and Value
|
||||
colors.forEachIndexed { i, v -> println("The value for index $i is $v") }
|
||||
for (indexedValue in colors.withIndex()) {
|
||||
println("The value for index ${indexedValue.index} is ${indexedValue.value}")
|
||||
}
|
||||
|
||||
for ((i, v) in colors.withIndex()) {
|
||||
println("The value for index $i is $v")
|
||||
}
|
||||
|
||||
colors.filterIndexed { i, _ -> i % 2 == 0 }
|
||||
colors.filterIndexed { _, v -> v == "RED" }
|
||||
}
|
|
@ -1,204 +0,0 @@
|
|||
package com.baeldung.kotlin.collections
|
||||
|
||||
import kotlin.collections.List
|
||||
|
||||
class ListExample {
|
||||
|
||||
private val countries = listOf("Germany", "India", "Japan", "Brazil", "Australia")
|
||||
private val cities = mutableListOf("Berlin", "Calcutta", "Seoul", "Sao Paulo", "Sydney")
|
||||
|
||||
fun createList(): List<String> {
|
||||
val countryList = listOf("Germany", "India", "Japan", "Brazil")
|
||||
return countryList
|
||||
}
|
||||
|
||||
fun createMutableList(): MutableList<String> {
|
||||
val cityList = mutableListOf("Berlin", "Calcutta", "Seoul", "Sao Paulo")
|
||||
return cityList
|
||||
}
|
||||
|
||||
fun iterateUsingForEachLoop(): List<Int> {
|
||||
val countryLength = mutableListOf<Int>()
|
||||
countries.forEach { it ->
|
||||
print("$it ")
|
||||
println(" Length: ${it.length}")
|
||||
countryLength.add(it.length)
|
||||
}
|
||||
return countryLength
|
||||
}
|
||||
|
||||
fun iterateUsingForLoop(): List<Int> {
|
||||
val countryLength = mutableListOf<Int>()
|
||||
for (country in countries) {
|
||||
print("$country ")
|
||||
println(" Length: ${country.length}")
|
||||
countryLength.add(country.length)
|
||||
}
|
||||
return countryLength
|
||||
}
|
||||
|
||||
fun iterateUsingForLoopRange(): List<Int> {
|
||||
val countryLength = mutableListOf<Int>()
|
||||
for (i in 0 until countries.size) {
|
||||
print("${countries[i]} ")
|
||||
println(" Length: ${countries[i].length}")
|
||||
countryLength.add(countries[i].length)
|
||||
}
|
||||
return countryLength
|
||||
}
|
||||
|
||||
fun iterateUsingForEachIndexedLoop(): List<Int> {
|
||||
val countryLength = mutableListOf<Int>()
|
||||
countries.forEachIndexed { i, e ->
|
||||
println("country[$i] = $e")
|
||||
print(" Index: $i")
|
||||
println(" Length: ${e.length}")
|
||||
countryLength.add(e.length)
|
||||
}
|
||||
return countryLength
|
||||
}
|
||||
|
||||
fun iterateUsingListIterator() {
|
||||
val iterator = countries.listIterator()
|
||||
while (iterator.hasNext()) {
|
||||
val country = iterator.next()
|
||||
print("$country ")
|
||||
}
|
||||
println()
|
||||
|
||||
while (iterator.hasPrevious()) {
|
||||
println("Index: ${iterator.previousIndex()}")
|
||||
}
|
||||
}
|
||||
|
||||
fun iterateUsingIterator() {
|
||||
val iterator = cities.iterator()
|
||||
iterator.next()
|
||||
iterator.remove()
|
||||
println(cities)
|
||||
}
|
||||
|
||||
fun iterateUsingMutableListIterator() {
|
||||
val iterator = cities.listIterator(1)
|
||||
iterator.next()
|
||||
iterator.add("London")
|
||||
iterator.next()
|
||||
iterator.set("Milan")
|
||||
println(cities)
|
||||
}
|
||||
|
||||
fun retrieveElementsInList(): String {
|
||||
println(countries[2])
|
||||
return countries[2]
|
||||
}
|
||||
|
||||
fun retrieveElementsUsingGet(): String {
|
||||
println(countries.get(3))
|
||||
return countries.get(3)
|
||||
}
|
||||
|
||||
fun retrieveElementsFirstAndLast(): String? {
|
||||
println(countries.first())
|
||||
println(countries.last())
|
||||
println(countries.first { it.length > 7 })
|
||||
println(countries.last { it.startsWith("J") })
|
||||
println(countries.firstOrNull { it.length > 8 })
|
||||
return countries.firstOrNull { it.length > 8 }
|
||||
}
|
||||
|
||||
fun retrieveSubList(): List<String> {
|
||||
val subList = countries.subList(1, 4)
|
||||
println(subList)
|
||||
return subList
|
||||
}
|
||||
|
||||
fun retrieveListSliceUsingIndices(): List<String> {
|
||||
val sliceList = countries.slice(1..4)
|
||||
println(sliceList)
|
||||
return sliceList
|
||||
}
|
||||
|
||||
fun retrieveListSliceUsingIndicesList(): List<String> {
|
||||
val sliceList = countries.slice(listOf(1, 4))
|
||||
println(sliceList)
|
||||
return sliceList
|
||||
}
|
||||
|
||||
fun countList(): Int {
|
||||
val count = countries.count()
|
||||
println(count)
|
||||
return count
|
||||
}
|
||||
|
||||
fun countListUsingPredicate(): Int {
|
||||
val count = countries.count { it.length > 5 }
|
||||
println(count)
|
||||
return count
|
||||
}
|
||||
|
||||
fun countListUsingProperty(): Int {
|
||||
val size = countries.size
|
||||
println(size)
|
||||
return size
|
||||
}
|
||||
|
||||
fun addToList(): List<String> {
|
||||
cities.add("Barcelona")
|
||||
println(cities)
|
||||
cities.add(3, "London")
|
||||
println(cities)
|
||||
cities.addAll(listOf("Singapore", "Moscow"))
|
||||
println(cities)
|
||||
cities.addAll(2, listOf("Prague", "Amsterdam"))
|
||||
println(cities)
|
||||
return cities
|
||||
}
|
||||
|
||||
fun removeFromList(): List<String> {
|
||||
cities.remove("Seoul")
|
||||
println(cities)
|
||||
cities.removeAt(1)
|
||||
println(cities)
|
||||
return cities
|
||||
}
|
||||
|
||||
fun replaceFromList(): List<String> {
|
||||
cities.set(3, "Prague")
|
||||
println(cities)
|
||||
cities[4] = "Moscow"
|
||||
println(cities)
|
||||
cities.fill("Barcelona")
|
||||
println(cities)
|
||||
return cities
|
||||
}
|
||||
|
||||
fun sortMutableList(): List<String> {
|
||||
cities.sort()
|
||||
println(cities)
|
||||
cities.sortDescending()
|
||||
println(cities)
|
||||
return cities
|
||||
}
|
||||
|
||||
fun sortList(): List<String> {
|
||||
val sortedCountries = countries.sorted()
|
||||
println("countries = $countries")
|
||||
println("sortedCountries = $sortedCountries")
|
||||
val sortedCountriesDescending = countries.sortedDescending()
|
||||
println("countries = $countries")
|
||||
println("sortedCountriesDescending = $sortedCountriesDescending")
|
||||
return sortedCountriesDescending
|
||||
}
|
||||
|
||||
fun checkOneElementInList(): Boolean {
|
||||
return countries.contains("Germany")
|
||||
}
|
||||
|
||||
fun checkOneElementInListUsingOperator(): Boolean {
|
||||
return "Spain" in countries
|
||||
}
|
||||
|
||||
fun checkElementsInList(): Boolean {
|
||||
return cities.containsAll(listOf("Calcutta", "Sao Paulo", "Sydney"))
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package com.baeldung.sorting
|
||||
|
||||
fun sortMethodUsage() {
|
||||
val sortedValues = mutableListOf(1, 2, 7, 6, 5, 6)
|
||||
sortedValues.sort()
|
||||
println(sortedValues)
|
||||
}
|
||||
|
||||
fun sortByMethodUsage() {
|
||||
val sortedValues = mutableListOf(1 to "a", 2 to "b", 7 to "c", 6 to "d", 5 to "c", 6 to "e")
|
||||
sortedValues.sortBy { it.second }
|
||||
println(sortedValues)
|
||||
}
|
||||
|
||||
fun sortWithMethodUsage() {
|
||||
val sortedValues = mutableListOf(1 to "a", 2 to "b", 7 to "c", 6 to "d", 5 to "c", 6 to "e")
|
||||
sortedValues.sortWith(compareBy({it.second}, {it.first}))
|
||||
println(sortedValues)
|
||||
}
|
||||
|
||||
fun <T : kotlin.Comparable<T>> getSimpleComparator() : Comparator<T> {
|
||||
val ascComparator = naturalOrder<T>()
|
||||
return ascComparator
|
||||
}
|
||||
|
||||
fun getComplexComparator() {
|
||||
val complexComparator = compareBy<Pair<Int, String>>({it.first}, {it.second})
|
||||
}
|
||||
|
||||
fun nullHandlingUsage() {
|
||||
val sortedValues = mutableListOf(1 to "a", 2 to null, 7 to "c", 6 to "d", 5 to "c", 6 to "e")
|
||||
sortedValues.sortWith(nullsLast(compareBy { it.second }))
|
||||
println(sortedValues)
|
||||
}
|
||||
|
||||
fun extendedComparatorUsage() {
|
||||
val students = mutableListOf(21 to "Helen", 21 to "Tom", 20 to "Jim")
|
||||
|
||||
val ageComparator = compareBy<Pair<Int, String?>> {it.first}
|
||||
val ageAndNameComparator = ageComparator.thenByDescending {it.second}
|
||||
println(students.sortedWith(ageAndNameComparator))
|
||||
}
|
|
@ -1,212 +0,0 @@
|
|||
package com.baeldung.collections
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class CollectionsTest {
|
||||
|
||||
@Test
|
||||
fun whenUseDifferentCollections_thenSuccess() {
|
||||
val theList = listOf("one", "two", "three")
|
||||
assertTrue(theList.contains("two"))
|
||||
|
||||
val theMutableList = mutableListOf("one", "two", "three")
|
||||
theMutableList.add("four")
|
||||
assertTrue(theMutableList.contains("four"))
|
||||
|
||||
val theSet = setOf("one", "two", "three")
|
||||
assertTrue(theSet.contains("three"))
|
||||
|
||||
val theMutableSet = mutableSetOf("one", "two", "three")
|
||||
theMutableSet.add("four")
|
||||
assertTrue(theMutableSet.contains("four"))
|
||||
|
||||
val theMap = mapOf(1 to "one", 2 to "two", 3 to "three")
|
||||
assertEquals(theMap[2], "two")
|
||||
|
||||
val theMutableMap = mutableMapOf(1 to "one", 2 to "two", 3 to "three")
|
||||
theMutableMap[4] = "four"
|
||||
assertEquals(theMutableMap[4], "four")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenSliceCollection_thenSuccess() {
|
||||
val theList = listOf("one", "two", "three")
|
||||
val resultList = theList.slice(1..2)
|
||||
|
||||
assertEquals(2, resultList.size)
|
||||
assertTrue(resultList.contains("two"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenJoinTwoCollections_thenSuccess() {
|
||||
val firstList = listOf("one", "two", "three")
|
||||
val secondList = listOf("four", "five", "six")
|
||||
val resultList = firstList + secondList
|
||||
|
||||
assertEquals(6, resultList.size)
|
||||
assertTrue(resultList.contains("two"))
|
||||
assertTrue(resultList.contains("five"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenFilterNullValues_thenSuccess() {
|
||||
val theList = listOf("one", null, "two", null, "three")
|
||||
val resultList = theList.filterNotNull()
|
||||
|
||||
assertEquals(3, resultList.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenFilterNonPositiveValues_thenSuccess() {
|
||||
val theList = listOf(1, 2, -3, -4, 5, -6)
|
||||
val resultList = theList.filter { it > 0 }
|
||||
//val resultList = theList.filter{ x -> x > 0}
|
||||
|
||||
assertEquals(3, resultList.size)
|
||||
assertTrue(resultList.contains(1))
|
||||
assertFalse(resultList.contains(-4))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenDropFirstItems_thenRemoved() {
|
||||
val theList = listOf("one", "two", "three", "four")
|
||||
val resultList = theList.drop(2)
|
||||
|
||||
assertEquals(2, resultList.size)
|
||||
assertFalse(resultList.contains("one"))
|
||||
assertFalse(resultList.contains("two"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenDropFirstItemsBasedOnCondition_thenRemoved() {
|
||||
val theList = listOf("one", "two", "three", "four")
|
||||
val resultList = theList.dropWhile { it.length < 4 }
|
||||
|
||||
assertEquals(2, resultList.size)
|
||||
assertFalse(resultList.contains("one"))
|
||||
assertFalse(resultList.contains("two"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenExcludeItems_thenRemoved() {
|
||||
val firstList = listOf("one", "two", "three")
|
||||
val secondList = listOf("one", "three")
|
||||
val resultList = firstList - secondList
|
||||
|
||||
assertEquals(1, resultList.size)
|
||||
assertTrue(resultList.contains("two"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenSearchForExistingItem_thenFound() {
|
||||
val theList = listOf("one", "two", "three")
|
||||
|
||||
assertTrue("two" in theList)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenGroupItems_thenSuccess() {
|
||||
val theList = listOf(1, 2, 3, 4, 5, 6)
|
||||
val resultMap = theList.groupBy { it % 3 }
|
||||
|
||||
assertEquals(3, resultMap.size)
|
||||
print(resultMap[1])
|
||||
assertTrue(resultMap[1]!!.contains(1))
|
||||
assertTrue(resultMap[2]!!.contains(5))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenApplyFunctionToAllItems_thenSuccess() {
|
||||
val theList = listOf(1, 2, 3, 4, 5, 6)
|
||||
val resultList = theList.map { it * it }
|
||||
print(resultList)
|
||||
assertEquals(4, resultList[1])
|
||||
assertEquals(9, resultList[2])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenApplyMultiOutputFunctionToAllItems_thenSuccess() {
|
||||
val theList = listOf("John", "Tom")
|
||||
val resultList = theList.flatMap { it.toLowerCase().toList() }
|
||||
print(resultList)
|
||||
assertEquals(7, resultList.size)
|
||||
assertTrue(resultList.contains('j'))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenApplyFunctionToAllItemsWithStartingValue_thenSuccess() {
|
||||
val theList = listOf(1, 2, 3, 4, 5, 6)
|
||||
val finalResult = theList.fold(1000, { oldResult, currentItem -> oldResult + (currentItem * currentItem) })
|
||||
print(finalResult)
|
||||
assertEquals(1091, finalResult)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenApplyingChunked_thenShouldBreakTheCollection() {
|
||||
val theList = listOf(1, 2, 3, 4, 5)
|
||||
val chunked = theList.chunked(2)
|
||||
|
||||
assertThat(chunked.size).isEqualTo(3)
|
||||
assertThat(chunked.first()).contains(1, 2)
|
||||
assertThat(chunked[1]).contains(3, 4)
|
||||
assertThat(chunked.last()).contains(5)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenApplyingChunkedWithTransformation_thenShouldBreakTheCollection() {
|
||||
val theList = listOf(1, 2, 3, 4, 5)
|
||||
val chunked = theList.chunked(3) { it.joinToString(", ") }
|
||||
|
||||
assertThat(chunked.size).isEqualTo(2)
|
||||
assertThat(chunked.first()).isEqualTo("1, 2, 3")
|
||||
assertThat(chunked.last()).isEqualTo("4, 5")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenApplyingWindowed_thenShouldCreateSlidingWindowsOfElements() {
|
||||
val theList = (1..6).toList()
|
||||
val windowed = theList.windowed(3)
|
||||
|
||||
assertThat(windowed.size).isEqualTo(4)
|
||||
assertThat(windowed.first()).contains(1, 2, 3)
|
||||
assertThat(windowed[1]).contains(2, 3, 4)
|
||||
assertThat(windowed[2]).contains(3, 4, 5)
|
||||
assertThat(windowed.last()).contains(4, 5, 6)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenApplyingWindowedWithTwoSteps_thenShouldCreateSlidingWindowsOfElements() {
|
||||
val theList = (1..6).toList()
|
||||
val windowed = theList.windowed(size = 3, step = 2)
|
||||
|
||||
assertThat(windowed.size).isEqualTo(2)
|
||||
assertThat(windowed.first()).contains(1, 2, 3)
|
||||
assertThat(windowed.last()).contains(3, 4, 5)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenApplyingPartialWindowedWithTwoSteps_thenShouldCreateSlidingWindowsOfElements() {
|
||||
val theList = (1..6).toList()
|
||||
val windowed = theList.windowed(size = 3, step = 2, partialWindows = true)
|
||||
|
||||
assertThat(windowed.size).isEqualTo(3)
|
||||
assertThat(windowed.first()).contains(1, 2, 3)
|
||||
assertThat(windowed[1]).contains(3, 4, 5)
|
||||
assertThat(windowed.last()).contains(5, 6)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenApplyingTransformingWindows_thenShouldCreateSlidingWindowsOfElements() {
|
||||
val theList = (1..6).toList()
|
||||
val windowed = theList.windowed(size = 3, step = 2, partialWindows = true) { it.joinToString(", ") }
|
||||
|
||||
assertThat(windowed.size).isEqualTo(3)
|
||||
assertThat(windowed.first()).isEqualTo("1, 2, 3")
|
||||
assertThat(windowed[1]).isEqualTo("3, 4, 5")
|
||||
assertThat(windowed.last()).isEqualTo("5, 6")
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
package com.baeldung.collections.transformations
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class AssociateUnitTest {
|
||||
@Test
|
||||
fun testToMap() {
|
||||
val input = listOf(Pair("one", 1), Pair("two", 2))
|
||||
val map = input.toMap()
|
||||
assertEquals(mapOf("one" to 1, "two" to 2), map)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAssociateWith() {
|
||||
val inputs = listOf("Hi", "there")
|
||||
val map = inputs.associateWith { k -> k.length }
|
||||
assertEquals(mapOf("Hi" to 2, "there" to 5), map)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAssociateBy() {
|
||||
val inputs = listOf("Hi", "there")
|
||||
val map = inputs.associateBy { v -> v.length }
|
||||
assertEquals(mapOf(2 to "Hi", 5 to "there"), map)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAssociate() {
|
||||
val inputs = listOf("Hi", "there")
|
||||
val map = inputs.associate { e -> Pair(e.toUpperCase(), e.reversed()) }
|
||||
assertEquals(mapOf("HI" to "iH", "THERE" to "ereht"), map)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAssociateByDuplicateKeys() {
|
||||
val inputs = listOf("one", "two")
|
||||
val map = inputs.associateBy { v -> v.length }
|
||||
assertEquals(mapOf(3 to "two"), map)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGroupBy() {
|
||||
val inputs = listOf("one", "two", "three")
|
||||
val map = inputs.groupBy { v -> v.length }
|
||||
assertEquals(mapOf(3 to listOf("one", "two"), 5 to listOf("three")), map)
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
package com.baeldung.collections.transformations
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class FilterUnitTest {
|
||||
@Test
|
||||
fun testFilterWithLambda() {
|
||||
val input = listOf(1, 2, 3, 4, 5)
|
||||
val filtered = input.filter { it <= 3 }
|
||||
assertEquals(listOf(1, 2, 3), filtered)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFilterWithMethodReference() {
|
||||
val input = listOf(1, 2, 3, 4, 5)
|
||||
val filtered = input.filter(this::isSmall)
|
||||
assertEquals(listOf(1, 2, 3), filtered)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFilterNotWithMethodReference() {
|
||||
val input = listOf(1, 2, 3, 4, 5)
|
||||
val filtered = input.filterNot(this::isSmall)
|
||||
assertEquals(listOf(4, 5), filtered)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFilterIndexed() {
|
||||
val input = listOf(5, 4, 3, 2, 1)
|
||||
val filtered = input.filterIndexed { index, element -> index < 3 }
|
||||
assertEquals(listOf(5, 4, 3), filtered)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFilterNotNull() {
|
||||
val nullable: List<String?> = listOf("Hello", null, "World")
|
||||
val nonnull: List<String> = nullable.filterNotNull()
|
||||
assertEquals(listOf("Hello", "World"), nonnull)
|
||||
}
|
||||
|
||||
private fun isSmall(i: Int) = i <= 3
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package com.baeldung.collections.transformations
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class FlattenUnitTest {
|
||||
@Test
|
||||
fun testFlatten() {
|
||||
val inputs = listOf("one", "two", "three")
|
||||
val characters = inputs.map(String::toList)
|
||||
val flattened = characters.flatten();
|
||||
assertEquals(listOf('o', 'n', 'e', 't', 'w', 'o', 't', 'h', 'r', 'e', 'e'), flattened)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFlatMap() {
|
||||
val inputs = listOf("one", "two", "three")
|
||||
val characters = inputs.flatMap(String::toList)
|
||||
assertEquals(listOf('o', 'n', 'e', 't', 'w', 'o', 't', 'h', 'r', 'e', 'e'), characters)
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
package com.baeldung.collections.transformations
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class JoinToUnitTest {
|
||||
@Test
|
||||
fun testJoinToString() {
|
||||
val inputs = listOf("Jan", "Feb", "Mar", "Apr", "May")
|
||||
|
||||
val simpleString = inputs.joinToString()
|
||||
assertEquals("Jan, Feb, Mar, Apr, May", simpleString)
|
||||
|
||||
val detailedString = inputs.joinToString(separator = ",", prefix="Months: ", postfix=".")
|
||||
assertEquals("Months: Jan,Feb,Mar,Apr,May.", detailedString)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testJoinToStringLimits() {
|
||||
val inputs = listOf("Jan", "Feb", "Mar", "Apr", "May")
|
||||
|
||||
val simpleString = inputs.joinToString(limit = 3)
|
||||
assertEquals("Jan, Feb, Mar, ...", simpleString)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testJoinToStringTransform() {
|
||||
val inputs = listOf("Jan", "Feb", "Mar", "Apr", "May")
|
||||
|
||||
val simpleString = inputs.joinToString(transform = String::toUpperCase)
|
||||
assertEquals("JAN, FEB, MAR, APR, MAY", simpleString)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testJoinTo() {
|
||||
val inputs = listOf("Jan", "Feb", "Mar", "Apr", "May")
|
||||
|
||||
val output = StringBuilder()
|
||||
output.append("My ")
|
||||
.append(inputs.size)
|
||||
.append(" elements: ")
|
||||
inputs.joinTo(output)
|
||||
|
||||
assertEquals("My 5 elements: Jan, Feb, Mar, Apr, May", output.toString())
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
package com.baeldung.collections.transformations
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class MapUnitTest {
|
||||
@Test
|
||||
fun testMapWithLambda() {
|
||||
val input = listOf("one", "two", "three")
|
||||
|
||||
val reversed = input.map { it.reversed() }
|
||||
assertEquals(listOf("eno", "owt", "eerht"), reversed)
|
||||
|
||||
val lengths = input.map { it.length }
|
||||
assertEquals(listOf(3, 3, 5), lengths)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMapIndexed() {
|
||||
val input = listOf(3, 2, 1)
|
||||
val result = input.mapIndexed { index, value -> index * value }
|
||||
assertEquals(listOf(0, 2, 2), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMapNotNull() {
|
||||
val input = listOf(1, 2, 3, 4, 5)
|
||||
val smallSquares = input.mapNotNull {
|
||||
if (it <= 3) {
|
||||
it * it
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
assertEquals(listOf(1, 4, 9), smallSquares)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mapMapKeys() {
|
||||
val inputs = mapOf("one" to 1, "two" to 2, "three" to 3)
|
||||
|
||||
val uppercases = inputs.mapKeys { it.key.toUpperCase() }
|
||||
assertEquals(mapOf("ONE" to 1, "TWO" to 2, "THREE" to 3), uppercases)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mapMapValues() {
|
||||
val inputs = mapOf("one" to 1, "two" to 2, "three" to 3)
|
||||
|
||||
val squares = inputs.mapValues { it.value * it.value }
|
||||
assertEquals(mapOf("one" to 1, "two" to 4, "three" to 9), squares)
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package com.baeldung.collections.transformations
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class ReduceUnitTest {
|
||||
@Test
|
||||
fun testJoinToStringAsReduce() {
|
||||
val inputs = listOf("Jan", "Feb", "Mar", "Apr", "May")
|
||||
|
||||
val result = inputs.reduce { acc, next -> "$acc, $next" }
|
||||
assertEquals("Jan, Feb, Mar, Apr, May", result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFoldToLength() {
|
||||
val inputs = listOf("Jan", "Feb", "Mar", "Apr", "May")
|
||||
|
||||
val result = inputs.fold(0) { acc, next -> acc + next.length }
|
||||
assertEquals(15, result)
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
package com.baeldung.collections.transformations
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class ZipUnitTest {
|
||||
@Test
|
||||
fun testZip() {
|
||||
val left = listOf("one", "two", "three")
|
||||
val right = listOf(1, 2, 3)
|
||||
val zipped = left.zip(right)
|
||||
assertEquals (listOf(Pair("one", 1), Pair("two", 2), Pair("three", 3)), zipped)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testZipShort() {
|
||||
val left = listOf("one", "two")
|
||||
val right = listOf(1, 2, 3)
|
||||
val zipped = left.zip(right)
|
||||
assertEquals (listOf(Pair("one", 1), Pair("two", 2)), zipped)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testUnzip() {
|
||||
val left = listOf("one", "two", "three")
|
||||
val right = listOf(1, 2, 3)
|
||||
val zipped = left.zip(right)
|
||||
|
||||
val (newLeft, newRight) = zipped.unzip()
|
||||
assertEquals(left, newLeft)
|
||||
assertEquals(right, newRight)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
package com.baeldung.filter
|
||||
|
||||
import org.junit.jupiter.api.Assertions.assertIterableEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
internal class ChunkedTest {
|
||||
|
||||
@Test
|
||||
fun givenDNAFragmentString_whenChunking_thenProduceListOfChunks() {
|
||||
val dnaFragment = "ATTCGCGGCCGCCAA"
|
||||
|
||||
val fragments = dnaFragment.chunked(3)
|
||||
|
||||
assertIterableEquals(listOf("ATT", "CGC", "GGC", "CGC", "CAA"), fragments)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenDNAString_whenChunkingWithTransformer_thenProduceTransformedList() {
|
||||
val codonTable = mapOf("ATT" to "Isoleucine", "CAA" to "Glutamine", "CGC" to "Arginine", "GGC" to "Glycine")
|
||||
val dnaFragment = "ATTCGCGGCCGCCAA"
|
||||
|
||||
val proteins = dnaFragment.chunked(3) { codon ->
|
||||
codonTable[codon.toString()] ?: error("Unknown codon")
|
||||
}
|
||||
|
||||
assertIterableEquals(listOf("Isoleucine", "Arginine", "Glycine", "Arginine", "Glutamine"), proteins)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenListOfValues_whenChunking_thenProduceListOfArrays() {
|
||||
val whole = listOf(1, 4, 7, 4753, 2, 34, 62, 76, 5868, 0)
|
||||
val chunks = whole.chunked(6)
|
||||
|
||||
val expected = listOf(listOf(1, 4, 7, 4753, 2, 34), listOf(62, 76, 5868, 0))
|
||||
|
||||
assertIterableEquals(expected, chunks)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
package com.baeldung.filter
|
||||
|
||||
import org.junit.jupiter.api.Assertions.assertIterableEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
internal class DistinctTest {
|
||||
data class SmallClass(val key: String, val num: Int)
|
||||
|
||||
@Test
|
||||
fun whenApplyingDistinct_thenReturnListOfNoDuplicateValues() {
|
||||
val array = arrayOf(1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 5, 6, 7, 8, 9)
|
||||
val result = array.distinct()
|
||||
val expected = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9)
|
||||
|
||||
assertIterableEquals(expected, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenArrayOfClassObjects_whenApplyingDistinctOnClassProperty_thenReturnListDistinctOnThatValue() {
|
||||
|
||||
val original = arrayOf(
|
||||
SmallClass("key1", 1),
|
||||
SmallClass("key2", 2),
|
||||
SmallClass("key3", 3),
|
||||
SmallClass("key4", 3),
|
||||
SmallClass("er", 9),
|
||||
SmallClass("er", 10),
|
||||
SmallClass("er", 11))
|
||||
|
||||
val actual = original.distinctBy { it.key }
|
||||
|
||||
val expected = listOf(
|
||||
SmallClass("key1", 1),
|
||||
SmallClass("key2", 2),
|
||||
SmallClass("key3", 3),
|
||||
SmallClass("key4", 3),
|
||||
SmallClass("er", 9))
|
||||
|
||||
|
||||
assertIterableEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenArrayOfClassObjects_whenApplyingComplicatedSelector_thenReturnFirstElementToMatchEachSelectorValue() {
|
||||
val array = arrayOf(
|
||||
SmallClass("key1", 1),
|
||||
SmallClass("key2", 2),
|
||||
SmallClass("key3", 3),
|
||||
SmallClass("key4", 3),
|
||||
SmallClass("er", 9),
|
||||
SmallClass("er", 10),
|
||||
SmallClass("er", 11),
|
||||
SmallClass("er", 11),
|
||||
SmallClass("er", 91),
|
||||
SmallClass("blob", 22),
|
||||
SmallClass("dob", 27),
|
||||
SmallClass("high", 201_434_314))
|
||||
|
||||
val actual = array.distinctBy { Math.floor(it.num / 10.0) }
|
||||
|
||||
val expected = listOf(
|
||||
SmallClass("key1", 1),
|
||||
SmallClass("er", 10),
|
||||
SmallClass("er", 91),
|
||||
SmallClass("blob", 22),
|
||||
SmallClass("high", 201_434_314))
|
||||
|
||||
assertIterableEquals(expected, actual)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
package com.baeldung.filter
|
||||
|
||||
import org.junit.jupiter.api.Assertions.assertIterableEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
internal class DropTest {
|
||||
|
||||
@Test
|
||||
fun whenDroppingFirstTwoItemsOfArray_thenTwoLess() {
|
||||
val array = arrayOf(1, 2, 3, 4)
|
||||
val result = array.drop(2)
|
||||
val expected = listOf(3, 4)
|
||||
|
||||
assertIterableEquals(expected, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenDroppingMoreItemsOfArray_thenEmptyList() {
|
||||
val array = arrayOf(1, 2, 3, 4)
|
||||
val result = array.drop(5)
|
||||
val expected = listOf<Int>()
|
||||
|
||||
assertIterableEquals(expected, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenArray_whenDroppingLastElement_thenReturnListWithoutLastElement() {
|
||||
val array = arrayOf("1", "2", "3", "4")
|
||||
val result = array.dropLast(1)
|
||||
val expected = listOf("1", "2", "3")
|
||||
|
||||
assertIterableEquals(expected, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenArrayOfFloats_whenDroppingLastUntilPredicateIsFalse_thenReturnSubsetListOfFloats() {
|
||||
val array = arrayOf(1f, 1f, 1f, 1f, 1f, 2f, 1f, 1f, 1f)
|
||||
val result = array.dropLastWhile { it == 1f }
|
||||
val expected = listOf(1f, 1f, 1f, 1f, 1f, 2f)
|
||||
|
||||
assertIterableEquals(expected, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenList_whenDroppingMoreThanAvailable_thenThrowException() {
|
||||
val list = listOf('a', 'e', 'i', 'o', 'u')
|
||||
val result = list.drop(6)
|
||||
val expected: List<String> = listOf()
|
||||
|
||||
assertIterableEquals(expected, result)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
package com.baeldung.filter
|
||||
|
||||
import org.apache.commons.math3.primes.Primes
|
||||
import org.junit.jupiter.api.Assertions.assertIterableEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
internal class FilterTest {
|
||||
|
||||
@Test
|
||||
fun givenAscendingValueMap_whenFilteringOnValue_ThenReturnSubsetOfMap() {
|
||||
val originalMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3)
|
||||
val filteredMap = originalMap.filter { it.value < 2 }
|
||||
val expectedMap = mapOf("key1" to 1)
|
||||
|
||||
assertTrue { expectedMap == filteredMap }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenSeveralCollections_whenFilteringToAccumulativeList_thenListContainsAllContents() {
|
||||
val array1 = arrayOf(90, 92, 93, 94, 92, 95, 93)
|
||||
val array2 = sequenceOf(51, 31, 83, 674_506_111, 256_203_161, 15_485_863)
|
||||
val list1 = listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
|
||||
val primes = mutableListOf<Int>()
|
||||
|
||||
val expected = listOf(2, 3, 5, 7, 31, 83, 15_485_863, 256_203_161, 674_506_111)
|
||||
|
||||
val primeCheck = { num: Int -> Primes.isPrime(num) }
|
||||
|
||||
array1.filterTo(primes, primeCheck)
|
||||
list1.filterTo(primes, primeCheck)
|
||||
array2.filterTo(primes, primeCheck)
|
||||
|
||||
primes.sort()
|
||||
|
||||
assertIterableEquals(expected, primes)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
package com.baeldung.filter
|
||||
|
||||
import org.junit.jupiter.api.Assertions.assertIterableEquals
|
||||
import org.junit.jupiter.api.Assertions.assertThrows
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
internal class SliceTest {
|
||||
|
||||
@Test
|
||||
fun whenSlicingAnArrayWithDotRange_ThenListEqualsTheSlice() {
|
||||
val original = arrayOf(1, 2, 3, 2, 1)
|
||||
val actual = original.slice(1..3)
|
||||
val expected = listOf(2, 3, 2)
|
||||
|
||||
assertIterableEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenSlicingAnArrayWithDownToRange_thenListMadeUpOfReverseSlice() {
|
||||
val original = arrayOf(1, 2, 3, 2, 1)
|
||||
val actual = original.slice(3 downTo 0)
|
||||
val expected = listOf(2, 3, 2, 1)
|
||||
|
||||
assertIterableEquals(expected, actual)
|
||||
}
|
||||
|
||||
// From the 1.3 version of Kotlin APIs, slice doesn't return array of nulls but throw IndexOutOfBoundsException
|
||||
// @Test
|
||||
// fun whenSlicingBeyondTheRangeOfTheArray_thenContainManyNulls() {
|
||||
// val original = arrayOf(12, 3, 34, 4)
|
||||
// val actual = original.slice(3..8)
|
||||
// val expected = listOf(4, null, null, null, null, null)
|
||||
//
|
||||
// assertIterableEquals(expected, actual)
|
||||
// }
|
||||
|
||||
@Test
|
||||
fun whenSlicingBeyondRangeOfArrayWithStep_thenOutOfBoundsException() {
|
||||
assertThrows(ArrayIndexOutOfBoundsException::class.java) {
|
||||
val original = arrayOf(12, 3, 34, 4)
|
||||
original.slice(3..8 step 2)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
package com.baeldung.filter
|
||||
|
||||
import org.junit.jupiter.api.Assertions.assertIterableEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
internal class TakeTest {
|
||||
|
||||
@Test
|
||||
fun `given array of alternating types, when predicating on 'is String', then produce list of array up until predicate is false`() {
|
||||
val originalArray = arrayOf("val1", 2, "val3", 4, "val5", 6)
|
||||
val actualList = originalArray.takeWhile { it is String }
|
||||
val expectedList = listOf("val1")
|
||||
|
||||
assertIterableEquals(expectedList, actualList)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given array of alternating types, when taking 4 items, then produce list of first 4 items`() {
|
||||
val originalArray = arrayOf("val1", 2, "val3", 4, "val5", 6)
|
||||
val actualList = originalArray.take(4)
|
||||
val expectedList = listOf("val1", 2, "val3", 4)
|
||||
|
||||
println(originalArray.drop(4))
|
||||
println(actualList)
|
||||
|
||||
assertIterableEquals(expectedList, actualList)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when taking more items than available, then return all elements`() {
|
||||
val originalArray = arrayOf(1, 2)
|
||||
val actual = originalArray.take(10)
|
||||
val expected = listOf(1, 2)
|
||||
|
||||
assertIterableEquals(expected, actual)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
package com.baeldung.findelement
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class FindAnElementInAListUnitTest {
|
||||
|
||||
var batmans: List<String> = listOf("Christian Bale", "Michael Keaton", "Ben Affleck", "George Clooney")
|
||||
|
||||
@Test
|
||||
fun whenFindASpecificItem_thenItemIsReturned() {
|
||||
//Returns the first element matching the given predicate, or null if no such element was found.
|
||||
val theFirstBatman = batmans.find { actor -> "Michael Keaton".equals(actor) }
|
||||
assertEquals(theFirstBatman, "Michael Keaton")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenFilterWithPredicate_thenMatchingItemsAreReturned() {
|
||||
//Returns a list containing only elements matching the given predicate.
|
||||
val theCoolestBatmans = batmans.filter { actor -> actor.contains("a") }
|
||||
assertTrue(theCoolestBatmans.contains("Christian Bale") && theCoolestBatmans.contains("Michael Keaton"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenFilterNotWithPredicate_thenMatchingItemsAreReturned() {
|
||||
//Returns a list containing only elements not matching the given predicate.
|
||||
val theMehBatmans = batmans.filterNot { actor -> actor.contains("a") }
|
||||
assertFalse(theMehBatmans.contains("Christian Bale") && theMehBatmans.contains("Michael Keaton"))
|
||||
assertTrue(theMehBatmans.contains("Ben Affleck") && theMehBatmans.contains("George Clooney"))
|
||||
}
|
||||
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
package com.baeldung.foldvsreduce
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import java.lang.RuntimeException
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class FoldAndReduceTest {
|
||||
|
||||
@Test
|
||||
fun testReduceLimitations() {
|
||||
val numbers: List<Int> = listOf(1, 2, 3)
|
||||
val sum: Number = numbers.reduce { acc, next -> acc + next }
|
||||
assertEquals(6, sum)
|
||||
|
||||
val emptyList = listOf<Int>()
|
||||
assertThrows<RuntimeException> { emptyList.reduce { acc, next -> acc + next } }
|
||||
|
||||
// doesn't compile
|
||||
// val sum = numbers.reduce { acc, next -> acc.toLong() + next.toLong()}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFold() {
|
||||
|
||||
val numbers: List<Int> = listOf(1, 2, 3)
|
||||
val sum: Int = numbers.fold(0, { acc, next -> acc + next })
|
||||
assertEquals(6, sum)
|
||||
|
||||
//change result type
|
||||
val sumLong: Long = numbers.fold(0L, { acc, next -> acc + next.toLong() })
|
||||
assertEquals(6L, sumLong)
|
||||
|
||||
val emptyList = listOf<Int>()
|
||||
val emptySum = emptyList.fold(0, { acc, next -> acc + next })
|
||||
assertEquals(0, emptySum)
|
||||
|
||||
//power of changing result type
|
||||
val (even, odd) = numbers.fold(Pair(listOf<Int>(), listOf<Int>()), { acc, next ->
|
||||
if (next % 2 == 0) Pair(acc.first + next, acc.second)
|
||||
else Pair(acc.first, acc.second + next)
|
||||
})
|
||||
|
||||
assertEquals(listOf(2), even)
|
||||
assertEquals(listOf(1, 3), odd)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testVariationsOfFold() {
|
||||
val numbers = listOf(1, 2, 3)
|
||||
val reversed = numbers.foldRight(listOf<Int>(), { next, acc -> acc + next})
|
||||
assertEquals(listOf(3,2,1), reversed)
|
||||
|
||||
val reversedIndexes = numbers.foldRightIndexed(listOf<Int>(), { i, _, acc -> acc + i })
|
||||
assertEquals(listOf(2,1,0), reversedIndexes)
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
package com.baeldung.kotlin.collections
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class ListExampleUnitTest {
|
||||
|
||||
private val classUnderTest: ListExample = ListExample()
|
||||
|
||||
@Test
|
||||
fun whenListIsCreated_thenContainsElements() {
|
||||
assertTrue(classUnderTest.createList().contains("India"))
|
||||
assertTrue(classUnderTest.createMutableList().contains("Seoul"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenIterateUsingForEachLoop_thenSuccess() {
|
||||
assertEquals(7, classUnderTest.iterateUsingForEachLoop()[0])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenIterateUsingForLoop_thenSuccess() {
|
||||
assertEquals(5, classUnderTest.iterateUsingForLoop()[1])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenIterateUsingForLoopRange_thenSuccess() {
|
||||
assertEquals(6, classUnderTest.iterateUsingForLoopRange()[3])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenIterateUsingForEachIndexedLoop_thenSuccess() {
|
||||
assertEquals(9, classUnderTest.iterateUsingForEachIndexedLoop()[4])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenRetrieveElementsInList_thenSuccess() {
|
||||
assertEquals("Japan", classUnderTest.retrieveElementsInList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenRetrieveElementsUsingGet_thenSuccess() {
|
||||
assertEquals("Brazil", classUnderTest.retrieveElementsUsingGet())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenRetrieveElementsFirstAndLast_thenSuccess() {
|
||||
assertEquals("Australia", classUnderTest.retrieveElementsFirstAndLast())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenRetrieveSubList_thenSuccess() {
|
||||
assertEquals(3, classUnderTest.retrieveSubList().size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenRetrieveListSliceUsingIndices_thenSuccess() {
|
||||
assertEquals(4, classUnderTest.retrieveListSliceUsingIndices().size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenRetrieveListSliceUsingIndicesList_thenSuccess() {
|
||||
assertEquals(2, classUnderTest.retrieveListSliceUsingIndicesList().size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenCountList_thenSuccess() {
|
||||
assertEquals(5, classUnderTest.countList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenCountListUsingPredicate_thenSuccess() {
|
||||
assertEquals(3, classUnderTest.countListUsingPredicate())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenCountListUsingProperty_thenSuccess() {
|
||||
assertEquals(5, classUnderTest.countListUsingProperty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenAddToList_thenSuccess() {
|
||||
assertEquals(11, classUnderTest.addToList().count())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenRemoveFromList_thenSuccess() {
|
||||
val list = classUnderTest.removeFromList()
|
||||
assertEquals(3, list.size)
|
||||
assertEquals("Sao Paulo", list[1])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenReplaceFromList_thenSuccess() {
|
||||
val list = classUnderTest.replaceFromList()
|
||||
assertEquals(5, list.size)
|
||||
assertEquals("Barcelona", list[1])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenSortMutableList_thenSuccess() {
|
||||
assertEquals("Sydney", classUnderTest.sortMutableList()[0])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenSortList_thenSuccess() {
|
||||
assertEquals("India", classUnderTest.sortList()[1])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenCheckOneElementInList_thenSuccess() {
|
||||
assertTrue(classUnderTest.checkOneElementInList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenCheckOneElementInListUsingOperator_thenSuccess() {
|
||||
assertFalse(classUnderTest.checkOneElementInListUsingOperator())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenCheckElementsInList_thenSuccess() {
|
||||
assertTrue(classUnderTest.checkElementsInList())
|
||||
}
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
package com.baeldung.listtomap
|
||||
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class ListToMapTest {
|
||||
|
||||
val user1 = User("John", 18, listOf("Hiking, Swimming"))
|
||||
val user2 = User("Sara", 25, listOf("Chess, Board Games"))
|
||||
val user3 = User("Dave", 34, listOf("Games, Racing sports"))
|
||||
val user4 = User("John", 30, listOf("Reading, Poker"))
|
||||
|
||||
@Test
|
||||
fun givenList_whenConvertToMap_thenResult() {
|
||||
val myList = listOf(user1, user2, user3)
|
||||
val myMap = myList.map { it.name to it.age }.toMap()
|
||||
|
||||
assertTrue(myMap.get("John") == 18)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenList_whenAssociatedBy_thenResult() {
|
||||
val myList = listOf(user1, user2, user3)
|
||||
val myMap = myList.associateBy({ it.name }, { it.hobbies })
|
||||
|
||||
assertTrue(myMap.get("John")!!.contains("Hiking, Swimming"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenStringList_whenConvertToMap_thenResult() {
|
||||
val myList = listOf("a", "b", "c")
|
||||
val myMap = myList.map { it to it }.toMap()
|
||||
|
||||
assertTrue(myMap.get("a") == "a")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenStringList_whenAssociate_thenResult() {
|
||||
val myList = listOf("a", "b", "c", "c", "b")
|
||||
val myMap = myList.associate{ it to it }
|
||||
|
||||
assertTrue(myMap.get("a") == "a")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenStringList_whenAssociateTo_thenResult() {
|
||||
val myList = listOf("a", "b", "c", "c", "b")
|
||||
val myMap = mutableMapOf<String, String>()
|
||||
|
||||
myList.associateTo(myMap) {it to it}
|
||||
|
||||
assertTrue(myMap.get("a") == "a")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenStringList_whenAssociateByTo_thenResult() {
|
||||
val myList = listOf(user1, user2, user3, user4)
|
||||
val myMap = mutableMapOf<String, Int>()
|
||||
|
||||
myList.associateByTo(myMap, {it.name}, {it.age})
|
||||
|
||||
assertTrue(myMap.get("Dave") == 34)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenStringList_whenAssociateByToUser_thenResult() {
|
||||
val myList = listOf(user1, user2, user3, user4)
|
||||
val myMap = mutableMapOf<String, User>()
|
||||
|
||||
myList.associateByTo(myMap) {it.name}
|
||||
|
||||
assertTrue(myMap.get("Dave")!!.age == 34)
|
||||
}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
package com.baeldung.listtomap
|
||||
|
||||
data class User(val name: String, val age: Int, val hobbies: List<String>)
|
|
@ -1,13 +0,0 @@
|
|||
package com.baeldung.sorting
|
||||
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class SortingExampleKtTest {
|
||||
|
||||
@Test
|
||||
fun naturalOrderComparator_ShouldBeAscendingTest() {
|
||||
val resultingList = listOf(1, 5, 6, 6, 2, 3, 4).sortedWith(getSimpleComparator())
|
||||
assertTrue(listOf(1, 2, 3, 4, 5, 6, 6) == resultingList)
|
||||
}
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
package com.baeldung.splitlist
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class SplitListIntoPartsTest {
|
||||
private val evenList = listOf(0, "a", 1, "b", 2, "c");
|
||||
|
||||
private val unevenList = listOf(0, "a", 1, "b", 2, "c", 3);
|
||||
|
||||
private fun verifyList(resultList: List<List<Any>>) {
|
||||
assertEquals("[[0, a], [1, b], [2, c]]", resultList.toString())
|
||||
}
|
||||
|
||||
private fun verifyPartialList(resultList: List<List<Any>>) {
|
||||
assertEquals("[[0, a], [1, b], [2, c], [3]]", resultList.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenChunked_thenListIsSplit() {
|
||||
val resultList = evenList.chunked(2)
|
||||
verifyList(resultList)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenUnevenChunked_thenListIsSplit() {
|
||||
val resultList = unevenList.chunked(2)
|
||||
verifyPartialList(resultList)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenWindowed_thenListIsSplit() {
|
||||
val resultList = evenList.windowed(2, 2)
|
||||
verifyList(resultList)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenUnevenPartialWindowed_thenListIsSplit() {
|
||||
val resultList = unevenList.windowed(2, 2, partialWindows = true)
|
||||
verifyPartialList(resultList)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenUnevenWindowed_thenListIsSplit() {
|
||||
val resultList = unevenList.windowed(2, 2, partialWindows = false)
|
||||
verifyList(resultList)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenGroupByWithAscendingNumbers_thenListIsSplit() {
|
||||
val numberList = listOf(1, 2, 3, 4, 5, 6);
|
||||
val resultList = numberList.groupBy { (it + 1) / 2 }
|
||||
assertEquals("[[1, 2], [3, 4], [5, 6]]", resultList.values.toString())
|
||||
assertEquals("[1, 2, 3]", resultList.keys.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenGroupByWithAscendingNumbersUneven_thenListIsSplit() {
|
||||
val numberList = listOf(1, 2, 3, 4, 5, 6, 7);
|
||||
val resultList = numberList.groupBy { (it + 1) / 2 }.values
|
||||
assertEquals("[[1, 2], [3, 4], [5, 6], [7]]", resultList.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenGroupByWithRandomNumbers_thenListIsSplitInWrongWay() {
|
||||
val numberList = listOf(1, 3, 8, 20, 23, 30);
|
||||
val resultList = numberList.groupBy { (it + 1) / 2 }
|
||||
assertEquals("[[1], [3], [8], [20], [23], [30]]", resultList.values.toString())
|
||||
assertEquals("[1, 2, 4, 10, 12, 15]", resultList.keys.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenWithIndexGroupBy_thenListIsSplit() {
|
||||
val resultList = evenList.withIndex()
|
||||
.groupBy { it.index / 2 }
|
||||
.map { it.value.map { it.value } }
|
||||
verifyList(resultList)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenWithIndexGroupByUneven_thenListIsSplit() {
|
||||
val resultList = unevenList.withIndex()
|
||||
.groupBy { it.index / 2 }
|
||||
.map { it.value.map { it.value } }
|
||||
verifyPartialList(resultList)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenFoldIndexed_thenListIsSplit() {
|
||||
val resultList = evenList.foldIndexed(ArrayList<ArrayList<Any>>(evenList.size / 2)) { index, acc, item ->
|
||||
if (index % 2 == 0) {
|
||||
acc.add(ArrayList(2))
|
||||
}
|
||||
acc.last().add(item)
|
||||
acc
|
||||
}
|
||||
verifyList(resultList)
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
## Core Kotlin Concurrency
|
||||
|
||||
This module contains articles about concurrency in Kotlin.
|
||||
|
||||
### Relevant articles:
|
||||
- [Threads vs Coroutines in Kotlin](https://www.baeldung.com/kotlin-threads-coroutines)
|
||||
- [Introduction to Kotlin Coroutines](https://www.baeldung.com/kotlin-coroutines)
|
||||
- [Introduction to Channels in Kotlin](https://www.baeldung.com/kotlin/channels)
|
|
@ -1,41 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-kotlin-concurrency</artifactId>
|
||||
<name>core-kotlin-concurrency</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-kotlin-modules</groupId>
|
||||
<artifactId>core-kotlin-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-test</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<kotlin.version>1.3.30</kotlin.version>
|
||||
<assertj.version>3.10.0</assertj.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -1,29 +0,0 @@
|
|||
package com.baeldung.channels
|
||||
|
||||
import kotlinx.coroutines.cancelChildren
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
fun main() = runBlocking {
|
||||
val basket = Channel<String>(1)
|
||||
|
||||
launch { // coroutine1
|
||||
val fruits = listOf("Apple", "Orange", "Banana")
|
||||
for (fruit in fruits) {
|
||||
println("coroutine1: Sending $fruit")
|
||||
basket.send(fruit)
|
||||
}
|
||||
}
|
||||
|
||||
launch { // coroutine2
|
||||
repeat(3) {
|
||||
delay(100)
|
||||
println("coroutine2: Received ${basket.receive()}")
|
||||
}
|
||||
}
|
||||
|
||||
delay(2000)
|
||||
coroutineContext.cancelChildren()
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package com.baeldung.channels
|
||||
|
||||
import kotlinx.coroutines.cancelChildren
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.channels.Channel.Factory.CONFLATED
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
fun main() = runBlocking {
|
||||
val basket = Channel<String>(CONFLATED)
|
||||
|
||||
launch { // coroutine1
|
||||
val fruits = listOf("Apple", "Orange", "Banana")
|
||||
for (fruit in fruits) {
|
||||
println("coroutine1: Sending $fruit")
|
||||
basket.send(fruit)
|
||||
}
|
||||
}
|
||||
|
||||
launch { // coroutine2
|
||||
println("coroutine2: Received ${basket.receive()}")
|
||||
}
|
||||
|
||||
delay(2000)
|
||||
coroutineContext.cancelChildren()
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
package com.baeldung.channels
|
||||
|
||||
import com.baeldung.channels.OrderStatus.*
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.ReceiveChannel
|
||||
import kotlinx.coroutines.channels.produce
|
||||
|
||||
enum class OrderStatus { ORDERED, BAKED, TOPPED, SERVED }
|
||||
|
||||
data class PizzaOrder(val orderNumber: Int, val orderStatus: OrderStatus = ORDERED)
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
fun CoroutineScope.baking(orders: ReceiveChannel<PizzaOrder>) = produce {
|
||||
for (order in orders) {
|
||||
delay(200)
|
||||
println("Baking ${order.orderNumber}")
|
||||
send(order.copy(orderStatus = BAKED))
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
fun CoroutineScope.topping(orders: ReceiveChannel<PizzaOrder>) = produce {
|
||||
for (order in orders) {
|
||||
delay(50)
|
||||
println("Topping ${order.orderNumber}")
|
||||
send(order.copy(orderStatus = TOPPED))
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
fun CoroutineScope.produceOrders(count: Int) = produce {
|
||||
repeat(count) {
|
||||
delay(50)
|
||||
send(PizzaOrder(orderNumber = it + 1))
|
||||
}
|
||||
}
|
||||
|
||||
@ObsoleteCoroutinesApi
|
||||
@ExperimentalCoroutinesApi
|
||||
fun main() = runBlocking {
|
||||
val orders = produceOrders(3)
|
||||
|
||||
val readyOrders = topping(baking(orders))
|
||||
|
||||
for (order in readyOrders) {
|
||||
println("Serving ${order.orderNumber}")
|
||||
}
|
||||
|
||||
delay(3000)
|
||||
println("End!")
|
||||
coroutineContext.cancelChildren()
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package com.baeldung.channels
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.channels.ReceiveChannel
|
||||
import kotlinx.coroutines.channels.produce
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
fun CoroutineScope.produceFruits(): ReceiveChannel<String> = produce {
|
||||
val fruits = listOf("Apple", "Orange", "Apple")
|
||||
for (fruit in fruits) send(fruit)
|
||||
}
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
fun main() = runBlocking {
|
||||
val fruitChannel = produceFruits()
|
||||
for (fruit in fruitChannel) {
|
||||
println(fruit)
|
||||
}
|
||||
println("End!")
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package com.baeldung.channels
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
|
||||
fun main() = runBlocking {
|
||||
val basket = Channel<String>()
|
||||
|
||||
launch { // coroutine1
|
||||
val fruits = listOf("Apple", "Orange", "Banana")
|
||||
for (fruit in fruits) {
|
||||
println("coroutine1: Sending $fruit")
|
||||
basket.send(fruit)
|
||||
}
|
||||
}
|
||||
|
||||
launch { // coroutine2
|
||||
repeat(3) {
|
||||
delay(100)
|
||||
println("coroutine2: Received ${basket.receive()}")
|
||||
}
|
||||
}
|
||||
|
||||
delay(2000)
|
||||
coroutineContext.cancelChildren()
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package com.baeldung.channels
|
||||
|
||||
import kotlinx.coroutines.cancelChildren
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.channels.SendChannel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
suspend fun fetchYoutubeVideos(channel: SendChannel<String>) {
|
||||
val videos = listOf("cat video", "food video")
|
||||
for (video in videos) {
|
||||
delay(100)
|
||||
channel.send(video)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun fetchTweets(channel: SendChannel<String>) {
|
||||
val tweets = listOf("tweet: Earth is round", "tweet: Coroutines and channels are cool")
|
||||
for (tweet in tweets) {
|
||||
delay(100)
|
||||
channel.send(tweet)
|
||||
}
|
||||
}
|
||||
|
||||
fun main() = runBlocking {
|
||||
val aggregate = Channel<String>()
|
||||
launch { fetchYoutubeVideos(aggregate) }
|
||||
launch { fetchTweets(aggregate) }
|
||||
|
||||
repeat(4) {
|
||||
println(aggregate.receive())
|
||||
}
|
||||
|
||||
coroutineContext.cancelChildren()
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package com.baeldung.channels
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.ReceiveChannel
|
||||
import kotlinx.coroutines.channels.produce
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
fun CoroutineScope.producePizzaOrders(): ReceiveChannel<String> = produce {
|
||||
var x = 1
|
||||
while (true) {
|
||||
send("Pizza Order No. ${x++}")
|
||||
delay(100)
|
||||
}
|
||||
}
|
||||
|
||||
fun CoroutineScope.pizzaOrderProcessor(id: Int, orders: ReceiveChannel<String>) = launch {
|
||||
for (order in orders) {
|
||||
println("Processor #$id is processing $order")
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
fun main() = runBlocking {
|
||||
val pizzaOrders = producePizzaOrders()
|
||||
repeat(3) {
|
||||
pizzaOrderProcessor(it + 1, pizzaOrders)
|
||||
}
|
||||
|
||||
delay(1000)
|
||||
pizzaOrders.cancel()
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package com.baeldung.channels
|
||||
|
||||
import kotlinx.coroutines.channels.ticker
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import java.time.Duration
|
||||
import kotlin.random.Random
|
||||
|
||||
fun stockPrice(stock: String): Double {
|
||||
log("Fetching stock price of $stock")
|
||||
return Random.nextDouble(2.0, 3.0)
|
||||
}
|
||||
|
||||
fun main() = runBlocking {
|
||||
val tickerChannel = ticker(Duration.ofSeconds(5).toMillis())
|
||||
|
||||
repeat(3) {
|
||||
tickerChannel.receive()
|
||||
log(stockPrice("TESLA"))
|
||||
}
|
||||
|
||||
delay(Duration.ofSeconds(11).toMillis())
|
||||
tickerChannel.cancel()
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package com.baeldung.channels
|
||||
|
||||
import kotlinx.coroutines.cancelChildren
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
fun main() = runBlocking {
|
||||
val channel = Channel<Int>(UNLIMITED)
|
||||
|
||||
launch { // coroutine1
|
||||
repeat(100) {
|
||||
println("coroutine1: Sending $it")
|
||||
channel.send(it)
|
||||
}
|
||||
}
|
||||
|
||||
launch { // coroutine2
|
||||
repeat(100) {
|
||||
println("coroutine2: Received ${channel.receive()}")
|
||||
}
|
||||
}
|
||||
|
||||
delay(2000)
|
||||
coroutineContext.cancelChildren()
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package com.baeldung.channels
|
||||
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
fun log(value: Any) {
|
||||
println(SimpleDateFormat("HH:MM:ss").format(Date()) + " - $value")
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package com.baeldung.threadsvscoroutines
|
||||
|
||||
class SimpleRunnable: Runnable {
|
||||
|
||||
override fun run() {
|
||||
println("${Thread.currentThread()} has run.")
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package com.baeldung.threadsvscoroutines
|
||||
|
||||
class SimpleThread: Thread() {
|
||||
|
||||
override fun run() {
|
||||
println("${Thread.currentThread()} has run.")
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package com.baeldung.channels
|
||||
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class ChannelsTest {
|
||||
@Test
|
||||
fun should_pass_data_from_one_coroutine_to_another() {
|
||||
runBlocking {
|
||||
// given
|
||||
val channel = Channel<String>()
|
||||
|
||||
// when
|
||||
launch { // coroutine1
|
||||
channel.send("Hello World!")
|
||||
}
|
||||
val result = async { // coroutine 2
|
||||
channel.receive()
|
||||
}
|
||||
|
||||
// then
|
||||
assertThat(result.await()).isEqualTo("Hello World!")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,178 +0,0 @@
|
|||
package com.baeldung.coroutines
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
import org.junit.Test
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import kotlin.system.measureTimeMillis
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
|
||||
class CoroutinesTest {
|
||||
|
||||
@Test
|
||||
fun givenBuildSequence_whenTakeNElements_thenShouldReturnItInALazyWay() {
|
||||
//given
|
||||
val fibonacciSeq = sequence {
|
||||
var a = 0
|
||||
var b = 1
|
||||
|
||||
yield(1)
|
||||
|
||||
while (true) {
|
||||
yield(a + b)
|
||||
|
||||
val tmp = a + b
|
||||
a = b
|
||||
b = tmp
|
||||
}
|
||||
}
|
||||
|
||||
//when
|
||||
val res = fibonacciSeq.take(5).toList()
|
||||
|
||||
//then
|
||||
assertEquals(res, listOf(1, 1, 2, 3, 5))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenLazySeq_whenTakeNElements_thenShouldReturnAllElements() {
|
||||
//given
|
||||
val lazySeq = sequence {
|
||||
print("START ")
|
||||
for (i in 1..5) {
|
||||
yield(i)
|
||||
print("STEP ")
|
||||
}
|
||||
print("END")
|
||||
}
|
||||
//when
|
||||
val res = lazySeq.take(10).toList()
|
||||
|
||||
//then
|
||||
assertEquals(res, listOf(1, 2, 3, 4, 5))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenAsyncCoroutine_whenStartIt_thenShouldExecuteItInTheAsyncWay() {
|
||||
//given
|
||||
val res = mutableListOf<String>()
|
||||
|
||||
//when
|
||||
runBlocking {
|
||||
val promise = launch(Dispatchers.Default) { expensiveComputation(res) }
|
||||
res.add("Hello,")
|
||||
promise.join()
|
||||
}
|
||||
|
||||
//then
|
||||
assertEquals(res, listOf("Hello,", "word!"))
|
||||
}
|
||||
|
||||
|
||||
suspend fun expensiveComputation(res: MutableList<String>) {
|
||||
delay(1000L)
|
||||
res.add("word!")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenHugeAmountOfCoroutines_whenStartIt_thenShouldExecuteItWithoutOutOfMemory() {
|
||||
runBlocking<Unit> {
|
||||
//given
|
||||
val counter = AtomicInteger(0)
|
||||
val numberOfCoroutines = 100_000
|
||||
|
||||
//when
|
||||
val jobs = List(numberOfCoroutines) {
|
||||
launch(Dispatchers.Default) {
|
||||
delay(1L)
|
||||
counter.incrementAndGet()
|
||||
}
|
||||
}
|
||||
jobs.forEach { it.join() }
|
||||
|
||||
//then
|
||||
assertEquals(counter.get(), numberOfCoroutines)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenCancellableJob_whenRequestForCancel_thenShouldQuit() {
|
||||
runBlocking<Unit> {
|
||||
//given
|
||||
val job = launch(Dispatchers.Default) {
|
||||
while (isActive) {
|
||||
//println("is working")
|
||||
}
|
||||
}
|
||||
|
||||
delay(1300L)
|
||||
|
||||
//when
|
||||
job.cancel()
|
||||
|
||||
//then cancel successfully
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = CancellationException::class)
|
||||
fun givenAsyncAction_whenDeclareTimeout_thenShouldFinishWhenTimedOut() {
|
||||
runBlocking<Unit> {
|
||||
withTimeout(1300L) {
|
||||
repeat(1000) { i ->
|
||||
println("Some expensive computation $i ...")
|
||||
delay(500L)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenHaveTwoExpensiveAction_whenExecuteThemAsync_thenTheyShouldRunConcurrently() {
|
||||
runBlocking<Unit> {
|
||||
val delay = 1000L
|
||||
val time = measureTimeMillis {
|
||||
//given
|
||||
val one = async(Dispatchers.Default) { someExpensiveComputation(delay) }
|
||||
val two = async(Dispatchers.Default) { someExpensiveComputation(delay) }
|
||||
|
||||
//when
|
||||
runBlocking {
|
||||
one.await()
|
||||
two.await()
|
||||
}
|
||||
}
|
||||
|
||||
//then
|
||||
assertTrue(time < delay * 2)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenTwoExpensiveAction_whenExecuteThemLazy_thenTheyShouldNotConcurrently() {
|
||||
runBlocking<Unit> {
|
||||
val delay = 1000L
|
||||
val time = measureTimeMillis {
|
||||
//given
|
||||
val one = async(Dispatchers.Default, CoroutineStart.LAZY) { someExpensiveComputation(delay) }
|
||||
val two = async(Dispatchers.Default, CoroutineStart.LAZY) { someExpensiveComputation(delay) }
|
||||
|
||||
//when
|
||||
runBlocking {
|
||||
one.await()
|
||||
two.await()
|
||||
}
|
||||
}
|
||||
|
||||
//then
|
||||
assertTrue(time > delay * 2)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun someExpensiveComputation(delayInMilliseconds: Long) {
|
||||
delay(delayInMilliseconds)
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
package com.baeldung.threadsvscoroutines
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class CoroutineUnitTest {
|
||||
|
||||
@Test
|
||||
fun whenCreateCoroutineWithLaunchWithoutContext_thenRun() = runBlocking {
|
||||
|
||||
val job = launch {
|
||||
println("${Thread.currentThread()} has run.")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenCreateCoroutineWithLaunchWithDefaultContext_thenRun() = runBlocking {
|
||||
|
||||
val job = launch(Dispatchers.Default) {
|
||||
println("${Thread.currentThread()} has run.")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenCreateCoroutineWithLaunchWithUnconfinedContext_thenRun() = runBlocking {
|
||||
|
||||
val job = launch(Dispatchers.Unconfined) {
|
||||
println("${Thread.currentThread()} has run.")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenCreateCoroutineWithLaunchWithDedicatedThread_thenRun() = runBlocking {
|
||||
|
||||
val job = launch(newSingleThreadContext("dedicatedThread")) {
|
||||
println("${Thread.currentThread()} has run.")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenCreateAsyncCoroutine_thenRun() = runBlocking {
|
||||
|
||||
val deferred = async(Dispatchers.IO) {
|
||||
return@async "${Thread.currentThread()} has run."
|
||||
}
|
||||
|
||||
val result = deferred.await()
|
||||
println(result)
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
package com.baeldung.threadsvscoroutines
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
class ThreadUnitTest {
|
||||
|
||||
@Test
|
||||
fun whenCreateThread_thenRun() {
|
||||
|
||||
val thread = SimpleThread()
|
||||
thread.start()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenCreateThreadWithRunnable_thenRun() {
|
||||
|
||||
val threadWithRunnable = Thread(SimpleRunnable())
|
||||
threadWithRunnable.start()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenCreateThreadWithSAMConversions_thenRun() {
|
||||
|
||||
val thread = Thread {
|
||||
println("${Thread.currentThread()} has run.")
|
||||
}
|
||||
thread.start()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenCreateThreadWithMethodExtension_thenRun() {
|
||||
|
||||
thread(start = true) {
|
||||
println("${Thread.currentThread()} has run.")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
## Core Kotlin
|
||||
|
||||
This module contains articles about data structures in Kotlin
|
||||
|
||||
### Relevant articles:
|
||||
[Implementing a Binary Tree in Kotlin](https://www.baeldung.com/kotlin-binary-tree)
|
|
@ -1,29 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-kotlin-datastructures</artifactId>
|
||||
<name>core-kotlin-datastructures</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-kotlin-modules</groupId>
|
||||
<artifactId>core-kotlin-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-runner</artifactId>
|
||||
<version>${junit.platform.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<junit.platform.version>1.1.1</junit.platform.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -1,19 +0,0 @@
|
|||
package com.baeldung.binarytree
|
||||
|
||||
/**
|
||||
* Example of how to use the {@link Node} class.
|
||||
*
|
||||
*/
|
||||
fun main(args: Array<String>) {
|
||||
val tree = Node(4)
|
||||
val keys = arrayOf(8, 15, 21, 3, 7, 2, 5, 10, 2, 3, 4, 6, 11)
|
||||
for (key in keys) {
|
||||
tree.insert(key)
|
||||
}
|
||||
val node = tree.find(4)!!
|
||||
println("Node with value ${node.key} [left = ${node.left?.key}, right = ${node.right?.key}]")
|
||||
println("Delete node with key = 3")
|
||||
node.delete(3)
|
||||
print("Tree content after the node elimination: ")
|
||||
println(tree.visit().joinToString { it.toString() })
|
||||
}
|
|
@ -1,167 +0,0 @@
|
|||
package com.baeldung.binarytree
|
||||
|
||||
/**
|
||||
* An ADT for a binary search tree.
|
||||
* Note that this data type is neither immutable nor thread safe.
|
||||
*/
|
||||
class Node(
|
||||
var key: Int,
|
||||
var left: Node? = null,
|
||||
var right: Node? = null) {
|
||||
|
||||
/**
|
||||
* Return a node with given value. If no such node exists, return null.
|
||||
* @param value
|
||||
*/
|
||||
fun find(value: Int): Node? = when {
|
||||
this.key > value -> left?.find(value)
|
||||
this.key < value -> right?.find(value)
|
||||
else -> this
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a given value into the tree.
|
||||
* After insertion, the tree should contain a node with the given value.
|
||||
* If the tree already contains the given value, nothing is performed.
|
||||
* @param value
|
||||
*/
|
||||
fun insert(value: Int) {
|
||||
if (value > this.key) {
|
||||
if (this.right == null) {
|
||||
this.right = Node(value)
|
||||
} else {
|
||||
this.right?.insert(value)
|
||||
}
|
||||
} else if (value < this.key) {
|
||||
if (this.left == null) {
|
||||
this.left = Node(value)
|
||||
} else {
|
||||
this.left?.insert(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the value from the given tree. If the tree does not contain the value, the tree remains unchanged.
|
||||
* @param value
|
||||
*/
|
||||
fun delete(value: Int) {
|
||||
when {
|
||||
value > key -> scan(value, this.right, this)
|
||||
value < key -> scan(value, this.left, this)
|
||||
else -> removeNode(this, null)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan the tree in the search of the given value.
|
||||
* @param value
|
||||
* @param node sub-tree that potentially might contain the sought value
|
||||
* @param parent node's parent
|
||||
*/
|
||||
private fun scan(value: Int, node: Node?, parent: Node?) {
|
||||
if (node == null) {
|
||||
System.out.println("value " + value
|
||||
+ " seems not present in the tree.")
|
||||
return
|
||||
}
|
||||
when {
|
||||
value > node.key -> scan(value, node.right, node)
|
||||
value < node.key -> scan(value, node.left, node)
|
||||
value == node.key -> removeNode(node, parent)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the node.
|
||||
*
|
||||
* Removal process depends on how many children the node has.
|
||||
*
|
||||
* @param node node that is to be removed
|
||||
* @param parent parent of the node to be removed
|
||||
*/
|
||||
private fun removeNode(node: Node, parent: Node?) {
|
||||
node.left?.let { leftChild ->
|
||||
run {
|
||||
node.right?.let {
|
||||
removeTwoChildNode(node)
|
||||
} ?: removeSingleChildNode(node, leftChild)
|
||||
}
|
||||
} ?: run {
|
||||
node.right?.let { rightChild -> removeSingleChildNode(node, rightChild) } ?: removeNoChildNode(node, parent)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the node without children.
|
||||
* @param node
|
||||
* @param parent
|
||||
*/
|
||||
private fun removeNoChildNode(node: Node, parent: Node?) {
|
||||
parent?.let { p ->
|
||||
if (node == p.left) {
|
||||
p.left = null
|
||||
} else if (node == p.right) {
|
||||
p.right = null
|
||||
}
|
||||
} ?: throw IllegalStateException(
|
||||
"Can not remove the root node without child nodes")
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a node that has two children.
|
||||
*
|
||||
* The process of elimination is to find the biggest key in the left sub-tree and replace the key of the
|
||||
* node that is to be deleted with that key.
|
||||
*/
|
||||
private fun removeTwoChildNode(node: Node) {
|
||||
val leftChild = node.left!!
|
||||
leftChild.right?.let {
|
||||
val maxParent = findParentOfMaxChild(leftChild)
|
||||
maxParent.right?.let {
|
||||
node.key = it.key
|
||||
maxParent.right = null
|
||||
} ?: throw IllegalStateException("Node with max child must have the right child!")
|
||||
|
||||
} ?: run {
|
||||
node.key = leftChild.key
|
||||
node.left = leftChild.left
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a node whose right child contains the biggest value in the given sub-tree.
|
||||
* Assume that the node n has a non-null right child.
|
||||
*
|
||||
* @param n
|
||||
*/
|
||||
private fun findParentOfMaxChild(n: Node): Node {
|
||||
return n.right?.let { r -> r.right?.let { findParentOfMaxChild(r) } ?: n }
|
||||
?: throw IllegalArgumentException("Right child must be non-null")
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a parent that has only one child.
|
||||
* Removal is effectively is just coping the data from the child parent to the parent parent.
|
||||
* @param parent Node to be deleted. Assume that it has just one child
|
||||
* @param child Assume it is a child of the parent
|
||||
*/
|
||||
private fun removeSingleChildNode(parent: Node, child: Node) {
|
||||
parent.key = child.key
|
||||
parent.left = child.left
|
||||
parent.right = child.right
|
||||
}
|
||||
|
||||
fun visit(): Array<Int> {
|
||||
val a = left?.visit() ?: emptyArray()
|
||||
val b = right?.visit() ?: emptyArray()
|
||||
return a + arrayOf(key) + b
|
||||
}
|
||||
}
|
|
@ -1,320 +0,0 @@
|
|||
package com.binarytree
|
||||
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
class NodeTest {
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test suit for finding the node by value
|
||||
* Partition the tests as follows:
|
||||
* 1. tree depth: 0, 1, > 1
|
||||
* 2. pivot depth location: not present, 0, 1, 2, > 2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Find the node by value
|
||||
* 1. tree depth: 0
|
||||
* 2. pivot depth location: not present
|
||||
*/
|
||||
@Test
|
||||
fun givenDepthZero_whenPivotNotPresent_thenNull() {
|
||||
val n = Node(1)
|
||||
assertNull(n.find(2))
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the node by value
|
||||
* 1. tree depth: 0
|
||||
* 2. pivot depth location: 0
|
||||
*/
|
||||
@Test
|
||||
fun givenDepthZero_whenPivotDepthZero_thenReturnNodeItself() {
|
||||
val n = Node(1)
|
||||
assertEquals(n, n.find(1))
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the node by value
|
||||
* 1. tree depth: 1
|
||||
* 2. pivot depth location: not present
|
||||
*/
|
||||
@Test
|
||||
fun givenDepthOne_whenPivotNotPresent_thenNull() {
|
||||
val n = Node(1, Node(0))
|
||||
assertNull(n.find(2))
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the node by value
|
||||
* 1. tree depth: 1
|
||||
* 2. pivot depth location: not present
|
||||
*/
|
||||
@Test
|
||||
fun givenDepthOne_whenPivotAtDepthOne_thenSuccess() {
|
||||
val n = Node(1, Node(0))
|
||||
assertEquals(n.left, n.find(0)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenDepthTwo_whenPivotAtDepth2_then_Success() {
|
||||
val left = Node(1, Node(0), Node(2))
|
||||
val right = Node(5, Node(4), Node(6))
|
||||
val n = Node(3, left, right)
|
||||
assertEquals(left.left, n.find(0))
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test suit for inserting a value
|
||||
* Partition the test as follows:
|
||||
* 1. tree depth: 0, 1, 2, > 2
|
||||
* 2. depth to insert: 0, 1, > 1
|
||||
* 3. is duplicate: no, yes
|
||||
* 4. sub-tree: left, right
|
||||
*/
|
||||
/**
|
||||
* Test for inserting a value
|
||||
* 1. tree depth: 0
|
||||
* 2. depth to insert: 1
|
||||
* 3. is duplicate: no
|
||||
* 4. sub-tree: right
|
||||
*/
|
||||
@Test
|
||||
fun givenTreeDepthZero_whenInsertNoDuplicateToRight_thenAddNode() {
|
||||
val n = Node(1)
|
||||
n.insert(2)
|
||||
assertEquals(1, n.key)
|
||||
with(n.right!!) {
|
||||
assertEquals(2, key)
|
||||
assertNull(left)
|
||||
assertNull(right)
|
||||
}
|
||||
assertNull(n.left)
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for inserting a value
|
||||
* 1. tree depth: 0
|
||||
* 2. depth to insert: 1
|
||||
* 3. is duplicate: no
|
||||
* 4. sub-tree: right
|
||||
*/
|
||||
@Test
|
||||
fun givenTreeDepthZero_whenInsertNoDuplicateToLeft_thenSuccess() {
|
||||
val n = Node(1)
|
||||
n.insert(0)
|
||||
assertEquals(1, n.key)
|
||||
with(n.left!!) {
|
||||
assertEquals(0, key)
|
||||
assertNull(left)
|
||||
assertNull(right)
|
||||
}
|
||||
assertNull(n.right)
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for inserting a value
|
||||
* 1. tree depth: 0
|
||||
* 2. depth to insert: 1
|
||||
* 3. is duplicate: yes
|
||||
*/
|
||||
@Test
|
||||
fun givenTreeDepthZero_whenInsertDuplicate_thenSuccess() {
|
||||
val n = Node(1)
|
||||
n.insert(1)
|
||||
assertEquals(1, n.key)
|
||||
assertNull(n.right)
|
||||
assertNull(n.left)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test suit for inserting a value
|
||||
* Partition the test as follows:
|
||||
* 1. tree depth: 0, 1, 2, > 2
|
||||
* 2. depth to insert: 0, 1, > 1
|
||||
* 3. is duplicate: no, yes
|
||||
* 4. sub-tree: left, right
|
||||
*/
|
||||
/**
|
||||
* Test for inserting a value
|
||||
* 1. tree depth: 1
|
||||
* 2. depth to insert: 1
|
||||
* 3. is duplicate: no
|
||||
* 4. sub-tree: right
|
||||
*/
|
||||
@Test
|
||||
fun givenTreeDepthOne_whenInsertNoDuplicateToRight_thenSuccess() {
|
||||
val n = Node(10, Node(3))
|
||||
n.insert(15)
|
||||
assertEquals(10, n.key)
|
||||
with(n.right!!) {
|
||||
assertEquals(15, key)
|
||||
assertNull(left)
|
||||
assertNull(right)
|
||||
}
|
||||
with(n.left!!) {
|
||||
assertEquals(3, key)
|
||||
assertNull(left)
|
||||
assertNull(right)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for inserting a value
|
||||
* 1. tree depth: 1
|
||||
* 2. depth to insert: 1
|
||||
* 3. is duplicate: no
|
||||
* 4. sub-tree: left
|
||||
*/
|
||||
@Test
|
||||
fun givenTreeDepthOne_whenInsertNoDuplicateToLeft_thenAddNode() {
|
||||
val n = Node(10, null, Node(15))
|
||||
n.insert(3)
|
||||
assertEquals(10, n.key)
|
||||
with(n.right!!) {
|
||||
assertEquals(15, key)
|
||||
assertNull(left)
|
||||
assertNull(right)
|
||||
}
|
||||
with(n.left!!) {
|
||||
assertEquals(3, key)
|
||||
assertNull(left)
|
||||
assertNull(right)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for inserting a value
|
||||
* 1. tree depth: 1
|
||||
* 2. depth to insert: 1
|
||||
* 3. is duplicate: yes
|
||||
*/
|
||||
@Test
|
||||
fun givenTreeDepthOne_whenInsertDuplicate_thenNoChange() {
|
||||
val n = Node(10, null, Node(15))
|
||||
n.insert(15)
|
||||
assertEquals(10, n.key)
|
||||
with(n.right!!) {
|
||||
assertEquals(15, key)
|
||||
assertNull(left)
|
||||
assertNull(right)
|
||||
}
|
||||
assertNull(n.left)
|
||||
}
|
||||
|
||||
/**
|
||||
* Test suit for removal
|
||||
* Partition the input as follows:
|
||||
* 1. tree depth: 0, 1, 2, > 2
|
||||
* 2. value to delete: absent, present
|
||||
* 3. # child nodes: 0, 1, 2
|
||||
*/
|
||||
/**
|
||||
* Test for removal value
|
||||
* 1. tree depth: 0
|
||||
* 2. value to delete: absent
|
||||
*/
|
||||
@Test
|
||||
fun givenTreeDepthZero_whenValueAbsent_thenNoChange() {
|
||||
val n = Node(1)
|
||||
n.delete(0)
|
||||
assertEquals(1, n.key)
|
||||
assertNull(n.left)
|
||||
assertNull(n.right)
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for removal
|
||||
* 1. tree depth: 1
|
||||
* 2. value to delete: absent
|
||||
*/
|
||||
@Test
|
||||
fun givenTreeDepthOne_whenValueAbsent_thenNoChange() {
|
||||
val n = Node(1, Node(0), Node(2))
|
||||
n.delete(3)
|
||||
assertEquals(1, n.key)
|
||||
assertEquals(2, n.right!!.key)
|
||||
with(n.left!!) {
|
||||
assertEquals(0, key)
|
||||
assertNull(left)
|
||||
assertNull(right)
|
||||
}
|
||||
with(n.right!!) {
|
||||
assertNull(left)
|
||||
assertNull(right)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test suit for removal
|
||||
* 1. tree depth: 1
|
||||
* 2. value to delete: present
|
||||
* 3. # child nodes: 0
|
||||
*/
|
||||
@Test
|
||||
fun givenTreeDepthOne_whenNodeToDeleteHasNoChildren_thenChangeTree() {
|
||||
val n = Node(1, Node(0))
|
||||
n.delete(0)
|
||||
assertEquals(1, n.key)
|
||||
assertNull(n.left)
|
||||
assertNull(n.right)
|
||||
}
|
||||
|
||||
/**
|
||||
* Test suit for removal
|
||||
* 1. tree depth: 2
|
||||
* 2. value to delete: present
|
||||
* 3. # child nodes: 1
|
||||
*/
|
||||
@Test
|
||||
fun givenTreeDepthTwo_whenNodeToDeleteHasOneChild_thenChangeTree() {
|
||||
val n = Node(2, Node(0, null, Node(1)), Node(3))
|
||||
n.delete(0)
|
||||
assertEquals(2, n.key)
|
||||
with(n.right!!) {
|
||||
assertEquals(3, key)
|
||||
assertNull(left)
|
||||
assertNull(right)
|
||||
}
|
||||
with(n.left!!) {
|
||||
assertEquals(1, key)
|
||||
assertNull(left)
|
||||
assertNull(right)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenTreeDepthThree_whenNodeToDeleteHasTwoChildren_thenChangeTree() {
|
||||
val l = Node(2, Node(1), Node(5, Node(4), Node(6)))
|
||||
val r = Node(10, Node(9), Node(11))
|
||||
val n = Node(8, l, r)
|
||||
n.delete(8)
|
||||
assertEquals(6, n.key)
|
||||
with(n.left!!) {
|
||||
assertEquals(2, key)
|
||||
assertEquals(1, left!!.key)
|
||||
assertEquals(5, right!!.key)
|
||||
assertEquals(4, right!!.left!!.key)
|
||||
}
|
||||
with(n.right!!) {
|
||||
assertEquals(10, key)
|
||||
assertEquals(9, left!!.key)
|
||||
assertEquals(11, right!!.key)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
## Core Kotlin Date and Time
|
||||
|
||||
This module contains articles about Kotlin core date/time features.
|
||||
|
||||
### Relevant articles:
|
||||
[Working with Dates in Kotlin](https://www.baeldung.com/kotlin-dates)
|
|
@ -1,36 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-kotlin-date-time</artifactId>
|
||||
<name>core-kotlin-date-time</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-kotlin-modules</groupId>
|
||||
<artifactId>core-kotlin-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${org.assertj.core.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-runner</artifactId>
|
||||
<version>${junit.platform.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<junit.platform.version>1.1.1</junit.platform.version>
|
||||
<org.assertj.core.version>3.9.0</org.assertj.core.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -1,15 +0,0 @@
|
|||
package com.baeldung.dates.datetime
|
||||
|
||||
import java.time.Duration
|
||||
import java.time.LocalTime
|
||||
|
||||
class UseDuration {
|
||||
|
||||
fun modifyDates(localTime: LocalTime, duration: Duration): LocalTime {
|
||||
return localTime.plus(duration)
|
||||
}
|
||||
|
||||
fun getDifferenceBetweenDates(localTime1: LocalTime, localTime2: LocalTime): Duration {
|
||||
return Duration.between(localTime1, localTime2)
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package com.baeldung.dates.datetime
|
||||
|
||||
import java.time.DayOfWeek
|
||||
import java.time.LocalDate
|
||||
import java.time.LocalDateTime
|
||||
import java.time.temporal.ChronoUnit
|
||||
import java.time.temporal.TemporalAdjusters
|
||||
|
||||
class UseLocalDate {
|
||||
|
||||
fun getLocalDateUsingFactoryOfMethod(year: Int, month: Int, dayOfMonth: Int): LocalDate {
|
||||
return LocalDate.of(year, month, dayOfMonth)
|
||||
}
|
||||
|
||||
fun getLocalDateUsingParseMethod(representation: String): LocalDate {
|
||||
return LocalDate.parse(representation)
|
||||
}
|
||||
|
||||
fun getLocalDateFromClock(): LocalDate {
|
||||
return LocalDate.now()
|
||||
}
|
||||
|
||||
fun getNextDay(localDate: LocalDate): LocalDate {
|
||||
return localDate.plusDays(1)
|
||||
}
|
||||
|
||||
fun getPreviousDay(localDate: LocalDate): LocalDate {
|
||||
return localDate.minus(1, ChronoUnit.DAYS)
|
||||
}
|
||||
|
||||
fun getDayOfWeek(localDate: LocalDate): DayOfWeek {
|
||||
return localDate.dayOfWeek
|
||||
}
|
||||
|
||||
fun getFirstDayOfMonth(): LocalDate {
|
||||
return LocalDate.now().with(TemporalAdjusters.firstDayOfMonth())
|
||||
}
|
||||
|
||||
fun getStartOfDay(localDate: LocalDate): LocalDateTime {
|
||||
return localDate.atStartOfDay()
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package com.baeldung.dates.datetime
|
||||
|
||||
import java.time.LocalDateTime
|
||||
|
||||
class UseLocalDateTime {
|
||||
|
||||
fun getLocalDateTimeUsingParseMethod(representation: String): LocalDateTime {
|
||||
return LocalDateTime.parse(representation)
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package com.baeldung.dates.datetime
|
||||
|
||||
import java.time.LocalTime
|
||||
import java.time.temporal.ChronoUnit
|
||||
|
||||
class UseLocalTime {
|
||||
|
||||
fun getLocalTimeUsingFactoryOfMethod(hour: Int, min: Int, seconds: Int): LocalTime {
|
||||
return LocalTime.of(hour, min, seconds)
|
||||
}
|
||||
|
||||
fun getLocalTimeUsingParseMethod(timeRepresentation: String): LocalTime {
|
||||
return LocalTime.parse(timeRepresentation)
|
||||
}
|
||||
|
||||
fun getLocalTimeFromClock(): LocalTime {
|
||||
return LocalTime.now()
|
||||
}
|
||||
|
||||
fun addAnHour(localTime: LocalTime): LocalTime {
|
||||
return localTime.plus(1, ChronoUnit.HOURS)
|
||||
}
|
||||
|
||||
fun getHourFromLocalTime(localTime: LocalTime): Int {
|
||||
return localTime.hour
|
||||
}
|
||||
|
||||
fun getLocalTimeWithMinuteSetToValue(localTime: LocalTime, minute: Int): LocalTime {
|
||||
return localTime.withMinute(minute)
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
package com.baeldung.dates.datetime
|
||||
|
||||
import java.time.LocalDate
|
||||
import java.time.Period
|
||||
|
||||
class UsePeriod {
|
||||
|
||||
fun modifyDates(localDate: LocalDate, period: Period): LocalDate {
|
||||
return localDate.plus(period)
|
||||
}
|
||||
|
||||
fun getDifferenceBetweenDates(localDate1: LocalDate, localDate2: LocalDate): Period {
|
||||
return Period.between(localDate1, localDate2)
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
package com.baeldung.dates.datetime
|
||||
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
import java.time.ZonedDateTime
|
||||
|
||||
class UseZonedDateTime {
|
||||
|
||||
fun getZonedDateTime(localDateTime: LocalDateTime, zoneId: ZoneId): ZonedDateTime {
|
||||
return ZonedDateTime.of(localDateTime, zoneId)
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
package com.baeldung.kotlin.dates
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.time.LocalDate
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
class CreateDateUnitTest {
|
||||
|
||||
@Test
|
||||
fun givenString_whenDefaultFormat_thenCreated() {
|
||||
|
||||
var date = LocalDate.parse("2018-12-31")
|
||||
|
||||
assertThat(date).isEqualTo("2018-12-31")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenString_whenCustomFormat_thenCreated() {
|
||||
|
||||
var formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy")
|
||||
var date = LocalDate.parse("31-12-2018", formatter)
|
||||
|
||||
assertThat(date).isEqualTo("2018-12-31")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenYMD_whenUsingOf_thenCreated() {
|
||||
var date = LocalDate.of(2018, 12, 31)
|
||||
|
||||
assertThat(date).isEqualTo("2018-12-31")
|
||||
}
|
||||
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package com.baeldung.kotlin.dates
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.time.DayOfWeek
|
||||
import java.time.LocalDate
|
||||
import java.time.Month
|
||||
|
||||
class ExtractDateUnitTest {
|
||||
|
||||
@Test
|
||||
fun givenDate_thenExtractedYMD() {
|
||||
var date = LocalDate.parse("2018-12-31")
|
||||
|
||||
assertThat(date.year).isEqualTo(2018)
|
||||
assertThat(date.month).isEqualTo(Month.DECEMBER)
|
||||
assertThat(date.dayOfMonth).isEqualTo(31)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenDate_thenExtractedEraDowDoy() {
|
||||
var date = LocalDate.parse("2018-12-31")
|
||||
|
||||
assertThat(date.era.toString()).isEqualTo("CE")
|
||||
assertThat(date.dayOfWeek).isEqualTo(DayOfWeek.MONDAY)
|
||||
assertThat(date.dayOfYear).isEqualTo(365)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package com.baeldung.kotlin.dates
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.time.LocalDate
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
class FormatDateUnitTest {
|
||||
|
||||
@Test
|
||||
fun givenDate_whenDefaultFormat_thenFormattedString() {
|
||||
|
||||
var date = LocalDate.parse("2018-12-31")
|
||||
|
||||
assertThat(date.toString()).isEqualTo("2018-12-31")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenDate_whenCustomFormat_thenFormattedString() {
|
||||
|
||||
var date = LocalDate.parse("2018-12-31")
|
||||
|
||||
var formatter = DateTimeFormatter.ofPattern("dd-MMMM-yyyy")
|
||||
var formattedDate = date.format(formatter)
|
||||
|
||||
assertThat(formattedDate).isEqualTo("31-December-2018")
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue