java--基础--25--函数式接口

java–基础–25–函数式接口


代码
https://gitee.com/DanShenGuiZu/learnDemo/tree/mysql_mybaties_DB/jdk8-learn
 

1、函数式接口定义

  1. 有且仅有一个抽象方法的接口

2、@FunctionalInterface

  1. 放在接口定义的上方,表示该接口是函数式接口
  2. 接口有且仅有一个抽象方法
  3. 定义函数式接口的时候,@FunctionalInterface是可选的,就算不写这个注解,只要保证满足函数式接口定义的条件,也照样是函数式接口。

2.1、常用的函数式接口

  1. Supplier接口
  2. Consumer接口
  3. Predicate接口
  4. Function接口

2.2、案例

2.2.1、函数式接口作为方法的参数

在这里插入图片描述

public class Demo1 {
	
	public static void main(String[] args) {
		System.out.println("-----函数式接口作为方法的参数----");
		method((String s) -> {
			System.out.println(s);
		});
		
	}
	
	public static void method(Toshow toshow) {
		toshow.toSee("小明");
	}
	
	interface Toshow {
		void toSee(String userName);
	}
}

2.2.2、函数式接口作为方法的返回值

在这里插入图片描述

	 
public class Demo2 {
	
	public static void main(String[] args) {
		Toshow method = method();
		method.toSee("小苗");

	}
	
	public static Toshow method() {
//        // 匿名内部类实现
//        return new Toshow() {
//            @Override
//            public void toSee(String userName) {
//                System.out.println(userName);
//            }
//        };
		
		return (String s) -> {
			System.out.println(s);
		};
		
	}
	
	interface Toshow {
		void toSee(String userName);
	}
	
}

3、Supplier<T>

3.1、介绍

package java.util.function;

/**
 * 表示结果的 supplier  
 * 不要求每次调用supplier时都返回新的或不同的结果  
 * @param <T>  表示 Supplier 提供的结果类型
 *  
 */
@FunctionalInterface
public interface Supplier<T> {

    /**
     * 返回结果
     * 该方法不需要参数,它会按照某种实现逻辑(由Lambda表达式实现)返回一个数据
     */
    T get();
}


  1. 这个接口 用于转换结果类型,结果类型是<T>
  2. 这个接口 被称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中的get方法就会生产什么类型的数据供我们使用

3.2、案例

3.2.1、案例1

package fei.zhou.lambdalearn.demo7.supplier;

import java.util.function.Supplier;

public class Test {
    public static void main(String[] args) {

        String s = getString(() -> {
            return "小苗";
        });

        System.out.println(s);
        System.out.println("---------------");

        Integer i = getInteger(() -> 30);
        System.out.println(i);
    }

    //定义一个方法,返回一个整数数据
    private static Integer getInteger(Supplier<Integer> sup) {
        return sup.get();
    }

    //定义一个方法,返回一个字符串数据
    private static String getString(Supplier<String> sup) {
        return sup.get();
    }
}

输出:
小苗
---------------
30

3.2.2、案例2

package fei.zhou.lambdalearn.demo7.supplier;

import java.util.function.Supplier;

// 用于返回一个int数组中的最大值
public class Test2 {

    public static void main(String[] args) {
        // 定义一个int数组
        int[] arr = {1, 2, 13, 4, 5};

        int maxValue = getMax(() -> {
            int max = arr[0];
            for (int i = 1; i < arr.length; i++) {
                if (arr[i] > max) {
                    max = arr[i];
                }
            }
            return max;
        });
        System.out.println(maxValue);
    }

    // 返回一个int数组中的最大值
    private static int getMax(Supplier<Integer> sup) {
        return sup.get();
    }
}

输出:
13

4、Consumer<T>

4.1、介绍


/**
 * 
 * 表示接受单个输入参数但不返回结果的操作 
 *   
 * @param <T> 操作输入的类型
 * 
 */
@FunctionalInterface
public interface Consumer<T> {

    /** 
     * @param t 输入单个参数,对给定的参数执行此操作
     */
    void accept(T t);

    /**
     * 返回一个组合的Consumer,该Consumer先执行原始的Consumer操作,然后按照从左到右的顺序执行给定的andThen操作。 
     */
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

被称为消费型接口,它消费的数据类型由泛型指定。

4.2、案例

4.2.1、案例

public class Demo3 {
	
	public static void main(String[] args) {
		operatorString("ABC", (String s) -> {
			System.out.println(s.toLowerCase());
		});
		
		System.out.println("-----------");
		
		operatorString("ABC", (String s) -> {
			System.out.println(s + "转小写:" + s.toLowerCase());
		}, (String s) -> {
			System.out.println("倒序:" + new StringBuilder(s).reverse().toString());
		});
	}
	
	// 定义一个方法,用不同的方式消费同一个字符串数据两次
	private static void operatorString(String name, Consumer<String> con1, Consumer<String> con2) {
		// con1.accept(name);
		// con2.accept(name);
		con1.andThen(con2).accept(name);
	}
	
	// 定义一个方法,消费一个字符串数据
	private static void operatorString(String name, Consumer<String> con) {
		con.accept(name);
	}
	
}

输出:
abc
-----------
ABC转小写:abc
倒序:CBA

4.2.2、案例2

1. String[] strArray = {"林青霞,30", "张曼玉,35", "王祖贤,33"};
2. 字符串数组中有多条信息,请按照格式:"姓名:XX,年龄:XX"的格式将信息打印出来
要求:
	把打印姓名的动作作为第一个Consumer接口的Lambda实例
	把打印年龄的动作作为第二个Consumer接口的Lambda实例
	将两个Consumer接口按照顺序组合到一起使用

package fei.zhou.lambdalearn.demo7.consumer;

import java.util.function.Consumer;

/*
    String[] strArray = {"林青霞,30", "张曼玉,35", "王祖贤,33"};
    字符串数组中有多条信息,请按照格式:"姓名:XX,年龄:XX"的格式将信息打印出来
    要求:
        把打印姓名的动作作为第一个Consumer接口的Lambda实例
        把打印年龄的动作作为第二个Consumer接口的Lambda实例
        将两个Consumer接口按照顺序组合到一起使用
 */
public class Test2 {
    public static void main(String[] args) {
        String[] strArray = {"林青霞,30", "张曼玉,35", "王祖贤,33"};

        printInfo(strArray,
                (String str) -> {
                    String name = str.split(",")[0];
                    System.out.print("姓名:" + name);
                },
                (String str) -> {
                    int age = Integer.parseInt(str.split(",")[1]);
                    System.out.println(",年龄:" + age);
                });
    }

    private static void printInfo(String[] strArray, Consumer<String> con1, Consumer<String> con2) {
        for (String str : strArray) {
            con1.andThen(con2).accept(str);
        }
    }
}


输出:
姓名:林青霞,年龄:30
姓名:张曼玉,年龄:35
姓名:王祖贤,年龄:33

5、Predicate<T>

5.1、介绍

 
/** 
 * @param <T> 输入类型 
 */
@FunctionalInterface
public interface Predicate<T> {

  
    /**
     * 具体过滤操作 需要被子类实现.
     * 用来处理参数T是否满足要求,可以理解为 条件A
     */
    boolean test(T t);

    /**
     * 调用当前Predicate的test方法之后再去调用other的test方法,相当于进行两次判断
     * 可理解为 条件A && 条件B
     */
    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

   /**
     * 对当前判断进行"!"操作,即取非操作,可理解为 ! 条件A
     */
    default Predicate<T> negate() {
        return (t) -> !test(t);
    }
    /**
     * 对当前判断进行"||"操作,即取或操作,可以理解为 条件A ||条件B
     */
    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }

   /**
     * 对当前操作进行"="操作,即取等操作,可以理解为 A == B
     */
    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }

  
   /**
     * 对negate方法的加强,不许target为null 
     */
    @SuppressWarnings("unchecked")
    static <T> Predicate<T> not(Predicate<? super T> target) {
        Objects.requireNonNull(target);
        return (Predicate<T>)target.negate();
    }
}


Predicate<T> 接口通常用于判断参数是否满足指定的条件

5.2、案例

5.2.1、案例1

package fei.zhou.lambdalearn.demo7.predicate;

import java.util.function.Predicate;
 
public class Test {

    public static void main(String[] args) {
        boolean b1 = checkString("A", (String s) -> {
            return s.equals("A");
        });

        System.out.println("b1:" + b1);

        boolean b2 = checkString("A", (String s) -> {
            return s.equals("B");
        });
        System.out.println("b2:" + b2);

    }

    // 逻辑非操作
    private static boolean checkString(String s, Predicate<String> pre) {
//         return pre.test(s);
        // return !pre.test(s);
        return pre.negate().test(s);
    }
}

输出:
b1:false
b2:true

5.2.2、案例2

package fei.zhou.lambdalearn.demo7.predicate;

import java.util.function.Predicate;
 
public class Test2 {

    public static void main(String[] args) {
        boolean b1 = checkString2("A", (String s) -> {
            return s.equals("A");
        }, (String s) -> {
            return s.equals("B");
        });

        System.out.println("b1:" + b1);
        boolean b2 = checkString3("A", (String s) -> {
            return s.equals("A");
        }, (String s) -> {
            return s.equals("B");
        });
        System.out.println("b2:" + b2);
    }

    // 逻辑与运算
    private static boolean checkString2(String s, Predicate<String> pre1, Predicate<String> pre2) {
        return pre1.and(pre2).test(s);
    }

    // 逻辑或运算
    private static boolean checkString3(String s, Predicate<String> pre1, Predicate<String> pre2) {
        return pre1.or(pre2).test(s);
    }
}

输出:
b1:false
b2:true

5.2.3、案例3

1. String[] strArray = {"林青霞,30", "柳岩,34", "张曼玉,35", "貂蝉,31", "王祖贤,33"};
2. 字符串数组中有多条信息,请通过Predicate接口的拼装将符合要求的字符串筛选到集合ArrayList中,并遍历ArrayList集合
3. 要求:同时满足如下要求
    1:姓名长度大于2
    2:年龄大于33
4. 分析:
    1:有两个判断条件,所以需要使用两个Predicate接口,对条件进行判断
    2:必须同时满足两个条件,所以可以使用and方法连接两个判断条件
package fei.zhou.lambdalearn.demo7.predicate;

import java.util.ArrayList;
import java.util.function.Predicate;

public class Test3 {

    public static void main(String[] args) {
        String[] strArray = { "林青霞,30", "柳岩,34", "张曼玉,35", "貂蝉,31", "王祖贤,33" };
        ArrayList<String> array = myFilter(strArray,
                s -> s.split(",")[0].length() > 2,
                s -> Integer.parseInt(s.split(",")[1]) > 33);

        for (String str : array) {
            System.out.println(str);
        }
    }
    // 通过Predicate接口的拼装将符合要求的字符串筛选到集合ArrayList中
    private static ArrayList<String> myFilter(String[] strArray, Predicate<String> pre1, Predicate<String> pre2) {
        // 定义一个集合
        ArrayList<String> array = new ArrayList<>();
        // 遍历数组
        for (String str : strArray) {
            if (pre1.and(pre2).test(str)) {
                array.add(str);
            }
        }
        return array;
    }
}

输出:
张曼玉,35

6、Function<T,R>

6.1、介绍

  
T:输入参数,R:返回结果
@FunctionalInterface
public interface Function<T, R> {

    /**
     *  输入参数T,经过该函数处理得到R。  
     */
    R apply(T t);

    /**
     * 此函数有两个参数先将传进来的这个参数传入到before这个函数里面进行处理一下,然后before这个函数的返回结果再作为一个参数传递给外面的这个函数。
	 *  若before为空,则会抛出异常。 
     */
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    /**
     * 参数结构和compose雷同。但是应用方式是相反的。 
	 * 这个是先将参数应用到外层函数,然后得到的结果再传入after进行处理得到结果   
     */
    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

    /**
     *  
     *  返回这个函数的参数。 
     */
    static <T> Function<T, T> identity() {
        return t -> t;
    }
}


  1. Function<T,R> 通常用于对参数进行处理,转换,然后返回一个新的值。

6.2、案例

6.2.1、案例1

package fei.zhou.lambdalearn.demo7.function;

import java.util.function.Function;


public class Test {

    public static void main(String[] args) {

        System.out.println("--------把一个字符串转换int类型,在控制台输出----------");
        convert("100", s -> Integer.parseInt(s));

        System.out.println("--------把一个int类型的数据加上一个整数之后,转为字符串在控制台输出----------");
        convert(100, i -> String.valueOf(i + 566));

        System.out.println("--------把一个字符串转换int类型,把int类型的数据加上一个整数之后,转为字符串在控制台输出----------");
        convert("100", s -> Integer.parseInt(s), i -> String.valueOf(i + 566));
    }

    // 把一个字符串转换int类型,在控制台输出
    private static void convert(String s, Function<String, Integer> fun) {
        int i = fun.apply(s);
        System.out.println(i);
    }

    // 把一个int类型的数据加上一个整数之后,转为字符串在控制台输出
    private static void convert(int i, Function<Integer, String> fun) {
        String s = fun.apply(i);
        System.out.println(s);
    }

    // 把一个字符串转换int类型,把int类型的数据加上一个整数之后,转为字符串在控制台输出
    private static void convert(String s, Function<String, Integer> fun1, Function<Integer, String> fun2) {
        // Integer i = fun1.apply(s);
        // String ss = fun2.apply(i);
        // System.out.println(ss);

        String ss = fun1.andThen(fun2).apply(s);
        System.out.println(ss);
    }
}

输出:
--------把一个字符串转换int类型,在控制台输出----------
100
--------把一个int类型的数据加上一个整数之后,转为字符串在控制台输出----------
666
--------把一个字符串转换int类型,把int类型的数据加上一个整数之后,转为字符串在控制台输出----------
666

6.2.2、案例2

1. String s = "林青霞,30";
2. 请按照我指定的要求进行操作:
    1. 将字符串截取得到数字年龄部分
    2. 将上一步的年龄字符串转换成为int类型的数据
    3. 将上一步的int数据加70,得到一个int结果,在控制台输出
3. 请通过Function接口来实现函数拼接
package fei.zhou.lambdalearn.demo7.function;

import java.util.function.Function;

 
public class Test2 {

    public static void main(String[] args) {
        String s = "林青霞,30";

        convert(s,
                (String ss) -> {
                    return s.split(",")[1];
                },
                (String ss) -> {
                    return Integer.parseInt(ss);
                },
                (Integer i) -> {
                    return i + 70;
                });

    }

    private static void convert(String s, Function<String, String> fun1, Function<String, Integer> fun2,
                                Function<Integer, Integer> fun3) {
        int i = fun1.andThen(fun2).andThen(fun3).apply(s);
        System.out.println(i);
    }
}


输出:
100
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值