From 43e33fad9ad8b27137fa83794a5397ee25587c62 Mon Sep 17 00:00:00 2001 From: sudispersonalmac Date: Wed, 20 Nov 2024 07:21:55 +0000 Subject: [PATCH 1/5] KTLN-622: Implement code for the article differentiating Kotlin Any vs * in generics. --- core-kotlin-modules/core-kotlin-12/README.md | 2 + core-kotlin-modules/core-kotlin-12/pom.xml | 37 +++++++++++ .../main/kotlin/com/baeldung/casting/Candy.kt | 8 +++ .../com/baeldung/casting/SpookyTrinket.kt | 7 ++ .../com/baeldung/casting/TreatDispenser.kt | 36 ++++++++++ .../casting/TreatDispenserUnitTest.kt | 65 +++++++++++++++++++ core-kotlin-modules/pom.xml | 1 + 7 files changed, 156 insertions(+) create mode 100644 core-kotlin-modules/core-kotlin-12/README.md create mode 100644 core-kotlin-modules/core-kotlin-12/pom.xml create mode 100644 core-kotlin-modules/core-kotlin-12/src/main/kotlin/com/baeldung/casting/Candy.kt create mode 100644 core-kotlin-modules/core-kotlin-12/src/main/kotlin/com/baeldung/casting/SpookyTrinket.kt create mode 100644 core-kotlin-modules/core-kotlin-12/src/main/kotlin/com/baeldung/casting/TreatDispenser.kt create mode 100644 core-kotlin-modules/core-kotlin-12/src/test/kotlin/com/baeldung/casting/TreatDispenserUnitTest.kt diff --git a/core-kotlin-modules/core-kotlin-12/README.md b/core-kotlin-modules/core-kotlin-12/README.md new file mode 100644 index 000000000..7ec8919bb --- /dev/null +++ b/core-kotlin-modules/core-kotlin-12/README.md @@ -0,0 +1,2 @@ +### Relevant Articles +- [Difference between "*" and "Any" in Kotlin generics](TBD) diff --git a/core-kotlin-modules/core-kotlin-12/pom.xml b/core-kotlin-modules/core-kotlin-12/pom.xml new file mode 100644 index 000000000..e1572ace7 --- /dev/null +++ b/core-kotlin-modules/core-kotlin-12/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + core-kotlin-12 + core-kotlin-12 + jar + + + com.baeldung + core-kotlin-modules + 1.0.0-SNAPSHOT + + + + src/main/kotlin + src/test/kotlin + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + + + + diff --git a/core-kotlin-modules/core-kotlin-12/src/main/kotlin/com/baeldung/casting/Candy.kt b/core-kotlin-modules/core-kotlin-12/src/main/kotlin/com/baeldung/casting/Candy.kt new file mode 100644 index 000000000..698fcc1d1 --- /dev/null +++ b/core-kotlin-modules/core-kotlin-12/src/main/kotlin/com/baeldung/casting/Candy.kt @@ -0,0 +1,8 @@ +package com.baeldung.casting + +sealed class Candy(val name: String) { + override fun toString() = name +} + +object ChocolateBar: Candy("Chocolate Bar") +object Lollipop : Candy("Lollipop") \ No newline at end of file diff --git a/core-kotlin-modules/core-kotlin-12/src/main/kotlin/com/baeldung/casting/SpookyTrinket.kt b/core-kotlin-modules/core-kotlin-12/src/main/kotlin/com/baeldung/casting/SpookyTrinket.kt new file mode 100644 index 000000000..ff153cb44 --- /dev/null +++ b/core-kotlin-modules/core-kotlin-12/src/main/kotlin/com/baeldung/casting/SpookyTrinket.kt @@ -0,0 +1,7 @@ +package com.baeldung.casting + +sealed class SpookyTrinket(val name: String) { + override fun toString() = name +} +object FakeSpider : SpookyTrinket("Fake Spider") +object VampireFang : SpookyTrinket("Vampire Fang") \ No newline at end of file diff --git a/core-kotlin-modules/core-kotlin-12/src/main/kotlin/com/baeldung/casting/TreatDispenser.kt b/core-kotlin-modules/core-kotlin-12/src/main/kotlin/com/baeldung/casting/TreatDispenser.kt new file mode 100644 index 000000000..46656e114 --- /dev/null +++ b/core-kotlin-modules/core-kotlin-12/src/main/kotlin/com/baeldung/casting/TreatDispenser.kt @@ -0,0 +1,36 @@ +package com.baeldung.casting + +import kotlin.collections.MutableList +import kotlin.collections.mutableListOf +import kotlin.collections.firstOrNull +import kotlin.collections.removeFirst + +class TreatDispenser(private val treats: MutableList = mutableListOf()) { + + // Dispense the first treat + fun dispenseTreat(): T? { + return if (treats.isNotEmpty()) treats.removeFirst() else null + } + + // Peek at the next treat without removing it + fun peekNextTreat(): T? { + return treats.firstOrNull() + } + + // Add a treat to the dispenser + fun addTreat(treat: T) { + treats.add(treat) + } +} + +// Function using * (Star Projection) +fun peekAtNextTreat(dispenser: TreatDispenser<*>) { + val nextTreat = dispenser.peekNextTreat() + println("The next treat is: $nextTreat") +} + +// Function using Any (restricted to non-nullable types) +fun peekAtNextTreatAny(dispenser: TreatDispenser) { + val nextTreat = dispenser.peekNextTreat() + println("The next treat is: $nextTreat") +} diff --git a/core-kotlin-modules/core-kotlin-12/src/test/kotlin/com/baeldung/casting/TreatDispenserUnitTest.kt b/core-kotlin-modules/core-kotlin-12/src/test/kotlin/com/baeldung/casting/TreatDispenserUnitTest.kt new file mode 100644 index 000000000..1de0854cc --- /dev/null +++ b/core-kotlin-modules/core-kotlin-12/src/test/kotlin/com/baeldung/casting/TreatDispenserUnitTest.kt @@ -0,0 +1,65 @@ +package com.baeldung.casting + +import org.junit.Test +import org.junit.jupiter.api.Assertions.* + +class TreatDispenserUnitTest { + + @Test + fun `dispenseTreat should return the first treat`() { + + val dispenser = TreatDispenser() + dispenser.addTreat(ChocolateBar) + dispenser.addTreat(Lollipop) + + assertEquals(ChocolateBar, dispenser.dispenseTreat()) + assertEquals(Lollipop, dispenser.dispenseTreat()) + assertNull(dispenser.dispenseTreat()) + } + + @Test + fun `peekNextTreat should show the next treat without removing it`() { + val dispenser = TreatDispenser() + dispenser.addTreat(Lollipop) + + assertEquals(Lollipop, dispenser.peekNextTreat()) + assertEquals(Lollipop, dispenser.peekNextTreat()) + } + + @Test + fun `peekAtNextTreat using star projection works for all types`() { + val candyDispenser = TreatDispenser() + candyDispenser.addTreat(ChocolateBar) + + val trinketDispenser = TreatDispenser() + trinketDispenser.addTreat(VampireFang) + trinketDispenser.addTreat(FakeSpider) + + // Test with Candy dispenser + assertDoesNotThrow { + peekAtNextTreat(candyDispenser) + } + + // Test with Trinket dispenser + assertDoesNotThrow { + peekAtNextTreat(trinketDispenser) + } + } + + @Test + fun `peekAtNextTreatAny fails for non-Any dispensers`() { + val candyDispenser = TreatDispenser() + candyDispenser.addTreat(ChocolateBar) + + // This would fail type checking, hence commented: + // peekAtNextTreatAny(candyDispenser) // Error: Type mismatch + + val anyDispenser = TreatDispenser() + anyDispenser.addTreat("Surprise Treat") + + assertDoesNotThrow { + peekAtNextTreatAny(anyDispenser) + } + } + +} diff --git a/core-kotlin-modules/pom.xml b/core-kotlin-modules/pom.xml index e41a4e4fd..69dfd5ddc 100644 --- a/core-kotlin-modules/pom.xml +++ b/core-kotlin-modules/pom.xml @@ -26,6 +26,7 @@ core-kotlin-9 core-kotlin-10 core-kotlin-11 + core-kotlin-12 core-kotlin-advanced core-kotlin-advanced-2 core-kotlin-advanced-3 From ba79fc05a8f25625ad7e917a6c8e368e120c359d Mon Sep 17 00:00:00 2001 From: sudispersonalmac Date: Wed, 20 Nov 2024 07:22:37 +0000 Subject: [PATCH 2/5] KTLN-622: Implement code for the article differentiating Kotlin Any vs * in generics. --- core-kotlin-modules/core-kotlin-12/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-kotlin-modules/core-kotlin-12/README.md b/core-kotlin-modules/core-kotlin-12/README.md index 7ec8919bb..8b366f188 100644 --- a/core-kotlin-modules/core-kotlin-12/README.md +++ b/core-kotlin-modules/core-kotlin-12/README.md @@ -1,2 +1,2 @@ ### Relevant Articles -- [Difference between "*" and "Any" in Kotlin generics](TBD) +- Difference between "*" and "Any" in Kotlin generics - Link to be updated From bb3ee661208ebcf96fbb8c2d4cc37c8ebb1473d5 Mon Sep 17 00:00:00 2001 From: sudispersonalmac Date: Wed, 20 Nov 2024 07:23:20 +0000 Subject: [PATCH 3/5] KTLN-622: Implement code for the article differentiating Kotlin Any vs * in generics. --- core-kotlin-modules/pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/core-kotlin-modules/pom.xml b/core-kotlin-modules/pom.xml index 69dfd5ddc..2d5bb02c8 100644 --- a/core-kotlin-modules/pom.xml +++ b/core-kotlin-modules/pom.xml @@ -4,7 +4,6 @@ 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"> 4.0.0 - com.baeldung core-kotlin-modules pom From a9e52bdd0d555d9c1350bbe0f7f620246897737e Mon Sep 17 00:00:00 2001 From: sudispersonalmac Date: Wed, 20 Nov 2024 07:23:30 +0000 Subject: [PATCH 4/5] KTLN-622: Implement code for the article differentiating Kotlin Any vs * in generics. --- .../src/main/kotlin/com/baeldung/casting/TreatDispenser.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/core-kotlin-modules/core-kotlin-12/src/main/kotlin/com/baeldung/casting/TreatDispenser.kt b/core-kotlin-modules/core-kotlin-12/src/main/kotlin/com/baeldung/casting/TreatDispenser.kt index 46656e114..7da30f8ac 100644 --- a/core-kotlin-modules/core-kotlin-12/src/main/kotlin/com/baeldung/casting/TreatDispenser.kt +++ b/core-kotlin-modules/core-kotlin-12/src/main/kotlin/com/baeldung/casting/TreatDispenser.kt @@ -3,7 +3,6 @@ package com.baeldung.casting import kotlin.collections.MutableList import kotlin.collections.mutableListOf import kotlin.collections.firstOrNull -import kotlin.collections.removeFirst class TreatDispenser(private val treats: MutableList = mutableListOf()) { From 6c5a5b7a4ae473fc45f18988112a6db0274f26fb Mon Sep 17 00:00:00 2001 From: sudispersonalmac Date: Sat, 23 Nov 2024 07:14:50 +0000 Subject: [PATCH 5/5] KTLN-622: Implement code for the article differentiating Kotlin Any vs * in generics. --- core-kotlin-modules/core-kotlin-11/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-kotlin-modules/core-kotlin-11/README.md b/core-kotlin-modules/core-kotlin-11/README.md index 01d4be992..85dd5b68e 100644 --- a/core-kotlin-modules/core-kotlin-11/README.md +++ b/core-kotlin-modules/core-kotlin-11/README.md @@ -1,2 +1,2 @@ ### Relevant Articles -- [Convert a Data Class to ByteBuffer in Kotlin](https://www.baeldung.com/kotlin/convert-data-class-to-bytebuffer) +