├── .gitignore ├── LICENSE.md ├── README.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── rxfunctions ├── .gitignore ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── pacoworks │ │ └── rxfunctions │ │ └── RxFunctions.java │ └── test │ └── java │ └── com │ └── pacoworks │ └── rxfunctions │ └── RxFunctionsTest.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | .DS_Store 4 | */build 5 | */intermediates 6 | /captures 7 | /obj 8 | target 9 | .idea 10 | *.iml -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Apache License, Version 2.0 2 | =========================== 3 | 4 | Copyright 2016 pakoito 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License.n writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RxFunctions 2 | 3 | RxFunctions is a library to smooth RxJava usage by functionally composing functions. 4 | 5 | For the RxJava 2.X version please go to [RxFunctions2](https://github.com/pakoito/RxFunctions2). 6 | 7 | ## Rationale 8 | 9 | Oftentimes you want to filter an `Observable` based off several criteria, i.e. get your users above a certain age that also live in a certain city; a string that should not be null or empty; or two objects being equal and both higher than 0. 10 | 11 | Other times you have to chain several map operations in a row, like converting your network data from string to dto, and from dto to a viewmodel. 12 | 13 | Where you could write 2-9 operations every time that chain surfaces, instead you can compose them a create a new, single, more meaningful function. 14 | 15 | ## Usage 16 | 17 | ### General Functions 18 | 19 | These functions work for any type and situation. 20 | 21 | #### Same 22 | 23 | It allows you to chain `Func1` that have the same input and output types, like two `Func1`, or six `Func1`. 24 | 25 | The end result is a `Func1` that applies all of them sequentially and returns the result of the last one. 26 | 27 | #### Chain 28 | 29 | Chain allows composition of functions that change type, but maintain a logical sequence. This is useful in map operations, like transforming a string into an object `Func1` and then retrieving one of the fields `Func1>` to finally compose our target class `Func1, LocationDirectory>`. 30 | 31 | The end result is a `Func1` that applies all of them sequentially and returns a function that takes a parameter from the first one and returns the result of the last one. 32 | 33 | #### Combine 34 | 35 | Combine allows you to add up small operations into bigger ones. This case is common for object mutation, where you take one type parameter UserDto and have 4 functions `Func1` to transform its fields into strings used by a constructor function `Func4`. 36 | 37 | The end result is a function that applies several `Func1` `Func1` `Func1` parameters to the final aggregation function whose arity is one for each `Func3` 38 | 39 | #### Reduce 40 | 41 | Reduce is the most complicated to understand, as it allows for incremental composition. You provide: 42 | 43 | + An initial value of type R 44 | 45 | + An aggregation function of type `Func2` that takes the previous state, a new value obtained from the function being evaluated, and returns the new state 46 | 47 | + Any number of `Func1`. 48 | 49 | Each function will be applied individually to the initial value by using the aggregation function until the last one gives the final result. 50 | 51 | One example is the composition `and()` described below. It represents an operation of type `Func1`, which takes an initial value of true, a set of functions returning booleans, and applies aggregation by doing `&&` between them. 52 | 53 | The end result is a function `Func1` that has one input object, and returns the result of the internal aggregation. 54 | 55 | ### Boolean functions 56 | 57 | The next composers work only for `Func1`. 58 | 59 | #### Not 60 | 61 | Not negates the result of a `Func1` to allow the creation of opposite functions. The most common case is testing if a filter does not fit a function defined previously. 62 | 63 | #### And 64 | 65 | And aggregates the result of any number of `Func1` by means of `&&`. This helps composing more fine-grained filters into a single operation. 66 | 67 | #### Or 68 | 69 | And aggregates the result of any number of `Func1` by means of `||`. This helps composing more fine-grained filters into a single operation. 70 | 71 | ## Examples 72 | 73 | ```java 74 | Func1 INCREMENT = num -> num + 1; 75 | Func1 SUM_FOUR = 76 | RxFunctions.same(INCREMENT, INCREMENT, INCREMENT, INCREMENT).call(0) // returns 4 77 | 78 | Func1 TO_STRING = num -> num + ""; 79 | Func1 TO_INT = string -> Integer.parseInt(string); 80 | Func1 ROUND TRIPS = 81 | RxFunctions.chain(TO_STRING, TO_INT, TO_STRING, TO_INT, TO_STRING).call(5); // returns "5" 82 | ``` 83 | 84 | Or more complex cases: 85 | 86 | ```java 87 | Func1 BEST_USERS_FILTER = 88 | RxFunctions.and(NOT_NULL, 89 | RxFunctions.not(IS_DEACTIVATED) 90 | RxFunctions.or(HAS_MANY_PURCHASES, 91 | IS_HIGH_INCOME)); 92 | List bestUsersList = getUserList().filter(BEST_USERS_FILTER).toList().toBlocking().first(); 93 | ``` 94 | 95 | ## Distribution 96 | 97 | Add as a dependency to your `build.gradle` 98 | ```groovy 99 | repositories { 100 | ... 101 | maven { url "https://jitpack.io" } 102 | ... 103 | } 104 | 105 | dependencies { 106 | ... 107 | compile 'com.github.pakoito:RxFunctions:1.0.0' 108 | ... 109 | } 110 | ``` 111 | or to your `pom.xml` 112 | ```xml 113 | 114 | 115 | jitpack.io 116 | https://jitpack.io 117 | 118 | 119 | 120 | 121 | com.github.pakoito 122 | RxFunctions 123 | 1.0.0 124 | 125 | ``` 126 | 127 | ## License 128 | 129 | Copyright (c) pakoito 2016 130 | 131 | The Apache Software License, Version 2.0 132 | 133 | See LICENSE.md 134 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) pakoito 2016 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 18 | 19 | buildscript { 20 | repositories { 21 | jcenter() 22 | } 23 | dependencies { 24 | // NOTE: Do not place your application dependencies here; they belong 25 | // in the individual module build.gradle files 26 | } 27 | } 28 | 29 | allprojects { 30 | repositories { 31 | jcenter() 32 | } 33 | } 34 | 35 | task clean(type: Delete) { 36 | delete rootProject.buildDir 37 | } 38 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) pakoito 2015 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | # Project-wide Gradle settings. 18 | 19 | # IDE (e.g. Android Studio) users: 20 | # Gradle settings configured through the IDE *will override* 21 | # any settings specified in this file. 22 | 23 | # For more details on how to configure your build environment visit 24 | # http://www.gradle.org/docs/current/userguide/build_environment.html 25 | 26 | # Specifies the JVM arguments used for the daemon process. 27 | # The setting is particularly useful for tweaking memory settings. 28 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 29 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 30 | 31 | # When configured, Gradle will run in incubating parallel mode. 32 | # This option should only be used with decoupled projects. More details, visit 33 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 34 | # org.gradle.parallel=true -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pakoito/RxFunctions/4a7217898e70381ff82e11c72c6017c030c0cef4/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Mar 02 15:48:12 GMT 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-bin.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /rxfunctions/.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | .DS_Store 4 | */build 5 | */intermediates 6 | /captures 7 | /obj 8 | target 9 | .idea 10 | *.iml -------------------------------------------------------------------------------- /rxfunctions/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) pakoito 2016 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | apply plugin: 'java' 18 | apply plugin: 'maven' 19 | 20 | group = 'com.github.pakoito' 21 | 22 | sourceCompatibility = 1.6 23 | targetCompatibility = 1.6 24 | 25 | dependencies { 26 | compile 'io.reactivex:rxjava:1.1.0' 27 | testCompile 'junit:junit:4.12' 28 | } 29 | 30 | install { 31 | repositories.mavenInstaller { 32 | pom.project { 33 | licenses { 34 | license { 35 | name 'The Apache Software License, Version 2.0' 36 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt' 37 | distribution 'repo' 38 | } 39 | } 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /rxfunctions/src/main/java/com/pacoworks/rxfunctions/RxFunctions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) pakoito 2016 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.pacoworks.rxfunctions; 18 | 19 | import rx.Observable; 20 | import rx.functions.*; 21 | 22 | public final class RxFunctions { 23 | private static final Func2 AND = new Func2() { 24 | @Override 25 | public Boolean call(Boolean first, Boolean second) { 26 | return first && second; 27 | } 28 | }; 29 | 30 | private static final Func2 OR = new Func2() { 31 | @Override 32 | public Boolean call(Boolean first, Boolean second) { 33 | return first || second; 34 | } 35 | }; 36 | 37 | private RxFunctions() { 38 | } 39 | 40 | public static Func1 same(final Func1 func1, final Func1 func2) { 41 | return new Func1() { 42 | @Override 43 | public T call(T t) { 44 | return func2.call(func1.call(t)); 45 | } 46 | }; 47 | } 48 | 49 | public static Func1 same(final Func1 func1, final Func1 func2, 50 | final Func1 func3) { 51 | return new Func1() { 52 | @Override 53 | public T call(T t) { 54 | return func3.call(func2.call(func1.call(t))); 55 | } 56 | }; 57 | } 58 | 59 | public static Func1 same(final Func1 func1, final Func1 func2, 60 | final Func1 func3, final Func1 func4) { 61 | return new Func1() { 62 | @Override 63 | public T call(T t) { 64 | return func4.call(func3.call(func2.call(func1.call(t)))); 65 | } 66 | }; 67 | } 68 | 69 | public static Func1 same(final Func1 func1, final Func1 func2, 70 | final Func1 func3, final Func1 func4, final Func1 func5) { 71 | return new Func1() { 72 | @Override 73 | public T call(T t) { 74 | return func5.call(func4.call(func3.call(func2.call(func1.call(t))))); 75 | } 76 | }; 77 | } 78 | 79 | public static Func1 same(final Func1 func1, final Func1 func2, 80 | final Func1 func3, final Func1 func4, final Func1 func5, 81 | final Func1 func6) { 82 | return new Func1() { 83 | @Override 84 | public T call(T t) { 85 | return func6.call(func5.call(func4.call(func3.call(func2.call(func1.call(t)))))); 86 | } 87 | }; 88 | } 89 | 90 | public static Func1 same(final Func1 func1, final Func1 func2, 91 | final Func1 func3, final Func1 func4, final Func1 func5, 92 | final Func1 func6, final Func1 func7) { 93 | return new Func1() { 94 | @Override 95 | public T call(T t) { 96 | return func7.call( 97 | func6.call(func5.call(func4.call(func3.call(func2.call(func1.call(t))))))); 98 | } 99 | }; 100 | } 101 | 102 | public static Func1 same(final Func1 func1, final Func1 func2, 103 | final Func1 func3, final Func1 func4, final Func1 func5, 104 | final Func1 func6, final Func1 func7, final Func1 func8) { 105 | return new Func1() { 106 | @Override 107 | public T call(T t) { 108 | return func8.call(func7.call( 109 | func6.call(func5.call(func4.call(func3.call(func2.call(func1.call(t)))))))); 110 | } 111 | }; 112 | } 113 | 114 | public static Func1 same(final Func1 func1, final Func1 func2, 115 | final Func1 func3, final Func1 func4, final Func1 func5, 116 | final Func1 func6, final Func1 func7, final Func1 func8, 117 | final Func1 func9) { 118 | return new Func1() { 119 | @Override 120 | public T call(T t) { 121 | return func9.call(func8.call(func7.call(func6 122 | .call(func5.call(func4.call(func3.call(func2.call(func1.call(t))))))))); 123 | } 124 | }; 125 | } 126 | 127 | public static Func1 chain(final Func1 func1, final Func1 func2) { 128 | return new Func1() { 129 | @Override 130 | public R call(T t) { 131 | return func2.call(func1.call(t)); 132 | } 133 | }; 134 | } 135 | 136 | public static Func1 chain(final Func1 func1, final Func1 func2, 137 | final Func1 func3) { 138 | return new Func1() { 139 | @Override 140 | public R call(T t) { 141 | return func3.call(func2.call(func1.call(t))); 142 | } 143 | }; 144 | } 145 | 146 | public static Func1 chain(final Func1 func1, 147 | final Func1 func2, final Func1 func3, final Func1 func4) { 148 | return new Func1() { 149 | @Override 150 | public R call(T t) { 151 | return func4.call(func3.call(func2.call(func1.call(t)))); 152 | } 153 | }; 154 | } 155 | 156 | public static Func1 chain(final Func1 func1, 157 | final Func1 func2, final Func1 func3, final Func1 func4, 158 | final Func1 func5) { 159 | return new Func1() { 160 | @Override 161 | public R call(T t) { 162 | return func5.call(func4.call(func3.call(func2.call(func1.call(t))))); 163 | } 164 | }; 165 | } 166 | 167 | public static Func1 chain(final Func1 func1, 168 | final Func1 func2, final Func1 func3, final Func1 func4, 169 | final Func1 func5, final Func1 func6) { 170 | return new Func1() { 171 | @Override 172 | public R call(T t) { 173 | return (func6.call(func5.call(func4.call(func3.call(func2.call(func1.call(t))))))); 174 | } 175 | }; 176 | } 177 | 178 | public static Func1 chain(final Func1 func1, 179 | final Func1 func2, final Func1 func3, final Func1 func4, 180 | final Func1 func5, final Func1 func6, final Func1 func7) { 181 | return new Func1() { 182 | @Override 183 | public R call(T t) { 184 | return func7.call( 185 | func6.call(func5.call(func4.call(func3.call(func2.call(func1.call(t))))))); 186 | } 187 | }; 188 | } 189 | 190 | public static Func1 chain(final Func1 func1, 191 | final Func1 func2, final Func1 func3, final Func1 func4, 192 | final Func1 func5, final Func1 func6, final Func1 func7, 193 | final Func1 func8) { 194 | return new Func1() { 195 | @Override 196 | public R call(T t) { 197 | return func8.call(func7.call( 198 | func6.call(func5.call(func4.call(func3.call(func2.call(func1.call(t)))))))); 199 | } 200 | }; 201 | } 202 | 203 | public static Func1 chain(final Func1 func1, 204 | final Func1 func2, final Func1 func3, final Func1 func4, 205 | final Func1 func5, final Func1 func6, final Func1 func7, 206 | final Func1 func8, final Func1 func9) { 207 | return new Func1() { 208 | @Override 209 | public R call(T t) { 210 | return func9.call(func8.call(func7.call(func6 211 | .call(func5.call(func4.call(func3.call(func2.call(func1.call(t))))))))); 212 | } 213 | }; 214 | } 215 | 216 | public static Func1 combine(final Func1 func1, final Func1 func2, 217 | final Func2 funcResult) { 218 | return new Func1() { 219 | @Override 220 | public R call(T t) { 221 | return funcResult.call(func1.call(t), func2.call(t)); 222 | } 223 | }; 224 | } 225 | 226 | public static Func1 combine(final Func1 func1, 227 | final Func1 func2, final Func1 func3, final Func3 funcResult) { 228 | return new Func1() { 229 | @Override 230 | public R call(T t) { 231 | return funcResult.call(func1.call(t), func2.call(t), func3.call(t)); 232 | } 233 | }; 234 | } 235 | 236 | public static Func1 combine(final Func1 func1, 237 | final Func1 func2, final Func1 func3, final Func1 func4, 238 | final Func4 funcResult) { 239 | return new Func1() { 240 | @Override 241 | public R call(T t) { 242 | return funcResult.call(func1.call(t), func2.call(t), func3.call(t), func4.call(t)); 243 | } 244 | }; 245 | } 246 | 247 | public static Func1 combine(final Func1 func1, 248 | final Func1 func2, final Func1 func3, final Func1 func4, 249 | final Func1 func5, final Func1 func6, 250 | final Func6 funcResult) { 251 | return new Func1() { 252 | @Override 253 | public R call(T t) { 254 | return funcResult.call(func1.call(t), func2.call(t), func3.call(t), func4.call(t), 255 | func5.call(t), func6.call(t)); 256 | } 257 | }; 258 | } 259 | 260 | public static Func1 combine(final Func1 func1, 261 | final Func1 func2, final Func1 func3, final Func1 func4, 262 | final Func1 func5, final Func1 func6, final Func1 func7, 263 | final Func7 funcResult) { 264 | return new Func1() { 265 | @Override 266 | public R call(T t) { 267 | return funcResult.call(func1.call(t), func2.call(t), func3.call(t), func4.call(t), 268 | func5.call(t), func6.call(t), func7.call(t)); 269 | } 270 | }; 271 | } 272 | 273 | public static Func1 combine(final Func1 func1, 274 | final Func1 func2, final Func1 func3, final Func1 func4, 275 | final Func1 func5, final Func1 func6, final Func1 func7, 276 | final Func1 func8, final Func8 funcResult) { 277 | return new Func1() { 278 | @Override 279 | public R call(T t) { 280 | return funcResult.call(func1.call(t), func2.call(t), func3.call(t), func4.call(t), 281 | func5.call(t), func6.call(t), func7.call(t), func8.call(t)); 282 | } 283 | }; 284 | } 285 | 286 | public static Func1 combine(final Func1 func1, 287 | final Func1 func2, final Func1 func3, final Func1 func4, 288 | final Func1 func5, final Func1 func6, final Func1 func7, 289 | final Func1 func8, final Func1 func9, 290 | final Func9 funcResult) { 291 | return new Func1() { 292 | @Override 293 | public R call(T t) { 294 | return funcResult.call(func1.call(t), func2.call(t), func3.call(t), func4.call(t), 295 | func5.call(t), func6.call(t), func7.call(t), func8.call(t), func9.call(t)); 296 | } 297 | }; 298 | } 299 | 300 | @SuppressWarnings("unchecked") 301 | public static Func1 reduce(final R initial, final Func2 compose, 302 | final Func1 func1, final Func1 func2) { 303 | return reduceInternal(initial, compose, func1, func2); 304 | } 305 | 306 | @SuppressWarnings("unchecked") 307 | public static Func1 reduce(final R initial, final Func2 compose, 308 | final Func1 func1, final Func1 func2, final Func1 func3) { 309 | return reduceInternal(initial, compose, func1, func2, func3); 310 | } 311 | 312 | @SuppressWarnings("unchecked") 313 | public static Func1 reduce(final R initial, final Func2 compose, 314 | final Func1 func1, final Func1 func2, final Func1 func3, 315 | final Func1 func4) { 316 | return reduceInternal(initial, compose, func1, func2, func3, func4); 317 | } 318 | 319 | @SuppressWarnings("unchecked") 320 | public static Func1 reduce(final R initial, final Func2 compose, 321 | final Func1 func1, final Func1 func2, final Func1 func3, 322 | final Func1 func4, final Func1 func5) { 323 | return reduceInternal(initial, compose, func1, func2, func3, func4, func5); 324 | } 325 | 326 | @SuppressWarnings("unchecked") 327 | public static Func1 reduce(final R initial, final Func2 compose, 328 | final Func1 func1, final Func1 func2, final Func1 func3, 329 | final Func1 func4, final Func1 func5, final Func1 func6) { 330 | return reduceInternal(initial, compose, func1, func2, func3, func4, func5, func6); 331 | } 332 | 333 | @SuppressWarnings("unchecked") 334 | public static Func1 reduce(final R initial, final Func2 compose, 335 | final Func1 func1, final Func1 func2, final Func1 func3, 336 | final Func1 func4, final Func1 func5, final Func1 func6, 337 | final Func1 func7) { 338 | return reduceInternal(initial, compose, func1, func2, func3, func4, func5, func6, func7); 339 | } 340 | 341 | @SuppressWarnings("unchecked") 342 | public static Func1 reduce(final R initial, final Func2 compose, 343 | final Func1 func1, final Func1 func2, final Func1 func3, 344 | final Func1 func4, final Func1 func5, final Func1 func6, 345 | final Func1 func7, final Func1 func8) { 346 | return reduceInternal(initial, compose, func1, func2, func3, func4, func5, func6, func7, 347 | func8); 348 | } 349 | 350 | @SuppressWarnings("unchecked") 351 | public static Func1 reduce(final R initial, final Func2 compose, 352 | final Func1 func1, final Func1 func2, final Func1 func3, 353 | final Func1 func4, final Func1 func5, final Func1 func6, 354 | final Func1 func7, final Func1 func8, final Func1 func9) { 355 | return reduceInternal(initial, compose, func1, func2, func3, func4, func5, func6, func7, 356 | func8, func9); 357 | } 358 | 359 | public static Func1 not(final Func1 func1) { 360 | return new Func1() { 361 | @Override 362 | public Boolean call(T t) { 363 | return !func1.call(t); 364 | } 365 | }; 366 | } 367 | 368 | @SuppressWarnings("unchecked") 369 | public static Func1 and(final Func1 func1, 370 | final Func1 func2) { 371 | return reduceInternal(true, AND, func1, func2); 372 | } 373 | 374 | @SuppressWarnings("unchecked") 375 | public static Func1 and(final Func1 func1, 376 | final Func1 func2, final Func1 func3) { 377 | return reduceInternal(true, AND, func1, func2, func3); 378 | } 379 | 380 | @SuppressWarnings("unchecked") 381 | public static Func1 and(final Func1 func1, 382 | final Func1 func2, final Func1 func3, 383 | final Func1 func4) { 384 | return reduceInternal(true, AND, func1, func2, func3, func4); 385 | } 386 | 387 | @SuppressWarnings("unchecked") 388 | public static Func1 and(final Func1 func1, 389 | final Func1 func2, final Func1 func3, 390 | final Func1 func4, final Func1 func5) { 391 | return reduceInternal(true, AND, func1, func2, func3, func4, func5); 392 | } 393 | 394 | @SuppressWarnings("unchecked") 395 | public static Func1 and(final Func1 func1, 396 | final Func1 func2, final Func1 func3, 397 | final Func1 func4, final Func1 func5, 398 | final Func1 func6) { 399 | return reduceInternal(true, AND, func1, func2, func3, func4, func5, func6); 400 | } 401 | 402 | @SuppressWarnings("unchecked") 403 | public static Func1 and(final Func1 func1, 404 | final Func1 func2, final Func1 func3, 405 | final Func1 func4, final Func1 func5, 406 | final Func1 func6, final Func1 func7) { 407 | return reduceInternal(true, AND, func1, func2, func3, func4, func5, func6, func7); 408 | } 409 | 410 | @SuppressWarnings("unchecked") 411 | public static Func1 and(final Func1 func1, 412 | final Func1 func2, final Func1 func3, 413 | final Func1 func4, final Func1 func5, 414 | final Func1 func6, final Func1 func7, 415 | final Func1 func8) { 416 | return reduceInternal(true, AND, func1, func2, func3, func4, func5, func6, func7, func8); 417 | } 418 | 419 | @SuppressWarnings("unchecked") 420 | public static Func1 and(final Func1 func1, 421 | final Func1 func2, final Func1 func3, 422 | final Func1 func4, final Func1 func5, 423 | final Func1 func6, final Func1 func7, 424 | final Func1 func8, final Func1 func9) { 425 | return reduceInternal(true, AND, func1, func2, func3, func4, func5, func6, func7, func8, 426 | func9); 427 | } 428 | 429 | @SuppressWarnings("unchecked") 430 | public static Func1 or(final Func1 func1, 431 | final Func1 func2) { 432 | return reduceInternal(false, OR, func1, func2); 433 | } 434 | 435 | @SuppressWarnings("unchecked") 436 | public static Func1 or(final Func1 func1, 437 | final Func1 func2, final Func1 func3) { 438 | return reduceInternal(false, OR, func1, func2, func3); 439 | } 440 | 441 | @SuppressWarnings("unchecked") 442 | public static Func1 or(final Func1 func1, 443 | final Func1 func2, final Func1 func3, 444 | final Func1 func4) { 445 | return reduceInternal(false, OR, func1, func2, func3, func4); 446 | } 447 | 448 | @SuppressWarnings("unchecked") 449 | public static Func1 or(final Func1 func1, 450 | final Func1 func2, final Func1 func3, 451 | final Func1 func4, final Func1 func5) { 452 | return reduceInternal(false, OR, func1, func2, func3, func4, func5); 453 | } 454 | 455 | @SuppressWarnings("unchecked") 456 | public static Func1 or(final Func1 func1, 457 | final Func1 func2, final Func1 func3, 458 | final Func1 func4, final Func1 func5, 459 | final Func1 func6) { 460 | return reduceInternal(false, OR, func1, func2, func3, func4, func5, func6); 461 | } 462 | 463 | @SuppressWarnings("unchecked") 464 | public static Func1 or(final Func1 func1, 465 | final Func1 func2, final Func1 func3, 466 | final Func1 func4, final Func1 func5, 467 | final Func1 func6, final Func1 func7) { 468 | return reduceInternal(false, OR, func1, func2, func3, func4, func5, func6, func7); 469 | } 470 | 471 | @SuppressWarnings("unchecked") 472 | public static Func1 or(final Func1 func1, 473 | final Func1 func2, final Func1 func3, 474 | final Func1 func4, final Func1 func5, 475 | final Func1 func6, final Func1 func7, 476 | final Func1 func8) { 477 | return reduceInternal(false, OR, func1, func2, func3, func4, func5, func6, func7, func8); 478 | } 479 | 480 | @SuppressWarnings("unchecked") 481 | public static Func1 or(final Func1 func1, 482 | final Func1 func2, final Func1 func3, 483 | final Func1 func4, final Func1 func5, 484 | final Func1 func6, final Func1 func7, 485 | final Func1 func8, final Func1 func9) { 486 | return reduceInternal(false, OR, func1, func2, func3, func4, func5, func6, func7, func8, 487 | func9); 488 | } 489 | 490 | private static Func1 reduceInternal(final R initial, final Func2 compose, 491 | final Func1... actions) { 492 | return new Func1() { 493 | @Override 494 | public R call(final T t) { 495 | return Observable.from(actions).reduce(initial, new Func2, R>() { 496 | @Override 497 | public R call(R r, Func1 ttFunc1) { 498 | return compose.call(r, ttFunc1.call(t)); 499 | } 500 | }).toBlocking().first(); 501 | } 502 | }; 503 | } 504 | } 505 | -------------------------------------------------------------------------------- /rxfunctions/src/test/java/com/pacoworks/rxfunctions/RxFunctionsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) pakoito 2016 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.pacoworks.rxfunctions; 18 | 19 | import org.junit.Assert; 20 | import org.junit.Test; 21 | import rx.Observable; 22 | import rx.functions.*; 23 | 24 | import java.util.*; 25 | 26 | public class RxFunctionsTest { 27 | @Test 28 | public void testSame() throws Exception { 29 | final int start = 0; 30 | int separate = INCREMENT.call(INCREMENT.call(INCREMENT.call(INCREMENT.call(start)))); 31 | int chain = RxFunctions.same(INCREMENT, INCREMENT, INCREMENT, INCREMENT).call(start); 32 | Assert.assertEquals(separate, chain); 33 | } 34 | 35 | @Test 36 | public void testChain() throws Exception { 37 | final int start = 0; 38 | int separate = TO_INT.call(TO_STRING.call(TO_INT.call(TO_STRING.call(start)))); 39 | int chain = RxFunctions.chain(TO_STRING, TO_INT, TO_STRING, TO_INT).call(start); 40 | Assert.assertEquals(separate, chain); 41 | } 42 | 43 | @Test 44 | public void testCombine() throws Exception { 45 | User separate = TO_USER.call(TO_STRING.call(55), TO_STRING.call(55), IDENTITY.call(55), IDENTITY.call(55)); 46 | User chain = RxFunctions.combine(TO_STRING, TO_STRING, IDENTITY, IDENTITY, TO_USER) 47 | .call(55); 48 | Assert.assertEquals(separate, chain); 49 | } 50 | 51 | @Test 52 | public void testReduce() throws Exception { 53 | for (int i = 0; i < ITERATIONS; i++) { 54 | Collections.shuffle(USER_NAMES); 55 | final Observable userList = Observable.from(USER_NAMES).map(NAME_TO_USER).cache(); 56 | List separated = userList.filter(CORRECT_NAME).filter(IS_RETIRED) 57 | .filter(IS_HIGH_INCOME).toList().toBlocking().first(); 58 | final Func1 mergeFilter = RxFunctions.reduce(true, AND, CORRECT_NAME, 59 | IS_RETIRED, IS_HIGH_INCOME); 60 | List chained = userList.filter(mergeFilter).toList().toBlocking().first(); 61 | Assert.assertEquals(separated, chained); 62 | } 63 | } 64 | 65 | @Test 66 | public void testAnd() throws Exception { 67 | for (int i = 0; i < ITERATIONS; i++) { 68 | Collections.shuffle(USER_NAMES); 69 | final Observable userList = Observable.from(USER_NAMES).map(NAME_TO_USER).cache(); 70 | List separated = userList.filter(CORRECT_NAME).filter(IS_RETIRED) 71 | .filter(IS_HIGH_INCOME).toList().toBlocking().first(); 72 | final Func1 mergeFilter = RxFunctions.and(CORRECT_NAME, IS_RETIRED, 73 | IS_HIGH_INCOME); 74 | List chained = userList.filter(mergeFilter).toList().toBlocking().first(); 75 | Assert.assertEquals(separated, chained); 76 | } 77 | } 78 | 79 | @Test 80 | public void testOr() throws Exception { 81 | for (int i = 0; i < ITERATIONS; i++) { 82 | Collections.shuffle(USER_NAMES); 83 | final Observable userList = Observable.from(USER_NAMES).map(NAME_TO_USER).cache(); 84 | Set separated = userList.toList() 85 | .flatMap(new Func1, Observable>>() { 86 | @Override 87 | public Observable> call(List users) { 88 | final Observable from = Observable.from(users); 89 | return Observable 90 | .merge(from.filter(RxFunctions.not(CORRECT_NAME)), 91 | from.filter(IS_RETIRED), from.filter(IS_HIGH_INCOME)) 92 | .collect(NEW_SET, SET_COLLECTOR); 93 | } 94 | }).toBlocking().first(); 95 | final Func1 mergeFilter = 96 | RxFunctions.or(RxFunctions.not(CORRECT_NAME), IS_RETIRED, IS_HIGH_INCOME); 97 | Set chained = userList.filter(mergeFilter).collect(NEW_SET, SET_COLLECTOR) 98 | .toBlocking().first(); 99 | Assert.assertEquals(separated, chained); 100 | } 101 | } 102 | 103 | @Test 104 | public void testNot() throws Exception { 105 | User retired = new User("bla", "bla", 90, 10); 106 | Assert.assertEquals(!IS_RETIRED.call(retired), RxFunctions.not(IS_RETIRED).call(retired)); 107 | } 108 | 109 | public static final class User { 110 | public final String name; 111 | 112 | public final String surname; 113 | 114 | public final int age; 115 | 116 | public final float income; 117 | 118 | public User(String name, String surname, int age, float income) { 119 | this.name = name; 120 | this.surname = surname; 121 | this.age = age; 122 | this.income = income; 123 | } 124 | 125 | @Override 126 | public boolean equals(Object o) { 127 | if (this == o) 128 | return true; 129 | if (!(o instanceof User)) 130 | return false; 131 | User user = (User)o; 132 | if (age != user.age) 133 | return false; 134 | if (Float.compare(user.income, income) != 0) 135 | return false; 136 | if (!name.equals(user.name)) 137 | return false; 138 | return surname.equals(user.surname); 139 | } 140 | 141 | @Override 142 | public int hashCode() { 143 | int result = name.hashCode(); 144 | result = 31 * result + surname.hashCode(); 145 | result = 31 * result + age; 146 | result = 31 * result + (income != +0.0f ? Float.floatToIntBits(income) : 0); 147 | return result; 148 | } 149 | } 150 | 151 | public static final int ITERATIONS = 100; 152 | 153 | private static final Func1 INCREMENT = new Func1() { 154 | @Override 155 | public Integer call(Integer integer) { 156 | return integer + 1; 157 | } 158 | }; 159 | 160 | public static final Func1 NAME_TO_USER = new Func1() { 161 | @Override 162 | public User call(String s) { 163 | return new User(s, s, (int)(Math.random() * 120), (float)Math.random() * 100000); 164 | } 165 | }; 166 | 167 | private static final Func2 AND = new Func2() { 168 | @Override 169 | public Boolean call(Boolean aBoolean, Boolean aBoolean2) { 170 | return aBoolean && aBoolean2; 171 | } 172 | }; 173 | 174 | private static final Func1 CORRECT_NAME = new Func1() { 175 | @Override 176 | public Boolean call(User user) { 177 | return user.name.length() < 200 && user.surname.length() < 200; 178 | } 179 | }; 180 | 181 | private static final Func1 IS_RETIRED = new Func1() { 182 | @Override 183 | public Boolean call(User user) { 184 | return user.age > 65; 185 | } 186 | }; 187 | 188 | private static final Func1 IS_HIGH_INCOME = new Func1() { 189 | @Override 190 | public Boolean call(User user) { 191 | return user.income > 50000; 192 | } 193 | }; 194 | 195 | public static final Action2, User> SET_COLLECTOR = new Action2, User>() { 196 | @Override 197 | public void call(Set users, User user) { 198 | users.add(user); 199 | } 200 | }; 201 | 202 | public static final Func0> NEW_SET = new Func0>() { 203 | @Override 204 | public Set call() { 205 | return new HashSet(); 206 | } 207 | }; 208 | 209 | private static final Func1 TO_STRING = new Func1() { 210 | @Override 211 | public String call(Integer integer) { 212 | return integer + ""; 213 | } 214 | }; 215 | 216 | private static final Func1 TO_INT = new Func1() { 217 | @Override 218 | public Integer call(String s) { 219 | return Integer.parseInt(s); 220 | } 221 | }; 222 | 223 | private static final Func4 TO_USER = new Func4() { 224 | @Override 225 | public User call(String name, String surname, Integer age, Integer income) { 226 | return new User(name, surname, age, income); 227 | } 228 | }; 229 | 230 | private static final Func1 IDENTITY = new Func1() { 231 | @Override 232 | public Integer call(Integer integer) { 233 | return integer; 234 | } 235 | }; 236 | 237 | private static final List USER_NAMES = Arrays.asList("One", "Deux", "Pintru", 238 | "Maurition", "That weird guy", "Megamon"); 239 | } 240 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) pakoito 2016 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | include ':rxfunctions' 18 | --------------------------------------------------------------------------------