분류 전체보기 21

RecyclerView: Cannot call this method in a scroll callback.

Pagination 구현을 위해 리사이클러뷰에 OnScrollListener를 추가하여 마지막 아이템에 도달하면 프로그래스바가 포함된 아이템을 제거 후, notifyItemRemoved(position) 메서드를 통해 Adapter에 데이터의 변경을 알리는 코드를 작성하였다. 따로 에러가 발생하지는 않았지만 로그창에 스크롤 콜백에서 해당 메서드를 호출할 수 없다는 아래와 같은 메시지가 표시되었다. RecyclerView: Cannot call this method in a scroll callback. Scroll callbacks mightbe run during a measure & layout pass where you cannot change theRecyclerView data. Any meth..

Android 2022.02.23

메서드 체이닝 패턴이 적용된 코틀린 코드의 시간 복잡도 구하기

다음 코드의 시간 복잡도는 어떻게 될까? arr.filter { it > 0 }.reduce { acc, i -> acc + i } 일반적인 for-loop문이 들어간 명령형 코드에서 시간 복잡도를 계산하는건 직관적이고 익숙하지만, 코틀린 표준 라이브러리의 컬렉션 함수형 API 함수들의 시간 복잡도를 계산하는건 다소 낯선 일이다. 더욱이 위의 코드와 같이 메서드 체이닝(method chaining) 패턴으로 작성된 코드의 시간 복잡도를 구하라는 이야기를 처음 들으면 당황스러울 수 있다(면접에서 내가 그랬다...). 다음에는 당황하는 일이 없도록 잘 정리해보자. 아래 예제의 확장 함수 IntArray.sumPositive()는 IntArray의 요소 중 양수만 걸러내고(filter) 그 결과에 대해 초기값..

Kotlin 2022.02.05

[디자인 패턴] 반복자 패턴 (Iterator Pattern) with 코틀린

내부 표현부를 노출하지 않고 어떤 객체 집합에 속한 원소들을 순차적으로 접근할 수 있는 방법을 제공하는 패턴 반복자 패턴의 아이디어는 객체가 데이터를 저장하는 방법과 이 데이터를 순회하는 방법을 분리하는 것이다. (집합 객체 단순화) 구조 Iterator: 원소를 접근하고 순회하는 데 필요한 인터페이스를 제공한다. ConcreteIterator: Iterator에 정의된 인터페이스를 구현하는 클래스로, 순회 과정 중 집합 객체 내에서 현재 위치를 기억한다. Aggregate: Iterator 객체를 생성하는 인터페이스를 정의한다. (Aggreate는 '집합'이라는 뜻을 가지고 있음) ConcreteAggregate: 해당하는 ConcreteIterator의 인스턴스를 반환하는 Iterato..

[Kotlin] 최상위 함수와 프로퍼티

최상위 함수 객체 지향 언어인 자바에서는 모든 코드를 클래스의 메소드로 작성해야 한다. 하지만 실제 코드를 작성하면 어느 한 클래스에 포함시키기 어려운 코드가 많이 생긴다. 중요한 객체는 하나뿐이지만 그 연산을 객체의 인스턴스 API에 추가해서 API를 너무 크게 만들고 싶지 않은 경우가 있다. 그 결과 다양한 정적 메서드를 모아두는 역할만 담당하며, 특별한 상태나 인스턴스 메서드는 없는 클래스가 생겨난다. JDK의 Collectios 클래스가 전형적인 예시이며, 프로그래머가 작성한 코드에서 Util이 이름에 들어있는 클래스가 비슷한 예이다. 코틀린에서는 이런 무의미한 클래스가 필요없다. 대신 함수를 직접 소스 파일의 최상위 수준, 모든 다른 클래스의 밖에 위치시키면 된다. 이러한 함수를 최상위 함수(T..

Kotlin 2021.12.29

[Kotlin] 코틀린과 함수형 프로그래밍

함수형 프로그래밍의 핵심 개념 1. 일급 시민(first-class) 함수 함수(프로그램의 행동을 나타내는 코드 조각)을 일반 값처럼 다룰 수 있다. 함수를 변수에 저장할 수 있고, 함수를 인자로 다른 함수에 전달할 수 있으며, 함수에서 새로운 함수를 만들어서 반환할 수 있다. (일급 시민에 대한 설명은 여기에서 확인) 2. 불변성(immutability) 함수형 프로그래밍에서는 일단 만들어지고 나면 내부 상태가 절대로 바뀌지 않는 불변 객체를 사용해 프로그램을 작성한다. 3. 부수 효과(side effect) 없음 함수형 프로그래밍에서는 입력이 같으면 항상 같은 출력을 내놓고 다른 객체의 상태를 변경하지 않으며, 함수 외부나 다른 바깥 환경과 상호작용하지 않는 순수 함수(pure function)를 사..

Kotlin 2021.12.27

[Kotlin] 1급 시민(first-class citizen)이란?

1급 시민(first-class citizen)이란? 프로그래밍에서 1급 시민이란 다음의 조건을 충족하는 것을 말한다. 변수에 담을 수 있다. 함수의 인자로 전달할 수 있다. 함수의 반환값으로 전달할 수 있다. 1급 객체와 1급 함수? 1급 시민, 1급 객체, 1급 함수와 같이 비슷한 용어들이 존재하는데 그 미묘한 차이를 정리해보자. 1급 객체는 말 그대로 1급 시민의 조건을 충족하는 객체를 이야기한다. 코틀린의 함수는 객체로 사용할 수 있기 때문에 1급 객체에 속한다. 1급 함수는 1급 객체이면서 아래의 조건들은 추가로 만족하는 함수를 말한다. 런타임에 생성이 가능하다. 익명으로 생성이 가능하다. 코틀린과 1급 함수 코틀린의 함수는 1급(first-class)이다. 자바의 경우 함수는 클래스의 멤버의 ..

Kotlin 2021.12.27

[Kotlin] 정적 타입 언어 vs 동적 타입 언어

정적 타입(Statically typed) 언어 정적 타입 언어는 컴파일 타임에 타입 검증이 일어난다. 프로그램 안에서 객체의 필드나 메서드를 사용할 때마다 컴파일러가 타입을 검증해준다. 기본적으로 자바, C, C++는 모든 변수의 타입을 프로그래머가 직접 명시해야 한다(언어의 버전이 올라가면서 타입 추론 기능을 지원하기도 한다). 하지만 정적 타입 언어 중에서도 코틀린, 하스칼, 오카멜(OCaml)과 같은 언어는 컴파일러가 문맥으로부터 변수 타입을 자동으로 유추하여 프로그래머가 타입 선언을 생략할 수 있다. 컴파일러가 문맥을 고려해 변수 타입을 결정하는 기능을 타입 추론(type inference)이라고 한다. var x = 1 위의 코드는 코틀린으로 작성되었다. 변수를 정의하면서 정수 값으로 초기화하..

Kotlin 2021.12.25

[Java] fail-fast vs weakly consistent iterator

자바 컬렉션 프레임워크에서 Map 인터페이스와 관련된 내용을 찾다보면 fail-fast와 fail-safe iterator에 대한 내용이 자주 보인다. 이 주제는 Concurrency(동시성)과 관련이 있는데, Map의 대표적인 구현 클래스인 HashMap의 요소를 for-each문 내부에서 변경할 경우 ConcurrentModificationException을 던지는 것을 한번쯤은 경험해봤을 것이다. 이 예외를 처음 경험한게 코딩테스트 도중이었기에 적잖이 당황했던 기억이 있기에 이번 기회에 정리하고자 한다. HashMap에서의 ConcurrentModificationException 예시 private HashMap map; // 특정 카테고리를 제외한 모든 요소 삭제 public void clear(..

Java 2021.12.20

[Java] jenv로 자바 버전 쉽게 변경하기

java -version과 javac -version이 다르게 표시될 때 터미널에서 java -version과 javac -version을 실행했을 때 Java(JDK)의 버전이 다르게 표시되는 경우가 있다. 개인적으론 특정 버전 설치와 변경이 편리한 jenv를 이용하는 두 번째 방법을 개인적으로 추천한다. 방법 1 먼저 /usr/libexec/java_home -V을 실행하면 다음과 같이 출력이 된다. Matching Java Virtual Machines (3): 15.0.2 (x86_64) "AdoptOpenJDK" - "AdoptOpenJDK 15" /Library/Java/JavaVirtualMachines/adoptopenjdk-15.jdk/Contents/Home 1.8.0_311 (x86_..

Java 2021.12.19

[Java] String, StringBuilder, StringBuffer의 차이점

Java를 공부하다보면 String은 불변(immutable) 객체라는 이야기를 많이 듣게 된다. String text = "Java"; text = text + " String"; System.out.println(text); // Java String 아니 위 코드처럼 String 값이 잘만 변하는데 무슨 말이야! 라고 생각될 수 있지만 Java의 String 객체는 변하지 않는다. 객체가 불변일 경우 멀티 쓰레드 환경에서 값이 변경될 일이 없이 때문에 자연스럽게 Thread safe하게 된다. JDK 5 이전에는 String 문자열을 더하면 새로운 String 객체가 생성되고, 기존 객체는 쓰레기가 되어 나중에 GC(Garbage Collection)의 대상이 되었다. 이것이 반복되면 쓰레기가 계속..

Java 2021.12.17