728x90
- 함수형 프로그래밍
- 순수 함수: 수학의 함수처럼 특정한 데이터에 의존하지 않고, 관련없는 데이터를 변경하지도 않으며, 결과값이 오직 입력값에만 영향을 받는 함수
- 효용
- 검증이 쉽다
- 성능 최적화가 쉽다
- 동시성 문제를 해결하기 쉽다
- 모던 자바 : 자바 8 변경점
- 함수형 프로그래밍 아이디어 1: 함수를 일급 값(일급 객체)으로
- 일급 객체 특징
- 함수에 인자로 넘길 수 있다.
- 함수의 결과로 반환할 수 있다.
- 값을 수정할 수 있다.
- 값을 변수에 대입할 수 있다.
- 결론: 메서드 참조 기능 도입
- 일급 객체 특징
- 함수형 프로그래밍 아이디어 2: 람다(익명함수)
- 익명함수란 이름이 없는 함수를 뜻하며 일급 객체로 취급됨
- 함수를 값으로 사용할 수 있으며 파라미터에 전달 가능
- 연산 가능
- 스트림
- 데이터 처리연산을 지원하도록 소스에서 추출된 연속된 요소
- 컬렉션의 반복을 처리하는 일종의 기능이자 멀티스레드 관련 코드를 구현하지 않아도 알아서 병렬로 추가해주는 기능
- 함수형 프로그래밍 아이디어 1: 함수를 일급 값(일급 객체)으로
람다와 스트림 문법 살펴보기
- 함수를 값으로 전달하기: 함수형 인터페이스
- 추상 메소드를 딱 하나만 가지고 있는 인터페이스
- @FunctionalInterface 어노테이션으로 검증할 수 있음
interface Predicate<T> {
boolean test(T t);
}
함수형 인터페이스를 타입 삼아 인자로 전달받는 함수
// 변경점 1 : Predicate<Car> 인터페이스를 타입 삼아 함수를 전달합니다!
public static List<Car> parkCars(List<Car> carsWantToPark, Predicate<Car> function) {
List<Car> cars = new ArrayList<>();
for (Car car : carsWantToPark) {
// 변경점 2 : 전달된 함수는 다음과 같이 사용됩니다!
if (function.test(car)) {
cars.add(car);
}
}
return cars;
}
위의 함수를 사용
parkingLot.addAll(parkCars(carsWantToPark, Car::hasTicket));
parkingLot.addAll(parkCars(carsWantToPark, Car::noTicketButMoney));
- 함수를 값으로 취급하기 때문에 함수를 참조로 불러서 사용
- Car :: Car 클래스 내부의 메소드
- 람다
// 기본적으로 문법은 다음과 같습니다.
(파라미터 값, ...) -> { 함수 몸체 }
// 아래의 함수 두개는 같은 함수입니다.
// 이름 반환타입, return문 여부에 따라 {}까지도 생략이 가능합니다.
public int toLambdaMethod(int x, int y) {
return x + y;
}
(x, y) -> x + y
// 이런 함수도 가능하겠죠?
public int toLambdaMethod2() {
return 100;
}
() -> 100
// 모든 유형의 함수에 가능합니다.
public void toLambdaMethod3() {
System.out.println("Hello World");
}
() -> System.out.println("Hello World")
// 주말의 주차장 추가
ArrayList<Car> weekendParkingLot = new ArrayList<>();
weekendParkingLot
.addAll(parkCars(carsWantToPark, (Car car) -> car.hasParkingTicket() && car.getParkingMoney() > 1000));
- 스트림
한번 더 추상화된 자료구조와 자주 사용하는 프로그래밍 API를 제공한 것
자료구조의 “흐름”을 객체로 제공해주고, 그 흐름동안 사용할 수 있는 메서드들을 api로 제공
컬렉션에 정의되어 있으므로 컬렉션을 상속하는 구현체들은 스트림을 반환할 수 있
- 스트림의 특징
- 원본 데이터를 변경하지 않음: 자바 컬렉션으로부터 스트림을 받아서 한 번 사용
- 일회용: 한 번 사용한 스트림은 어디에도 남지 않음
- 사용 예시
List<Car> benzParkingLot =
// carsWantToPark의 스트림값을 받아와서
carsWantToPark.stream()
// 거기 구현되어 있는 filter()메서드를 사용합니다.
// filter메서드는 함수를 파라미터로 전달받습니다.
// 여기서 함수는 제조사가 벤츠면 true를 반환하는 함수네요.
// 필터 메서드는 이름처럼 false를 반환한 스트림의 원소들을 제거합니다.
.filter((Car car) -> car.getCompany().equals("Benz"))
// 이 결과도 반환을 받아서 다시 리스트로 묶어줍니다.
.toList();
- 대표적인 스트림 API
forEach()
넘겨받은 함수를 각각의 원소에 대하여 실행
반환값이 있어도 무시됨
List<String> carNames = Arrays.asList("Series 6", "A9", "Ionic 6");
carNames.stream()
.forEach(System.out::println);
// 결과
// Series 6
// A9
// Ionic 6
map()
조건에 맞는 것만 반환하는 filter()와 달리 모든 요소를 변환하여 반환
carNames.stream()
.map(name -> name.toUpperCase()).toList();
// 결과
// ["SERIES 6", "A9", "IONIC 6"]
NULL
기본적으로 아무것도 참조하지 않는다는 것을 의미
- null을 다룰 때 조심해야 하는 점
- null이 반환될 여지를 명시하고 그 메서드를 사용할 때 조심하기
- null 체크를 매번하기 보다 객체 감싸서 반환하기
- 감싸는 객체를 추상화하기 -> java.util.Optional 객체
- Optional 기본 정리
- Optional<T> 클래스로 Nulll Pointer Exception을 방지할 수 있도록 도와줌
- null이 올 수 있는 값을 감싸는 Wrapper 클래스
- Optional이 비어있더라도 참조할 때 Null Pointer Exception이 발생하지 않음
- Optional 간단 사용법
1. 값이 null인 Optional 생성
Optional<Car> emptyOptional = Optional.empty();
2. 값이 있는 Optional 생성
Optional<Car> hasDataOptional = Optional.of(new Car());
3. 값이 있을수도 없을수도 있는 Optional 생성
Optional<Car> hasDataOptional = Optional.ofNullable(getCarFromDB());
4. Optional 객체 사용하기
Optional<String> carName = getCarNameFromDB();
// orElse() 를 통해 값을 받아옵니다, 파라미터로는 null인 경우 반환할 값을 적습니다.
String realCarName = carName.orElse("NoCar");
// 위는 예시코드고 실제는 보통 아래와 같이 사용하겠죠?
String carName = getCarNameFromDB().orElse("NoCar");
// orElseGet()이라는 메서드를 사용해서 값을 받아올 수 있습니다.
// 파라미터로는 없는 경우 실행될 함수를 전달합니다.
Car car = getCarNameFromDB().orElseGet(Car::new);
// 값이 없으면, 그 아래 로직을 수행하는데 큰 장애가 되는경우 에러를 발생시킬수도 있습니다.
Car car = getCarNameFromDB()
.orElseThrow(() -> new CarNotFoundException("NO CAR!)
'[스파르타코딩클럽] > Java 문법 종합반' 카테고리의 다른 글
Chapter 12. 스레드 (0) | 2023.10.18 |
---|---|
Chapter 11. 제네릭(Generic) (0) | 2023.10.17 |
Chapter 10. 예외처리 (0) | 2023.10.17 |
Chapter 9. 인터페이스 (0) | 2023.10.17 |
Chapter 8. 상속 (0) | 2023.10.16 |