-
Kotlin 기본 문법Kotlin 2019. 8. 3. 16:39
타입 체크
- if(true is Boolean)
- if('a' is Char)
타입 케스팅
- Double to Int : double.toInt()
- Int to Double : myInt.toDouble();
- Char to Int : char.toInt()
var, val 차이
- var : 변경가능 변수
- val : 변경불가 변수
String pretty
var logStr = """SELECT * FROM TABLE""";
Compare
"A".compareTo("B")
String find, check
val myString = "0123456789"; println(myString.get(1)); println(myString.subSequence(0,3)) println(myString.contains("3"));
Array
// 배열 선언 (index 초기화) var sqArray = Array(5, { x -> x * x }); // 기본 배열 선언 var array2: Array<Int> = arrayOf(1,2,3); // 배열 선언 values var myArray = arrayOf(1, 2, 3, "ok"); // get myArray[3] myArray.get(3) myArray.first() // get Index myArray.indexOf("ok") // replace value myArray[3] = "fail"; // copy var copyArray = myArray.copyOfRange(0,1);
Rang
// orderBy ASc var onToTen = 1..10; var oneToTen2 = 1.rangeTo(10); // String range var alpha = "A".."Z"; // orderBy Desc var tenToOne = 10.downTo(1); // step (jump) var range3 = oneToTen2.step(3);
Opermiation
if (age < 5) { println("Go to Preschool"); } else if (age == 5) { println("Go to Kindergarten"); } else if (5 > age && age <= 17) { var grade = age - 5 println("Go to school"); } else { println("do nothing") } when (age) { 0, 1, 2, 3, 4 -> println("go to Preschool"); 5 -> println("Go to Kindergarten"); in 6..17 -> { var grade = age - 5 println("Go to school") } else -> println("do nothing") }
loop
for((index, value) in arrayOf(1,2,3).withIndex())
function
fun main(args: Array<String>) { fun add(num1: Int, num2: Int): Int = num1 + num2 println(add(1, 2)); // 매개변서명 지정하여 값넘기기 fun subTract(num1: Int, num2: Int): Int = num1 - num2 println(subTract(num2 = 3, num1 = 5)); // 리턴타입없는 function fun sayHello(name: String): Unit = println("Hello ${name}"); println(sayHello("Justin")) runApplication<KokotripApplication>(*args) // 여러개의 Value Return with Pair val (two, three) = nextTwo(1); println("1, $two, $three") } // Paire을 쓰면 여러개의 value을 순서대로 넘길수 있다. fun nextTwo(num: Int): Pair<Int, Int> { return Pair(num + 1, num + 2); } // 여러개의 매개변수 넘기기 (vararg) fun main(args: Array<String>) { println(getSum(1, 2, 3, 4, 5)) } fun getSum(vararg nums: Int): Int { var sum = 0; nums.forEach { n -> sum += n } return sum; }
function 2 self 재귀함수
fun fact(x: Int): Int { tailrec fun factTail(y: Int, z: Int): Int { if (y == 0) return z; else return factTail(y - 1, y * z) } return factTail(x, 1); }
filter, reduce, fold, map, foreEach
var numList = 1..20; var evenList = numList.filter { it % 2 == 0 } evenList.forEach { n -> println(n) } val numList2 = 1..2; // 초기값 없이 계 val listSum = numList2.reduce { x, y -> x + y }; println(listSum) // 초기값 셋팅후 계산 val listSum2 = numList2.fold(1) { x, y -> x + y }; println(listSum2) // any : Boolean val any = numList2.any { it % 2 == 0 }; println(any); // map val map = numList2.map { it * 10 } println(map);
function to create function
val callbackFunction = makeMathFunc(10) println(callbackFunction(5)); fun makeFunction(num1: Int): (Int) -> Int = { num2 -> num1 * num2 }
function to parameter
fun main(args: Array<String>) { val inputNum = 10; val (name, value) = mathOnList(inputNum, { num: Int -> num * inputNum; }); println("$name : $value") } fun mathOnList(num: Int, myFunc: (num: Int) -> Int): Pair<String, Int> { return Pair("kim", myFunc(num)); }
MutableList (변경가능)
var mutableList: MutableList<Int> = mutableListOf(1, 2, 3); mutableList.clear(); mutableList.add(4); mutableList.remove(2); mutableList.removeAt(0);
MutableMap (변경가능Map)
var mutableMap2 = mutableMapOf<Int, Any?>(1 to "kim", 2 to "justin", 3 to "seunggab") var mutableMap = mutableMapOf<Int, Any?>() // map[Key] = value mutableMap[1] = "kim"; mutableMap[2] = "justin"; mutableMap.put(3, "seunggab") for((key, value) in mutableMap){ println("$key : $value") }
Class 생성
fun main(args: Array<String>) { val justin = Animal("Justin", 20.0, 13.5); justin.getInfo(); justin.height; var myDog = Dog("myDog", 20.0, 13.0, "Justin"); myDog.getInfo(); } open class Animal(val name: String, var height: Double, var weight: Double) { init { val regex = Regex(".*\\d+.*") require(!name.matches(regex)) { "Animal name Can't contain Numbers" } require(height > 0) { "Height must be greater then 0" } require(weight > 0) { "Weight must be greater then 0" } } open fun getInfo(): Unit { println("$name is $height tall and weights $weight"); } } class Dog(name: String, height: Double, weight: Double, var owner: String) : Animal(name, height, weight) { override fun getInfo(): Unit { println("$name is $height tall and weights $weight and owner is $owner"); } }
interface
fun main(args: Array<String>) { val myBird = Bird("tweety", true); myBird.fly(100.0); } interface Flyable { var flies: Boolean fun fly(distMile: Double): Unit } // Interface 내부 변수는 반드시 parameter 받는 부분에서 override 해야한다. class Bird constructor( val name: String, override var flies: Boolean = true) : Flyable { override fun fly(distMile: Double) { println("$name flies $distMile miles") } }
null
// error var nullVal: String = null; // null 가능 var nullVal2: String? = null; // return null 가능 fun myFun(): String? = null; // null가능하기 떄문에 에러 var nullVal3 = nullVal2.length; // 무조건 null이 아니다고 명시해준다 (!!) var nullVal4 = nullVal2!!.length; // elvis Null 아닐떄 var nullVal5 = nullVal2 ?: 30;
By 클래스 구현 유임
불필요한 중복된 구현을 없애고 별도 커스텀하고 싶은 기능만 따로 구현하며, 기본적으로 부모의 기능을 그대로 사용한다.
class CounterBy<T>( private val innerSet: MutableCollection<T> = HashSet<T>() ) : MutableCollection<T> by innerSet { var objectsAdded = 0; override fun add(element: T): Boolean { objectsAdded++; return innerSet.add(element); } override fun addAll(elements: Collection<T>): Boolean { objectsAdded += elements.size; return innerSet.addAll(elements); } }
object
싱글톤
object Single { var container = HashMap<String, String>(); fun add(map: HashMap<String, String>) { container = map; } fun get(key: String): String? { return container.get("key"); } }
동반객체 (companion object) 펙토리 패턴에 사용
코틀린에는 static키워드가 없다. 대신해서 최상위 함수를 사용할수 있지만 때에따라 private으로 표시된 클래스 비공개 멤버에 접근할수 있다.
그예가 팩토리패턴!! capanition object 클래스는 자신을 감싸고 있는 클래스의 모든 private을 접근할수 있다.class Sns private constructor(val nickName: String) { companion object { // companion object Loader 처럼 Alias을 붙힐수 있다. fun makeFacebook(id: String) = Sns("facebook_$id") fun makeGoogle(id: String) = Sns("google_$id") } }
무명 내부 클래스
fun countClick(window: Window) { window.addMouseListener(object : MouseAdapter() { // do something }) }
람다
람다예제1
val person1 = Person("first", 1, "man"); val person2 = Person("second", 2, "man"); val people = listOf<Person>(person1, person2); val maxOrigin = people.maxBy { p: Person -> p.age } // 괄호안 맨뒤 인자가 람다라면 밖으로 뺄수 있다 val maxOrigin2 = people.maxBy() { p: Person -> p.age } // p의 타입을 생략할수 있다. val maxOrigin3 = people.maxBy() { p -> p.age } val max2 = people.maxBy(Person::age) val sum = { first: Int, second: Int -> first + second } // 결론으로 이렇게 간단하게 쓸수 있다. val max1 = people.maxBy { it.age } // 3가지 방법 val maxOrigin10 = people.maxBy { p: Person -> p.age } val max10 = people.maxBy { it.age } val max20 = people.maxBy(Person::age)
함수나, 프로퍼티도 값도 저장할수 있다.
fun test2(){ val sender = ::sendMail; sender("1", "2"); } fun sendMail(first: String, second: String) { println("$first, $second") }
Collection
val list = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // filter 은 true을 반환하는 원소의 집합이다. val filtered = list.filter { it % 2 == 0 } var filtered2 = list.filter { p: Int -> p % 2 == 0 } println(filtered); println(filtered2); // map은 원소 값을 변경하여 새로운 컬렉션을 만든다. val multiple = list.map { it * 10 } val multiple2 = list.map { p: Int -> p * 10 } println(multiple) println(multiple2) val people = listOf( Person("firstName", 1, "male"), Person("secondName", 2, "male"), Person("thirdName", 3, "female"), Person("forthName", 4, "male"), Person("fifth", 5, "female") ); // 원소의 일부 정보의 새로운 집한 val names = people.map { it.name } val names2 = people.map(Person::name) val names3 = people.map { p: Person -> p.name } println(names) println(names2) println(names3) // 틀정 필터 조건의 이름 val oldPeopleNames = people .filter { it.age > 4 } .map { it.name } println(oldPeopleNames); // 가장 나이가 많은 사람의 이름 val olderPerson = people.maxBy { it.age } val older = people.filter { it == olderPerson } .map { it.name } println("olderName $older") // Map collection val numbersMap = mapOf(0 to "zero", 1 to "one", 2 to "two") val uppers = numbersMap .mapValues { it.value.toUpperCase() } .forEach { println(it) } println(uppers) val people = listOf( Person("firstName", 1, "male"), Person("secondName", 2, "male"), Person("thirdName", 3, "female"), Person("forthName", 4, "male"), Person("fifth", 5, "female") ); /** * find * 리스트에서 해당하는 첫번째 원소를 리턴한다. 없으면 null * @return null | list */ val find = people.find { it.name == "justin" } val firstOrNull = people.firstOrNull { it.name == "justin" } println("find : $find, firstOrNull : $firstOrNull"); /** * any * 조건에 해당하는 원소가 하나라도 있는가? * @return true | false */ val any = people.any { it.name == "justin" } println("any : $any") /** * all * 조건에 모든 원소가 해당하는지 true : false * @return true : false */ val all = people.all { it.name != "" } println("all : $all") /** * groupBy * @return Map<Object, List<T>> */ val groupBy = people.groupBy { it.age } println("groupBy : $groupBy") /** * flatMap * 여러 리스트를 하나의 리스트로 모은다. * String을ㅇ toList 하면 한글자씩 쪼개 리스트로 생성한다. * @return list */ val flatMap = listOf("first", "second").flatMap { it.toList() } println("flatMap : $flatMap") /** * flatMap with toSet * List<Map<Object, List>> 리스트안에 존재하는 리스트를 단일 리스트로 반환 * @return list */ val peopleWithFriends = listOf( Person("firstName", 1, "male", listOf("a", "b")), Person("secondName", 2, "male", listOf("a", "b")), Person("thirdName", 3, "female", listOf("c", "b")), Person("forthName", 4, "male", listOf("a", "b")), Person("fifth", 5, "female", listOf("a", "d")) ) val flatMapToSet = peopleWithFriends.flatMap { it.friends }.toSet() println("flatMapToSet : $flatMapToSet")
sequence
java의 stream과 같으며 stream을 지원하지 않는 버전을 위해 만드러짐
/** * asSequence == stream 구버전에서 stream이 없는경우가 있어 sequence을 사용함 * filter, map이 있을때 시퀀스가 없을땐 filter을 다수행하고, map 다수행하고 결과를 만들지만 * sequence는 원소 하나가 기준이 되어 filter, map을 순차적으로 한번씩 수행한다. * @return toList을 해야지 새로운 리스트가 생성된다. */ val list = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val asSequence = list.asSequence().filter { it % 2 == 0 } .map { it * 10 } .toList() println("asSequence : $asSequence") val asSequence2 = people.asSequence().firstOrNull { it.name == "firstName" } println("asSequence2 : $asSequence2");
'Kotlin' 카테고리의 다른 글
Kotlin Clock mockito (1) 2021.11.10 코틀린 기본요소 (2) 2019.03.20 코틀린 프로젝트 생성 및 실행 (0) 2019.03.20 코틀린 소개 (1) 2019.03.17