JAVA8学习2-函数式接口

2 函数式接口

2.1 主要信息:

  1. Note that instances of functional interfaces can be created with lambda expressions, method references, or constructor references.重点
  2. an interface declares an abstract method overriding one of the public methods of {@codejava.lang.Object}, that also does not count toward the interface's abstract method count since any implementation of the interface will have an implementation from {@code java.lang.Object} or elsewhere.
  3. The type is an interface type and not an annotation type, enum, or class. The annotated type satisfies the requirements of a functional interface.
  4. the compiler will treat any interface meeting the definition of a functional interface as a functional interface regardless of whether or not a {@code FunctionalInterface} annotation is present on the interface declaration.

2.2 关于函数式接口的条件:

  1. 如果一个接口只有一个抽象方法,那么该接口就是一个函数式接口。
  2. 如果我们在某个接口上声明了 FunctionInterface 注解,则编译器会按照函数式接口的定义来要求该接口
  3. 如果某个接口只有一个抽象方法,但我们没有给该接口声明 FunctionInterface 注解,那么编译器依旧会将该接口看作是函数是借口

注意: 重写Object对象方法不计算在接口个数上

2.3 函数式接口的实现方法

  1. lambda 实现

  2. 方法应用: 四种情况,这里简单介绍

    1. 类::非静态方法: 非静态方法没有参数,且一般必须是由实例来调用,所以用这个实现接口,必会有个对应的实例调用这各方法。Function<String,String> 第一个参数就是输入参数,刚好是是String类型,可以调用toUpperCase方法
    2. 类::静态方法:静态方法需要参数类型与函数相同
    3. 类::new:构造器引用实现,要求参数符合
// 函数 String toUpperCasre(); 类::非静态方法,
Function<String, String> function = String::toUpperCase;
// 断言 Object.isNull(Object); 类::静态方法
Predicate<Object> predicate = Objects::isNull; 
// 供应商 new Student(); 类::new 对象
Supplier<Student> supplier1 = Student::new;
  1. 构造函数实现

java8后接口出现了接口默认方法、方法 default 、静态方法、内部迭代、外部迭代

2.4 java.util.function 下常用函数式接口

2.4.1 Consumer 消费行为

​ 接受单个参数,不返还任何结果 接收 T, 用 accept(T t) 消费 执行这个动作

常在迭代中出现: list.forEach(Consumer) 这个是集合新出的遍历方法、Stram.forEach(Consumer) 这是流的元数据的遍历方法

package cn.zxhysy.jdk8;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class Test1 {

    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
//
//        for(int i = 0; i < list.size(); ++i) {
//            System.out.print(" " + list.get(i));
//        }
//        System.out.println("\n---------------");
//        for(Integer i: list) {
//            System.out.print(" " + i);
//        }
//        System.out.println("\n---------------");
//        list.forEach(new Consumer<Integer>() {
//            @Override
//            public void accept(Integer integer) {
//                System.out.print(" " + 2 * integer);
//            }
//        });
//        list.forEach(i -> System.out.println(i));
        /* 通过方法引用的形式来创建Lambda表达式 */
        list.forEach(System.out::println);
    }
}
2.4.2 Function<T,R> 单参数函数

​ 接收两个类型,第一个是输入参数,第二个是输出(表示返回参数)通过使用 R apply(T t) 达到目的

package cn.zxhysy.jdk8;

import javax.sound.midi.Soundbank;
import java.util.function.Function;

public class FunctionTest {

    public static void main(String[] args) {
        FunctionTest test = new FunctionTest();
        int compute = test.compute(1, value -> 2 * value);
        System.out.println(compute);
        System.out.println(test.compute(3, value -> value * value));
        System.out.println(test.convert(4, value -> String.valueOf(value+"hello word")));
        System.out.println(test.method1(2));
    }

    public int compute(int a, Function<Integer, Integer> function){
        return function.apply(a);
    }

    public String convert(int a, Function<Integer, String> function){
        return function.apply(a);
    }

    public int method1(int a){
        return 2+a;
    }
    public int method2(int a){
        return 2+a;
    }
    public int method3(int a){
        return 2+a;
    }
}

Function 默认接口实现:

​ default Function<V, R> compose<Function<> before) 先应用before 再应用当前对象Fun, 简单就是说就是执行before.apply之后的值传递给自己对象进行this.apply

​ andTen(Function after) 先应用当前对象Fun 再应用 after

​ static Function<T,T> identity() 返回输入元素

public class FunctionTest2 {

    public static void main(String[] args) {

        FunctionTest2 test = new FunctionTest2();
        System.out.println(test.compute(2, value -> value * 3, value -> value * value)); // 2²*3 = 12 
        System.out.println(test.compute2(2, value -> value * 3, value -> value * value)); // (2*3)² = 36
    }

    public int compute(int a, Function<Integer,Integer> function1, Function<Integer,Integer> function2){
        return function1.compose(function2).apply(a);
    }

    public int compute2(int a, Function<Integer,Integer> function1, Function<Integer,Integer> function2){
        return function1.andThen(function2).apply(a);
    }

}
2.4.3 BiFunction<T, U, R> 双参数函数

​ R apply(T t, U u) 接收2个参数,返回操作结果集

 // 1 和 2 四则运算
        System.out.println(test.compute3(1, 2,(value1, value2) -> value1 + value2));
        System.out.println(test.compute3(1, 2,(value1, value2) -> value1 - value2));
        System.out.println(test.compute3(1, 2,(value1, value2) -> value1 * value2));
        System.out.println(test.compute3(1, 2,(value1, value2) -> value1 / value2));

        System.out.println(test.compute4(1, 2,(value1, value2) -> value1 + value2, value -> value*value));

public int compute3(int a, int b, BiFunction<Integer, Integer, Integer> biFunction){
  return biFunction.apply(a,b);
}

public int compute4(int a, int b, BiFunction<Integer, Integer, Integer> biFunction, Function<Integer,Integer> function){
  return biFunction.andThen(function).apply(a, b);
}

map(Function) 映射值,值在操作后返回流

list.stream().map(item -> item.toUpperCase()).forEach(item -> System.out.println(item));

上面代码就是 list 转 流,通过 map 方法操作流的元,遍历每个集合中的数据,变成大写,再用 forEach 遍历,可换写为方法引用实现函数式接口

list.stream().map(String::toUpperCase).forEach(System.out::println);
2.4.4 Predicate< T > 断言

​ 返回一个boolean值,由 boolean test(T t) 方法实现操作

Predicate 实现的方法:

  1. default Predicate and(Predicate<? super T> other) 并且

  2. default Predicate negate() 取反

  3. default Predicate or(Predicate<? super T> other) 或者

  4. static Predicate isEqual(Object targetRef) 判断两个参数是否相等返回一个函数

    static <T> Predicate<T> isEqual(Object targetRef){
      return (null == targetRef)
        ? Objects::isNull
          : object -> targetRef.equals(object);
    }
    
package cn.zxhysy.jdk8;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;

public class PredicateTest2 {

    public static void main(String[] args) {

        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        PredicateTest2 predicateTest2 = new PredicateTest2();
        // 偶数
        predicateTest2.conditionFilter(list, item -> item % 2 == 0);
        System.out.println("------------------");
        // 奇数
        predicateTest2.conditionFilter(list, item -> item % 2 != 0);
        System.out.println("------------------");
        // > 3
        predicateTest2.conditionFilter(list, item -> item > 3);
        System.out.println("------------------");
        // < 5
        predicateTest2.conditionFilter(list, item -> item < 5);
        System.out.println("------------------");
        // 打印全部
        predicateTest2.conditionFilter(list, item -> true);
        System.out.println("------------------");

        // >5 偶数 方法带上取反
        predicateTest2.conditionFilter2(list, item -> item > 5, item -> item % 2 ==0);
//        Predicate<Integer> predicate = Objects::isNull;
//        boolean test = predicate.test(13);
//        System.out.println(test);
        System.out.println(predicateTest2.isEqual("test").test("test"));
    }

    public void conditionFilter(List<Integer> list, Predicate<Integer> predicate){
        for (Integer integer: list) {
            if (predicate.test(integer)){
                System.out.println(integer);
            }
        }
    }

    public void conditionFilter2(List<Integer> list, Predicate<Integer> predicate1, Predicate<Integer> predicate2){
        for (Integer integer: list) {
            // negate 取反
            if (predicate1.and(predicate2).negate().test(integer)){
                System.out.println(integer);
            }
        }
    }

    public Predicate<String> isEqual(Object object){
        return Predicate.isEqual(object);
    }

}

fliter(Predicate<>) 过滤

collect(Collectors.toList()); 将流转换为list集合

package cn.zxhysy.jdk8;

import java.util.Arrays;
import java.util.List;
import java.util.function.BiFunction;
import java.util.stream.Collectors;

public class PersonTest {

    public static void main(String[] args) {

        Person person1 = new Person("zhangsan", 13);
        Person person2 = new Person("lisi", 25);
        Person person3 = new Person("wangwu", 30);

        List<Person> persons = Arrays.asList(person1,person2,person3);

        PersonTest test = new PersonTest();

//        List<Person> personResult = test.gePersonByUserName("zhangsan", persons);
//        personResult.forEach(person -> System.out.println(person.getUsername()));

//        List<Person> personResult = test.getPersonByAge(20, persons);
//        personResult.forEach(person -> System.out.println(person.getUsername()));

        List<Person> personResult = test.getPersonByAge2(20, persons, (age, personList) -> personList.stream().filter(person -> person.getAge() > age).collect(Collectors.toList()));
        personResult.forEach(person -> System.out.println(person.getUsername()));
        System.out.println("--------------------------");
        List<Person> personResult2 = test.getPersonByAge2(20, persons, (age, personList) -> personList.stream().filter(person -> person.getAge() < age).collect(Collectors.toList()));
        personResult2.forEach(person -> System.out.println(person.getUsername()));

    }

    public List<Person> gePersonByUserName(String username, List<Person> persons){
        return persons.stream().filter(person -> person.getUsername().equals(username)).collect(Collectors.toList());
    }

    public List<Person> getPersonByAge(Integer age, List<Person> persons) {
        BiFunction<Integer, List<Person>, List<Person>> biFunction = (ageOfPerson, personList) -> personList.stream().filter(person -> person.getAge() > ageOfPerson).collect(Collectors.toList());
        return biFunction.apply(age, persons);
    }

    public List<Person> getPersonByAge2(Integer age, List<Person> persons, BiFunction<Integer, List<Person>, List<Person>> biFunction){
        return biFunction.apply(age, persons);
    }
}
2.4.5 Supplier 供应商

​ 不接收参数同时返回一个结果, 由 T get() 实现

package cn.zxhysy.jdk8;
import java.util.function.Supplier;
public class SupplierTest {
    public static void main(String[] args) {
        // 可用于工厂模式
        Supplier<String> supplier = () -> "hello World";
        System.out.println(supplier.get());
    }
}

测试下工厂模式:

package cn.zxhysy.jdk8;

public class Student {
    private String name = "zhangsan";
    private int age = 20;
    public Student(){};
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}
package cn.zxhysy.jdk8;

import java.util.function.Supplier;

public class StudentTest {

    public static void main(String[] args) {
        Supplier<Student> supplier = () -> new Student();
        System.out.println(supplier.get().getName());

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

        // 不接受参数,返回对象
        Supplier<Student> supplier1 = Student::new;
        System.out.println(supplier1.get().getName());

    }

}
2.4.6 BinaryOperatoer extend BiFunction<T, T, T> 二元操作

​ 是一个特殊的二元参数操作。接受一种类型并返回同种类型的 BiFunction 函数。用 T apply(T t, T r) 实现

BinaryOperatoer 静态方法

​ static BinaryOperator minBy(Comparator<? super T> comparator) {

​ Objects.requireNonNull(comparator);
​ return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;

}

通过比较器比较返回的值判断返回较小值

​ static BinaryOperator maxBy(Comparator<? super T> comparator) 通过比较器比较返回的值判断返回较小值

package cn.zxhysy.jdk8;

import java.util.Comparator;
import java.util.function.BinaryOperator;

public class BinaryOperatorTest {

    public static void main(String[] args) {
        BinaryOperator<Integer> binaryOperator = (value1,value2) -> value1 + value2;
        System.out.println(binaryOperator.apply(13,16));

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

        BinaryOperatorTest test = new BinaryOperatorTest();
        System.out.println(test.operator(15, 26, (val1, val2) -> val1 * val2));
        System.out.println("-------------------");

//        BinaryOperator<Integer> integerBinaryOperator = BinaryOperator.minBy(new Comparator<Integer>() {
//            @Override
//            public int compare(Integer o1, Integer o2) {
//                return Integer.compare(o1, o2);
//            }
//        });
//        BinaryOperator<Integer> integerBinaryOperator = BinaryOperator.minBy((o1, o2) -> o1 - o2);
        // 上面注释的两种写法都可以被改进为下面的方法
        // minBy 静态方法接收的是 Comparator 返回 BinaryOperator实例
        // BinaryOperator实例 通过调用 apply 方法接受参数(两个值)传递到 minBy(此时minBy就是apply的实现方法), minBy 再调用比较器 Comparator
        // 而比较器Comparator实例是由 comparingInt 静态方法通过接受 ToIntFunction 函数applyAsInt方法获取两个对象的值再相减作为方法体生成的实例
        BinaryOperator<Integer> integerBinaryOperator3 = BinaryOperator.minBy(Comparator.comparingInt(o -> o));
        System.out.println(test.operator(13, 12, integerBinaryOperator3));
        // 上面方法改进采用这种方式
        System.out.println(test.operatorComparator(13, 12, Comparator.comparingInt(o -> o)));

        System.out.println("-------------------");
        // 同样道理
        System.out.println(test.strOperatorMinBy("dfsa","wangas", Comparator.comparingInt(String::length)));

    }

    public int operator(int val1, int val2, BinaryOperator<Integer> binaryOperator){
        return binaryOperator.apply(val1, val2);
    }
    public int operatorComparator(int val1, int val2,  Comparator<Integer> comparator){
        return  BinaryOperator.maxBy(comparator).apply(val1, val2);
    }
    public String strOperatorMinBy(String val1, String val2, Comparator<String> comparator){
        return BinaryOperator.maxBy(comparator).apply(val1, val2);
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值