RxJava2, RxAndroid2

[RxJava2] 리액티브 연산자 map(), flatMap(), filter(), reduce()

알통몬_ 2018. 9. 27. 15:00
반응형


공감 및 댓글은 포스팅 하는데

 아주아주 큰 힘이 됩니다!!

포스팅 내용이 찾아주신 분들께 

도움이 되길 바라며

더 깔끔하고 좋은 포스팅을 

만들어 나가겠습니다^^

 



이번 포스팅에서는 리액티브 연산자에 대해 공부합니다.


map()

입력 값을 어떠한 함수에 넣어서 원하는 값을 반환하는 함수

String to String, String to Integer or 원하는 객체로 반환 가능.


map() 함수는 입력 데이터와 그것을 변환해줄 함수를 이어주는 중개 업자가 있다고

생각하면 쉽습니다.

map() 의 인자로는 변수가 아닌 '어떤 함수'가 들어가면 됩니다.

예제)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import io.reactivex.Observable;
import io.reactivex.functions.Function;
 
public class MapEx {
 
    public static void main(String[] args) {
 
        
        String[] names = {"alpha""bravo""charlie"};
        
        Observable<String> src = Observable.fromArray(names)
                .map(name -> "welcome " + name);
        
        src.subscribe(System.out::println);
 
        System.out.println("=====================");
        
        Function<StringString> func = name -> "Hi," + name;
        
        Observable<String> src2 = Observable.fromArray(names)
                .map(func);
        
        src2.subscribe(System.out::println);
 
    }
 
}
 
cs

map() 안에 직접 함수를 정의해도 되고, 아래 func 처럼 함수를 정의한 후

함수를 넣어줘도 됩니다.

RxJava에서 람다표현식은 세 가지 제네릭 함수형 인터페이스 중에서 하나로

나타냅니다. java8과 동일한 인터페이스입니다.

Function<T, R>

T 값을 받아 결과를 반환, 결과 값은 정의하기 나름. R을 포함해서 반환해도 되고

아니어도 됨.


Consumer<T>

T 값을 받아서 처리함. 반환 값은 없음.


Predicate<T>

T 값을 받아서 True or False 반환함.


위 예제에서 Function을 사용했습니다.

Function함수를 아래 예제처럼 정의할 수도 있습니다.

입장료 예제)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import io.reactivex.Observable;
import io.reactivex.functions.Function;
 
public class MapEx {
 
    public static void main(String[] args) {
 
        
        Function<String, Integer> fee = name -> {
            int charge = 0;
            switch(name) {
            case "65세 이상" : charge = 5000;
            break;
            case "성인(20~64세)" : charge = 7000;
            break;
            case "청소년(14세~19세)" : charge = 4000;
            break;
            case "어린이 및 미취학 아동" : charge = 3000;
            break;
            }
            return charge;
        };
        
        String[] names = {"65세 이상""성인(20~64세)",
                "청소년(14세~19세)""어린이 및 미취학 아동"};
        
        
        Observable<Integer> src = Observable.fromArray(names)
                .map(fee);
        
        src.subscribe(System.out::println);
 
    }
 
}
 
cs



flatMap()

map() 에서 한 단계 발전된 함수. 

map() 과는 다르게 Observable을 결과로 반환하는 특징을 가집니다.

=> map() 이 일대일 함수라면 flatMap()은 일대일 또는 일대다 함수입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package rx.java.chapter03;
 
import io.reactivex.Observable;
import io.reactivex.functions.Function;
 
public class FlatMapEx {
 
    public static void main(String[] args) {
        
        Function<String, Observable<String>> func = 
                data -> Observable.just("[" + data + "]");
        
        String[] greeting = {"Hi""Hello""What's up"};
        
        Observable<String> src = Observable.fromArray(greeting)
                .flatMap(func);
        src.subscribe(System.out::println);
        
    }
 
}
 
cs


*구구단 만들기*

구구단 코드를 기존에 자바로 짠다면 굉장히 쉽게 작성할 수 있는데요.

flatMap() 함수를 사용해서 짠다면 어떻게 될까요?

생각보다 쉽지 않음을 느끼실 수 있습니다.

각자 만들어보시면 되겠습니다.

for문 대신에 Observable.range(int start, int end) 를 사용할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package rx.java.chapter03;
 
import java.util.Scanner;
 
import io.reactivex.Observable;
import io.reactivex.functions.Function;
 
public class Gugudan {
 
    public static void main(String[] args) {
 
        Scanner scanner = new Scanner(System.in);
        
        int dan = scanner.nextInt();
        
        Function<Integer, Observable<String>> func = in ->
            Observable.range(19).map(row -> in + " * " + row + " = " + (row*in));
        
        Observable<String> gugu = Observable.just(dan)
                .flatMap(func);
        gugu.subscribe(System.out::println);
        scanner.close();
        
    }
 
}
 
cs

[ 광고 보고 가시죠! ]



[ 감사합니다! ]

filter()

이름처럼 Observable에서 원하는 데이터만 걸러내는 역할.

필요하지 않은 데이터는 제거하고 필요한 데이터만 filter() 함수를 통과함.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package rx.java.chapter03;
 
import io.reactivex.Observable;
 
public class FilterEx {
 
    public static void main(String[] args) {
 
        String[] names = {"Thomas""Tom""Tommy""Thomas Park"};
        
        Observable<String> src = Observable.fromArray(names)
                .filter(name -> name.startsWith("To"));
        src.subscribe(System.out::println);
        
    }
 
}
 
cs


filter() 와 비슷한 함수들도 있습니다.

first(default) : Observable의 첫 번째 값을 필터. 값이 없이 완료되면 default를 리턴.

last(default) : Observable의 마지막 값을 필터. 값이 없이 완료되면 default를 리턴.

take(N) : 최초 N 개만 가져옵니다.

takeLast(N) : 마지막 N개 값만 필터합니다.

skip(N) : 최초 N개 값을 건너뜁니다.

skipLast(N) : 마지막 N개 값을 건너 뜁니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package rx.java.chapter03;
 
import io.reactivex.Observable;
import io.reactivex.Single;
 
public class FilterEx {
 
    public static void main(String[] args) {
 
        String[] names = {"Thomas""Tom""Tommy""Thomas Park"};
        
        Single<String> src = Observable.fromArray(names).first("None");
        src.subscribe(System.out::println);
        
        System.out.println("===========");
 
        Single<String> src2 = Observable.fromArray(names).last("None");
        src2.subscribe(System.out::println);
        
        System.out.println("===========");
 
        Observable<String> src3 = Observable.fromArray(names).take(2);
        src3.subscribe(System.out::println);
        
        System.out.println("===========");
 
        Observable<String> src4 = Observable.fromArray(names).takeLast(2);
        src4.subscribe(System.out::println);
        
        System.out.println("===========");
 
        Observable<String> src5 = Observable.fromArray(names).skip(1);
        src5.subscribe(System.out::println);
        
        System.out.println("===========");
 
        Observable<String> src6 = Observable.fromArray(names).skipLast(1);
        src6.subscribe(System.out::println);
 
    }
 
}
 
cs


reduce()

발행한 데이터를 사용해서 어떠한 최종 결과 데이터를 합성할 때 사용합니다.

map, filter, reduce 패턴을 이루는 마지막 필수 함수.

reduce() 함수는 Observable이 아닌 Maybe를 반환합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package rx.java.chapter03;
 
import io.reactivex.Maybe;
import io.reactivex.Observable;
 
public class ReduceEx {
 
    public static void main(String[] args) {
        
        String names[] = {"aaa""bbb""ccc"};
        
        Maybe<String> src = Observable.fromArray(names)
                .reduce((in1, in2) -> in2 + "[" + in1 + "]");
        
        src.subscribe(System.out::println);
    }
 
}
 
cs


이상입니다. 다음 포스팅부터는 리액티브 연산자 활용에 대해 공부합니다.

반응형