函数式编程
什么是函数式接口:
1.只有一个抽象方法的接口;
2.可以通过lambad表达式来创建该接口对象;
3.可以使用@FunctionalInterface注解来检验它是否为函数式接口,接口中默认的方法和静态方法并不会违反函数式接口的约定(java8特性规定);
Example:
1 public class Demo { 2 3 public static String get(String str,Practise practise){ 4 return practise.getValue(str); 5 } 6 7 public static void main(String[] args) { 8 String str = get("aaa", (item) -> item.toUpperCase()); 9 System.out.println(str); 10 } 11 } 12 interface Practise{ 13 String getValue(String string); 14 }
lambad表达式:
它允许我们将一个函数当作方法的参数(传递函数),或者说把代码当作数据;
格式:()->() 无参数
(item...)->() 有一个过着多个参数
()->{ } 也可以跟代码块
方法引用:
方法引用结合lambad提供了一种非常简洁方式,用来直接访问类或实例中已存在的方法或者构造方法。方法引用的标准形式是:类名::方法名。(注意:只需要写方法名,不需要写括号)
有以下四种形式的方法引用:
| 类型 | 示例 |
| 引用静态方法 | ContainingClass::staticMethodName |
| 引用某个对象的实例方法 | containingObject::instanceMethodName |
| 引用某个类型的任意对象的实例方法 | ContainingType::methodName |
| 引用构造方法 | ClassName::new |
1.静态方法引用:
1 public class Demo1 { 2 public static String get(StringDemo demo,String s){ 3 return demo.fun(s); 4 } 5 6 public static void main(String[] args) { 7 8 String a="123456"; 9 String s = get(StringFun::reverseStr, a); 10 System.out.println(s); 11 } 12 13 } 14 interface StringDemo{ 15 String fun(String str); 16 } 17 class StringFun{ 18 static String reverseStr(String str){ 19 String result=""; 20 for (int i = str.length() - 1; i >= 0; i--) { 21 result += str.charAt(i); 22 } 23 return result; 24 } 25 }
2.某个对象方实例方法:
1 public class Demo3 { 2 public int compareName(String a,String b){ 3 return a.compareTo(b); 4 } 5 public static void main(String[] args) { 6 Demo3 demo=new Demo3(); 7 String[] strings={"9", "8", "7"}; 8 Arrays.sort(strings,demo::compareName); 9 System.out.println(Arrays.asList(strings)); 10 } 11 }
3.某个类型的任意对象的实例方法(与2同)
4.引用构造方法
1 public class Demo4 { 2 3 public static void main(String[] args) { 4 Funa funa=Person::new; 5 Person func = funa.func(10); 6 System.out.println(func); 7 } 8 } 9 interface Funa{ 10 Person func(int age); 11 } 12 @Data 13 class Person{ 14 Integer age; 15 public Person(Integer age){this.age=age;} 16 }
java中内置的函数式接口
每次使用lambad时,都需要自己创建函数式接口,而在java.util.function包下提供了一些内置的接口,直接使用即可。
| name | type | description |
|---|---|---|
| Consumer | Consumer< T > | 接收T对象,不返回值 |
| Predicate | Predicate< T > | 接收T对象并返回boolean |
| Function | Function< T, R > | 接收T对象,返回R对象 |
| Supplier | Supplier< T > | 提供T对象(例如工厂),不接收值 |
| UnaryOperator | UnaryOperator< T > | 接收T对象,返回T对象 |
| BiConsumer | BiConsumer<T, U> | 接收T对象和U对象,不返回值 |
| BiPredicate | BiPredicate<T, U> | 接收T对象和U对象,返回boolean |
| BiFunction | BiFunction<T, U, R> | 接收T对象和U对象,返回R对象 |
| BinaryOperator | BinaryOperator< T > | 接收两个T对象,返回T对象 |
1.Consumer和BiConsumer
1 public class ConsumerDemo { 2 3 public static void addApply(int a,Consumer<Integer> consumer){ 4 consumer.accept(a); 5 } 6 public static void addAndThen(int a,Consumer<Integer> consumer,Consumer<Integer> consumer1){ 7 consumer.andThen(consumer1).accept(a); 8 } 9 10 public static void main(String[] args) { 11 12 addApply(1,(item)-> System.out.println(1+1)); 13 addAndThen(1,a-> System.out.println(a+1),a-> System.out.println(a+1)); 14 } 15 16 }
//接受一个参数执行方法 void accept(T t); //对给定的参数T执行定义的操作执行再继续执行after定义的操作 default Consumer<T> andThen(Consumer<? super T> after) { Objects.requireNonNull(after); return (T t) -> { accept(t); after.accept(t); }; }
BiConsumer与Consumer的唯一的区别在于可以对接受一个参数;
1 @FunctionalInterface 2 public interface BiConsumer<T, U> { 3 void accept(T t, U u); 4 5 default BiConsumer<T, U> andThen(BiConsumer<? super T, ? super U> after) { 6 Objects.requireNonNull(after); 7 8 return (l, r) -> { 9 accept(l, r); 10 after.accept(l, r); 11 }; 12 } 13 }
2.Function和BiFunction
1 public class FunctionTest { 2 3 public static int add(int a,Function<Integer,Integer> function){ 4 return function.apply(a); 5 } 6 public static int addAndThen(int a,Function<Integer,Integer> function,Function<Integer,Integer> function1){ 7 return function.andThen(function1).apply(a); 8 } 9 public static int addCompose(int a,Function<Integer,Integer> function,Function<Integer,Integer> function1){ 10 return function.compose(function1).apply(a); 11 } 12 13 public static void main(String[] args) { 14 //接受一个参数,操作后返回 15 int add = add(1, a -> a + 1); 16 System.out.println(add); 17 //接受一个参数,先执行function,将结果作为function1的参数,再执行操作,再返回 18 int i = addAndThen(3, a -> a * 2, a -> a * a); 19 System.out.println(i); 20 //先执行function1,在执行function 21 int i1 = addCompose(3, a -> a * 2, a -> a * a); 22 System.out.println(i1); 23 24 25 //identify输入啥参数,返回啥参数 26 Object aaa = Function.identity().apply("aaa"); 27 System.out.println("identify ="+aaa); 28 29 List<String> strs=Arrays.asList("aa","bb","cc","dd","ee"); 30 //流中的map就使用了Function,传入一个参数,操作后返回 31 strs.stream().map(String::toUpperCase).forEach(System.out::println); 32 33 } 34 }
1 @FunctionalInterface 2 public interface Function<T, R> { 3 4 5 R apply(T t); 6 7 8 default <V> Function<V, R> compose(Function<? super V, ? extends T> before) { 9 Objects.requireNonNull(before); 10 return (V v) -> apply(before.apply(v)); 11 } 12 13 14 default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) { 15 Objects.requireNonNull(after); 16 return (T t) -> after.apply(apply(t)); 17 } 18 19 20 static <T> Function<T, T> identity() { 21 return t -> t; 22 } 23 }
BiFunction与Function区别也是在于可以传两个参数。
1 @FunctionalInterface 2 public interface BiFunction<T, U, R> { 3 4 R apply(T t, U u); 5 6 default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) { 7 Objects.requireNonNull(after); 8 return (T t, U u) -> after.apply(apply(t, u)); 9 } 10 //为什么没有compose()方法? 11 /* 12 由于传的类型是Function 而compose会先执行function,后执行biFunction,第一次返回了一个结果作为biFunction的参数,而它是接受两个参数的,所以不行,
而andThen是先执行biFunction返回结果作为function的参数,所以可以有andThen 13 */ 14 }
3.Predicete和BiPredicate
1 class Function4{ 2 public static void main(String[] args) { 3 Function4 fun = new Function4(); 4 fun.printValue(10, val -> val > 5); 5 fun.printBigValueAnd(10,20,(a,b)->a>b); 6 fun.printAnd(10,a->a>1,a->a<2); 7 fun.printNegate(10,a->a<1); 8 } 9 public void printValue(int value, Predicate<Integer> predicate) { 10 if (predicate.test(value)) { 11 System.out.println(value); 12 } 13 } 14 public void printBigValueAnd(int value, int value1,BiPredicate<Integer,Integer> predicate) { 15 if(predicate.test(value,value1)){ 16 System.out.println("-----"); 17 } 18 } 19 //与 20 public void printAnd(int value,Predicate<Integer> predicate,Predicate<Integer> predicate1) { 21 if(predicate.and(predicate1).test(value)){ 22 System.out.println("and----"); 23 } 24 } 25 //或 26 public void printOr(int value,Predicate<Integer> predicate,Predicate<Integer> predicate1) { 27 if(predicate.or(predicate1).test(value)){ 28 System.out.println("or----"); 29 } 30 } 31 //非 32 public void printNegate(int value,Predicate<Integer> predicate) { 33 if(predicate.negate().test(value)){ 34 System.out.println("negate----"); 35 } 36 } 37 }
BiPredicate唯一区别可以传两个参数,
1 @FunctionalInterface 2 public interface Predicate<T> { 3 4 boolean test(T t); 5 6 default Predicate<T> and(Predicate<? super T> other) { 7 Objects.requireNonNull(other); 8 return (t) -> test(t) && other.test(t); 9 } 10 11 default Predicate<T> negate() { 12 return (t) -> !test(t); 13 } 14 15 default Predicate<T> or(Predicate<? super T> other) { 16 Objects.requireNonNull(other); 17 return (t) -> test(t) || other.test(t); 18 } 19 20 static <T> Predicate<T> isEqual(Object targetRef) { 21 return (null == targetRef) 22 ? Objects::isNull 23 : object -> targetRef.equals(object); 24 } 25 }
4.Supplier
1 class Function5{ 2 public static Car get(Supplier<Car> supplier){ 3 return supplier.get(); 4 } 5 6 public static void main(String[] args) { 7 Car car = get(() -> new Car("111")); 8 System.out.println(car); 9 } 10 } 11 @Data 12 class Car{ 13 String name; 14 public Car(String name){ 15 this.name=name; 16 } 17 }
1 @FunctionalInterface 2 public interface Supplier<T> { 3 4 /** 5 * Gets a result. 6 * 7 * @return a result 8 */ 9 T get(); 10 }
5.UnaryOperator和BiUnaryOperator
1 class Function3{ 2 public static void main(String[] args) { 3 UnaryOperator<Integer> add = x -> x + 1; 4 System.out.println(add.apply(1)); 5 6 BinaryOperator<Integer> addxy = (x, y) -> x + y; 7 System.out.println(addxy.apply(3, 5)); 8 9 BinaryOperator<Integer> min = BinaryOperator.minBy((o1, o2) -> o1 - o2); 10 System.out.println(min.apply(100, 200)); 11 12 BinaryOperator<Integer> max = BinaryOperator.maxBy((o1, o2) -> o1 - o2); 13 System.out.println(max.apply(100, 200)); 14 } 15 }
1 @FunctionalInterface 2 public interface UnaryOperator<T> extends Function<T, T> { 3 4 /**没啥吊用 5 * Returns a unary operator that always returns its input argument. 6 * 7 * @param <T> the type of the input and output of the operator 8 * @return a unary operator that always returns its input argument 9 */ 10 static <T> UnaryOperator<T> identity() { 11 return t -> t; 12 } 13 }
1 @FunctionalInterface 2 public interface BinaryOperator<T> extends BiFunction<T,T,T> { 3 4 public static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) { 5 Objects.requireNonNull(comparator); 6 return (a, b) -> comparator.compare(a, b) <= 0 ? a : b; 7 } 8 9 public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) { 10 Objects.requireNonNull(comparator); 11 return (a, b) -> comparator.compare(a, b) >= 0 ? a : b; 12 } 13 }

浙公网安备 33010602011771号