转 四大内置核心函数式接口

大部分函数式接口都不用我们自己写,Java8都给我们写好啦。这些接口都在java.util.function包里,下面简单介绍其中的几个。
(1)Predicate函数式接口
Predicate是一个断言型接口,用于做判断操作,所以抽象方法返回的是Boolean。该接口包含多种默认方法来将Predicate组合成其他复杂的逻辑(与、或、非)。
Predicate接口定义如下:

@FunctionalInterface
public interface Predicate<T> {

    boolean test(T t);

    //返回值为已实现Predicate接口抽象方法的类
    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }
   
    default Predicate<T> negate() {
        return (t) -> !test(t);
    }

    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }
   
    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
  1. Predicate的基本使用
public class Main{

   @Test
    public void test(){
        List<String> list = Arrays.asList("hEOOL","AJS","ashdkjas","ww");
        List<String> strlist = filterStr(list,(s)->s.length()>3);
    }

    // 需求:将满足条件的字符串放到集合中
    public List<String> filterStr(List<String> list, Predicate<String> pre){
        List<String> strlist = new ArrayList<>();

        for(String str:list){
            if(pre.test(str)){
                strlist.add(str);
            }
        }
        return strlist;
    }
}
  1. Predicate的默认方法and、or、negate(取反)
public class Main{

    public static void main(String[] args){
        Predicate<Integer> p1 = age -> age>18;
        Predicate<Integer> p2 = age -> age<30;
        //其实就是表达式(age -> age>18)&&(age -> age<30)赋值给and
        Predicate<Integer> and = p1.and(p2);   
        boolean test1 = and.test(20);  //返回p1和p2的与结果
        out.println(test1);    //输出true
    }
}  

(2)Function函数式接口
Function接口为函数型接口,该接口的抽象方法接收一个参数并且做一些处理然后返回,Function接口还附带了一些可以和其他函数组合的默认方法(compose,andThen)。

  1. Function基本使用
public class Main{

   @Test
    public void test(){
        String newStr = steHandler("/t /t /t 朱一龙么么哒",(str)-> str.trim());
        System.out.print(newStr);

        String newStr1 = steHandler("朱一龙么么哒",(str)-> str.substring(0,3));
        System.out.print(newStr1);
    }

    // 需求:用于处理字符串
    public String steHandler(String str, Function<String,String> fun){
        return fun.apply(str);
    }
}  
  1. Function的默认方法andThen(协作)
public class Main{

    public static void main(String[] args){
        //f1参数为String,结果为Boolean
        Function<String,Boolean> f1 = s1 -> s1!=null;   
        Function<Boolean,Integer> f2 = b -> b?1:0;

        //将f1的布尔值结果作为f2函数式接口的参数来传递
        //所以stringIntegerFunction接收值为f1的参数类型String,返回值类型为f2的返回类型Integer
        Function<String,Integer> stringIntegerFunction = f1.andThen(f2);

        Integer apply = stringIntegerFunction.apply("123");
        out.println(apply);  //输出1
    }
}  
  1. Function的默认方法compose(协作)
    和andThen方法大同小异。
public class Main{

    public static void main(String[] args){
        Function<String,Boolean>  f1 = s1 -> s1!=null;   //f1参数为String,结果为Boolean
        Function<Boolean,Integer>  f2 = b -> b?1:0;

        //将f1的布尔值结果作为f2函数式接口的参数来传递
        //所以compose接收值为f1的参数类型String,返回值类型为f2的返回类型Integer
        Function<String,Integer> compose= f2.compose(f1);

        Integer apply = compose.apply("123");
        out.println(apply);  //输出1
    }
}  

(3)Consumer函数式接口
Consumer是消费型接口。Consumer表示执行在单个参数上面的操作,但没有返回值的(正如消费有去无回)。该类的源码如下:

package java.util.function;
 
import java.util.Objects;
 
@FunctionalInterface
public interface Consumer<T> {
    //该函数式接口的唯一的抽象方法,接收一个参数,没有返回值
    void accept(T t);
 
   //在执行完调用者方法后再执行传入参数的方法
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}
  1. Consumer的基本使用
public class ConsumerTest {
    public static void main(String[] args) {
        Consumer<Integer> consumer = (x) -> {
            int num = x * 2;
            System.out.println(num);
        };
        Consumer<Integer> consumer1 = (x) -> {
            int num = x * 3;
            System.out.println(num);
        };
        consumer.andThen(consumer1).accept(10);
    }
}

(4)Supplier函数式接口
Supplier接口为供给型接口。该接口不接受任何参数,返回一个任意泛型的值。该类的源码如下:

package java.util.function;
 
@FunctionalInterface
public interface Supplier<T> {
    T get();
}
  1. supplier的基本使用
public class Main{

   @Test
    public void test(){
        List<Integer> list = getNumList(10,()->(int)Math.random()*100);
    }

    // 需求:产生指定个数的整数,并放入集合中
    public List<Integer> getNumList(int num, Supplier<Integer> sup){
        List<Integer> list = new ArrayList<>();

        for(int i=0;i<num;i++){
            Integer e = sup.get();
            list.add(e);
        }
        return list;
    }
}  

总结

Function<T, R>——将T作为输入,返回R作为输出
Predicate——将T作为输入,返回一个布尔值作为输出
Consumer——将T作为输入,不返回任何内容
Supplier——没有输入,返回T
BinaryOperator——将两个T作为输入,返回一个T作为输出

作者:zoyoto
链接:https://www.jianshu.com/p/c366c9238bb8
来源:简书

posted @ 2019-08-06 11:23  孔乙己的茴香豆  阅读(131)  评论(0编辑  收藏  举报