[Java 8+] Map과 merge(), compute()
·
Java/Modern Java(8~)
[Java 8+] Map.merge(), Map.compute()Map은 백엔드 개발에서도 자주 사용되는 컬렉션이고, PS 문제를 풀 때도 자주 등장하는 컬렉션이다.키의 존재 유무를 파악하고, 그 값에 따라 저장하는 값이 달라지는 형태의 문제를 자주 봤을 것이다. 자바의 Map 라이브러리에는 키가 이미 존재할 때 값 갱신을 간편하게 처리할 수 있는 유용한 메서드들이 있다. 그중 대표적인 것이 merge와 compute이다.MergeMap.merge(K key, V value, BiFunction remappingFunction)특정 키에 대해 새 값을 병합하는 메서드이다.동작 방식은 다음과 같다.키가 존재하지 않으면 value를 그대로 삽입한다.키가 존재하면 기존 값과 새로운 value를 remappin..
[JVM] 자바 유저 스레드와 커널 스레드
·
Java/JVM
자바 유저 스레드와 커널 스레드#Java/JVM스레드에는 사용자 수준 스레드(User Level Threads)와 커널 수준 스레드(Kernel Level Threads) 두 가지 유형이 있다. 두 가지의 장점을 합친 Hybrid 모델도 존재한다. Java에서는 Kernel thread와 User thread를 모두 사용하는 Hybrid 모델이다.사용자 수준 스레드는 사용자 라이브러리를 통해 사용자가 만든 스레드로, 스레드가 생성 된 프로세스의 주소 공간에서 해당 프로세스에 의해 실행되고 관리된다.커널 수준 스레드는 커널에 의해 생성되고 운영체제에 의해 직접 관리된다. 사용자 수준 스레드보다 생성 및 관리 속도가 느리다.두 유형의 차이는 누가 스레드를 제어하느냐에 있다.사용자 수준 스레드는 스레드가 생성..
[JVM] 자바 코드부터 JVM의 동작까지 구체적으로 살펴보기
·
Java/JVM
JVM#Java/JVM/자바의 등장 배경/JVM/자바 컴파일러/자바 클래스 로더/자바 실행 엔진(Execution Engine)/자바 인터프리터/자바 JIT 컴파일러/GraalVM/Garbage Collection/자바 런타임 시스템/정리: JVM이란?자바의 등장 배경1990년대 초반 당시 주로 사용되던 C/C++이 갖는 어려 문제점들을 극복하기 위해 개발하게 되었다.문제점들메모리를 개발자가 직접 제어해야 한다는 점복잡성이 높아 개발자가 오류를 만들어내기 쉽다는 점플랫폼에 따라 다른 결과를 출력할 수 있다는 점등등직접 위 문제의 해결 방법들을 찾아보자.메모리를 개발자가 직접 제어해야 한다는 점: 알고리즘을 통해 자동으로 제어하게 설계해보자.복잡성이 높아 개발자가 오류를 만들어내기 쉽다는 점: 선택의 폭을..
[Java] 68. 병렬 스트림
·
Java/Modern Java(8~)
병렬 스트림#Java/adv3단일 스트림HeavyJob 클래스는 오래 걸리는 작업을 시뮬레이션하는데, 각 작업은 1초 정도 소요된다고 가정하겠다. 입력값에 10을 곱한 결과를 반환하며, 작업이 실행될 때마다 로그를 출력한다.예제1 - 단일 스트림단일 스트림(sequential stream)으로 IntStream.rangeClosed(1, 8)에서 나온 1부터 8까지의 숫자 각각에 대해 heavyTask()를 수행long startTime = System.currentTimeMillis();int sum = IntStream.rangeClosed(1, 8) .map(HeavyJob::heavyTask) .reduce(0, (a, b) -> a + b); // sum()long en..
[Java] 67. 디폴트 메서드
·
Java/Modern Java(8~)
디폴트 메서드#Java/adv3디폴트 메서드가 등장한 이유자바 8에서 디폴트 메서드(default method) 가 등장하기 전에는 인터페이스에 메서드를 새로 추가하는 순간, 이미 배포된 기존 구현 클래스들이 해당 메서드를 구현하지 않았기 때문에 전부 컴파일 에러를 일으키게 되는 문제가 있었다.디폴트 메서드는 이러한 문제를 해결하기 위해 등장했다.자바 8부터는 인터페이스에서 메서드 본문을 가질 수 있도록 허용해 주어, 기존 코드를 깨뜨리지 않고 새 기능을 추가할 수 있게 되었다.디폴트 메서드로 문제 해결자바 8부터 이러한 하위 호환성 문제를 해결하기 위해 디폴트 메서드가 추가되었다. 인터페이스에 메서드를 새로 추가하면서, 기본 구현을 제공할 수 있는 기능이다.예를 들어, Notifier 인터페이스에 sc..
[Java] 66. Optional
·
Java/Modern Java(8~)
Optional#Java/adv3옵셔널이 필요한 이유NPE자바에서 null은 값이 없음을 표현하는 기본적인 방법이다.하지만, null을 잘못 사용하거나 null 참조에 대해 메서드를 호출하면 NullPointerException (NPE)이 발생하여 프로그램이 예기치 않게 종료될 수 있다.메서드 뎁스가 깊고, null 체크를 누락하면 추척하기 어렵고, 디버깅 비용이 증가한다.가독성 저하null을 반환하거나 사용하는 경우, 조건문을 통해 객체가 null인지 계속 확인해야 한다. 이러한 null 체크 로직이 누적되면 코드가 복잡해지고 가독성이 저하된다.의도가 드러나지 않음메서드 시그니처(String findNameById(Long id))만 보고서는 이 메서드가 null을 반환할 수도 있다는 사실을 명확히 ..
[Java] 65. 스트림 API3 - 컬렉터
·
Java/Modern Java(8~)
스트림 API3 - 컬렉터#Java/adv3컬렉터1스트림이 중간 연산을 거쳐 최종 연산으로써 데이터를 처리할 때, 그 결과물이 필요한 경우가 많다. 대표적으로 "리스트 나 맵 같은 자료 구조에 담고 싶다"거나 "통계 데이터를 내고 싶다"는 식의 요구가 있을 때, 이 최종 연산에 Collectors를 활용한다.collect 연산(예: stream.collect(...))은 반환값을 만들어내는 최종 연산이다. collect(Collector collector) 형태를 주로 사용하고, Collectors 클래스 안에 준비된 여러 메서드를 통해서 다양한 수집 방식을 적용할 수 있다.기능메서드 예시설명반환 타입List로 수집toList() toUnmodifiableList()스트림 요소를 List로 모은다. to..
[Java] 64. 스트림 API2 - 기능
·
Java/Modern Java(8~)
스트림 API2 - 기능#Java/adv3스트림 생성스트림이 제공하는 다양한 스트림 생성, 중간 연산, 최종 연산을 자세히 알아보자.생성 방법코드 예시특징컬렉션list.stream()List, Set 등 컬렉션에서 스트림 생성배열Arrays.stream(arr)배열에서 스트림 생성Stream.of(...)Stream.of("a", "b", "c")직접 요소를 입력해 스트림 생성무한 스트림(iterate)Stream.iterate(0, n -> n + 2)무한 스트림 생성(초깃값 + 함수)무한 스트림(generate)Stream.generate(Math::random)무한 스트림 생성 (Supplier 사용)컬렉션, 배열, Stream.of 은 기본적으로 유한한 데이터 소스로부터 스트림을 생성한다.iter..
[Java] 63. 스트림 API1 - 기본
·
Java/Modern Java(8~)
스트림 API1 - 기본#Java/adv3스트림 API 시작우리가 만든 MyStreamV3를 사용할 때를 떠올려보면 데이터들이 흘러가면서 필터되고, 매핑된다.자바도 스트림 API라는 이름으로 스트림 관련 기능들을 제공한다. (I/O 스트림이 아니다.)자바가 제공하는 스트림 API는 더 정교하고, 더 많은 기능을 제공한다.List names = List.of("Apple", "Banana", "Berry", "Tomato");// "B"로 시작하는 이름만 필터 후 대문자로 바꿔서 리스트로 수집Stream stream = names.stream();List result = stream .filter(name -> name.startsWith("B")) .map(s -> s.toUp..
[Java] 62. 메서드 참조
·
Java/Modern Java(8~)
메서드 참조#Java/adv3메서드 참조가 필요한 이유/예제1BinaryOperator add1 = (x, y) -> x + y;BinaryOperator add2 = (x, y) -> x + y;동일한 기능을 하는 람다를 여러 번 작성했는데, 코드가 중복되어 있어 유지 보수가 어려울 수 있다./예제2x + y를 하나의 메서드 add()로 분리하였다. 람다가 add()를 호출하게 된다.(x, y) -> add(x, y)남은 문제람다를 작성할 때마다 (x, y)-> add(x, y) 형태의 코드를 반복해서 작성해야 한다.매개변수를 전달하는 부분이 장황하다. 람다에서 동일한 모양의 매개변수를 add() 메서드에 그대로 전달하고 있다./예제3: 메서드 참조(Method Reference) 문법를 사용메서드 참..