Completed Coursera: Kotlin for developers course
This commit is contained in:
32
.gitignore
vendored
Normal file
32
.gitignore
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
### IntelliJ IDEA ###
|
||||||
|
out/
|
||||||
|
!**/src/main/**/out/
|
||||||
|
!**/src/test/**/out/
|
||||||
|
|
||||||
|
### Kotlin ###
|
||||||
|
.kotlin
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
bin/
|
||||||
|
!**/src/main/**/bin/
|
||||||
|
!**/src/test/**/bin/
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
10
.idea/.gitignore
generated
vendored
Normal file
10
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Environment-dependent path to Maven home directory
|
||||||
|
/mavenHomeManager.xml
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
13
.idea/codeStyles/Project.xml
generated
Normal file
13
.idea/codeStyles/Project.xml
generated
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<code_scheme name="Project" version="173">
|
||||||
|
<JetCodeStyleSettings>
|
||||||
|
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||||
|
</JetCodeStyleSettings>
|
||||||
|
<codeStyleSettings language="JAVA">
|
||||||
|
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="kotlin">
|
||||||
|
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||||
|
</codeStyleSettings>
|
||||||
|
</code_scheme>
|
||||||
|
</component>
|
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
|
</state>
|
||||||
|
</component>
|
12
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
12
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="GrazieInspection" enabled="false" level="GRAMMAR_ERROR" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="LanguageDetectionInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
||||||
|
<option name="processCode" value="true" />
|
||||||
|
<option name="processLiterals" value="true" />
|
||||||
|
<option name="processComments" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
10
.idea/kotlinc.xml
generated
Normal file
10
.idea/kotlinc.xml
generated
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Kotlin2JvmCompilerArguments">
|
||||||
|
<option name="jvmTarget" value="1.8" />
|
||||||
|
</component>
|
||||||
|
<component name="KotlinCommonCompilerArguments">
|
||||||
|
<option name="apiVersion" value="2.1" />
|
||||||
|
<option name="languageVersion" value="2.1" />
|
||||||
|
</component>
|
||||||
|
</project>
|
17
.idea/libraries/KotlinJavaRuntime.xml
generated
Normal file
17
.idea/libraries/KotlinJavaRuntime.xml
generated
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<component name="libraryTable">
|
||||||
|
<library name="KotlinJavaRuntime" type="repository">
|
||||||
|
<properties maven-id="org.jetbrains.kotlin:kotlin-stdlib:2.1.21" />
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/2.1.21/kotlin-stdlib-2.1.21.jar!/" />
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/2.1.21/kotlin-stdlib-2.1.21-javadoc.jar!/" />
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/2.1.21/kotlin-stdlib-2.1.21-sources.jar!/" />
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
6
.idea/misc.xml
generated
Normal file
6
.idea/misc.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_24" default="true" project-jdk-name="openjdk-24" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/kotlin-for-java-developers.iml" filepath="$PROJECT_DIR$/kotlin-for-java-developers.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
15
kotlin-for-java-developers.iml
Normal file
15
kotlin-for-java-developers.iml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/testResources" type="java-test-resource" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
4
src/Also.kt
Normal file
4
src/Also.kt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fun main() {
|
||||||
|
// Takes a regular lambda without a receiver
|
||||||
|
val uppercase = "Hello".also { it.uppercase() }
|
||||||
|
}
|
4
src/Apply.kt
Normal file
4
src/Apply.kt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fun main() {
|
||||||
|
// Returns the receiver as the result
|
||||||
|
val apply = "Hello".apply { print(this) }
|
||||||
|
}
|
27
src/Classes.kt
Normal file
27
src/Classes.kt
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Cannot initialize class, must be extended
|
||||||
|
abstract class Classes(val name: String) {
|
||||||
|
|
||||||
|
// Makes it possible to override method
|
||||||
|
open fun finalFunction() = 1
|
||||||
|
|
||||||
|
// Must be overridden when extending
|
||||||
|
abstract fun overrideMe()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Primary constructor
|
||||||
|
class ExtendedClass(name: String, val age: Int) : Classes(name) {
|
||||||
|
|
||||||
|
// Called after primary constructor
|
||||||
|
init {
|
||||||
|
println(age)
|
||||||
|
}
|
||||||
|
|
||||||
|
// secondary constructor
|
||||||
|
constructor(name: String) : this(name, age = 0)
|
||||||
|
|
||||||
|
// Overrides a method
|
||||||
|
override fun overrideMe() {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
30
src/Conditionals.kt
Normal file
30
src/Conditionals.kt
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import Color.*;
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
when (RED) {
|
||||||
|
RED -> println("red")
|
||||||
|
BLUE -> println("blue")
|
||||||
|
GREEN -> println("green")
|
||||||
|
}
|
||||||
|
|
||||||
|
when ("y") {
|
||||||
|
"yes", "y" -> println("Yes")
|
||||||
|
else -> println("No")
|
||||||
|
}
|
||||||
|
|
||||||
|
val b: A = B()
|
||||||
|
|
||||||
|
when (b) {
|
||||||
|
// Smart cast b to the type B
|
||||||
|
is B -> println("B")
|
||||||
|
else -> println("Unknown")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class Color {
|
||||||
|
BLUE, GREEN, RED
|
||||||
|
}
|
||||||
|
|
||||||
|
open class A
|
||||||
|
|
||||||
|
class B : A()
|
8
src/Constants.kt
Normal file
8
src/Constants.kt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// Compile time constant. Is inlined by the compiler. Only works for primitives and Strings. static method in Java
|
||||||
|
const val MAGIC_NUMBER = 42
|
||||||
|
|
||||||
|
// Is converted into a static final in Java. Supports all types
|
||||||
|
@JvmField
|
||||||
|
val JAVA_CONSTANT = MyClass()
|
||||||
|
|
||||||
|
class MyClass
|
2
src/DataClass.kt
Normal file
2
src/DataClass.kt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
// data adds extra methods like toString, equals and hashcode, only uses data from primary constructor
|
||||||
|
data class DataClass(val name: String, val age: Int)
|
17
src/Exceptions.kt
Normal file
17
src/Exceptions.kt
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
val value = try {
|
||||||
|
throw NullPointerException("Whoops")
|
||||||
|
} catch (e: NullPointerException) {
|
||||||
|
println(e.message)
|
||||||
|
"Caught NullPointerException"
|
||||||
|
}
|
||||||
|
println(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Like the throws keyword in Java. Only needed when calling from Java
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun catchedException() {
|
||||||
|
throw IOException("Whoops")
|
||||||
|
}
|
20
src/Extensions.kt
Normal file
20
src/Extensions.kt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
println(9.random())
|
||||||
|
listOf(1, 2, 3).sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Defines an extension function on the Int type, must be imported outside the file
|
||||||
|
// This refers to the value we extend
|
||||||
|
// Static function under the hood
|
||||||
|
fun Int.random(): Int = Random.nextInt(this)
|
||||||
|
|
||||||
|
// Add extension to List class of Int
|
||||||
|
fun List<Int>.sum(): Int {
|
||||||
|
var result = 0
|
||||||
|
for (i in this) {
|
||||||
|
result += i
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
11
src/FunctionTypes.kt
Normal file
11
src/FunctionTypes.kt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fun main() {
|
||||||
|
// Defines a function type with two int args and one int result
|
||||||
|
val sum: (Int, Int) -> Int = { a, b -> a + b }
|
||||||
|
println(run { "This is a function which is called immediately" })
|
||||||
|
val nullableFunctionType: (() -> Unit)? = null
|
||||||
|
nullableFunctionType?.invoke() // Safe call a nullable function type
|
||||||
|
|
||||||
|
val isEvenVariable = ::isEven // Store a ref to a function
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isEven(x: Int) = x % 2 == 0
|
34
src/Functions.kt
Normal file
34
src/Functions.kt
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// Specify the name to use when calling from another language
|
||||||
|
@file:JvmName("fun")
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
print(max(2, 3))
|
||||||
|
|
||||||
|
println(
|
||||||
|
// Named arguments are optional
|
||||||
|
listOf("a", "b", "c").joinToString(
|
||||||
|
separator = "",
|
||||||
|
prefix = "(",
|
||||||
|
postfix = ")"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Using default value
|
||||||
|
println(repeatString("*"))
|
||||||
|
println(repeatString("*", 2))
|
||||||
|
// Flip the arguments by using named arguments
|
||||||
|
println(repeatString(times = 5, s = "*"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Top-level function
|
||||||
|
fun max(a: Int, b: Int): Int = if (a > b) a else b
|
||||||
|
|
||||||
|
// Unit return type
|
||||||
|
fun print(value: Int) = println("Max is $value")
|
||||||
|
|
||||||
|
// Times has a default value
|
||||||
|
fun repeatString(s: String, times: Int = 10): String = s.repeat(times)
|
||||||
|
|
||||||
|
// Generates 4 overloaded functions for the JVM. Not needed when only using Kotlin
|
||||||
|
@JvmOverloads
|
||||||
|
fun sum(a: Int = 0, b: Int = 0, c: Int = 0) = a + b + c
|
30
src/Generics.kt
Normal file
30
src/Generics.kt
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// T? marks type T as nullable
|
||||||
|
fun <T> List<T>.filterNullable(predicate: (T) -> Boolean): T? {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> List<T>.filterCanBeNull(predicate: (T) -> Boolean) {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
// T cannot be nullable
|
||||||
|
fun <T : Any> List<T>.filterNotNull(predicate: (T) -> Boolean) {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define bounds using where clause
|
||||||
|
fun <T> ensureTrailingPeriod(seq: T) where T : CharSequence, T : Appendable {
|
||||||
|
if (seq.endsWith(".")) {
|
||||||
|
seq.append('.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun List<Int>.avg(): Double {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Java doesn't allow overloaded methods that differ only by generic types. We add @JvmName to create a new name when used from Java
|
||||||
|
@JvmName(name = "avgDouble")
|
||||||
|
fun List<Double>.avg(): Double {
|
||||||
|
TODO()
|
||||||
|
}
|
1
src/HelloWorld.kt
Normal file
1
src/HelloWorld.kt
Normal file
@ -0,0 +1 @@
|
|||||||
|
fun main() = println("Hello World")
|
24
src/In.kt
Normal file
24
src/In.kt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import java.time.Instant
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
// Check if a is in abc
|
||||||
|
println('a' in "abc")
|
||||||
|
// Check if a is not in abc
|
||||||
|
println('a' !in "abc")
|
||||||
|
// Check if now is within the bounds, using comparable under the hood
|
||||||
|
println(Instant.now() in Instant.MIN..Instant.MAX)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Playground
|
||||||
|
fun isValidIdentifier(s: String): Boolean {
|
||||||
|
fun isValidCharacter(ch: Char): Boolean = ch == '_' || ch.isLetterOrDigit()
|
||||||
|
if (s.isEmpty() || s[0].isDigit()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for (ch in s) {
|
||||||
|
if (!isValidCharacter(ch)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
7
src/Inline.kt
Normal file
7
src/Inline.kt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fun main() {
|
||||||
|
thisIsInlined { true }
|
||||||
|
}
|
||||||
|
|
||||||
|
// The function is replaced with the contects of the function
|
||||||
|
// No performance overhead
|
||||||
|
inline fun thisIsInlined(predicate: (Int) -> Boolean): Int? = 42.takeIf(predicate)
|
35
src/Lambdas.kt
Normal file
35
src/Lambdas.kt
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
fun main() {
|
||||||
|
listOf(1, 2, 3)
|
||||||
|
// Lambda, it is inferred argument, only used for single argument lambdas
|
||||||
|
.filter { it % 2 == 0 }
|
||||||
|
// Explicitly define args
|
||||||
|
.map { value -> value * value }
|
||||||
|
|
||||||
|
mapOf(1 to 2)
|
||||||
|
// Automatic destructuring of mep entries
|
||||||
|
.mapValues { (key, value) -> "$key $value" }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun returnFromLambda(): List<Int> {
|
||||||
|
return listOf(3, 0, 5)
|
||||||
|
.flatMap {
|
||||||
|
if (it == 0) return emptyList() // Returns from the function, will always return an empty list when 0
|
||||||
|
listOf(it, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun returnFromLambda2(): List<Int> {
|
||||||
|
return listOf(3, 0, 5)
|
||||||
|
.flatMap {
|
||||||
|
if (it == 0) return@flatMap emptyList() // Returns from the lambda
|
||||||
|
listOf(it, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun returnFromLambda3(): List<Int> {
|
||||||
|
return listOf(3, 0, 5)
|
||||||
|
.flatMap l@{ // Define custom label
|
||||||
|
if (it == 0) return@l emptyList() // Returns from the lambda
|
||||||
|
listOf(it, it)
|
||||||
|
}
|
||||||
|
}
|
14
src/Lateinit.kt
Normal file
14
src/Lateinit.kt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
fun main() {
|
||||||
|
val init = Init()
|
||||||
|
init.name = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
class Init {
|
||||||
|
// Allows setting the value at a later time without making it nullable. We can't use primitives
|
||||||
|
lateinit var name: String
|
||||||
|
|
||||||
|
/// Checks if name is initialized
|
||||||
|
fun isInitialized(): Boolean {
|
||||||
|
return ::name.isInitialized
|
||||||
|
}
|
||||||
|
}
|
8
src/Lazy.kt
Normal file
8
src/Lazy.kt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fun main() {
|
||||||
|
|
||||||
|
// Computes only when called and only once
|
||||||
|
val lazyValue: String by lazy {
|
||||||
|
println("computed!")
|
||||||
|
"Hello"
|
||||||
|
}
|
||||||
|
}
|
11
src/Let.kt
Normal file
11
src/Let.kt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fun main() {
|
||||||
|
val string = getString()
|
||||||
|
// Lambda is only called if string is not null
|
||||||
|
string?.let { println(it) }
|
||||||
|
val uppercaseMaybe = string
|
||||||
|
// Return value if predicate is true, otherwise null
|
||||||
|
?.takeIf { it.length > 4 }
|
||||||
|
?.let { it.uppercase() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getString(): String? = "Hello"
|
21
src/Loops.kt
Normal file
21
src/Loops.kt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
fun main() {
|
||||||
|
while (true) {
|
||||||
|
println("While")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Including upper bound
|
||||||
|
for (x in 1..10) {
|
||||||
|
print(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Excluding upper bound
|
||||||
|
for (x in 1 until 10) {
|
||||||
|
print(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpack the map to key and value
|
||||||
|
for ((key, value) in mapOf("key" to 1, "value" to 2, "key2" to 3)) {
|
||||||
|
println("$key = $value")
|
||||||
|
}
|
||||||
|
}
|
14
src/Main.kt
Normal file
14
src/Main.kt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
|
||||||
|
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
|
||||||
|
fun main() {
|
||||||
|
val name = "Kotlin"
|
||||||
|
//TIP Press <shortcut actionId="ShowIntentionActions"/> with your caret at the highlighted text
|
||||||
|
// to see how IntelliJ IDEA suggests fixing it.
|
||||||
|
println("Hello, $name!")
|
||||||
|
|
||||||
|
for (i in 1..5) {
|
||||||
|
//TIP Press <shortcut actionId="Debug"/> to start debugging your code. We have set one <icon src="AllIcons.Debugger.Db_set_breakpoint"/> breakpoint
|
||||||
|
// for you, but you can always add more by pressing <shortcut actionId="ToggleLineBreakpoint"/>.
|
||||||
|
println("i = $i")
|
||||||
|
}
|
||||||
|
}
|
8
src/Nothing.kt
Normal file
8
src/Nothing.kt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fun main() {
|
||||||
|
doesNotReturn()
|
||||||
|
println("This is unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun doesNotReturn(): Nothing {
|
||||||
|
throw RuntimeException("This function should always fail")
|
||||||
|
}
|
10
src/Nullable.kt
Normal file
10
src/Nullable.kt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
fun main() {
|
||||||
|
var nullableString: String? = null
|
||||||
|
println(nullableString?.length ?: 0) // Null safe method call with elvis operator for fallback
|
||||||
|
nullableString = "Not Null"
|
||||||
|
println(nullableString)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun nullableFun(value: Any?) {
|
||||||
|
value!! // Explicitly tell the compilar that it's not null
|
||||||
|
}
|
20
src/Object.kt
Normal file
20
src/Object.kt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// A singleton object
|
||||||
|
object Object {
|
||||||
|
val name: String
|
||||||
|
get() {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Static {
|
||||||
|
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
// Makes it possible to call it from Java as a static method on the class
|
||||||
|
// Default is a static method on the companion object
|
||||||
|
@JvmStatic
|
||||||
|
fun create(): Companion /* Companion is default name of companion object */ {
|
||||||
|
return Static
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
src/OperatorOverloading.kt
Normal file
7
src/OperatorOverloading.kt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// Implement the plus method on custom class
|
||||||
|
// Same with other operators
|
||||||
|
operator fun MyNewOperator.plus(other: MyNewOperator): MyNewOperator {
|
||||||
|
return TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyNewOperator
|
24
src/Properties.kt
Normal file
24
src/Properties.kt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
fun main() {
|
||||||
|
val person = Person("name", age = 5)
|
||||||
|
println(person.name) // Calling getter
|
||||||
|
person.age = 6 // Calling setter
|
||||||
|
}
|
||||||
|
|
||||||
|
// Defines a class with 2 properties.
|
||||||
|
// val generates only getter, var generates both getters and setters
|
||||||
|
class Person(val name: String, var age: Int)
|
||||||
|
|
||||||
|
class Address {
|
||||||
|
|
||||||
|
// Defines get and set methods with custom logic
|
||||||
|
var place: String = ""
|
||||||
|
get() = field.uppercase()
|
||||||
|
set(value) {
|
||||||
|
field = value.lowercase()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extension property on String
|
||||||
|
val String.name: String
|
||||||
|
get() = this.lowercase()
|
6
src/Run.kt
Normal file
6
src/Run.kt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
fun main() {
|
||||||
|
// Similar to with but can be used with nullable values
|
||||||
|
val uppercase = nullableString()?.run { uppercase() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun nullableString(): String? = "Hello"
|
11
src/SafeCast.kt
Normal file
11
src/SafeCast.kt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fun main() {
|
||||||
|
any("Whoops")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun any(any: Any) {
|
||||||
|
if (any is String) {
|
||||||
|
println(any.length)
|
||||||
|
}
|
||||||
|
// Safe case
|
||||||
|
println((any as? String)?.uppercase())
|
||||||
|
}
|
11
src/SealedClass.kt
Normal file
11
src/SealedClass.kt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
sealed class SealedClass
|
||||||
|
class OK : SealedClass()
|
||||||
|
class NotFound : SealedClass()
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
// Is exhaustive since we know only Ok and NotFound extends sealed class
|
||||||
|
when (OK() as SealedClass) {
|
||||||
|
is OK -> println("OK")
|
||||||
|
is NotFound -> println("Not found")
|
||||||
|
}
|
||||||
|
}
|
22
src/Sequences.kt
Normal file
22
src/Sequences.kt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
fun main() {
|
||||||
|
// Lazy list, like Java Streams
|
||||||
|
sequenceOf(1, 2, 3)
|
||||||
|
.map { it * it }
|
||||||
|
// Will only enumerate the first 2 elements
|
||||||
|
.first { it > 2 }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun yieldSequence(): Sequence<Int> = sequence {
|
||||||
|
// yield returns a value to generate a sequence
|
||||||
|
while (true) yield(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fibonacci(): Sequence<Int> = sequence {
|
||||||
|
yieldAll(0..1)
|
||||||
|
var values = Pair(0, 1)
|
||||||
|
while (true) {
|
||||||
|
val nextValue = values.first + values.second
|
||||||
|
yield(nextValue)
|
||||||
|
values = Pair(values.second, nextValue)
|
||||||
|
}
|
||||||
|
}
|
33
src/With.kt
Normal file
33
src/With.kt
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
fun main() {
|
||||||
|
val sb = StringBuilder()
|
||||||
|
// sb becomes this within the lambda scope
|
||||||
|
val string = with(sb) /* Is an extention function on type T */ {
|
||||||
|
appendLine("Something")
|
||||||
|
append('a')
|
||||||
|
toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
val buildString = buildString {
|
||||||
|
append(1)
|
||||||
|
append(2)
|
||||||
|
toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
val words = Words()
|
||||||
|
with(words) {
|
||||||
|
// The following two lines should compile:
|
||||||
|
"one".record()
|
||||||
|
+"two"
|
||||||
|
}
|
||||||
|
words.toString() == "[one, two]"
|
||||||
|
}
|
||||||
|
|
||||||
|
class Words {
|
||||||
|
private val list = mutableListOf<String>()
|
||||||
|
|
||||||
|
fun String.record() = list.add(this)
|
||||||
|
|
||||||
|
operator fun String.unaryPlus() = list.add(this)
|
||||||
|
|
||||||
|
override fun toString() = list.toString()
|
||||||
|
}
|
Reference in New Issue
Block a user