7월, 2019의 게시물 표시

코틀린 (Kotlin) with() apply() 함수 정리

with 함수 객체 이름을 반복하지 않고 사용하고 싶을 때 with 함수를 사용하면 편리합니다. val stringBuilder = StringBuilder() val text = with ( stringBuilder ) { //수신객체 지정     for (letter in 'A'..'Z') {         append(letter) //바로 사용가능, this.append(letter) 와 동일     }     toString() //블럭마지막은 리턴값 } 만약 with 블럭 안에서 함수 이름이 같은 바깥 함수를 호출하고 싶을 경우에는 this@OuterClass.함수() 처럼 호출하면 됩니다. val dup = with (stringBuilder) {     //바깥 클래스와 이름이 중첩되었고     //바깥 클래스 함수를 호출하고 싶다면 this@outerclass.함수() 한다     this @RamdaActivity .toString() } apply 함수 apply 함수는 with 와 비슷하지만 자기 자신을 리턴합니다. 객체를 생성하면서 속성을 초기화할 때 사용됩니다. 그리고 자바의 빌더 객체와 비슷한 기능을 따라할 수 있습니다. //자신에게 전달된 수신객체를 리턴한다 val text = StringBuilder(). apply {     for (letter in 'A'..'Z') {         append (letter) //바로 사용가능     } }. toString () //리턴된 StringBuilder의 toString() 을 호출 //StringBuilder 를 편리하게 사용 가능 //buildString 은 표준라이브러리로 StringBuilder와 toString() 을 호출해주는 함수 val text = buildString {     for (letter in 'A'..&

코틀린 (Kotlin) 시퀀스 사용하기(지연 계산)

지연 계산 아래 코드는 map과 filter 를 호출합니다. 그러나 map 에서 리스트를 생성하고 filter 에서도 리스트를 새로 생성하기때문에 데이터가 많은 경우 효율적이지 않습니다. people. map (Person::name). filter { it.startsWith("A") } 시퀀스(sequence) 큰 데이터를 연산할 때는 중간 리스트를 생성하지 않는 시퀀스를 사용하는 것이 효율적입니다. 시퀀스는 아래 연산처럼 중간 연산에서는 아무것도 실행되지 않습니다. listOf(1, 2, 3, 4)             . asSequence ()             . map { it * it }             . filter { it % 2 == 0 } 시퀀스는 최종 연산이 호출될 때 실행됩니다. listOf(1, 2, 3, 4)     . asSequence ()     . map { it * it }     . filter { it % 2 == 0 }     . toList () //최종 연산 시퀀스의 실행 시퀀스의 연산은 각 값에 대해 순차적으로 적용됩니다. listOf(1, 2, 3, 4)     . asSequence ()     . map { it * it }     . find { it > 3 } 위 코드의 경우 실행 순서는 다음과 같습니다. list(1) -> map (1*1) -> find (1>3) -> list(2) -> map (2*2) -> find (4>3) -> 종료 이처럼 시퀀스는 중간 리스트를 만들지않고 값을 순차적으로 계산하기때문에 특정 조건이 만족하는경우 중간에 이터레이션을 종료할 수 있습니다. 시퀀스가 없는 경우에는 map 리스트(1,4,9,10) 을 생성하고 map 리스트 값에서 find 로 4를 찾아 반환할 것이기 때문에 불필요한 중간 리스트가 생성됩니다

코틀린 (Kotlin) filter, map, all, any, count, find, groupBy, flatMap 함수 정리

filter 함수 filter 함수는 리스트를 이터레이션하면서 리턴이 true 인 값만 필터링합니다. var listInts = listOf(1,2,3,4) //filter listInts. filter { it % 2 == 0 } //출력 [2,4] map 함수 map 함수는 값을 변형해서 새로운 리스트를 생성합니다. var listInts = listOf(1,2,3,4) listInts. map { it * it } //출력 [1,4,9,16] val people = listOf(Person("A", 27), Person("B", 35), Person("C", 35)) listInts. map { it.name } //출력 [A, B, C] //심플한 방법 people. map (Person::name) //30살이상의 이름 출력 people. filter { it.age >= 30 }. map (Person::name) //가장 나이가 많은 사람들 모두 출력하기 //1. 최대값을 구하는 반복작업이 쓸데없이 많은 코드 people. filter { it.age == (people.maxBy(Person::age)!!.age) } //매번 maxBy 호출 //2. 계산이 중복되는것을 피하자. 람다안에 람다를 넣는것은 내부 로직을 매우 복잡하게 할 수 있음 val maxAge = people. maxBy (Person::age)!!.age //외부로 빼서 불필요한 반복 제거 people. filter { it.age == maxAge } //맵 사용 //map 에는 filterKeys, mapKeys 와 filterValues, mapValues 함수가 있음 val numbers = mapOf (0 to "zero", 1 to "one") val upperNumbers = numbers.ma

코틀린 (Kotlin) 람다 문법

코틀린 람다 문법 코틀린 람다는 자바의 람다와 비슷하지만 문법이 조금 다릅니다. { x: Int, y:Int -> x+y} 처럼 블럭({..}) 안에 파라메터와 -> 를 구분자로해서 본문을 작성할 수 있습니다. 그리고 람다를 변수에 저장할 수 있습니다. val sum = { x: Int, y:Int -> x+y} //람다식을 변수에 저장 //사용 sum(1,2) //풀어쓴 람다 people. maxBy ({ p : Person -> p.age}) //맨 뒤에 있는 인자가 람다 식인경우 밖으로 뺄 수 있다 people. maxBy () {     p : Person -> p.age } //람다가 유일한 인자인경우 괄호 생략 가능 people. maxBy {     p : Person -> p.age } 아래 코드는 파라메터가 두개 이상이고 마지막 하나만 람다인 경우입니다. people. joinToString (" ") { p: Person -> p.name } //마지막 람다를 블럭밖으로 뺌 람다 파라미터에서 타입을 제거할 수 있습니다. //파라미터 타입 명시 people. maxBy { p:Person -> p.age } //파라미터 타입 추론(컴파일러가 추론) people. maxBy { p -> p.age } 람다의 파라미터가 하나이고 컴파일러가 타입을 추론할 수 있는 경우 it 을 사용 할 수 있습니다. //it 사용 : 람다의 파라미터가 하나인경우 컴파일러가 추론 가능 //중첩된 람다에서는 it 보다는 파라미터를 명시하는 것이 좋다 people. maxBy { it .age } 람다를 변수에 저장할 때는 타입을 추론할 수 없기때문에 타입을 명시해야 됩니다. //람다를 변수에 저장할때는 추론할수 없기때문에 파라미터를 명시한다 val getAge = { p:Person -> p.age }

코틀린 (Kotlin) object 키워드와 동반 객체 정리

코틀린 obeject 키워드 object 는 흔히 자바나 안드로이드에서 사용하는 무명 내부 클래스(anonymous inner class) 처럼 사용할 수 있습니다. object 키워드는 클래스를 정의하면서 객체를 생성 합니다. 코틀린 싱글턴 만들기 코틀린은 object 키워드를 이용해서 별다른 코드없이 싱글턴 구현을 지원합니다. 자바처럼 클래스를 만들고 static 객체로 한번만 할당해주는 코드가 object Payroll 이라고 클래스를 생성해 주기만하면 static 객체에 할당해주는 것을 자동으로 생성해줍니다. object Payroll { //object 클래스 생성으로 싱글턴을 구현     val allEmplyees = arrayListOf<Person> ()     fun calculateSalary() {         //...     } } //사용 Payroll.calculateSalary() //싱글턴처럼 . 으로 접근 Payroll.allEmplyees. add(Person( "zerog" , Company( "zerog" , Address( "" )))) object 생성자 object 객체는 주 생성자와 부 생성자 모두 사용할 수 없습니다. //ERROR!!! object 는 생성자를 사용할 수 없음 object Payroll(val a:String) {    ... } object 상속 object 객체는 상속이 가능합니다. 예를들어 멤버변수로 상태값을 저장하지않고 메소드만 override 하여 사용하는 클래스의 경우 object 로 상속을 받아 생성자없이 바로 사용가능하도록 만들수 있습니다. //object 로 구현한 경우 object CaseInsensitiveFileComparator: Comparator {     override fun compare(o1: File?, o2: F