전체 글 171

[Kotlin] lazy(지연) 컬렉션 연산, sequence(시퀀스)

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. 이전 글에서 몇가지 컬렉션 함수를 살펴보았다. 그 함수들은 결과 컬렉션을 eagerly(즉시) 생성한다. 즉, '컬렉션 함수를 연쇄하면, 매 단계마다 연산의 중간 결과를 새로운 컬렉션에 임시로 담는다'는 의미이다. 컬렉션 함수 연쇄 (시퀀스 사용 X) data class Person(val name: String, val age: Int) people.map(Person::name).filter { it.startsWith('A') } (`people` 은 `List` 이다.) `filter` 와 `map` 은 리스트를 리턴한다. 즉, 위 코드에서는 두 함수를 연쇄 호출하여 리스트를 두 개..

Kotlin 2024.01.12

[Kotlin] 람다를 인자로 받는 컬렉션 함수형 API

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. 함수형 프로그래밍 스타일을 사용하면 컬렉션을 다룰 때 편하다. 컬렉션을 다루는 코틀린 표준 라이브러리를 몇가지 살펴보자. `filter` 와 `map` 함수, 그 함수를 뒷받침하는 개념으로부터 시작된다. filter & map 함수 대부분의 컬렉션 연산을 `filter` 와 `map` 함수를 통해 표현할 수 있다. filter 함수 `filter` 함수는 컬렉션을 iteration 하면서 주어진 람다에 각 원소를 넘겨서 람다가 `true` 를 리턴하는 원소만 모아서 `List` 로 리턴한다. val list = listOf(1, 2, 3, 4) assert( list.filter { it ..

Kotlin 2024.01.12

[Kotlin] Lambda 식(람다 식) & 람다의 캡처 & Member Reference(멤버 참조)

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. lambda expression(람다 식) 또는 lambda(람다)는 다른 함수에 넘길 수 있는 작은 코드 조각이다. 코틀린 표준 라이브러리는 람다를 아주 많이 사용하며, 특히 컬렉션 처리에서 많이 사용한다. 람다 소개 일련의 동작을 변수에 저장하거나 다른 함수에 넘겨야 하는 경우가 자주 있다. 자바에서는 익명 내부 클래스를 통해 이를 구현했다. 하지만, 이는 꽤 번거롭다. 함수형 프로그래밍에서는 함수를 값처럼 다룬다. 그래서 함수를 직접 다른 함수에 전달할 수 있다. 자바 코드 - 버튼에 액션을 추가하는 리스너(익명 내부 클래스로 구현) public void setListener(Butt..

Kotlin 2024.01.11

[Kotlin] object 객체: 객체 선언, 동반 객체, 객체 식

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. 코틀린에서는 `object` 키워드를 다양한 상황에서 사용할 수 있다. 객체 선언(object declaration): 싱글턴을 정의하는 방법 동반 객체(companion object): 주로 어떤 클래스와 관련있는 메서드와 팩토리 메서드를 담을 때 사용 객체 식: 자바의 익명 내부 클래스(anonymous inner class) 대신 사용 모든 경우 클래스를 정의하면서 동시에 인스턴스(객체)를 생성한다. 객체 선언(object declarationi) 인스턴스가 하나만 필요할 때 Singleton(싱글턴) 패턴을 사용하여 이를 구현한다. 자바에서는 보통 클래스의 생성자를 private 으..

Kotlin 2024.01.11

[Kotlin] 클래스 위임과 by, Decorator(데코레이터) 패턴

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. 보통 객체지향 시스템을 설계할 때 시스템을 취약하게 만드는 것은 구현 상속(implementation inheritance)에 의해 발생한다. 이와 관련해서는 이 글과 이 글에서 설명한다. 그래서 코틀린은 기본적으로 클래스를 `final` 로 하여 기본적으로 상속을 금지하고 있다.(not `open`) Decorator(데코레이터) 패턴 하지만 종종 상속을 허용하지 않는 클래스에 새로운 동작을 추가해야 할 때가 있다. 이럴 때 사용하는 일반적인 방법이 Decorator(데코레이터) 패턴이다. 이 패턴의 핵심은 상속을 허용하지 않는 클래스(기존 클래스) 대신 사용할 수 있는 새로운 클래스(데..

Kotlin 2024.01.10

[Kotlin] data class: toString, equals, hashCode, copy, componentN

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. 어떤 클래스가 데이터를 저장하는 역할만을 수행한다면 `toStirng`, `equals`, `hashCode` 를 반드시 오버라이드 해야 한다. 다행히, 여러 IDE 에서는 자동으로 그런 메서드를 정의해주는 기능이 있다. 그런데 코틀린에서는 더 편하다. data class(데이터 클래스) `data` 라는 변경자를 클래스 앞에 붙이면 필요한 메서드를 컴파일러가 자동으로 만들어준다. `data` 변경자가 붙은 클래스를 데이터 클래스라고 한다. `Client` 를 데이터 클래스로 data class Client(val name: String, val postalCode: Int) 이제 `Cli..

Kotlin 2024.01.10

[Kotlin] 모든 클래스가 정의해야 하는 메서드 toString, equals, hashCode

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. 자바와 마찬가지로 코틀린 클래스도 `toString`, `equlas`, `hashCode` 등을 오버라이드 할 수 있다. 이런 메서드들을 알아보면서 아래 `Client` 라는 클래스를 만들어서 예제에 사용하자. class Client(val name: String, val postalCode: Int) toString(): 문자열 표현 자바처럼 코틀린의 모든 클래스도 인스턴스의 문자열 표현을 얻을 방법을 제공한다. 주로 디버깅과 로깅 시 이 메서드를 사용한다. 기본 제공되는 객체의 문자열 표현은 `Client@5e9f23b4` 같은 방식이다. 이는 디버깅, 로깅 시 유용하지 않으며, `t..

Kotlin 2024.01.09

[Kotlin] 인터페이스의 프로퍼티 & 접근자에서 backing field 에 접근, 접근자의 가시성

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. 인터페이스에 선언된 프로퍼티 코틀린에서는 인터페이스에 추상 프로퍼티 선언을 넣을 수 있다. interface User { val nickname: String } `User` 인터페이스를 구현하는 클래스는 `nickname` 의 값을 얻을 수 있는 방법을 제공해야 한다. 인터페이스에 있는 프로퍼티 선언에는 어떠한 상태를 포함할 수 없다. 즉, backing field 에 대한 정보가 들어있지 않다. 프로퍼티 선언을 가진 인터페이스 구현 인터페이스를 구현하는 방법을 코드로 보자 class PrivateUser(override val nickname: String) : User class Su..

Kotlin 2024.01.09

[Kotlin] 주 생성자 & 부 생성자 & 초기화 블록

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. 자바에서는 생성자를 하나 이상 선언할 수 있다.코틀린에서도 비슷하지만 바뀐 점들이 있다. 코틀린에서는 primary constructor(주 생성자), secondary constructor(부 생성자)를 구분하며, initializer block(초기화 블록)을 통해 초기화 로직을 추가할 수 있다. 주 생성자 & 초기화 블록 코틀린에서 가장 일반적으로 사용하는 주 생성자 초기화를 보이기 전에, 가장 복잡한 형태로 초기화하는 방식부터 보자. 프로퍼티 `nickname` 을 가지고 있는 `User` 클래스 class User constructor(_nickname: String) { val ..

Kotlin 2024.01.06

[Kotlin] sealed 로 클래스 계층 확장을 제한하기 + 태그 클래스 VS 상태 패턴

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. 이전 글에서 `Expr` 인터페이스와 `Num`, `Sum` 이라는 하위 클래스를 가지고 덧셈을 구현했었다. (이전 글: [Kotlin] enum & when & smart cast(스마트 캐스트) interface Expr class Num(val value: Int) : Expr class Sum(val left: Expr, val right: Expr) : Expr fun evaluate(e: Expr): Int = when (e) { is Num -> e.value is Sum -> evaluate(e.right) + evaluate(e.left) else -> throw Illeg..

Kotlin 2024.01.06