[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) 문법를 사용메서드 참..
[Java] 61. 람다 vs 익명 클래스
·
Java/Modern Java(8~)
람다 vs 익명 클래스#Java/adv3문법 차이익명 클래스익명 클래스는 클래스를 선언하고 즉시 인스턴스를 생성하는 방식이다.익명 클래스도 하나의 클래스이다.람다 표현식람다 표현식은 함수를 간결하게 표현할 수 있는 방식이다. ( 연산자 사용)함수형 인터페이스(메서드가 하나인 인터페이스)를 간단히 구현할 때 주로 사용한다.람다도 인스턴스가 생성된다.코드의 간결함익명 클래스는 람다 표현식에 비해 코드의 양이 상대적으로 많다.람다 표현식은 간결하고, 불필요한 코드를 최소화한다. 많은 생략 기능도 지원한다.상속 관계익명 클래스는 일반적인 클래스처럼 다양한 인터페이스와 클래스를 구현하거나 상속할 수 있다. 크게 제한사항이 없다.람다 표현식은 메서드를 딱 하나만 가지는 함수형 인터페이스만을 구현할 수 있다. 클..
[Java] 60. 람다 활용
·
Java/Modern Java(8~)
람다 활용#Java/adv3필터 만들기1psvm { List numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // 짝수만 거르기 List evenNumbers = filter(numbers, n -> n % 2 == 0); // 홀수만 거르기 List oddNumbers = filter(numbers, n -> n % 2 == 1);}static List filter(List numbers, Predicate predicate) { List filtered = new ArrayList(); for (Integer number : numbers) { if (predicate.test(number)) { filter..
[Java] 59. 함수형 인터페이스
·
Java/Modern Java(8~)
함수형 인터페이스#Java/adv3함수형 인터페이스와 제네릭1함수형 인터페이스에서 제네릭이 필요한 이유방법1: 함수형 인터페이스 따로 선언@FunctionalInterfaceinterface StringFunction { String apply(String s);}@FunctionalInterfaceinterface NumberFunction { Integer apply(Integer s);}StringFunction upperCase = s -> s.toUpperCase();NumberFunction square = n -> n * n;두 인터페이스의 apply 메서드는 하나의 인자를 입력받고 결과를 반환한다.타입이 다르기 때문에 두 개의 인터페이스를 따로 만들어서 람다를 할당해야 한다.타입..