안드로이드 람다 조합 (RxJava2 호환)
해당 포스팅에서 언급된 내용은 Ndroid 에서 제공합니다.
RxJava2 와 더불어 안드로이드에서 더욱 Functional Programming 을 할 수 방법이 늘어났습니다.
점점 JAVA8 에서 언급된 내용들이 지원이 되고 있죠.
특히 RxJava 진영에서 JAVA8 의 기본 함수형 인터페이스를 제공해주기 때문에, 더욱 개발은 편해질 수 있을 것이라 생각합니다. (없었다면 람다를 인스턴스로 가지고 있기 위해, 함수형인터페이스를 만들어주었어야 할 것입니다.)
하지만 RxJava 의 함수형 인터페이스를 사용하는데 있어서 불편한 점이 두 가지가 있었습니다.
1. 함수형 인터페이스의 함수들이 모두 throws Exception
RxJava 에서 지원하는 함수형 인터페이스들은 모두 예외를 필수적으로 출력하도록 되어 있습니다. 기존 JAVA8 에서는 그렇지 않았으며, RxJava 의 Observerable 이 더이상 NULL 을 허용하지 않겠다는 정책이 만들어짐에 따라 생긴 특성일 것이라 생각합니다.
물론 어떤면에서는 좋겠지만 이 행위는 람다를 쓸 때마다 Exception 에 대한 처리를 해야함을 말합니다. Exception 이 생길 일이 없는데 무조건 처리해야한다는 것은 안타까운 일입니다.
1 2 3 4 5 6 7 8 9 10 11 | @FunctionalInterface public interface BiFunction<T, U, R> { R apply(T t, U u) throws Exception } try { BiFunction<Integer, Integer, Integer> biFunction = (Integer a, Integer b) -> a + b; biFunction.apply(2, 5); } catch (Exception e) { // Exception Required. ㅡㅡ^ } | cs |
Ndroid 이를 위해 JAVA8 에서 지원하는 기본 함수형 인터페이스를 다시 만들었습니다.
Ndroid 에서 지원하는 기본형들은 모두 인터페이스임을 명시하기 위해 Ixxxx 형식을 사용합니다.
(ex. IPredicate, IFunction)
상황에 따라 RxJava 의 람다와 섞어 사용할 수 있을 것이라 생각합니다.
1 2 3 4 5 6 7 8 9 | @FunctionalInterface public interface IBiFunction<T, U, R> { R apply(T t, U u) throws Exception } // Too simple. None Exception IBiFunction<Integer, Integer, Integer> biFunction = (Integer a, Integer b) -> a + b; biFunction.apply(2, 5); | cs |
2. 람다 조합 불가
람다를 조합할 수 있다는 것은 매우 편리한 기능입니다.
각종 조건들에 대해서, 더이상 논리연산자를 복잡하게 추가하지 않아도 되며, 이는 한결 유지보수에 도움이 될 수 있습니다.
그러나 JAVA8 의 디폴트, 정적 메소드들이 안드로이드 24버전부터 지원함에 따라 해당 기능을 사용할 수 없었습니다.
RxJava 역시 해당 기능을 지원하지 않기 때문에 조합을 할 수 없는 방법이 없을까 고민하던 찰나, 해당 기능을 지원하는 Builder 를 만들기로 했습니다.
Ndroid 의 LambdaUtil 은 람다에 대한 조합을 할 수 있으며, Java8 에서 사용가능한 모든 기능을 지원합니다.
1 2 3 4 | IPredicate<Integer> predicate = LambdaUtil.PredicateBuilder((Integer a) -> a >= 5). and(a -> a < 10). or(a -> a == 0). get(); | cs |
LambdaUtil 은 기본적으로 Ndroid 에 정의된 기본형 인터페이스들을 지원합니다.
하지만 조합된 람다는 RxJava 의 Observable 과도 호환되야 하기 때문에, Rx 스타일의 람다 역시 지원하도록 하였습니다.
1 2 3 4 5 6 7 | // a % 5 == 0 && a > 40 || a < 20 Observable.range(0, 60).filter( LambdaUtil.PredicateBuilder((Integer a) -> a % 5 == 0). and(a -> a > 40). or(a -> a < 20). getRx()). subscribe(System.out::println); | cs |
자세한 내용은 Ndroid 의 ReadMe 에서 확인할 수 있습니다.
[https://github.com/skaengus2012/N-java/wiki/N-java-v0.2-wiki#lambda-combination]
비록 안드로이드에서 JAVA8 의 모든 기능을 사용할 수 없지만, 조금씩 그 격차는 줄어들고 있습니다.
우리의 코드는 계속해서 자리를 잡을 것입니다. 언제나 그랬던 것 처럼 말이죠. :-)
'개발이야기 > 오픈소스 N series ' 카테고리의 다른 글
예외처리를 간소화하여, 코드를 이쁘게 해보자! (9) | 2017.05.10 |
---|---|
Calendar 를 조금 더 쉽게 써보자, TimeUtil & TimeBuilder (0) | 2017.03.26 |
RxJava2 의 Maybe를 조금 더 적극적으로 써보자! MaybeUtil! (2) | 2017.03.16 |
조금 더 구체적인 안드로이드 개발 패턴화 (2) | 2017.01.30 |
보다 쉽게 사용가능한 WeakReference! (0) | 2017.01.26 |