병렬 스트림 컬렉션에 parallelStream을 호출하면 병렬 스트림이 생성됨 병렬 스트림이란 각각의 스레드에서 처리할 수 있도록 스트림 요소를 여러 청크로 분할한 스트림 모든 멀티코어 프로세서가 각각의 청크를 처리하도록 할당 순차 스트림을 병렬 스트림으로 변환하기 순차 스트림에 parallel 메서드를 호출하면 함수형 리듀싱 연산이 병렬로 처리 public long parallelSum(long n) { return Stream.iterate(1L, i -> i+1) .limit(n) .parallel() .reduce(0L, Long::sum); } 반대로 sequential() 로 병렬 스트림을 순차 스트림으로 바꿀 수 있음 parallel 과 sequential 중 최종적으로 호출된 메서드가 전..
분할 Predicate를 분류 함수로 사용하는 특수한 그룹화 기능 분할 함수는 boolean을 반환하므로 Map의 키 형식은 Boolean Map partitionedMenu = menu.stream().collect(partitionBy(Dish::isVegetarian); //{false=[pork, beef, chicken, prawns, salmon], true=[french fries, rice, season fruit, pizza]} List vegetarianDishes = partitionedMenu.get(true);//채식 요리 List vegetarianDishes = menu.stream().filter(Dish::isVegetarian).collect(toList());//동일 분..
그룹화 groupingBy() 연산의 결과로 그룹화 함수가 반환하는 키, 각 키에 대응하는 스트림의 모든 항목 리스트를 값으로 갖는 Map 반환 Map dishesByType = menu.stream() .collect(groupingBy(Dish::getType)); Map dishesByCaloricLevel = menu.stream().collect(//복잡한 분류 기준이 필요한 상황 groupingBy(dish -> { if (dish.getCalories() 500) .collect(groupingBy(Dish::getType)); //{OTHER=[french fries, pizza], MEAT=[pork, beef]}, FISH 요리가 없으면 키 자체가 사라짐 Map caloricDishes..
컬렉터 Stream.collect 메서드의 인수로 스트림의 항목을 컬렉션으로 재구성 컬렉터로 스트림의 모든 항목을 하나의 결과로 합침 Collector 인터페이스 구현은 스트림의 요소를 어떤 식으로 도출할지 지정 collect로 결과를 수집하는 과정을 간단하면서도 유연한 방식으로 정의할 수 있음 스트림에 collect를 호출하면 스트림의 요소에 리듀싱 연산이 수행 리듀싱 연산을 이용해서 스트림의 각 요소를 방문하면서 컬렉터가 작업을 처리 Collectors 유틸리티 클래스는 자주 사용하는 Collector 인스턴스를 생성할 수 있는 정적 팩토리 메서드 제공 Collectos에서 미리 정의된 컬렉터 스트림 요소를 하나의 값으로 리듀스하고 요약 요소 그룹화 요소 분할 최대값과 최소값 검색 Collectors..
Stream 데이터의 흐름 Collection 형태로 구성된 데이터를 람다를 이용해 간결하고 직관적으로 프로세싱 for, while 등 기존 loop 를 대체 병렬처리 가능 데이터 소스를 변경하지 않음 재사용 불가 컬렉션은 현재 자료구조가 포함되는 모든 값을 메모리에 저장하는 자료구조 스트림은 요청할 때만 요소를 계산하는 고정된 자료구조 내부반복은 데이터 표현과 하드웨어를 활용한 병렬성 구현을 자동으로 선택 지연된 연산 : 중간 연산을 합친 다음에 합쳐진 중간 연산을 최종 연산으로 한번에 처리 Filter 만족하는 데이터만 걸러내는데 사용 Predicate에 true를 반환하는 데이터만 존재하는 stream을 리턴 중간처리 기능 Intermediate Operation, 여러가지 중간처리 이어붙이기 가능..
동작 파라미터화 메서드가 다양한 동작(전략)을 받아서 내부적으로 다양한 동작을 수행할 수 있다. 코드/동작(전략)을 메서드 인수로 전달, 한 개의 파라미터로 다양한 동작 변화하는 요구사항에 더 잘 대응할 수 있는 코드를 구현 //As-Is public static List filterGreenApples(List inventory) { List result = new ArrayList(); for (Apple apple : inventory) { if (GREEN.equals(apple.getColor())) { //색으로 필터링 result.add(apple); } } return result; } //Step1 public static List filterGreenApplesByColor(List i..
메소드에서 알고리즘의 골격을 정의함. 알고리즘의 여러 단계 중 일부는 서브클래스에서 구현할 수 있음. 알고리즘의 구조는 유지하면서 서브클래스의 특정 단계를 재정의 가능. public abstract class CaffeineBeverage { //전체적인 처리 과정을 관리 final void prepareRecipe() { //템플릿 메소드. 아무렇게나 음료를 만들지 못하도록 final 선언 boilWater(); brew(); pourInCup(); addCondiments(); } abstract void brew(); //서로 다른 방식으로 처리되는 메소드를 추상화 abstract void addCondiments(); //메소드를 일반화시켜서 베이스 클래스에 등록 void boilWater() {..
어떤 서브시스템의 일련의 인터페이스에 대한 통합된 인터페이스를 제공 퍼사드에서 고수준 인터페이스를 정의하기 때문에 서브시스템을 더 쉽게 사용 가능 인터페이스를 단순화 시키고 클라이언트와 구성요소들로 이루어진 서브시스템을 분리 public class HomeTheaterTestDrive { public static void main(String[] args) { Amplifier amp = new Amplifier("Top-O-Line Amplifier"); Tuner tuner = new Tuner("Top-O-Line AM/FM Tuner", amp); DvdPlayer dvd = new DvdPlayer("Top-O-Line DVD Player", amp); CdPlayer cd = new CdPla..
한 클래스의 인터페이스를 클라이언트에서 사용하고자 하는 다른 인터페이스로 변환 어댑터를 이용하면 인터페이스 호환성 문제 때문에 같이 쓸 수 없는 클래스들을 연결해서 사용 가능 호환되지 않는 인터페이스를 사용하는 클라이언트를 그대로 활용 가능 클라이언트와 구현된 인터페이스를 분리 인터페이스가 바뀌더라도 변경 내역은 어댑터에서 캡슐화되기 때문에 클라이언트는 바뀔 필요 없음 public interface Duck { void quack(); void fly(); } public interface Turkey { void gobble(); void fly(); } public class WildTurkey implements Turkey{ @Override public void gobble() { System...
커맨드 패턴 커맨드(Command) 패턴은 객체지향 디자인 패턴 중 하나로, 요청을 객체의 형태로 캡슐화하여 사용자가 서로 다른 요청을 실행할 수 있도록 합니다. 즉, 요청을 발생시키는 객체와 요청을 처리하는 객체 사이의 결합도를 낮추는 데에 사용됩니다. 요청을 하는 객체(Invoker)와 요청을 수행하는 객체(Receiver)를 분리 Command 객체가 Receiver 객체를 캡슐화 Command 객체를 이용해서 요청을 매개변수화 가능 Command 인터페이스: 수신자 객체와 관련된 작업을 수행하는 execute 메서드를 제공합니다. ConcreteCommand 클래스: Command 인터페이스를 구현하는 구체적인 커맨드 클래스입니다. 요청을 수신자 객체에 전달하는 책임을 갖습니다. Receiver ..