'Lambda combination'에 해당되는 글 1건

  1. 2017.03.08안드로이드 람다 조합 (RxJava2 호환)

해당 포스팅에서 언급된 내용은 Ndroid 에서 제공합니다.

https://github.com/skaengus2012/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(25);
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(25);
 
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(060).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 의 모든 기능을 사용할 수 없지만, 조금씩 그 격차는 줄어들고 있습니다. 

우리의 코드는 계속해서 자리를 잡을 것입니다. 언제나 그랬던 것 처럼 말이죠. :-)


반응형
Posted by N'