mikr
2019-12-29 23:57:04 +01:00
parent 710fcfe69f
commit e6aa30a7ca
51 changed files with 79 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
inline fun <reified T> Iterable<*>.filterIsInstance() = filter { it is T }
fun main(args: Array<String>) {
val set = setOf("1984", 2, 3, "Brave new world", 11)
println(set.filterIsInstance<Int>())
}

View File

@@ -0,0 +1,35 @@
package com.baeldung.kotlin.delegates
val data = arrayOf<MutableMap<String, Any?>>(
mutableMapOf(
"id" to 1,
"name" to "George",
"age" to 4
),
mutableMapOf(
"id" to 2,
"name" to "Charlotte",
"age" to 2
)
)
class NoRecordFoundException(id: Int) : Exception("No record found for id $id") {
init {
println("No record found for ID $id")
}
}
fun queryForValue(field: String, id: Int): Any {
println("Loading record $id from the fake database")
val value = data.firstOrNull { it["id"] == id }
?.get(field) ?: throw NoRecordFoundException(id)
println("Loaded value $value for field $field of record $id")
return value
}
fun update(field: String, id: Int, value: Any?) {
println("Updating field $field of record $id to value $value in the fake database")
data.firstOrNull { it["id"] == id }
?.put(field, value)
?: throw NoRecordFoundException(id)
}

View File

@@ -0,0 +1,13 @@
package com.baeldung.kotlin.delegates
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
class DatabaseDelegate<in R, T>(private val field: String, private val id: Int) : ReadWriteProperty<R, T> {
override fun getValue(thisRef: R, property: KProperty<*>): T =
queryForValue(field, id) as T
override fun setValue(thisRef: R, property: KProperty<*>, value: T) {
update(field, id, value)
}
}

View File

@@ -0,0 +1,64 @@
package com.baeldung.kotlin.delegates
import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock
interface Producer {
fun produce(): String
}
class ProducerImpl : Producer {
override fun produce() = "ProducerImpl"
}
class EnhancedProducer(private val delegate: Producer) : Producer by delegate {
override fun produce() = "${delegate.produce()} and EnhancedProducer"
}
interface MessageService {
fun processMessage(message: String): String
}
class MessageServiceImpl : MessageService {
override fun processMessage(message: String): String {
return "MessageServiceImpl: $message"
}
}
interface UserService {
fun processUser(userId: String): String
}
class UserServiceImpl : UserService {
override fun processUser(userId: String): String {
return "UserServiceImpl: $userId"
}
}
class CompositeService : UserService by UserServiceImpl(), MessageService by MessageServiceImpl()
interface Service {
val seed: Int
fun serve(action: (Int) -> Unit)
}
class ServiceImpl : Service {
override val seed = 1
override fun serve(action: (Int) -> Unit) {
action(seed)
}
}
class ServiceDecorator : Service by ServiceImpl() {
override val seed = 2
}

View File

@@ -0,0 +1,6 @@
package com.baeldung.kotlin.delegates
class User(val id: Int) {
var name: String by DatabaseDelegate("name", id)
var age: Int by DatabaseDelegate("age", id)
}

View File

@@ -0,0 +1,143 @@
package com.baeldung.kotlin
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class GenericsTest {
@Test
fun givenParametrizeClass_whenInitializeItWithSpecificType_thenShouldBeParameterized() {
//given
val parameterizedClass = ParameterizedClass<String>("string-value")
//when
val res = parameterizedClass.getValue()
//then
assertTrue(res is String)
}
@Test
fun givenParametrizeClass_whenInitializeIt_thenShouldBeParameterizedByInferredType() {
//given
val parameterizedClass = ParameterizedClass("string-value")
//when
val res = parameterizedClass.getValue()
//then
assertTrue(res is String)
}
@Test
fun givenParameterizedProducerByOutKeyword_whenGetValue_thenCanAssignItToSuperType() {
//given
val parameterizedProducer = ParameterizedProducer("string")
//when
val ref: ParameterizedProducer<Any> = parameterizedProducer
//then
assertTrue(ref is ParameterizedProducer<Any>)
}
@Test
fun givenParameterizedConsumerByInKeyword_whenGetValue_thenCanAssignItToSubType() {
//given
val parameterizedConsumer = ParameterizedConsumer<Number>()
//when
val ref: ParameterizedConsumer<Double> = parameterizedConsumer
//then
assertTrue(ref is ParameterizedConsumer<Double>)
}
@Test
fun givenTypeProjections_whenOperateOnTwoList_thenCanAcceptListOfSubtypes() {
//given
val ints: Array<Int> = arrayOf(1, 2, 3)
val any: Array<Any?> = arrayOfNulls(3)
//when
copy(ints, any)
//then
assertEquals(any[0], 1)
assertEquals(any[1], 2)
assertEquals(any[2], 3)
}
fun copy(from: Array<out Any>, to: Array<Any?>) {
assert(from.size == to.size)
for (i in from.indices)
to[i] = from[i]
}
@Test
fun givenTypeProjection_whenHaveArrayOfIn_thenShouldAddElementsOfSubtypesToIt() {
//given
val objects: Array<Any?> = arrayOfNulls(1)
//when
fill(objects, 1)
//then
assertEquals(objects[0], 1)
}
fun fill(dest: Array<in Int>, value: Int) {
dest[0] = value
}
@Test
fun givenStartProjection_whenPassAnyType_thenCompile() {
//given
val array = arrayOf(1,2,3)
//then
printArray(array)
}
fun printArray(array: Array<*>) {
array.forEach { println(it) }
}
@Test
fun givenFunctionWithDefinedGenericConstraints_whenCallWithProperType_thenCompile(){
//given
val listOfInts = listOf(5,2,3,4,1)
//when
val sorted = sort(listOfInts)
//then
assertEquals(sorted, listOf(1,2,3,4,5))
}
fun <T: Comparable<T>> sort(list: List<T>): List<T>{
return list.sorted()
}
class ParameterizedClass<A>(private val value: A) {
fun getValue(): A {
return value
}
}
class ParameterizedProducer<out T>(private val value: T) {
fun get(): T {
return value
}
}
class ParameterizedConsumer<in T> {
fun toString(value: T): String {
return value.toString()
}
}
}

View File

@@ -0,0 +1,26 @@
package com.baeldung.kotlin.delegates
import org.junit.Test
import kotlin.test.assertEquals
class DatabaseDelegatesTest {
@Test
fun testGetKnownFields() {
val user = User(1)
assertEquals("George", user.name)
assertEquals(4, user.age)
}
@Test
fun testSetKnownFields() {
val user = User(2)
user.age = 3
assertEquals(3, user.age)
}
@Test(expected = NoRecordFoundException::class)
fun testGetKnownField() {
val user = User(3)
user.name
}
}

View File

@@ -0,0 +1,28 @@
package com.baeldung.kotlin.delegates
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
class InterfaceDelegationTest {
@Test
fun `when delegated implementation is used then it works as expected`() {
val producer = EnhancedProducer(ProducerImpl())
assertThat(producer.produce()).isEqualTo("ProducerImpl and EnhancedProducer")
}
@Test
fun `when composite delegation is used then it works as expected`() {
val service = CompositeService()
assertThat(service.processMessage("message")).isEqualTo("MessageServiceImpl: message")
assertThat(service.processUser("user")).isEqualTo("UserServiceImpl: user")
}
@Test
fun `when decoration is used then delegate knows nothing about it`() {
val service = ServiceDecorator()
service.serve {
assertThat(it).isEqualTo(1)
}
}
}