├── lecture7 ├── settings.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── src │ └── main │ │ ├── _1LambdaWithReceiver │ │ ├── _2Apply.kt │ │ ├── _3ApplyWithAndRun.kt │ │ ├── _1LambdaVsLambdaWithReceiver.kt │ │ ├── _4Usage.kt │ │ └── _1BuildString.kt │ │ └── _2HTMLBuilders │ │ ├── _1SimpleExample.kt │ │ └── _2Tags.kt ├── build.gradle ├── gradlew.bat └── gradlew ├── lecture8 ├── settings.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── src │ └── main │ │ ├── _1Questions │ │ ├── ApplyExample.kt │ │ ├── HTMLBuilders │ │ │ ├── HtmlExample.kt │ │ │ ├── data.kt │ │ │ └── html.kt │ │ ├── breakfastMenu.xml │ │ ├── BreakfastMenu.kt │ │ └── Alert.kt │ │ ├── _3DropdownExample │ │ ├── dropdown-snippet.html │ │ ├── _1DropdownHtml.kt │ │ ├── _2DropdownAbstraction.kt │ │ └── _3DropdownAbstractionImpl.kt │ │ └── _2HTMLBuilders │ │ └── Impl.kt ├── build.gradle ├── gradlew.bat └── gradlew ├── lecture4 ├── src │ ├── _2Object │ │ ├── Object.kt │ │ ├── JSingleton.java │ │ └── UseKotlinObjectFromJava.java │ ├── _1ClassDeclaration │ │ ├── InnerAndNestedClasses.kt │ │ ├── InnerAndNestedClassesInJava.java │ │ └── ConstructorShortSynstax.kt │ ├── _3CompanionObject │ │ ├── UsingCompanionObjectsFromJava.java │ │ └── CompanionObject.kt │ ├── _4DelegatedProperties │ │ ├── LazyProperty.kt │ │ ├── MapAccessors.kt │ │ ├── DelegatesTheory.kt │ │ └── MapExample.kt │ ├── _5MoreAboutOperationsOnCollections │ │ ├── UseAnonymousClass.java │ │ ├── InlineFunctions.kt │ │ ├── GeneratedCodeForInlineFunction.kt │ │ └── CollectionVsSequences.kt │ ├── _3DelegationBy │ │ ├── DelegatingCollection.kt │ │ └── ExampleWithBoards.kt │ └── _0MemberExtension │ │ └── MemberExtensionExample.kt └── lecture4.iml ├── .idea ├── copyright │ └── profiles_settings.xml ├── inspectionProfiles │ ├── profiles_settings.xml │ └── Project_Default.xml ├── vcs.xml ├── misc.xml ├── libraries │ ├── KotlinJavaRuntime.xml │ ├── Gradle__junit_junit_4_11.xml │ ├── Gradle__org_hamcrest_hamcrest_core_1_3.xml │ ├── Gradle__org_jetbrains_kotlin_kotlin_stdlib_1_0_4.xml │ ├── Gradle__org_jetbrains_kotlin_kotlin_runtime_1_0_4.xml │ ├── Gradle__org_jetbrains_kotlinx_kotlinx_html_shared_0_5_11.xml │ └── Gradle__org_jetbrains_kotlinx_kotlinx_html_jvm_0_5_11.xml ├── modules │ ├── lecture7.iml │ ├── lecture8.iml │ ├── lecture7_main.iml │ ├── lecture8_main.iml │ ├── lecture7_test.iml │ └── lecture8_test.iml ├── compiler.xml ├── gradle.xml ├── modules.xml └── uiDesigner.xml ├── README.md ├── questions ├── src │ └── questions │ │ ├── _8JavaClass.java │ │ ├── _3Extensions.kt │ │ ├── _3ExtensionsFromJava.java │ │ ├── _4Todo.kt │ │ ├── _14NPEPureKotlin.kt │ │ ├── _8NPEKotlinJava.kt │ │ ├── _1Zip.kt │ │ ├── _9Subtypes.kt │ │ ├── _2AssociateBy.kt │ │ ├── _10Builders.kt │ │ ├── _11LazyDelegate.kt │ │ └── _5FilterIsInstance.kt └── questions.iml ├── lecture6 ├── src │ ├── _1Object │ │ ├── KSingleton.kt │ │ ├── JMain.java │ │ ├── Main.kt │ │ └── JSingleton.java │ ├── _2Reified │ │ ├── _1Reified.kt │ │ ├── _5RestrictionsOnReifiedTypeParameters.kt │ │ ├── _3ClassReferences.kt │ │ ├── _0TypeErasure.kt │ │ ├── _2FilterIsInstance.kt │ │ └── _4Validators.kt │ └── _0Questions │ │ ├── _2SafeCast.kt │ │ ├── _3SafeCastsAndErasedGenerics.kt │ │ └── _1SafeCastAndNull.kt └── lecture6.iml ├── lecture1 ├── src │ ├── _0Main.kt │ ├── _10BuildString.kt │ ├── _8Pair.kt │ ├── _3Classes.kt │ ├── _4PropertiesWithCustomAccessors.kt │ ├── _6Collections.kt │ ├── _2Functions.kt │ ├── javaCode │ │ ├── Person.java │ │ └── Rectangle.java │ ├── _7IteratingOverMaps.kt │ ├── _1Variables.kt │ ├── _5ControlStructures.kt │ └── _9Ranges.kt └── lecture1.iml ├── lecture2 ├── src │ ├── questions │ │ ├── JavaCode.java │ │ └── Answers.kt │ ├── _0EqualityAndDataClasses │ │ ├── 1Equals.kt │ │ └── 2DataClass.kt │ ├── _2Extensions │ │ ├── Extensions.kt │ │ └── ExtensionsFromJava.java │ ├── _3ExtensionsOnCollections │ │ └── libraryFunctions.kt │ └── _1Nullability │ │ └── 1Nullability.kt └── lecture2.iml ├── lecture3 ├── src │ ├── _1Questions │ │ ├── _3EqualsArrays.kt │ │ ├── _5IsNullOrEmpty.kt │ │ ├── _5UsingIsNullOrEmptyFromJava.java │ │ ├── _7EqualsWithoutHashCode.kt │ │ ├── _1Nullability.kt │ │ ├── _2EqualsImplementation.kt │ │ ├── _4ListOfNullableVsNullableList.kt │ │ └── _6Mastermind.kt │ ├── _2When │ │ ├── WhenAndSmartCasts.kt │ │ └── When.kt │ ├── _4ClassDeclarationSyntax │ │ └── ConstructorSyntax.kt │ └── _3Conventions │ │ └── Conventions.kt └── lecture3.iml ├── lecture5 ├── src │ ├── _1Questions │ │ ├── _2MultipleThis.kt │ │ ├── _1Objects.kt │ │ ├── _6Extensions.kt │ │ ├── _5FilterFunctionFromJava.java │ │ ├── _3LazyProperty.kt │ │ └── _4FilterFunction.kt │ ├── _5ErasedGenerics │ │ ├── _1ErasedGenerics.kt │ │ └── _2Casts.kt │ ├── _4MoreInlineFunctions │ │ ├── _2LetFunction.kt │ │ ├── _3SynchronizedFunction.kt │ │ └── _1RunFunction.kt │ └── _2DelegatedProperties │ │ └── Observable.kt └── lecture5.iml └── kotlin-course.iml /lecture7/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'lecture7' 2 | 3 | -------------------------------------------------------------------------------- /lecture8/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'lecture8' 2 | 3 | -------------------------------------------------------------------------------- /lecture4/src/_2Object/Object.kt: -------------------------------------------------------------------------------- 1 | package _2Object 2 | 3 | object KSingleton { 4 | fun foo() {} 5 | } -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /lecture7/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/svtk/kotlin-course/HEAD/lecture7/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /lecture8/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/svtk/kotlin-course/HEAD/lecture8/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # kotlin-course 2 | 3 | Code examples for the kotlin course in cs center, https://compscicenter.ru/courses/kotlin/2016-autumn/. 4 | -------------------------------------------------------------------------------- /questions/src/questions/_8JavaClass.java: -------------------------------------------------------------------------------- 1 | package questions; 2 | 3 | public class _8JavaClass { 4 | public static Integer foo() { 5 | return null; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lecture6/src/_1Object/KSingleton.kt: -------------------------------------------------------------------------------- 1 | package _1Object 2 | 3 | object KSingleton { 4 | init { 5 | println("Constructor") 6 | } 7 | 8 | fun foo() = println("Foo") 9 | } -------------------------------------------------------------------------------- /questions/src/questions/_3Extensions.kt: -------------------------------------------------------------------------------- 1 | // Напишите вызов extension функции isAnswer из Java. 2 | 3 | @file:JvmName("IntExtensions") 4 | package questions 5 | 6 | fun Int.isAnswer() = this == 42 -------------------------------------------------------------------------------- /lecture1/src/_0Main.kt: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | fun main(args: Array) { 4 | val name = if (args.size > 0) args[0] else "Kotlin" 5 | println("Hello, $name!") 6 | 7 | // ${} 8 | } 9 | -------------------------------------------------------------------------------- /lecture6/src/_2Reified/_1Reified.kt: -------------------------------------------------------------------------------- 1 | package _2Reified 2 | 3 | inline fun isA(value: Any) = value is T 4 | 5 | fun main(args: Array) { 6 | println(isA("abc")) 7 | println(isA(123)) 8 | } -------------------------------------------------------------------------------- /lecture4/src/_1ClassDeclaration/InnerAndNestedClasses.kt: -------------------------------------------------------------------------------- 1 | package _1ClassDeclaration 2 | 3 | class A { 4 | // implicit reference to A 5 | inner class Inner 6 | 7 | // static 8 | // no implicit reference to A 9 | class Nested 10 | } -------------------------------------------------------------------------------- /lecture4/src/_2Object/JSingleton.java: -------------------------------------------------------------------------------- 1 | package _2Object; 2 | 3 | public class JSingleton { 4 | public final static JSingleton INSTANCE = new JSingleton(); 5 | 6 | private JSingleton() { 7 | } 8 | 9 | public void foo() {} 10 | } 11 | -------------------------------------------------------------------------------- /lecture4/src/_2Object/UseKotlinObjectFromJava.java: -------------------------------------------------------------------------------- 1 | package _2Object; 2 | 3 | public class UseKotlinObjectFromJava { 4 | public static void main(String[] args) { 5 | JSingleton.INSTANCE.foo(); 6 | KSingleton.INSTANCE.foo(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lecture1/src/_10BuildString.kt: -------------------------------------------------------------------------------- 1 | package buildString 2 | 3 | fun main(args: Array) { 4 | val s = buildString { 5 | for (i in 1..9) { 6 | append(i) 7 | } 8 | append('!') 9 | } 10 | println(s) //123456789! 11 | } -------------------------------------------------------------------------------- /lecture2/src/questions/JavaCode.java: -------------------------------------------------------------------------------- 1 | package questions; 2 | 3 | public class JavaCode { 4 | public static void foo(String[] args) { 5 | 6 | } 7 | 8 | public static boolean isNotDigit(char c) { 9 | return c < '0' || c > '9'; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /lecture6/src/_2Reified/_5RestrictionsOnReifiedTypeParameters.kt: -------------------------------------------------------------------------------- 1 | package _2Reified 2 | 3 | // Какой из следующих вызовов не будет компилироваться и почему? 4 | 5 | inline fun foo(t: T) { 6 | // bar(t) 7 | } 8 | 9 | fun bar(t: T) { 10 | // foo(t) 11 | } -------------------------------------------------------------------------------- /lecture6/src/_0Questions/_2SafeCast.kt: -------------------------------------------------------------------------------- 1 | package _0Questions 2 | 3 | fun main(args: Array) { 4 | // Объявите переменную i так, чтобы одно из приведений типа ниже кидало исключение, а другое возвращало null. 5 | val i = "" 6 | println(i as Int?) 7 | println(i as? Int) 8 | } -------------------------------------------------------------------------------- /lecture6/src/_1Object/JMain.java: -------------------------------------------------------------------------------- 1 | package _1Object; 2 | 3 | public class JMain { 4 | public static void main(String[] args) { 5 | Class singletonClass = JSingleton.class; 6 | System.out.println("==="); 7 | JSingleton.INSTANCE.foo(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /lecture7/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Oct 31 14:54:20 MSK 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-all.zip 7 | -------------------------------------------------------------------------------- /lecture8/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Oct 31 23:41:30 MSK 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-all.zip 7 | -------------------------------------------------------------------------------- /lecture1/src/_8Pair.kt: -------------------------------------------------------------------------------- 1 | package pair 2 | 3 | // Pair - просто класс стандартной библиотеки 4 | fun functionReturningPair() = Pair(42, "answer") 5 | 6 | fun main(args: Array) { 7 | // можно сразу присваивать двум переменным 8 | val (i, s) = functionReturningPair() 9 | println(i) 10 | } -------------------------------------------------------------------------------- /lecture3/src/_1Questions/_3EqualsArrays.kt: -------------------------------------------------------------------------------- 1 | package _1Questions 2 | 3 | fun main(args: Array) { 4 | 5 | // никакой специальной оптимизации для сравнения массивов нет 6 | 7 | println(arrayOf(1, 2) == arrayOf(1, 2)) // false 8 | 9 | println(listOf(1, 2) == listOf(1, 2)) // true 10 | } -------------------------------------------------------------------------------- /lecture4/src/_1ClassDeclaration/InnerAndNestedClassesInJava.java: -------------------------------------------------------------------------------- 1 | package _1ClassDeclaration; 2 | 3 | public class InnerAndNestedClassesInJava { 4 | 5 | // implicit reference to A 6 | class Inner {} 7 | 8 | // static 9 | // no implicit reference to A 10 | static class Nested {} 11 | } 12 | -------------------------------------------------------------------------------- /lecture5/src/_1Questions/_2MultipleThis.kt: -------------------------------------------------------------------------------- 1 | package _1Questions 2 | 3 | // Исправьте ошибку в некомпилирующемся коде ниже 4 | 5 | class A { 6 | class B 7 | inner class C { 8 | // fun B.foo() = listOf(this@A, this@B, this@C) 9 | fun B.foo() = listOf(this@A, this, this@C) 10 | } 11 | } -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /questions/src/questions/_3ExtensionsFromJava.java: -------------------------------------------------------------------------------- 1 | package questions; 2 | 3 | public class _3ExtensionsFromJava { 4 | public static void main(String[] args) { 5 | int i = 41; 6 | boolean isAnswer = IntExtensions.isAnswer(i); 7 | System.out.println(isAnswer); // false 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lecture2/src/_0EqualityAndDataClasses/1Equals.kt: -------------------------------------------------------------------------------- 1 | package _0EqualityAndDataClasses 2 | 3 | fun main(args: Array) { 4 | val set1 = setOf(1, 2, 3) 5 | val set2 = setOf(1, 2, 3) 6 | 7 | // проверяет равенство ссылок 8 | println(set1 === set2) 9 | 10 | // вызывает equals 11 | println(set1 == set2) 12 | } -------------------------------------------------------------------------------- /lecture3/src/_1Questions/_5IsNullOrEmpty.kt: -------------------------------------------------------------------------------- 1 | package _1Questions 2 | 3 | fun main(args: Array) { 4 | val s1: String? = null 5 | val s2: String? = "" 6 | println(s1.isNullOrEmpty() && s2.isNullOrEmpty()) // true 7 | } 8 | 9 | fun String?.isNullOrEmpty(): Boolean = 10 | this == null || this.isEmpty() -------------------------------------------------------------------------------- /lecture3/src/_1Questions/_5UsingIsNullOrEmptyFromJava.java: -------------------------------------------------------------------------------- 1 | package _1Questions; 2 | 3 | import static _1Questions._5IsNullOrEmptyKt.isNullOrEmpty; 4 | 5 | public class _5UsingIsNullOrEmptyFromJava { 6 | public static void main(String[] args) { 7 | isNullOrEmpty("abc"); 8 | isNullOrEmpty(null); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lecture4/src/_3CompanionObject/UsingCompanionObjectsFromJava.java: -------------------------------------------------------------------------------- 1 | package _3CompanionObject; 2 | 3 | public class UsingCompanionObjectsFromJava { 4 | 5 | public static void main(String[] args) { 6 | 7 | A.Companion.create(); 8 | // A.create() - doesn't compile 9 | 10 | A.staticFunction(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lecture6/src/_2Reified/_3ClassReferences.kt: -------------------------------------------------------------------------------- 1 | package _2Reified 2 | 3 | import java.util.* 4 | 5 | class Service 6 | 7 | fun main(args: Array) { 8 | 9 | ServiceLoader.load(Service::class.java) 10 | 11 | loadService() 12 | } 13 | 14 | inline fun loadService() = 15 | ServiceLoader.load(T::class.java) 16 | -------------------------------------------------------------------------------- /lecture1/src/_3Classes.kt: -------------------------------------------------------------------------------- 1 | package classes 2 | 3 | // скомпилированная версия совпадает с классом javaCode.Person 4 | 5 | class Person(val name: String, var age: Int) 6 | 7 | fun main(args: Array) { 8 | // нет слова new, конструктор вызывается как обычная функция 9 | val person = Person("Alice", 26) 10 | 11 | println(person.name) 12 | } -------------------------------------------------------------------------------- /questions/src/questions/_4Todo.kt: -------------------------------------------------------------------------------- 1 | package questions 2 | 3 | // Реализуйте функцию todo (выписав явно тип возвращаемого значения) так, чтобы 4 | // ее результат можно было присвоить в переменную любого типа. 5 | 6 | fun main(args: Array) { 7 | val i: Int = todo() 8 | val s: String = todo() 9 | } 10 | 11 | fun todo(): Nothing = throw Exception() -------------------------------------------------------------------------------- /questions/src/questions/_14NPEPureKotlin.kt: -------------------------------------------------------------------------------- 1 | package questions 2 | 3 | // Bonus. 4 | // Завершите объявление класса A, так чтобы во время создания элемента B кидалось NPE. 5 | 6 | open class A(open val value: String) { 7 | val x = value.length 8 | } 9 | 10 | class B(override val value: String) : A(value) 11 | 12 | fun main(args: Array) { 13 | B("a") 14 | } -------------------------------------------------------------------------------- /lecture8/src/main/_1Questions/ApplyExample.kt: -------------------------------------------------------------------------------- 1 | package _1Questions 2 | 3 | fun main(args: Array) { 4 | val s = StringBuilder().apply { 5 | for (i in 0..9) { 6 | append(i) 7 | } 8 | }.toString() 9 | println(s) // 0123456789 10 | } 11 | 12 | inline fun T.apply(block: T.() -> Unit): T { 13 | this.block() 14 | return this 15 | } -------------------------------------------------------------------------------- /lecture1/src/_4PropertiesWithCustomAccessors.kt: -------------------------------------------------------------------------------- 1 | package classes 2 | 3 | class Rectangle(val height: Int, val width: Int) { 4 | // можно переопределять getter (и setter тоже) 5 | val isSquare: Boolean 6 | get() { 7 | return height == width 8 | } 9 | } 10 | 11 | fun main(args: Array) { 12 | val rectangle = Rectangle(41, 43) 13 | println(rectangle.isSquare) 14 | } -------------------------------------------------------------------------------- /lecture5/src/_5ErasedGenerics/_1ErasedGenerics.kt: -------------------------------------------------------------------------------- 1 | package _5ErasedGenerics 2 | 3 | val list1: List = listOf("a", "b") 4 | val list2: List = listOf(1, 2, 3) 5 | 6 | fun main(args: Array) { 7 | foo(list1) 8 | foo(list2) 9 | } 10 | 11 | fun foo(list: Collection) { 12 | // generics are erased 13 | // if (list is List) { 14 | // } 15 | if (list is List<*>) {} 16 | } 17 | -------------------------------------------------------------------------------- /lecture7/src/main/_1LambdaWithReceiver/_2Apply.kt: -------------------------------------------------------------------------------- 1 | package _1LambdaWithReceiver 2 | 3 | fun buildString3( 4 | builderAction: StringBuilder.() -> Unit 5 | ): String { 6 | val sb = StringBuilder() 7 | sb.builderAction() 8 | return sb.toString() 9 | } 10 | 11 | fun buildString4( 12 | builderAction: StringBuilder.() -> Unit 13 | ): String = 14 | StringBuilder().apply(builderAction).toString() -------------------------------------------------------------------------------- /lecture3/src/_1Questions/_7EqualsWithoutHashCode.kt: -------------------------------------------------------------------------------- 1 | package _1Questions 2 | 3 | class Value(val i: Int) { 4 | override fun equals(other: Any?): Boolean{ 5 | if (this === other) return true 6 | if (other !is Value) return false 7 | return i == other.i 8 | } 9 | } 10 | 11 | fun main(args: Array) { 12 | val set = hashSetOf(Value(1)) 13 | println(set.contains(Value(1))) // false 14 | } -------------------------------------------------------------------------------- /lecture6/src/_1Object/Main.kt: -------------------------------------------------------------------------------- 1 | package _1Object 2 | 3 | // В каком порядке будет напечатано Constructor, === и Foo? (Для случая Java класса и Kotlin object'а) 4 | fun main(args: Array) { 5 | // java 6 | JSingleton::class.java 7 | println("===") 8 | JSingleton.INSTANCE.foo() 9 | 10 | println() 11 | 12 | // kotlin 13 | KSingleton::class 14 | println("===") 15 | KSingleton.foo() 16 | } -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lecture3/src/_1Questions/_1Nullability.kt: -------------------------------------------------------------------------------- 1 | package _1Questions 2 | 3 | class Name(val value: String?) 4 | 5 | fun isFoo1(n: Name) = n.value == "foo" 6 | fun isFoo2(n: Name?) = true//n.value == "foo" 7 | fun isFoo3(n: Name?) = n != null && n.value == "foo" 8 | fun isFoo4(n: Name?) = n?.value == "foo" 9 | 10 | fun main(args: Array) { 11 | // isFoo1(null) 12 | isFoo2(null) 13 | isFoo3(null) 14 | isFoo4(null) 15 | } -------------------------------------------------------------------------------- /lecture1/src/_6Collections.kt: -------------------------------------------------------------------------------- 1 | package collections 2 | 3 | fun main(args: Array) { 4 | val list = listOf(1, 2, 3) 5 | for (i in list) { 6 | println(i) 7 | } 8 | // не компилируется, нет методов, меняющих list: 9 | // list.add(4) 10 | println(list) 11 | 12 | val mutableList = mutableListOf(1, 2, 3) 13 | mutableList.add(4) 14 | println(mutableList) 15 | 16 | //read-only vs mutable 17 | } 18 | -------------------------------------------------------------------------------- /lecture2/src/_2Extensions/Extensions.kt: -------------------------------------------------------------------------------- 1 | // можно специфицировать имя класса, в котором будут жить функции и проперти, объявленные на уровне пакета 2 | //@file:JvmName("StringUtil") 3 | package _2Extensions 4 | 5 | fun String.lastChar() = 6 | this.get(this.length - 1) 7 | 8 | // 'this' можно опустить 9 | fun String.lastChar1() = 10 | get(length - 1) 11 | 12 | fun test() { 13 | // можно вызвать из completion 14 | "abc".lastChar() 15 | } -------------------------------------------------------------------------------- /.idea/libraries/KotlinJavaRuntime.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /lecture6/src/_0Questions/_3SafeCastsAndErasedGenerics.kt: -------------------------------------------------------------------------------- 1 | package _0Questions 2 | 3 | fun foo(c: Collection) { 4 | println(c as List) 5 | } 6 | 7 | fun main(args: Array) { 8 | // В каких из случаев ниже будет брошено исключение ClassCastException? 9 | 10 | foo(listOf("a", "b", "c")) 11 | foo(listOf(1, 2, 3)) 12 | foo(setOf("a", "b", "c")) 13 | // ClassCastException: java.util.LinkedHashSet cannot be cast to java.util.List 14 | } -------------------------------------------------------------------------------- /questions/src/questions/_8NPEKotlinJava.kt: -------------------------------------------------------------------------------- 1 | package questions 2 | 3 | // Реализуйте функцию foo на Java, так, чтобы 4 | // функция unsafe компилировалась, но при этом при ее выполнении вылетало исключение NullPointerException. 5 | // Функция safe при этом не должна кидать NPE. 6 | 7 | fun unsafe() = _8JavaClass.foo() + 1 8 | 9 | fun safe() = _8JavaClass.foo()?.let { it + 1 } 10 | 11 | fun main(args: Array) { 12 | println(unsafe()) 13 | println(safe()) 14 | } -------------------------------------------------------------------------------- /lecture3/src/_2When/WhenAndSmartCasts.kt: -------------------------------------------------------------------------------- 1 | package _2When; 2 | 3 | import _2When.Expr.* 4 | 5 | sealed class Expr { 6 | class Num(val value : Int) : Expr() 7 | class Sum(val left : Expr, val right : Expr) : Expr() 8 | } 9 | 10 | fun eval(e: Expr): Int = when (e) { 11 | is Num -> e.value 12 | is Sum -> eval(e.left) + eval(e.right) 13 | } 14 | 15 | fun main(args: Array) { 16 | // 1 + (2 + 3) 17 | println(eval(Sum(Num(1), Sum(Num(2), Num(3))))) 18 | } -------------------------------------------------------------------------------- /lecture5/src/_1Questions/_1Objects.kt: -------------------------------------------------------------------------------- 1 | package _1Questions.objects 2 | 3 | // Напишите все строки, в которых компилятор выдаст ошибку. 4 | class A { 5 | fun foo() {} 6 | 7 | inner class B { 8 | fun b() = this@A.foo() 9 | } 10 | 11 | /* 12 | class C { 13 | fun c() = this@A.foo() 14 | } 15 | 16 | inner object D { 17 | fun d() = this@A.foo() 18 | } 19 | 20 | object E { 21 | fun e() = this@A.foo() 22 | } 23 | */ 24 | } -------------------------------------------------------------------------------- /lecture5/src/_5ErasedGenerics/_2Casts.kt: -------------------------------------------------------------------------------- 1 | package _5ErasedGenerics 2 | 3 | fun printSum(c: Collection<*>) { 4 | val intList = c as? List 5 | ?: throw IllegalArgumentException("List is expected") 6 | println(intList.sum()) 7 | } 8 | 9 | fun main(args: Array) { 10 | 11 | printSum(listOf(1, 2, 3)) 12 | // ok 13 | 14 | // printSum(setOf(1, 2, 3)) 15 | // IllegalArgumentException: List is expected 16 | 17 | printSum(listOf("a", "b", "c")) 18 | } -------------------------------------------------------------------------------- /lecture1/src/_2Functions.kt: -------------------------------------------------------------------------------- 1 | package functions 2 | 3 | fun max(a: Int, b: Int): Int { 4 | return if (a < b) a else b 5 | } 6 | 7 | // краткий синтаксис для функции, возвращающей одно выражение 8 | fun max2(a: Int, b: Int) = if (a < b) a else b 9 | 10 | // можно писать значения аргументов по умолчанию 11 | fun sum(a: Int, b: Int, c: Int = 0) = a + b + c 12 | 13 | fun use() { 14 | sum(1, 2) 15 | sum(1, 2, 3) 16 | // можно передавать аргументы по имени 17 | sum(b = 2, a = 1) 18 | } -------------------------------------------------------------------------------- /lecture5/src/_4MoreInlineFunctions/_2LetFunction.kt: -------------------------------------------------------------------------------- 1 | package _4MoreInlineFunctions 2 | 3 | fun sendEmailTo(email: String) { /*...*/ } 4 | 5 | fun example(email: String?) { 6 | 7 | if (email != null) sendEmailTo(email) 8 | email?.let { e -> sendEmailTo(e) } 9 | 10 | val e = getEmail() 11 | if (e != null) sendEmailTo(e) 12 | 13 | getEmail()?.let { sendEmailTo(it) } 14 | } 15 | 16 | inline fun T.let(block: (T) -> R): R = block(this) 17 | 18 | fun getEmail(): String? = null -------------------------------------------------------------------------------- /lecture6/src/_0Questions/_1SafeCastAndNull.kt: -------------------------------------------------------------------------------- 1 | package _0Questions 2 | 3 | // as - кидает исключение ClassCastException, если не удалось привести к нужному типу 4 | // as? - возвращает null, если не удалось привести к нужному типу 5 | // as Int, as? Int 6 | // as Int?, as? Int? 7 | 8 | fun main(args: Array) { 9 | // В каких из следующих приведений типа произойдет исключение? 10 | val i = null 11 | println(i as Int) 12 | println(i as Int?) 13 | println(i as? Int) 14 | } -------------------------------------------------------------------------------- /lecture4/src/_4DelegatedProperties/LazyProperty.kt: -------------------------------------------------------------------------------- 1 | package _4DelegatedProperties 2 | 3 | class Email { /*...*/ } 4 | 5 | fun loadEmails(person: Person): List { 6 | println("Load emails for ${person.name}") 7 | return listOf(/*...*/) 8 | } 9 | 10 | class Person(val name: String) { 11 | val emails by lazy { loadEmails(this) } 12 | } 13 | 14 | fun main(args: Array) { 15 | val p = Person("Alice") 16 | println("---") 17 | p.emails 18 | println("---") 19 | p.emails 20 | } -------------------------------------------------------------------------------- /lecture8/src/main/_3DropdownExample/dropdown-snippet.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lecture2/src/_2Extensions/ExtensionsFromJava.java: -------------------------------------------------------------------------------- 1 | package _2Extensions; 2 | 3 | import static _2Extensions.ExtensionsKt.lastChar; 4 | 5 | public class ExtensionsFromJava { 6 | public static void main(String[] args) { 7 | // из Java вызывается как обычный статический метод, принимающий String в качестве первого параметра 8 | char ch = lastChar("abc"); 9 | 10 | // если мы добавим аннотацию @file:JvmName("StringUtil") 11 | // char ch = StringUtil.lastChar("abc"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lecture1/src/javaCode/Person.java: -------------------------------------------------------------------------------- 1 | package javaCode; 2 | 3 | public class Person { 4 | private final String name; 5 | private final int age; 6 | 7 | public Person(String name, int age) { 8 | this.name = name; 9 | this.age = age; 10 | } 11 | 12 | public String getName() { 13 | return name; 14 | } 15 | 16 | public int getAge() { 17 | return age; 18 | } 19 | 20 | public static boolean isNotDigit(char c) { 21 | return c < '0' || c > '9'; 22 | } 23 | } -------------------------------------------------------------------------------- /lecture2/src/_0EqualityAndDataClasses/2DataClass.kt: -------------------------------------------------------------------------------- 1 | package _0EqualityAndDataClasses 2 | 3 | // Добавление модификатора data заставляет компилятор сгенерировать полезные методы, 4 | // такие как equals, hashCode, toString. 5 | data class Person( 6 | val name: String, 7 | val age: Int) 8 | 9 | // Можно убрать data и посмотреть, что поменяется. 10 | fun main(args: Array) { 11 | val person1 = Person("Alice", 21) 12 | val person2 = Person("Alice", 21) 13 | println(person1) 14 | println(person1 == person2) 15 | } -------------------------------------------------------------------------------- /lecture7/src/main/_2HTMLBuilders/_1SimpleExample.kt: -------------------------------------------------------------------------------- 1 | package _2HTMLBuilders 2 | 3 | import kotlinx.html.stream.createHTML 4 | import kotlinx.html.table 5 | import kotlinx.html.td 6 | import kotlinx.html.tr 7 | 8 | fun createSimpleTable() = 9 | createHTML().table { 10 | tr { 11 | for (i in 1..3) { 12 | td { +"$i" } 13 | } 14 | td { +"cell" } 15 | } 16 | } 17 | 18 | fun main(args: Array) { 19 | println(createSimpleTable()) 20 | } -------------------------------------------------------------------------------- /lecture3/src/_1Questions/_2EqualsImplementation.kt: -------------------------------------------------------------------------------- 1 | package _1Questions 2 | 3 | fun eq1(s1: String?, s2: String?): Boolean { 4 | return s1 == s2 5 | } 6 | 7 | fun eq2(s1: String?, s2: String?): Boolean = 8 | if (s1 === null) s2 === null else s1.equals(s2) 9 | 10 | fun eq3(s1: String?, s2: String?): Boolean = 11 | s1?.equals(s2) ?: (s2 === null) 12 | 13 | fun main(args: Array) { 14 | eq1("abc", "abc") // true 15 | eq1(null, "abc") // false 16 | eq1("abc", null) // false 17 | eq1(null, null) // true 18 | } -------------------------------------------------------------------------------- /.idea/libraries/Gradle__junit_junit_4_11.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /lecture1/lecture1.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /lecture2/lecture2.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /lecture3/lecture3.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /lecture4/lecture4.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /lecture5/lecture5.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /questions/questions.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /lecture1/src/_7IteratingOverMaps.kt: -------------------------------------------------------------------------------- 1 | package controlStructures 2 | 3 | import java.util.* 4 | 5 | fun iteratingOverMap() { 6 | val binaryReps = HashMap() 7 | 8 | for (i in 1..10) { 9 | binaryReps[i] = Integer.toBinaryString(i) 10 | } 11 | 12 | for ((number, binary) in binaryReps) { 13 | println("$number = $binary") 14 | } 15 | } 16 | 17 | fun main(args: Array) { 18 | iteratingOverMap() 19 | 20 | for ((index, element) in listOf("a", "b", "c").withIndex()) { 21 | println("$index $element") 22 | } 23 | } -------------------------------------------------------------------------------- /lecture4/src/_4DelegatedProperties/MapAccessors.kt: -------------------------------------------------------------------------------- 1 | package _4DelegatedProperties 2 | 3 | import kotlin.reflect.KProperty 4 | 5 | operator fun Map.getValue(thisRef: Any?, property: KProperty<*>): V1 6 | = this[property.name] as V1 7 | 8 | 9 | /*operator fun MutableMap.getValue(thisRef: Any?, property: KProperty<*>): V 10 | = this[property.name] as V 11 | 12 | operator fun MutableMap.setValue(thisRef: Any?, property: KProperty<*>, value: V) { 13 | this[property.name] = value 14 | }*/ 15 | 16 | -------------------------------------------------------------------------------- /lecture6/src/_1Object/JSingleton.java: -------------------------------------------------------------------------------- 1 | package _1Object; 2 | 3 | // В Java инициализация статического поля происходит при первом обращении (а не при загрузке класса). 4 | // Для object в Котлине генерируется код, эквивалентный Java классу. 5 | 6 | public class JSingleton { 7 | public final static JSingleton INSTANCE; 8 | 9 | static { 10 | INSTANCE = new JSingleton(); 11 | } 12 | 13 | private JSingleton() { 14 | System.out.println("Constructor"); 15 | } 16 | 17 | public void foo() { 18 | System.out.println("Foo"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lecture1/src/javaCode/Rectangle.java: -------------------------------------------------------------------------------- 1 | package javaCode; 2 | 3 | public class Rectangle { 4 | private final int width; 5 | private final int height; 6 | private final boolean isSquare; 7 | 8 | public Rectangle(int width, int height) { 9 | this.width = width; 10 | this.height = height; 11 | this.isSquare = width == height; 12 | } 13 | 14 | public int getWidth() { 15 | return width; 16 | } 17 | 18 | public int getHeight() { 19 | return height; 20 | } 21 | 22 | public boolean isSquare() { 23 | return isSquare; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lecture6/lecture6.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /lecture3/src/_4ClassDeclarationSyntax/ConstructorSyntax.kt: -------------------------------------------------------------------------------- 1 | package _4ClassDeclarationSyntax 2 | 3 | // полный синтаксис: явно объявить параметр конструктора и блок инициализации init 4 | class Foo1(_i: Int) { // объявляем параметр конструктора 5 | val i: Int // объявляем property 6 | 7 | init { // блок инициализации init - по сути тело конструктора 8 | this.i = _i // инициализуем property 9 | } 10 | } 11 | 12 | 13 | // краткий синтаксис: добавить val (или var) к параметру конструктора, 14 | // и это автоматически сгенерирует соответствующий property 15 | class Foo2(val i: Int) -------------------------------------------------------------------------------- /.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /lecture5/src/_4MoreInlineFunctions/_3SynchronizedFunction.kt: -------------------------------------------------------------------------------- 1 | package _4MoreInlineFunctions 2 | 3 | import java.util.concurrent.locks.Lock 4 | import java.util.concurrent.locks.ReentrantLock 5 | import kotlin.concurrent.withLock 6 | 7 | inline fun synchronized(lock: Lock, action: () -> T): T { 8 | lock.lock() 9 | try { 10 | return action() 11 | } finally { 12 | lock.unlock() 13 | } 14 | } 15 | 16 | fun main(args: Array) { 17 | 18 | val l = ReentrantLock() 19 | 20 | synchronized(l) { 21 | // ... 22 | } 23 | 24 | l.withLock { 25 | // ... 26 | } 27 | } -------------------------------------------------------------------------------- /lecture4/src/_5MoreAboutOperationsOnCollections/UseAnonymousClass.java: -------------------------------------------------------------------------------- 1 | package _5MoreAboutOperationsOnCollections; 2 | 3 | import kotlin.jvm.functions.Function1; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class UseAnonymousClass { 9 | public static void main(String[] args) { 10 | List stringList = new ArrayList<>(); 11 | InlineFunctionsKt.filter(stringList, new Function1() { 12 | @Override 13 | public Boolean invoke(String s) { 14 | return !s.isEmpty(); 15 | } 16 | }); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lecture1/src/_1Variables.kt: -------------------------------------------------------------------------------- 1 | package variables 2 | 3 | fun main(args: Array) { 4 | // read-only 5 | val question: String = 6 | "life, the universe, " + 7 | "and everything" 8 | println("$question?") 9 | 10 | // mutable 11 | var answer: Int = 0 12 | answer = 42 13 | println(answer) 14 | 15 | // тип переменной выводится из инициализатора, если не указан явно и не может поменяться 16 | // answer = "no answer" 17 | 18 | // val обозначает неизменяемую ссылку, а не изменяемый объект 19 | val languages = mutableListOf("Java") 20 | languages.add("Kotlin") 21 | } -------------------------------------------------------------------------------- /kotlin-course.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /lecture4/src/_4DelegatedProperties/DelegatesTheory.kt: -------------------------------------------------------------------------------- 1 | package _4DelegatedProperties 2 | 3 | import kotlin.reflect.KProperty 4 | 5 | class Type 6 | 7 | class Delegate { 8 | operator fun getValue(thisRef: Foo, property: KProperty<*>): Type = TODO() 9 | 10 | operator fun setValue(thisRef: Foo, property: KProperty<*>, value: Type) { TODO() } 11 | } 12 | 13 | class Foo { 14 | var p: Type by Delegate() 15 | } 16 | 17 | /* 18 | class Foo { 19 | private val p$delegate = Delegate() 20 | var p: Type 21 | set(value: Type) = p$delegate.setValue(..., value) 22 | get() = p$delegate.getValue(...) 23 | } 24 | */ 25 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_1_0_4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /lecture5/src/_1Questions/_6Extensions.kt: -------------------------------------------------------------------------------- 1 | package _1Questions.extensions 2 | 3 | // Напишите реализацию member extension функций record & unaryPlus, 4 | // чтобы код внизу компилировался. 5 | 6 | class Words { 7 | private val list = mutableListOf() 8 | 9 | fun String.record() { 10 | list += this 11 | } 12 | 13 | operator fun String.unaryPlus() { 14 | this.record() 15 | } 16 | 17 | override fun toString() = list.toString() 18 | } 19 | 20 | fun main(args: Array) { 21 | val words = Words() 22 | with(words) { 23 | "one".record() 24 | + "two" 25 | } 26 | println(words) 27 | } 28 | 29 | -------------------------------------------------------------------------------- /lecture7/src/main/_1LambdaWithReceiver/_3ApplyWithAndRun.kt: -------------------------------------------------------------------------------- 1 | package _1LambdaWithReceiver 2 | 3 | fun main(args: Array) { 4 | val map = mutableMapOf(1 to "one") 5 | with (map) { 6 | this[2] = "two" 7 | } 8 | map.apply { this[3] = "three" } 9 | map.run { this[4] = "four" } 10 | println(map) 11 | 12 | } 13 | 14 | // the declarations copied from the standard library 15 | 16 | inline fun with(receiver: T, block: T.() -> R): R = 17 | receiver.block() 18 | 19 | inline fun T.run(block: T.() -> R): R = block() 20 | 21 | inline fun T.apply(block: T.() -> Unit): T { 22 | this.block() 23 | return this 24 | } -------------------------------------------------------------------------------- /.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_runtime_1_0_4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /lecture4/src/_3CompanionObject/CompanionObject.kt: -------------------------------------------------------------------------------- 1 | package _3CompanionObject 2 | 3 | interface Factory { 4 | fun create(): T 5 | } 6 | 7 | // В Java статические методы не могут имплементить методы интерфейсов. 8 | // В Kotlin методы companion object'а могут имплементить методы интерфейсов. 9 | class A { 10 | private constructor() 11 | 12 | companion object : Factory { 13 | override fun create(): A { 14 | return A() 15 | } 16 | 17 | // Чтобы эти методы были доступны из Java как статические методы класса A, 18 | // нужна специальная аннотация 19 | @JvmStatic 20 | fun staticFunction() {} 21 | } 22 | } -------------------------------------------------------------------------------- /lecture4/src/_5MoreAboutOperationsOnCollections/InlineFunctions.kt: -------------------------------------------------------------------------------- 1 | package _5MoreAboutOperationsOnCollections 2 | 3 | fun main(args: Array) { 4 | val list = listOf(1, 2, 3, 4, 5) 5 | 6 | list.filter { it % 2 == 1 } // [1, 3, 5] 7 | // this method is inlined 8 | 9 | list.filter { it % 2 == 1 }.map { it * 2 } // [1, 9 25] 10 | // eager evaluation 11 | // intermediate collection is created 12 | } 13 | 14 | inline fun Iterable.filter(predicate: (T) -> Boolean): List { 15 | val destination = arrayListOf() 16 | for (element in this) if (predicate(element)) destination.add(element) 17 | return destination 18 | } -------------------------------------------------------------------------------- /lecture3/src/_1Questions/_4ListOfNullableVsNullableList.kt: -------------------------------------------------------------------------------- 1 | package _1Questions 2 | 3 | fun task3(list1: List, list2: List?) { 4 | 5 | list1.size 6 | list2?.size 7 | // 8 | val i: Int? = list1.get(0) 9 | 10 | val j: Int = list2?.get(0) ?: 0 11 | val j1: Int? = list2?.get(0) 12 | } 13 | 14 | // List - список, в котором могут храниться нулевые ссылки 15 | // [1, null, 2] 16 | 17 | // List? - переменная такого типа сама может быть null, но при этом в списке хранятся только ненулевые элементы 18 | // null | [1, 2, 3] 19 | 20 | // List? - и сам список, и элементы в нем могут быть null 21 | // null | [1, null, 2] 22 | -------------------------------------------------------------------------------- /lecture7/src/main/_1LambdaWithReceiver/_1LambdaVsLambdaWithReceiver.kt: -------------------------------------------------------------------------------- 1 | package _1LambdaWithReceiver 2 | 3 | fun main(args: Array) { 4 | // regular lambda 5 | val sum = { x: Int, y: Int -> 6 | x + y 7 | } 8 | 9 | // lambda with receiver 10 | val appendExcl: StringBuilder.() -> Unit = { 11 | this.append("!") 12 | } 13 | 14 | // lambda with receiver with non-empty list of parameters 15 | val appendTwice: StringBuilder.(Char) -> Unit = { 16 | append("$it$it") 17 | } 18 | 19 | println(sum(1, 2)) 20 | val sb = StringBuilder() 21 | sb.appendExcl() 22 | sb.appendTwice('1') 23 | println(sb) //!11 24 | } -------------------------------------------------------------------------------- /lecture4/src/_4DelegatedProperties/MapExample.kt: -------------------------------------------------------------------------------- 1 | package _4DelegatedProperties 2 | 3 | class Person1 { 4 | private val _attributes = hashMapOf() 5 | fun setAttribute(attrName: String, value: String) { 6 | _attributes[attrName] = value 7 | } 8 | 9 | // по конвенции вызываются библиотечные методы, похожие на объявления в MapAccessors.kt 10 | val name: String by _attributes 11 | } 12 | 13 | fun main(args: Array) { 14 | val p = Person1() 15 | val data = mapOf("name" to "Alice", "phoneNumber" to "1234567") 16 | for ((attrName, value) in data) { 17 | p.setAttribute(attrName, value) 18 | } 19 | println(p.name) 20 | } -------------------------------------------------------------------------------- /lecture5/src/_2DelegatedProperties/Observable.kt: -------------------------------------------------------------------------------- 1 | package _2DelegatedProperties 2 | 3 | import kotlin.properties.Delegates 4 | import kotlin.reflect.KProperty 5 | 6 | class Person( 7 | val name: String, age: Int, salary: Int 8 | ) { 9 | private val observer = { 10 | prop: KProperty<*>, oldValue: Int, newValue: Int -> 11 | println("Property value $oldValue has changed to $newValue") 12 | } 13 | var age: Int by Delegates.observable(age, observer) 14 | var salary: Int by Delegates.observable(salary, observer) 15 | } 16 | 17 | fun main(args: Array) { 18 | val person = Person("Alice", 25, 2000) 19 | person.age++ 20 | person.salary += 100 21 | } -------------------------------------------------------------------------------- /questions/src/questions/_1Zip.kt: -------------------------------------------------------------------------------- 1 | package questions 2 | 3 | fun main(args: Array) { 4 | println("abcde" zip "123") // [(a, 1), (b, 2), (c, 3)] 5 | } 6 | 7 | // Допишите реализацию функции zip. Пример использования представлен ниже. 8 | 9 | /* 10 | * Returns a list of pairs built from characters of both strings with same indexes. 11 | * List has length of shortest string. 12 | */ 13 | infix fun String.zip(other: String): List> { 14 | val result = arrayListOf>() 15 | val length = Math.min(length, other.length) 16 | for (index in 0 until length) { 17 | result += (this[index] to other[index]) 18 | } 19 | return result 20 | } -------------------------------------------------------------------------------- /lecture5/src/_1Questions/_5FilterFunctionFromJava.java: -------------------------------------------------------------------------------- 1 | package _1Questions; 2 | 3 | import kotlin.collections.CollectionsKt; 4 | 5 | import java.util.List; 6 | 7 | // Заинлайнит ли Java компилятор вызов функции filter? (Да / нет). 8 | 9 | public class _5FilterFunctionFromJava { 10 | public static void foo(List list) { 11 | List positive = 12 | CollectionsKt.filter(list, element -> element > 0); 13 | 14 | /* 15 | InlineFunctionsKt.filter(list, new Function1() { 16 | @Override 17 | public Boolean invoke(Integer i) { 18 | return i > 0; 19 | } 20 | }); 21 | */ 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lecture6/src/_2Reified/_0TypeErasure.kt: -------------------------------------------------------------------------------- 1 | package _2Reified.typeErasure 2 | 3 | // Erasure of Generic Types 4 | 5 | // Erasure of Generic Methods 6 | 7 | class Node(val data: T, val next: Node) 8 | 9 | /* 10 | public final class Node { 11 | 12 | private final Ljava/lang/Object; data 13 | 14 | public final getData()Ljava/lang/Object; 15 | 16 | private final LNode; next 17 | 18 | public final getNext()LNode; 19 | 20 | public (Ljava/lang/Object;LNode;)V 21 | } 22 | 23 | */ 24 | 25 | fun foo(t: T) {} 26 | fun > bar(t: T) {} 27 | 28 | /* 29 | public final static foo(Ljava/lang/Object;)V 30 | 31 | public final static bar(Ljava/lang/Comparable;)V 32 | */ 33 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__org_jetbrains_kotlinx_kotlinx_html_shared_0_5_11.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /lecture8/src/main/_1Questions/HTMLBuilders/HtmlExample.kt: -------------------------------------------------------------------------------- 1 | package _1Questions.HTMLBuilders 2 | 3 | fun getTitleColor() = "#b9c9fe" 4 | fun getCellColor(row: Int, column: Int) = if ((row + column) %2 == 0) "#dce4ff" else "#eff2ff" 5 | 6 | fun renderProductTable(): String { 7 | return html { 8 | table { 9 | tr (color = getTitleColor()) { 10 | td { 11 | text("Product") 12 | } 13 | td { 14 | text("Price") 15 | } 16 | td { 17 | text("Popularity") 18 | } 19 | } 20 | val products = getProducts() 21 | 22 | } 23 | }.toString() 24 | } -------------------------------------------------------------------------------- /lecture4/src/_5MoreAboutOperationsOnCollections/GeneratedCodeForInlineFunction.kt: -------------------------------------------------------------------------------- 1 | package _5MoreAboutOperationsOnCollections 2 | 3 | inline fun max(i1: T, i2: T, selector: (T) -> Int): T { 4 | val v1 = selector(i1) 5 | val v2 = selector(i2) 6 | return if (v1 >= v2) i1 else i2 7 | } 8 | data class Person(val name: String, val age: Int) 9 | 10 | fun main(args: Array) { 11 | val p1 = Person("Alice", 29) 12 | val p2 = Person("Bob", 21) 13 | 14 | val m = max(p1, p2, { it.age }) 15 | 16 | // Функция max инлайнится. 17 | // Код, генерируемый компилятором: 18 | // val i1 = p1 19 | // val i2 = p2 20 | // val v1 = i1.age 21 | // val v2 = i2.age 22 | // val m = if (v1 >= v2) i1 else i2 23 | } -------------------------------------------------------------------------------- /lecture8/src/main/_3DropdownExample/_1DropdownHtml.kt: -------------------------------------------------------------------------------- 1 | package _3DropdownExample 2 | 3 | import kotlinx.html.* 4 | import kotlinx.html.stream.createHTML 5 | 6 | fun buildDropdown() = createHTML().div(classes = "dropdown") { 7 | button(classes = "btn dropdown-toggle") { 8 | +"Dropdown" 9 | span(classes = "caret") 10 | } 11 | ul(classes = "dropdown-menu") { 12 | li { a("#") { +"Action" } } 13 | li { a("#") { +"Another action" } } 14 | li { role = "separator"; classes = setOf("divider") } 15 | li { classes = setOf("dropdown-header"); +"Header" } 16 | li { a("#") { +"Separated link" } } 17 | } 18 | } 19 | 20 | fun main(args: Array) { 21 | println(buildDropdown()) 22 | } -------------------------------------------------------------------------------- /lecture1/src/_5ControlStructures.kt: -------------------------------------------------------------------------------- 1 | package controlStructures 2 | 3 | fun whileLoop() { 4 | fun condition() = true 5 | 6 | while (condition()) { 7 | /*...​*/ 8 | } 9 | 10 | do { 11 | /*...​*/ 12 | } while (condition()) 13 | } 14 | 15 | 16 | fun forLoop() { 17 | val list = listOf(1, 2, 3) 18 | for (element in list) { 19 | print(element) 20 | } 21 | 22 | for (i in 1..9) { // включая границы 23 | print(i) 24 | } 25 | 26 | // не включая вторую границу (т.е. то же самое, что 1..9) 27 | for (i in 1 until 10) { 28 | print(i) 29 | } 30 | 31 | for (i in 9 downTo 1 step 2) { 32 | print(i) 33 | } 34 | } 35 | 36 | fun main(args: Array) { 37 | forLoop() 38 | } -------------------------------------------------------------------------------- /questions/src/questions/_9Subtypes.kt: -------------------------------------------------------------------------------- 1 | package questions 2 | 3 | fun subtype() {} 4 | 5 | open class Parent 6 | class Child: Parent() 7 | 8 | // Нарисуйте стрелочки, если соответствующие типы связаны отношением "является подтипом" 9 | // (на рисунке Child является подтипом Parent) 10 | 11 | fun main(args: Array) { 12 | subtype, List>() 13 | subtype, List>() 14 | // subtype, MutableList>() 15 | // subtype, MutableList>() 16 | 17 | // vice versa! 18 | subtype<(Child) -> Unit, (Parent) -> Unit>() 19 | 20 | // subtype() 21 | subtype() 22 | subtype() 23 | subtype() 24 | } -------------------------------------------------------------------------------- /lecture4/src/_1ClassDeclaration/ConstructorShortSynstax.kt: -------------------------------------------------------------------------------- 1 | package _1ClassDeclaration 2 | 3 | // primary constructor parameters 4 | class Foo1(_i: Int) { 5 | val i: Int 6 | 7 | // primary constructor body 8 | init { 9 | this.i = _i 10 | } 11 | } 12 | 13 | // эквивалентно декларации Foo1 14 | class Foo2(val i: Int) 15 | 16 | class Foo3 { 17 | // свойства (properties), которым не соответствует параметр конструктора, 18 | // стоит объявлять внутри тела класса 19 | var prop1 = 0 20 | val prop2 = arrayListOf() 21 | 22 | init { 23 | for (i in 0..10) { 24 | prop2.add("$i") 25 | } 26 | } 27 | } 28 | 29 | // secondary constructors 30 | class Foo4 { 31 | constructor(i: Int) 32 | constructor(s: String) 33 | } -------------------------------------------------------------------------------- /.idea/libraries/Gradle__org_jetbrains_kotlinx_kotlinx_html_jvm_0_5_11.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /lecture7/build.gradle: -------------------------------------------------------------------------------- 1 | group 'lecture7' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.0.4' 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | dependencies { 11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 12 | } 13 | } 14 | 15 | apply plugin: 'java' 16 | apply plugin: 'kotlin' 17 | 18 | sourceCompatibility = 1.5 19 | 20 | repositories { 21 | mavenCentral() 22 | jcenter() 23 | } 24 | 25 | dependencies { 26 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 27 | compile 'org.jetbrains.kotlinx:kotlinx.html.jvm:0.5.11' 28 | testCompile group: 'junit', name: 'junit', version: '4.11' 29 | } 30 | 31 | sourceSets { 32 | main.kotlin.srcDirs += 'src/main' 33 | test.kotlin.srcDirs += 'src/test' 34 | } -------------------------------------------------------------------------------- /lecture8/build.gradle: -------------------------------------------------------------------------------- 1 | group 'lecture8' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.0.4' 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | dependencies { 11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 12 | } 13 | } 14 | 15 | apply plugin: 'java' 16 | apply plugin: 'kotlin' 17 | 18 | sourceCompatibility = 1.5 19 | 20 | repositories { 21 | mavenCentral() 22 | jcenter() 23 | } 24 | 25 | dependencies { 26 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 27 | compile 'org.jetbrains.kotlinx:kotlinx.html.jvm:0.5.11' 28 | testCompile group: 'junit', name: 'junit', version: '4.11' 29 | } 30 | 31 | sourceSets { 32 | main.kotlin.srcDirs += 'src/main' 33 | test.kotlin.srcDirs += 'src/test' 34 | } -------------------------------------------------------------------------------- /.idea/modules/lecture7.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/modules/lecture8.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /lecture3/src/_1Questions/_6Mastermind.kt: -------------------------------------------------------------------------------- 1 | package _1Questions 2 | 3 | fun main(args: Array) { 4 | println(evaluateGuess("BCDF", "ACEB")) 5 | println(evaluateGuess("AAAF", "ABCA")) 6 | println(evaluateGuess("ABCA", "AAAF")) 7 | // Evaluation(positions=1, letters=1) 8 | } 9 | 10 | data class Evaluation(val positions: Int, val letters: Int) 11 | 12 | fun evaluateGuess(secret: String, guess: String): Evaluation { 13 | val positions = secret.zip(guess).count { it.first == it.second } 14 | // "BCDF", "ACEB" 15 | // (B, A), (C, C), (D, E), (F, B) 16 | 17 | val commonLetters = "ABCDEF".sumBy { ch -> 18 | Math.min(secret.count { it == ch }, guess.count { it == ch }) 19 | } 20 | // "AAAF", "ABCA" 21 | // A: min(3, 2) -> 2 22 | 23 | return Evaluation(positions, commonLetters - positions) 24 | } 25 | 26 | -------------------------------------------------------------------------------- /lecture8/src/main/_1Questions/breakfastMenu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Belgian Waffles 4 | $5.95 5 | 650 6 | 7 | 8 | 9 | Strawberry Belgian Waffles 10 | $7.95 11 | 900 12 | 13 | 14 | Berry-Berry Belgian Waffles 15 | $8.95 16 | 900 17 | 18 | 19 | French Toast 20 | $4.50 21 | 600 22 | 23 | 24 | Homestyle Breakfast 25 | $6.95 26 | 950 27 | 28 | -------------------------------------------------------------------------------- /lecture4/src/_3DelegationBy/DelegatingCollection.kt: -------------------------------------------------------------------------------- 1 | package _3DelegationBy 2 | 3 | class DelegatingCollection : Collection { 4 | private val innerList = arrayListOf() 5 | override val size: Int 6 | get() = innerList.size 7 | 8 | override fun isEmpty(): Boolean = 9 | innerList.isEmpty() 10 | 11 | override fun contains(element: T): Boolean = 12 | innerList.contains(element) 13 | 14 | override fun iterator(): Iterator = 15 | innerList.iterator() 16 | 17 | override fun containsAll(elements: Collection): Boolean = 18 | innerList.containsAll(elements) 19 | } 20 | 21 | // Можно записать короче: 22 | class DelegatingCollection1( 23 | innerList: Collection = arrayListOf() 24 | ) : Collection by innerList { 25 | override fun contains(element: T): Boolean = true 26 | } -------------------------------------------------------------------------------- /lecture8/src/main/_1Questions/BreakfastMenu.kt: -------------------------------------------------------------------------------- 1 | package _1Questions 2 | 3 | fun main(args: Array) { 4 | breakfastMenu { 5 | item { 6 | name = "Belgian Waffles" 7 | price = 5.95 8 | calories = 650 9 | } 10 | } 11 | } 12 | 13 | class BreakfastMenu { 14 | val items = mutableListOf() 15 | 16 | fun item(f: BreakfastMenuItem.() -> Unit) = 17 | BreakfastMenuItem().apply { f(); items += this } 18 | } 19 | 20 | fun breakfastMenu(init: BreakfastMenu.() -> Unit): BreakfastMenu { 21 | // can be rewritten using 'apply' as well 22 | val breakfastMenu = BreakfastMenu() 23 | breakfastMenu.init() 24 | return breakfastMenu 25 | } 26 | 27 | class BreakfastMenuItem { 28 | var name: String? = null 29 | var price: Double? = null 30 | var calories: Int? = null 31 | 32 | } -------------------------------------------------------------------------------- /lecture4/src/_5MoreAboutOperationsOnCollections/CollectionVsSequences.kt: -------------------------------------------------------------------------------- 1 | package _5MoreAboutOperationsOnCollections 2 | 3 | // Eager and lazy evaluation 4 | 5 | fun main(args: Array) { 6 | val list = listOf(1, 2, 3, 4, 5) 7 | 8 | list.map { print("m$it "); it * it } 9 | .filter { print("f$it "); it % 2 == 0 } 10 | 11 | println() 12 | 13 | list.asSequence() // stream 14 | .map { print("m$it "); it * it } 15 | .filter { print("f$it "); it % 2 == 0 } 16 | .toList() 17 | 18 | println() 19 | list.asSequence() 20 | .map { print("m$it "); it * it } 21 | .filter { print("f$it "); it % 2 == 0 } 22 | 23 | println() 24 | list.asSequence() 25 | .filter { print("f$it "); it % 2 == 0 } 26 | .map { print("m$it "); it * it } 27 | .toList() 28 | 29 | } -------------------------------------------------------------------------------- /lecture3/src/_2When/When.kt: -------------------------------------------------------------------------------- 1 | package whenAsExpression 2 | 3 | import whenAsExpression.Colour.* 4 | 5 | enum class Colour { 6 | BLUE, ORANGE, RED 7 | } 8 | 9 | fun updateWeather( 10 | celsiusDegrees: Double 11 | ) { 12 | val description: String 13 | val colour: Colour 14 | if (celsiusDegrees < 0) { 15 | description = "cold" 16 | colour = BLUE 17 | } else if (celsiusDegrees in 0..15) { 18 | description = "mild" 19 | colour = ORANGE 20 | } else { 21 | description = "hot" 22 | colour = RED 23 | } 24 | } 25 | 26 | fun updateWeather1(celsiusDegrees: Double) { 27 | val (description, colour) = when { 28 | celsiusDegrees < 0 -> Pair("cold", BLUE) 29 | celsiusDegrees in 0..15 -> "mild".to(ORANGE) 30 | else -> "hot" to RED 31 | } 32 | } 33 | 34 | infix fun A.to(that: B): Pair = Pair(this, that) -------------------------------------------------------------------------------- /lecture5/src/_4MoreInlineFunctions/_1RunFunction.kt: -------------------------------------------------------------------------------- 1 | package _4MoreInlineFunctions 2 | 3 | class Board(val width: Int) { 4 | val indices1: List> 5 | 6 | init { 7 | val result = mutableListOf>() 8 | for (i in 1..width) { 9 | for (j in 1..width) { 10 | result += i to j 11 | } 12 | } 13 | indices1 = result 14 | } 15 | 16 | val indices = run { 17 | val result = mutableListOf>() 18 | for (i in 1..width) { 19 | for (j in 1..width) { 20 | result += i to j 21 | } 22 | } 23 | result.toList() 24 | } 25 | } 26 | 27 | inline fun T.run(block: T.() -> R): R = block() 28 | 29 | fun main(args: Array) { 30 | val table = Board(3) 31 | for ((i, j) in table.indices) { 32 | print("($i, $j) ") 33 | } 34 | } -------------------------------------------------------------------------------- /lecture7/src/main/_1LambdaWithReceiver/_4Usage.kt: -------------------------------------------------------------------------------- 1 | package _1LambdaWithReceiver 2 | 3 | class Component 4 | fun createComponent() = Component() 5 | 6 | // Вопрос: как можно упростить код? 7 | class A { 8 | private var _component: Component? = null 9 | val component: Component 10 | get() { 11 | val component = _component 12 | if (component != null) return component 13 | val newComponent = createComponent() 14 | _component = newComponent 15 | return newComponent 16 | } 17 | } 18 | 19 | // Ответ #1 (правильный) 20 | class B { 21 | val component by lazy { createComponent() } 22 | } 23 | 24 | // Ответ #2 (на случай, если не хочется использовать делегаты, например, не хочется создавать лямбду) 25 | class С { 26 | private var _component: Component? = null 27 | val component: Component 28 | get() = _component ?: createComponent().apply { _component = this } 29 | } -------------------------------------------------------------------------------- /lecture6/src/_2Reified/_2FilterIsInstance.kt: -------------------------------------------------------------------------------- 1 | package _2Reified 2 | 3 | fun main(args: Array) { 4 | val anys: List = 5 | listOf(1, "one", 2.0) 6 | 7 | val strings: List = 8 | anys. 9 | filterIsInstance() 10 | /* 11 | The code generated by the compiler 12 | instead of calling inline function 'filterIsInstance': 13 | val destination = mutableListOf() 14 | for (element in this) { 15 | if (element is String) { 16 | destination.add(element) 17 | } 18 | } 19 | val strings = destination 20 | */ 21 | 22 | println(strings) 23 | } 24 | 25 | inline fun 26 | Iterable<*>.filterIsInstance(): List { 27 | 28 | val destination = mutableListOf() 29 | for (element in this) { 30 | if (element is T) { 31 | destination.add(element) 32 | } 33 | } 34 | return destination 35 | } -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | -------------------------------------------------------------------------------- /questions/src/questions/_2AssociateBy.kt: -------------------------------------------------------------------------------- 1 | package questions 2 | 3 | import java.util.* 4 | 5 | data class Person(val name: String, val age: Int) 6 | 7 | fun main(args: Array) { 8 | val list = listOf(Person("Alice", 21), Person("Bob", 25)) 9 | println(list.associateBy(Person::name)) 10 | // {Alice=Person(name=Alice, age=21), Bob=Person(name=Bob, age=25)} 11 | } 12 | 13 | // Допишите реализацию функции associateBy. Пример использования представлен ниже. 14 | 15 | /* 16 | * Returns a [Map] containing the elements from the given collection indexed by the key 17 | * returned from [keySelector] function applied to each element. 18 | * If any two elements would have the same key returned by [keySelector] the last one gets added to the map. 19 | */ 20 | inline fun Iterable.associateBy(keySelector: (T) -> K): Map { 21 | val destination = LinkedHashMap() 22 | for (element in this) { 23 | destination.put(keySelector(element), element) 24 | } 25 | return destination 26 | } 27 | -------------------------------------------------------------------------------- /lecture1/src/_9Ranges.kt: -------------------------------------------------------------------------------- 1 | package controlStructuresAndCollections 2 | 3 | fun isLetter(c: Char) = c in 'a'..'z' || c in 'A'..'Z' 4 | // c in 'a'..'z' 5 | // компилируется в: 6 | // 'a' <= c && c <= 'z' 7 | 8 | fun isNotDigit(c: Char) = c !in '0'..'9' 9 | 10 | fun main(args: Array) { 11 | println(isLetter('q')) // true 12 | println(isNotDigit('x')) // true 13 | } 14 | 15 | fun recognize(c: Char) = when (c) { 16 | in '0'..'9' -> "It's a digit!" 17 | in 'a'..'z', in 'A'..'Z' -> "It's a letter!" 18 | else -> "I don't know…​" 19 | } 20 | 21 | fun whatWillBePrinted() { 22 | println("Kotlin" in "Java".."Scala") 23 | println("Kotlin" in setOf("Java", "Scala")) 24 | } 25 | 26 | fun ranges() { 27 | val intRange = 1..10 28 | for (i in intRange) { /*...*/ } 29 | for (i in 1..10) { /*...*/ } 30 | 31 | val list = listOf(1, 2) 32 | if (3 in list) { /*...*/ } 33 | // компилируется в: 34 | // list.contains(3) 35 | } 36 | 37 | fun foo() { 38 | for (c in '0'..'9') { 39 | println(c) 40 | } 41 | } -------------------------------------------------------------------------------- /lecture5/src/_1Questions/_3LazyProperty.kt: -------------------------------------------------------------------------------- 1 | package _1Questions 2 | 3 | class Email { /*...*/ } 4 | 5 | fun loadEmails(person: Person): List { 6 | println("Load emails for ${person.name}") 7 | return listOf(/*...*/) 8 | } 9 | 10 | class Person(val name: String) { 11 | // val emails by lazy { loadEmails(this) } 12 | 13 | private val lazyEmails = LazyProperty { loadEmails(this)} 14 | val emails: List 15 | get() = lazyEmails.getValue() 16 | } 17 | 18 | // Напишите реализацию класса LazyProperty так, 19 | // чтобы можно было создать LazyProperty любого типа и получить его значение через метод getValue. 20 | 21 | class LazyProperty(val initializer: () -> T) { 22 | private var value: T? = null 23 | 24 | fun getValue(): T { 25 | if (value == null) { 26 | value = initializer() 27 | } 28 | return value!! 29 | } 30 | } 31 | 32 | fun main(args: Array) { 33 | val p = Person("Alice") 34 | println("---") 35 | p.emails 36 | println("---") 37 | p.emails 38 | } -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /lecture7/src/main/_1LambdaWithReceiver/_1BuildString.kt: -------------------------------------------------------------------------------- 1 | package _1LambdaWithReceiver 2 | 3 | fun String.lastChar() = get(length - 1) 4 | 5 | fun main(args: Array) { 6 | val stringBuilder = StringBuilder() 7 | 8 | for (i in 1..9) { 9 | stringBuilder.append(i) 10 | } 11 | stringBuilder.append('!') 12 | 13 | with (stringBuilder) { 14 | for (i in 1..9) { 15 | append(i) 16 | } 17 | append('!') 18 | } 19 | 20 | val result = stringBuilder.toString() 21 | 22 | val s = buildString2 { 23 | for (i in 1..9) { 24 | append(i) 25 | } 26 | append('!') 27 | } 28 | println(s) 29 | } 30 | 31 | fun buildString1( 32 | builderAction: (StringBuilder) -> Unit 33 | ): String { 34 | val sb = StringBuilder() 35 | builderAction(sb) 36 | return sb.toString() 37 | } 38 | 39 | fun buildString2( 40 | builderAction: StringBuilder.() -> Unit 41 | ): String { 42 | val sb = StringBuilder() 43 | sb.builderAction() 44 | return sb.toString() 45 | } 46 | -------------------------------------------------------------------------------- /lecture8/src/main/_3DropdownExample/_2DropdownAbstraction.kt: -------------------------------------------------------------------------------- 1 | package _3DropdownExample 2 | 3 | import _3DropdownExample.impl.* 4 | import kotlinx.html.* 5 | import kotlinx.html.stream.createHTML 6 | 7 | fun buildDropdown1() = createHTML().div(classes = "dropdown") { 8 | button(classes = "btn dropdown-toggle") { 9 | +"Dropdown" 10 | span(classes = "caret") 11 | } 12 | ul(classes = "dropdown-menu") { 13 | li { a("#") { +"Action" } } 14 | li { a("#") { +"Another action" } } 15 | li { role = "separator"; classes = setOf("divider") } 16 | li { classes = setOf("dropdown-header"); +"Header" } 17 | li { a("#") { +"Separated link" } } 18 | } 19 | } 20 | 21 | fun buildDropdown2() = createHTML().dropdown { 22 | dropdownButton { +"Dropdown" } 23 | dropdownMenu { 24 | item("#", "Action") 25 | item("#", "Another action") 26 | divider() 27 | dropdownHeader("Header") 28 | item("#", "Separated link") 29 | } 30 | } 31 | 32 | fun main(args: Array) { 33 | println(buildDropdown2()) 34 | } -------------------------------------------------------------------------------- /lecture8/src/main/_1Questions/HTMLBuilders/data.kt: -------------------------------------------------------------------------------- 1 | package _1Questions.HTMLBuilders 2 | 3 | data class Product(val description: String, val price: Double, val popularity: Int) 4 | 5 | val cactus = Product("cactus", 11.2, 13) 6 | val cake = Product("cake", 3.2, 111) 7 | val camera = Product("camera", 134.5, 2) 8 | val car = Product("car", 30000.0, 0) 9 | val carrot = Product("carrot", 1.34, 5) 10 | val cellPhone = Product("cell phone", 129.9, 99) 11 | val chimney = Product("chimney", 190.0, 2) 12 | val certificate = Product("certificate", 99.9, 1) 13 | val cigar = Product("cigar", 8.0, 51) 14 | val coffee = Product("coffee", 8.0, 67) 15 | val coffeeMaker = Product("coffee maker", 201.2, 1) 16 | val cola = Product("cola", 4.0, 67) 17 | val cranberry = Product("cranberry", 4.1, 39) 18 | val crocs = Product("crocs", 18.7, 10) 19 | val crocodile = Product("crocodile", 20000.2, 1) 20 | val cushion = Product("cushion", 131.0, 0) 21 | 22 | fun getProducts() = listOf(cactus, cake, camera, car, carrot, cellPhone, chimney, certificate, cigar, coffee, coffeeMaker, 23 | cola, cranberry, crocs, crocodile, cushion) -------------------------------------------------------------------------------- /lecture5/src/_1Questions/_4FilterFunction.kt: -------------------------------------------------------------------------------- 1 | package _5MoreAboutOperationsOnCollections 2 | 3 | import java.util.* 4 | 5 | fun main(args: Array) { 6 | val list = listOf(2, -1, 1, 0) 7 | 8 | // Напишите код на Kotlin, эквивалентный тому байткоду, 9 | // который сгенерирует Kotlin компилятор вместо вызова функции 'filter' 10 | // (объявление функции приведено ниже). 11 | val result = list.filter { it > 0 } 12 | 13 | /* 14 | result = filterTo(ArrayList(), { it > 0 }) 15 | 16 | ========= 17 | val destination = ArrayList() 18 | for (element in this) { 19 | if (element > 0) destination.add(element) 20 | } 21 | result = destination 22 | */ 23 | } 24 | 25 | inline fun Iterable.filter(predicate: (T) -> Boolean): List { 26 | return filterTo(ArrayList(), predicate) 27 | } 28 | 29 | inline fun > 30 | Iterable.filterTo(destination: C, predicate: (T) -> Boolean): C { 31 | for (element in this) { 32 | if (predicate(element)) destination.add(element) 33 | } 34 | return destination 35 | } 36 | -------------------------------------------------------------------------------- /questions/src/questions/_10Builders.kt: -------------------------------------------------------------------------------- 1 | package questions.builders 2 | 3 | data class Course(val name: String, val students: List) 4 | data class Student(val name: String) 5 | 6 | 7 | fun buildCourse(name: String, init: CourseBuilder.() -> Unit): Course = 8 | CourseBuilder(name).apply(init).build() 9 | 10 | open class CourseBuilder(val name: String) { 11 | 12 | private val students = mutableListOf() 13 | 14 | fun student(name: String) { 15 | students += Student(name) 16 | } 17 | 18 | fun build() = Course(name, students) 19 | } 20 | 21 | 22 | // Реализуйте функцию buildCourse и класс CourseBuilder, 23 | // так чтобы функция возвращала объект Course с упомянутыми в лямбда-аргументе студентами. 24 | 25 | fun kotlinCourse() = buildCourse("Kotlin") { 26 | student("Alice") 27 | student("Bob") 28 | for (i in 1..2) { 29 | student("Anonymous #$i") 30 | } 31 | } 32 | 33 | fun main(args: Array) { 34 | println(kotlinCourse()) 35 | // Course(name=Kotlin, students=[Student(name=Alice), Student(name=Bob), Student(name=Anonymous #1), Student(name=Anonymous #2)]) 36 | } 37 | -------------------------------------------------------------------------------- /lecture7/src/main/_2HTMLBuilders/_2Tags.kt: -------------------------------------------------------------------------------- 1 | package _2HTMLBuilders 2 | 3 | fun createTable() = 4 | table { 5 | tr { 6 | td { 7 | } 8 | } 9 | } 10 | 11 | fun table(init: TABLE.() -> Unit): TABLE { 12 | return TABLE().apply(init) 13 | } 14 | 15 | class TABLE : Tag("table") { 16 | fun tr(init: TR.() -> Unit) { 17 | doInit(TR(), init) 18 | } 19 | } 20 | 21 | class TR : Tag("tr") { 22 | fun td(init: TD.() -> Unit) { 23 | doInit(TD(), init) 24 | } 25 | } 26 | 27 | class TD : Tag("td") 28 | 29 | open class Tag(val name: String) { 30 | private val children = mutableListOf() 31 | protected fun doInit(child: T, init: T.() -> Unit) { 32 | child.init() 33 | children.add(child) 34 | } 35 | 36 | override fun toString() = 37 | "<$name>${children.joinToString("")}" 38 | } 39 | 40 | fun createAnotherTable() = table { 41 | for (i in 1..2) { 42 | tr { 43 | td { 44 | } 45 | } 46 | } 47 | } 48 | 49 | fun main(args: Array) { 50 | println(createTable()) 51 | } -------------------------------------------------------------------------------- /lecture8/src/main/_2HTMLBuilders/Impl.kt: -------------------------------------------------------------------------------- 1 | package _2HTMLBuilders 2 | 3 | fun createTable() = 4 | table { 5 | tr { 6 | td { 7 | } 8 | } 9 | } 10 | 11 | fun table(init: TABLE.() -> Unit): TABLE { 12 | return TABLE().apply(init) 13 | } 14 | 15 | class TABLE : Tag("table") { 16 | fun tr(init: TR.() -> Unit) { 17 | doInit(TR(), init) 18 | } 19 | } 20 | 21 | class TR : Tag("tr") { 22 | fun td(init: TD.() -> Unit) { 23 | doInit(TD(), init) 24 | } 25 | } 26 | 27 | class TD : Tag("td") 28 | 29 | open class Tag(val name: String) { 30 | private val children = mutableListOf() 31 | protected fun doInit(child: T, init: T.() -> Unit) { 32 | child.init() 33 | children.add(child) 34 | } 35 | 36 | override fun toString() = 37 | "<$name>${children.joinToString("")}" 38 | } 39 | 40 | fun createAnotherTable() = table { 41 | for (i in 1..2) { 42 | tr { 43 | td { 44 | } 45 | } 46 | } 47 | } 48 | 49 | fun main(args: Array) { 50 | println(createTable()) 51 | } -------------------------------------------------------------------------------- /lecture8/src/main/_3DropdownExample/_3DropdownAbstractionImpl.kt: -------------------------------------------------------------------------------- 1 | package _3DropdownExample.impl 2 | 3 | import kotlinx.html.* 4 | import kotlinx.html.stream.createHTML 5 | 6 | fun buildDropdown3() = createHTML().dropdown { 7 | dropdownButton { +"Dropdown" } 8 | dropdownMenu { 9 | item("#", "Action") 10 | item("#", "Another action") 11 | divider() 12 | dropdownHeader("Header") 13 | item("#", "Separated link") 14 | } 15 | } 16 | 17 | fun main(args: Array) { 18 | println(buildDropdown3()) 19 | } 20 | 21 | fun UL.item(href: String, name: String) = li { a(href) { +name } } 22 | 23 | fun UL.divider() = li { role = "separator"; classes = setOf("divider") } 24 | 25 | fun UL.dropdownHeader(text: String) = 26 | li { classes = setOf("dropdown-header"); +text } 27 | 28 | fun DIV.dropdownMenu(block: UL.() -> Unit) = ul("dropdown-menu", block) 29 | 30 | fun DIV.dropdownButton(block: BUTTON.() -> Unit) = button(classes = "btn dropdown-toggle") { 31 | block() 32 | span(classes = "caret") 33 | } 34 | 35 | fun TagConsumer.dropdown( 36 | block: DIV.() -> Unit 37 | ): String = div("dropdown", block) -------------------------------------------------------------------------------- /lecture3/src/_3Conventions/Conventions.kt: -------------------------------------------------------------------------------- 1 | package _3Conventions 2 | 3 | fun main(args: Array) { 4 | val list = listOf(1, 2, 3) 5 | println(list + 4) // [1, 2, 3, 4] 6 | println(list.plus(4)) // [1, 2, 3, 4] 7 | println(list - 2) // [1, 3] 8 | 9 | val mutableList = mutableListOf(1, 2, 3) 10 | mutableList += 4 // [1, 2, 3, 4] 11 | 12 | val s1 = "abc" 13 | val s2 = "def" 14 | s1 < s2 // s1.compareTo(s2) < 0 15 | s1 > s2 16 | s1 <= s2 17 | s1 >= s2 18 | 19 | val map = mutableMapOf(1 to "one", 2 to "two") 20 | val key = 3 21 | val value = "three" 22 | map[key] // operator get 23 | map[key] = value // operator set 24 | 25 | println(map[3]) 26 | 27 | println(3 in map) 28 | 29 | 1..2 30 | "abc".."def" 31 | 32 | for (i in 1..2) { } 33 | for (ch in "abc") { } 34 | "abc".iterator() 35 | 36 | // for (s in "abc".."def") { } - doesn't make sense 37 | 38 | val (i, s) = 1 to "s" 39 | val pair = 1 to "s" 40 | val ii = pair.component1() 41 | val ss = pair.component2() 42 | 43 | val (iii, sss) = Foo(1, "") 44 | } 45 | 46 | data class Foo(val i: Int, val s: String) -------------------------------------------------------------------------------- /lecture6/src/_2Reified/_4Validators.kt: -------------------------------------------------------------------------------- 1 | package reifiedGenerics 2 | 3 | import kotlin.reflect.KClass 4 | 5 | interface FieldValidator { 6 | fun validate(input: T): Boolean 7 | } 8 | 9 | object Validators { 10 | private val validators = mutableMapOf, FieldValidator<*>>() 11 | 12 | fun registerValidator( 13 | kClass: KClass, fieldValidator: FieldValidator) { 14 | validators[kClass] = fieldValidator 15 | } 16 | 17 | @Suppress("UNCHECKED_CAST") 18 | operator fun get(kClass: KClass): FieldValidator? = 19 | validators[kClass] as FieldValidator? 20 | } 21 | 22 | 23 | object DefaultStringValidator : FieldValidator { 24 | override fun validate(input: String) = input.isNotEmpty() 25 | } 26 | 27 | object DefaultIntValidator : FieldValidator { 28 | override fun validate(input: Int) = input >= 0 29 | } 30 | 31 | fun main(args: Array) { 32 | Validators.registerValidator(String::class, DefaultStringValidator) 33 | Validators.registerValidator(Int::class, DefaultIntValidator) 34 | 35 | println(Validators[String::class]?.validate("Kotlin")) 36 | println(Validators[Int::class]?.validate(42)) 37 | } -------------------------------------------------------------------------------- /lecture8/src/main/_1Questions/Alert.kt: -------------------------------------------------------------------------------- 1 | package _1Questions 2 | 3 | fun Context.showAreYouSureAlert(process: () -> Unit) { 4 | alert(title = "Are you sure?", message = "Are you really sure?") { 5 | positiveButton("Yes") { process() } 6 | negativeButton("No") { } 7 | }.show() 8 | } 9 | 10 | fun Context.alert( 11 | message: String, 12 | title: String? = null, 13 | init: (AlertDialogBuilder.() -> Unit)? = null 14 | ): AlertDialogBuilder { 15 | return AlertDialogBuilder(this).apply { 16 | message(message) 17 | if (title != null) title(title) 18 | if (init != null) init() 19 | } 20 | } 21 | 22 | /* android framework */ 23 | 24 | class Context 25 | 26 | class DialogInterface { 27 | fun dismiss() { 28 | } 29 | } 30 | 31 | /* anko - extensions for android */ 32 | 33 | class AlertDialogBuilder(val ctx: Context) { 34 | 35 | fun title(title: CharSequence) { 36 | } 37 | 38 | fun message(title: CharSequence) { 39 | } 40 | 41 | fun positiveButton(title: String, f: DialogInterface.() -> Unit) { 42 | } 43 | 44 | fun negativeButton(title: String, f: DialogInterface.() -> Unit = { dismiss() }) { 45 | } 46 | 47 | fun show() { 48 | } 49 | } -------------------------------------------------------------------------------- /lecture2/src/_3ExtensionsOnCollections/libraryFunctions.kt: -------------------------------------------------------------------------------- 1 | package _3ExtensionsOnCollections 2 | 3 | // Подробные комментарии про синтаксис лямбд и семантику функций будут в домашнем задании. 4 | 5 | // Пока важно понимать, что все эти функции (filter, map, all, groupBy etc.) объявлены как extension-функции на коллекциях. 6 | // Можно снавигироваться по ним и посмотреть. 7 | 8 | data class Person(val name: String, val age: Int) 9 | 10 | fun example(people: List) { 11 | people.filter { person -> person.age >= 21 } 12 | people.filter { it.age >= 21 }.map { it.name } 13 | } 14 | 15 | fun main(args: Array) { 16 | val people = listOf(Person("Alice", 20), Person("Bob", 30)) 17 | println(people.asSequence().filter { it.age >= 21 }) 18 | 19 | println(people.maxBy { it.age }) 20 | 21 | val canBeInClub27 = { p: Person -> p.age <= 27 } 22 | println(people.all(canBeInClub27)) 23 | println(people.any(canBeInClub27)) 24 | println(people.count(canBeInClub27)) 25 | println(people.find(canBeInClub27)) 26 | 27 | println(people.groupBy { it.age }) 28 | 29 | val strings = listOf("abc", "def") 30 | println(strings.flatMap { it.toList() }) 31 | 32 | println("abca".count { it == 'a'}) 33 | 34 | val positions = "AACF".zip("ABCD").count { it.first == it.second } //2 35 | } -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 31 | 32 | -------------------------------------------------------------------------------- /lecture4/src/_0MemberExtension/MemberExtensionExample.kt: -------------------------------------------------------------------------------- 1 | package _0MemberExtension 2 | 3 | import _0MemberExtension.Direction.* 4 | 5 | interface Cell { 6 | val i: Int 7 | val j: Int 8 | } 9 | 10 | enum class Direction { 11 | UP, DOWN, RIGHT, LEFT 12 | } 13 | 14 | interface SquareBoard { 15 | fun getCell(i: Int, j: Int): Cell 16 | fun getCellOrNull(i: Int, j: Int): Cell? 17 | 18 | fun getRow(i: Int, jRange: IntProgression): List 19 | fun getColumn(iRange: IntProgression, j: Int): List 20 | 21 | fun Cell.getNeighbour(direction: Direction): Cell? 22 | } 23 | 24 | abstract class SquareBoardImpl: SquareBoard { 25 | override fun Cell.getNeighbour(direction: Direction): Cell? { 26 | 27 | // можно обратиться к instance объекту outer класса: 28 | this@SquareBoardImpl 29 | 30 | // можно обратиться к receiver объекту extension функции: 31 | this@getNeighbour 32 | this // просто this ссылается на ближайший labeled this 33 | 34 | return when (direction) { 35 | UP -> getCellOrNull(i - 1, j) 36 | DOWN -> getCellOrNull(i + 1, j) 37 | RIGHT -> getCellOrNull(i, j + 1) 38 | LEFT -> getCellOrNull(i, j - 1) 39 | } 40 | } 41 | } 42 | 43 | fun useBoard(board: SquareBoard) { 44 | with(board) { 45 | val cell = this.getCell(1, 1) // this можно опустить 46 | cell.getNeighbour(UP) 47 | } 48 | } -------------------------------------------------------------------------------- /.idea/modules/lecture7_main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/modules/lecture8_main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /questions/src/questions/_11LazyDelegate.kt: -------------------------------------------------------------------------------- 1 | package questions 2 | 3 | import kotlin.reflect.KProperty 4 | 5 | fun main(args: Array) { 6 | println("before") 7 | val example = DeepThought { 8 | println("calculation the answer for 7½ million years...") 9 | 42 10 | } 11 | println("start") 12 | println(example.answer) 13 | println("after") 14 | println(example.answer) 15 | } 16 | 17 | class DeepThought(calculation: () -> Any?) { 18 | val answer: Any? by LazyDelegate(calculation) 19 | } 20 | 21 | 22 | // Реализуйте класс LazyDelegate и метод getValue (без параметров) в этом классе. 23 | // Чтобы не нужно было вспоминать конвенцию, выразим ее через extension метод: 24 | operator fun LazyDelegate.getValue(thisRef: Any?, property: KProperty<*>): T = getValue() 25 | 26 | // Пример кода, использующий LazyDelegate, приведен ниже. 27 | 28 | // 1. 29 | // Напишете класс так, чтобы правильно обрабатывались нулевые ссылки. 30 | // Т.е. если в примере выше 42 заменить на null, "calculation the answer for 7½ million years..." будет напечатано 1 раз. 31 | 32 | // 2. 33 | // Напишите класс LazyDelegate так, чтобы он работал с любыми типами значений, т.е. чтобы можно было написать: 34 | 35 | val a: Int by LazyDelegate { 42 } 36 | 37 | /* 38 | before 39 | start 40 | calculation the answer for 7½ million years... 41 | 42 42 | after 43 | 42 44 | */ 45 | 46 | class LazyDelegate(val initializer: () -> T) { 47 | private var isInitialized: Boolean = false 48 | private var _value: T? = null 49 | 50 | fun getValue(): T { 51 | if (!isInitialized) { 52 | _value = initializer() 53 | isInitialized = true 54 | } 55 | return _value as T 56 | } 57 | } -------------------------------------------------------------------------------- /lecture8/src/main/_1Questions/HTMLBuilders/html.kt: -------------------------------------------------------------------------------- 1 | package _1Questions.HTMLBuilders 2 | 3 | import java.util.* 4 | 5 | open class Tag(val name: String) { 6 | val children: MutableList = ArrayList() 7 | val attributes: MutableList = ArrayList() 8 | 9 | override fun toString(): String { 10 | return "<$name" + 11 | (if (attributes.isEmpty()) "" else attributes.joinToString(separator = " ", prefix = " ")) + ">" + 12 | (if (children.isEmpty()) "" else children.joinToString(separator = "")) + 13 | "" 14 | } 15 | } 16 | 17 | class Attribute(val name : String, val value : String) { 18 | override fun toString() = """$name="$value"""" 19 | } 20 | 21 | fun T.set(name: String, value: String?): T { 22 | if (value != null) { 23 | attributes.add(Attribute(name, value)) 24 | } 25 | return this 26 | } 27 | 28 | fun Tag.doInit(tag: T, init: T.() -> Unit): T { 29 | tag.init() 30 | children.add(tag) 31 | return tag 32 | } 33 | 34 | class Html: Tag("html") 35 | class Table: Tag("table") 36 | class Center: Tag("center") 37 | class TR: Tag("tr") 38 | class TD: Tag("td") 39 | class Text(val text: String): Tag("b") { 40 | override fun toString() = text 41 | } 42 | 43 | fun html(init: Html.() -> Unit): Html = Html().apply(init) 44 | 45 | fun Html.table(init : Table.() -> Unit) = doInit(Table(), init) 46 | fun Html.center(init : Center.() -> Unit) = doInit(Center(), init) 47 | 48 | fun Table.tr(color: String? = null, init : TR.() -> Unit) = doInit(TR(), init).set("bgcolor", color) 49 | 50 | fun TR.td(color: String? = null, align : String = "left", init : TD.() -> Unit) = doInit(TD(), init).set("align", align).set("bgcolor", color) 51 | 52 | fun Tag.text(s : Any?) = doInit(Text(s.toString()), {}) 53 | 54 | -------------------------------------------------------------------------------- /lecture2/src/questions/Answers.kt: -------------------------------------------------------------------------------- 1 | package questions 2 | 3 | import java.util.* 4 | 5 | // task1, task2 6 | // Код на Котлине комплируется в Java байт-код. 7 | // В Идее есть экшн "Show Kotlin bytecode" (Help -> Find Action -> напечатать "Show Kotlin bytecode"). 8 | // Он показывает байткод, который генерится по данному Kotlin коду. 9 | // Чтобы посмотреть байткод для Java кода, можете вызвать экшн "Show bytecode" (только не забудьте скомпилировать ваш проект). 10 | // Например, можете сравнить сигнатуры: 11 | 12 | fun foo(strings: Array) { 13 | // ... и 14 | JavaCode.foo(strings) 15 | } 16 | 17 | 18 | fun task3() { 19 | var string = 1 20 | // тип у переменной Int 21 | // string = "a" 22 | } 23 | 24 | fun task4() { 25 | val languages = listOf("Java") 26 | // список read-only 27 | // languages.add("Kotlin") 28 | } 29 | 30 | fun task5() { 31 | // функция task5 компилируется в статическую функцию в классе AnswersKt (по имени файла). 32 | } 33 | 34 | fun task6() { 35 | println("Kotlin" in "Java".."Scala") // true 36 | println("Kotlin" in setOf("Java", "Scala")) // false 37 | } 38 | 39 | fun task7() { 40 | fun isNotDigit(c: Char) = c !in '0'..'9' 41 | 42 | // см. функцию 43 | JavaCode.isNotDigit('x') 44 | } 45 | 46 | fun task8() { 47 | // for (char c = '0'; c < '9'; c++) { 48 | // System.out.println(c); 49 | // } 50 | 51 | for (c in '0' until '9') { 52 | println(c) 53 | } 54 | 55 | } 56 | 57 | // task9 58 | class Person(val name: String, var age: Int) 59 | // 3 метода: getName, getAge, setAge 60 | // 1 конструктор 61 | 62 | 63 | // task10 64 | 65 | val bar1: Int 66 | get() = Random().nextInt() 67 | 68 | val bar2: Int 69 | get() = count++ 70 | var count = 0 71 | 72 | fun main(args: Array) { 73 | println(bar1) 74 | println(bar1) 75 | 76 | 77 | println(bar2) 78 | println(bar2) 79 | } -------------------------------------------------------------------------------- /lecture2/src/_1Nullability/1Nullability.kt: -------------------------------------------------------------------------------- 1 | package _1Nullability 2 | 3 | fun main(args: Array) { 4 | 5 | // разные типы: nullable & не-nullable (not-null) 6 | // только в переменной nullable типа (с вопросиком) можно хранить null 7 | val s1: String = "always not null" 8 | val s2: String? = null 9 | 10 | val i1: Int = s1.length 11 | // s2.length - нельзя просто разыменовать, ошибка 12 | 13 | // Что можно сделать? 14 | // можно явно проверить, что != null 15 | if (s2 != null) s2.length 16 | // компилятор предлагает упростить: 17 | s2?.length // если null, ничего не произойдет 18 | 19 | val i2: Int? = if (s2 != null) s2.length else null 20 | val i3: Int? = s2?.length // если null, вернется null в качестве результата 21 | 22 | val i4: Int? = if (s2 != null) s2.length else 0 23 | val i5: Int = s2?.length ?: 0 // если null, вернется 0 в качестве результата 24 | 25 | s2!! // явно кинуть NPE, если s2 хранит null 26 | } 27 | 28 | fun test1(s: String?) { 29 | // компилятор замечает return в ветке, когда переменная null или fail() (может только кинуть исключение) 30 | if (s == null) return 31 | s.length // можно разыменовывать 32 | } 33 | 34 | fun test2(s: String?) { 35 | // компилятор также замечает, если функция не может нормально завершиться, например fail может только кинуть исключение 36 | if (s == null) fail() 37 | s.length // можно разыменовывать 38 | } 39 | 40 | fun test3(s: String?) { 41 | // удобно писать return или fail после ?: 42 | val i: Int = s?.length ?: fail() 43 | } 44 | 45 | // В Котлине можно объявить функцию, которая может завершиться только аварийный образом: кинуть исключение. 46 | // Её тип Nothing нужно явно указать (про Nothing и иерархию типов мы поговорим потом). 47 | fun fail(): Nothing = 48 | throw UnsupportedOperationException() 49 | 50 | // В библиотеке, например, есть функция TODO, 51 | // которая возвращает Nothing 52 | fun notImplemented() { TODO() } -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/modules/lecture7_test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /.idea/modules/lecture8_test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /questions/src/questions/_5FilterIsInstance.kt: -------------------------------------------------------------------------------- 1 | package questions 2 | 3 | import java.util.* 4 | 5 | 6 | fun main(args: Array) { 7 | listOf(Cat()).getCatsOnly() 8 | } 9 | 10 | open class Animal 11 | class Cat: Animal() 12 | 13 | // Напишите код на Kotlin, эквивалентный тому байткоду, 14 | // который сгенерирует Kotlin компилятор вместо вызова функции filterInInstance (объявление функции приведено ниже). 15 | fun List.getCatsOnly(): List { 16 | return filterIsInstance() 17 | } 18 | 19 | fun List.getCatsOnlyBytecode(): List { 20 | val destination = ArrayList() 21 | for (element in this) if (element is Cat) destination.add(element) 22 | return destination 23 | } 24 | 25 | inline fun Iterable<*>.filterIsInstance(): List { 26 | return filterIsInstanceTo(ArrayList()) 27 | } 28 | 29 | inline fun > Iterable<*>.filterIsInstanceTo(destination: C): C { 30 | for (element in this) if (element is R) destination.add(element) 31 | return destination 32 | } 33 | 34 | // ---------- 6 ---------- 35 | 36 | // Если убрать ключевое слово reified из объявления функции filterIsInstance 37 | // (при этом функция filterIsInstanceTo остается без изменений), будет ли она компилироваться и почему? 38 | 39 | // Нет. Функция filterIsInstance вызывает функцию filterIsInstanceTo, 40 | // которая требует информацию про типовые аргументы, т.к. сохраняет ее. 41 | // Если мы стираем эту информацию в filterIsInstance (убирая слово reified), 42 | // то вызову filterIsInstanceTo неоткуда будет ее взять. 43 | 44 | // ---------- 7 ---------- 45 | 46 | // Можно ли вызвать функцию filterIsInstance из Java? (Если нет, то почему?) 47 | 48 | // Нет. Обычную inline функцию можно вызвать из Java (она не заинлайниться, но вызвать можно). 49 | // Однако inline функцию с reified дженериками вызвать нельзя, 50 | // т.к. для ее выполнения нужно дополнительно сохранять информацию про типовые аргументы, 51 | // и это уже умеет делать только компилятор Kotlin. -------------------------------------------------------------------------------- /lecture4/src/_3DelegationBy/ExampleWithBoards.kt: -------------------------------------------------------------------------------- 1 | package _3DelegationBy 2 | 3 | interface Cell { 4 | val i: Int 5 | val j: Int 6 | } 7 | 8 | enum class Direction { 9 | UP, DOWN, RIGHT, LEFT 10 | } 11 | 12 | interface SquareBoard { 13 | val width: Int 14 | 15 | fun getCell(i: Int, j: Int): Cell 16 | fun getCellOrNull(i: Int, j: Int): Cell? 17 | 18 | fun getAllCells(): Collection 19 | 20 | fun getRow(i: Int, jRange: IntProgression): List 21 | fun getColumn(iRange: IntProgression, j: Int): List 22 | 23 | fun Cell.getNeighbour(direction: Direction): Cell? 24 | } 25 | 26 | interface GameBoard : SquareBoard { 27 | 28 | operator fun get(cell: Cell): T? 29 | operator fun set(cell: Cell, value: T?) 30 | 31 | operator fun get(i: Int, j: Int): T? 32 | operator fun set(i: Int, j: Int, value: T?) 33 | 34 | operator fun contains(value: T): Boolean 35 | 36 | fun filter(predicate: (T?) -> Boolean): Collection 37 | fun any(predicate: (T?) -> Boolean): Boolean 38 | fun all(predicate: (T?) -> Boolean): Boolean 39 | } 40 | 41 | class SquareBoardImpl(override val width: Int) : SquareBoard { 42 | 43 | override fun getCell(i: Int, j: Int): Cell = TODO() 44 | override fun getCellOrNull(i: Int, j: Int): Cell = TODO() 45 | override fun getAllCells(): Collection = TODO() 46 | override fun getRow(i: Int, jRange: IntProgression): List = TODO() 47 | override fun getColumn(iRange: IntProgression, j: Int): List = TODO() 48 | override fun Cell.getNeighbour(direction: Direction): Cell = TODO() 49 | } 50 | 51 | class GameBoardImpl( 52 | val squareBoardImpl: SquareBoardImpl 53 | ) : GameBoard, SquareBoard by squareBoardImpl { 54 | 55 | override fun get(cell: Cell): T = TODO() 56 | override fun set(cell: Cell, value: T?) = TODO() 57 | override fun get(i: Int, j: Int): T = TODO() 58 | override fun set(i: Int, j: Int, value: T?) = TODO() 59 | override fun contains(value: T): Boolean = TODO() 60 | override fun filter(predicate: (T?) -> Boolean): Collection = TODO() 61 | override fun any(predicate: (T?) -> Boolean): Boolean = TODO() 62 | override fun all(predicate: (T?) -> Boolean): Boolean = TODO() 63 | } -------------------------------------------------------------------------------- /lecture7/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /lecture8/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /lecture7/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn ( ) { 37 | echo "$*" 38 | } 39 | 40 | die ( ) { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /lecture8/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn ( ) { 37 | echo "$*" 38 | } 39 | 40 | die ( ) { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | --------------------------------------------------------------------------------