
자바는 객체 지향 프로그래밍이지만 도태되지 않기 위해서 함수형 프로그래밍의 기능들과 스트림을 Java 8 부터 추가했다.
결과가 오직 입력값에만 영향을 받는 함수 : 순수함수
프로그램을 순수 함수의 모음으로 바라보고 구현하는게 함수형 프로그래밍이다.
함수형 프로그래밍은 검증이 쉬우며, 성능 최적화가 쉽고 동시성 문제를 해결하기 쉬운 장점들이 있다.
자바에서 개발자가 조작이 가능한 대상은 객체와 기본값 (int, long..)등이다.
이들은 함수에 인자로 넘길 수 있으며, 결과로 반환될 수 있고, 수정이 가능하며 변수에 대입이 간으하다.
하지만 메서드는 메서드의 인자로 사용할 수 없고, 반환을 메서드로 할 수 없으며 메서드를 변수에 대입할 수 없다. 하지만 이게 가능하진다면. 즉 함수를 값으로 취급한다면 할 수 있는게 매우 많아지기 때문에 Java 8 부터 메서드 참조 기능이 도입되었다.
람다는 익명 함수를 지칭한다. 즉 이름없은 함수며 이는 일급 객체로 취급된다. (자바의 객체와 기본값처럼 취급된다는 것)
함수를 값으로 전달하려면 다음과 같이 해야할거같다.
public exampleMethod(int pram1, ??? pramF) { ... }
???에 함수 타입을 넣어야하는데 지금까지 사용한 메소드 타입은 반환값 타입이지 메소드의 타입이 아니다.
???에 메소드 타입을 적으려면 함수형 인터페이스를 선언하거나 사용해야한다.
먼저 값으로 사용할 pramF를 구현하면 다음처럼 할 수 있다.
public static boolean pramF1(Man man) {
return man.isMale;
}
public static boolean pramF2(Man man) {
return !man.isMale&&man.hasCar;
}
이들을 위한 인터페이스는 다음처럼 할 수 있다.
interface Predicate<T> {
boolean test(T t);
}
이들을 가지고 사용한다면 다음과 같이 할 수 있다.
public static List<Man> hiMan(List<Man> hasCarHuman, Predicate<Man> function){
List<Man> mans = new ArrayList<>();
for(Man man : hasCarHuman){
if(function.test(man)){
mans.add(man);
}
}
return man;
}
실제로는 다음처럼 사용한다.
A.addAll(hihiman(hasCarHuman, Man::pramF1));
A.addAll(hihiman(hasCarHuman, Man::pramF2));
람다 익명 함수는 다음과 같이 사용한다.
// 주말의 주차장 추가
ArrayList<Car> weekendParkingLot = new ArrayList<>();
weekendParkingLot.addAll(parkCars(carsWantToPark, (Car car) -> car.hasParkingTicket() && car.getParkingMoney() > 1000));
parkCars의 매개변수로 2개가 필요하지만 뒤에를 보면 매개변수 형태가
(Car car) -> car.hasParkingTicket() && car.getParkingMoney() > 1000)
이렇게 되어있다. 이건 Car타입의 car 객체에서 뒤에 로직을 만족하는 원소들을 리턴한다는 것이다.
즉, 정리하면 다음과 같다.
(파라미터 값, ...) -> { 함수 몸체 }
public void F1(){sout("hello");} 람다식으로 표현하면 ()->sout("hello)가 되는것이다.
데이터 처리 연산을 지원하는 연속 요소다. 컬렉션이 저장용 인터페이스라면 스트림은 처리용 인터페이스이다.
List<Man> newMan = new ArrayList<>();
ArrayList<Man> amTheMan= newMan.stream()
.filter((Man man)-> man.isStudying())
.toList();
결과
List<Man> newMan = new ArrayList<>();
ArrayList<Man> amTheMan= newMan.stream().filter((Man man)-> man.isStudying()).toList();
복잡해 보이지만 간단하다.
스트림 객체를 받아서 이미 구현되어 있는 메소드들을 사용해서 조건을 거쳐 남은 것들을 toList를 통해 List로 만들어서 amTheMan에 저장하는거다.