博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

java8函数式接口Predicate示例----2021/3/5--v.0.01

Posted on 2021-03-05 23:36  海绵谷  阅读(213)  评论(0编辑  收藏  举报

1.Java 8引入了函数式接口的概念,函数式接口也是接口,但只能有一个抽象方法,本文主要描述了Predicate 的一些常用场景

  • Predicate 一个函数式接口,属于java.util.function包,主要用来对输入的对象按照指定的条件进行断言,返回值类型是boolean
  • Predicate接口里有4个默认方法default修饰和有且仅有的一个抽象方法test(),如下表展示,源代码在末尾贴出
test() and() or() isEqual() negate
抽象方法 逻辑与 逻辑或 是否相同 取反
  • 关于源码中的注解@FunctionalInterface 解释
    3.1该注解只能标记在"有且仅有一个抽象方法"的接口上。
    3.2JDK8接口中的静态方法和默认方法,都不算是抽象方法。
    3.3接口默认继承java.lang.Object,所以如果接口显示声明覆盖了Object中方法,那么也不算抽象方法。
    3.4 该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错

2.常见使用场景如下

  • 满足条件就抛出异常

  • 过滤,列表的类型经常不一样,过滤的条件也经常变化,但是最终的结果都是要列表

  • 带返回值情况:如果判断对象为空,就new 一个当前对象

  • 满足条件,就修改对应的值

package com.example.ngjava8func;

import com.example.dto.Apple;
import com.example.dto.ShangPin;
import net.sf.json.JSONObject;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * @author ngLee
 * @version 1.0
 * @Desc 函数式编程 Predicate
 * @date 2021/3/5 20:54
 */
public class Java8Predicate {
    /**
     * @desc 需求1 满足条件就抛出异常
     * @author ngLee
     * @date 2021/3/5 20:55
     */
    public static <T> void isTrue(T t, Predicate<T> p, Supplier<RuntimeException> r){
        if(p.test(t)){
            throw r.get();
        }
    }
    @Test
    public void test(){
        JSONObject json = new JSONObject();
        json.put("name","白酒");
        //如果是白酒,那么抛出异常
        Java8Predicate.isTrue(json,t->t.getString("name").equals("白酒2"),()->new RuntimeException("泡沫严重"));
        //使用2
        Java8Predicate.isTrue(json,t->checkBaijiu(t),()->new RuntimeException("泡沫严重"));
        
    }
    //如果把 t.getString("name").equals("白酒2") 当成方法抽出来
    public boolean checkBaijiu(JSONObject jsonObject){
        if(jsonObject.getString("name").equals("白酒")){
            return true;
        }
        return false;
    }
    /**
     * @desc 需求2 过滤,列表的类型经常不一样,过滤的条件也经常变化,但是最终的结果都是要列表
     * @author ngLee
     * @date 2021/3/5 21:16
     */
    public <E> List<E> filterList( List<E> list,Predicate<E> p){
        //为空抛异常
        Optional.ofNullable(list).orElseThrow(()->new RuntimeException("不能为空!!"));
        List<E> resultList = list.stream().filter( obj -> p.test(obj) ).collect(Collectors.toList());
        return resultList;
    }
    /**
     * @desc 1.重量大于16的苹果;2.找所有name为'酒'的商品
     * @author ngLee
     * @date 2021/3/5 21:49
     */
    @Test
    public void test2(){
        //例1
        List<Apple> apples = new ArrayList<>();
        Apple apple = new Apple("富士",20d,10d);
        Apple apple1 = new Apple("山东富士",21d,10d);
        Apple apple2 = new Apple("富士",15d,8d);
        apples.add(apple);apples.add(apple1);apples.add(apple2);
        //使用
        List<Apple> bigApple = filterList(apples,a->a.getWeight().compareTo(16d) >= 0);
        System.out.println(bigApple);
        //例2
        List<ShangPin> shangPins = new ArrayList<>();
        ShangPin shangPin = new ShangPin("1","酒");
        ShangPin shangPin1 = new ShangPin("2","酒");
        ShangPin shangPin2 = new ShangPin("3","奶制品");
        ShangPin shangPin3 = new ShangPin("4","茶叶");
        shangPins.add(shangPin);shangPins.add(shangPin1);shangPins.add(shangPin2);shangPins.add(shangPin3);
        //使用
        List<ShangPin> pins = filterList(shangPins,ele->ele.getMc().equals("酒"));
        System.out.println(pins);
    }
    /**
     * @desc 带返回值情况:如果判断对象为空,就new 一个当前对象
     * @author ngLee
     * @date 2021/3/5 22:05
     */
    public <T> T getObject(T t,Predicate<T> p,Supplier<T> s){
        if(p.test(t)){
            return t;
        }
        return s.get();
    }
    @Test
    public void test3(){
        Apple apple = new Apple("山东富士",21d,10d);
        //apple = null;
        Apple a = getObject(apple, p ->p != null,()->new Apple("富士",20d,10d));
        System.out.println(a);
    }
    /**
     * @desc 满足条件,就修改对应的值
     * @author ngLee
     * @date 2021/3/5 22:14c
     */
    public <T,R> void check(T t, Predicate<T> p, Consumer<T> trueDto,Consumer<T> falseDto){
        if(p.test(t)){
            trueDto.accept(t);
        }else {
            falseDto.accept(t);
        }
    }
    /**
     * @desc  例如假山东富士 价格就是 5元,真的就是15元
     * @author ngLee
     * @date 2021/3/5 22:46
     */
    @Test
    public void test4(){
        Apple apple = new Apple("山东富士",21d,10d);
        check(apple,p->p.getName().equals("山东富士"), trueDto-> trueDto.setPrice(15d),falseDto->falseDto.setPrice(5d));
        System.out.println(apple.getName()+"=="+apple.getPrice());
    }
}* 

3.Predicate接口源码

package java.util.function;

import java.util.Objects;


@FunctionalInterface
public interface Predicate<T> {

    //有且仅有的一个
    boolean test(T t);
    //逻辑与 &&
    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);
    }
}