常见的函数式接口

/*
    在jdk8之后,多了java.util.function 。这个包下面放了很多的常用的函数式接口。

    其中有一个接口叫做Supplier<T>(生产者), 里面有一个方法,可以获取一个对象。

    T get​(): 可以获取一个对象。


 */
public class Demo01Supplier {
    public static void main(String[] args) {
        method(()->"helloworld");

    }
    public static void method(Supplier<String> supplier){
        String s = supplier.get();//重写的接口的抽象方法get。午餐数
        System.out.println(s);
    }

}
import java.util.function.Supplier;

//    其中有一个接口叫做Supplier<T>(生产者), 里面有一个方法,可以获取一个对象。
//
//            T get​(): 可以获取一个对象。
/*
    使用函数式接口Supplier求数组元素的最大值
 */
public class Demo02SupplierTest {
    public static void main(String[] args) {
        int[] arr = new int[]{3, 4, 5, 2, 1, 10};
        getMax(() -> {
            int temp = 0;
            for (int i = 0; i < arr.length; i++) {
                if (arr[i] > temp) {
                    temp = arr[i];
                }

            }
            return temp;
        });


    }

    public static void getMax(Supplier<Integer> supplier) {
        Integer result = supplier.get();//无参数有返回值
        System.out.println(result);
    }
}

---------------------------------------------------------------------------------------

*
    在java.util.function包下,还有一个函数式接口叫做Consumer,这个接口表示消费者,可以消费一个数据(使用这个数据去干一些事情)

    Consumer<T>接口中的抽象方法:
        void accept​(T t): 消费一个数据。 接收到参数t,然后使用这个t。
 */
public class Demo02Consumer {
    public static void main(String[] args) {
//        method((b)-> System.out.println("我发现你了"));
      /*   method(new Consumer() {
            @Override
            public void accept(Object o) {
                System.out.println(o+"你好啊");

            }
         });*/

        method((t) -> System.out.println("你好啊"));//打印你好啊
        method(System.out::print);//拿到t值,转去操作别的,不会产生引用。结果hello
        System.out.println("----------------------------");
        method((Object t) -> System.out.println(t));//hello
        method(System.out::println);//对象引用成员方法,拿到对象直接对对象进行操作//hello


    }

    public static void method(Consumer consumer) {
        consumer.accept("hello");
    }


}
public class Demo03Consummer {
    public static void main(String[] args) {
        method(s -> System.out.println(s.toUpperCase()),
                s -> System.out.println(s.toLowerCase()));
    }

    public static void method(Consumer<String> one, Consumer<String> two) {
        // 先调用one的accept,再调用two的accept
        //one.accept("Hello");
        //two.accept("Hello");

        // 可以把one和two合并成一个Consumer
        //Consumer three = one.andThen(two); //three是合并之后的结果,里面包含了one的操作和two的操作
        //three.accept("Hello"); //通过three调用accept方法,因为trhee是one和two合并之后的结果。索引会先通过one调用accept,再通过two调用accept

        //最终写法
        one.andThen(two).accept("Hello");
    }
}

/*
    下面的字符串数组当中存有多条信息,请按照格式“ 姓名:XX。性别:XX。 ”的格式将信息打印出来。

    要求将打印姓
    名的动作作为第一个 Consumer 接口的Lambda实例,将打印性别的动作作为第二个 Consumer 接口的Lambda实
    例,将两个 Consumer 接口按照顺序“拼接”到一起。



    使用两个Consumer,一个打印姓名,一个打印性别。

    最终打印结果
    姓名: 迪丽热巴  性别:女
    姓名: 古力娜扎  性别:女
    姓名: 马尔扎哈  性别:男

 */
public class Demo04ConsumerTest {
    public static void main(String[] args) {
        String[] array = {"迪丽热巴,女", "古力娜扎,女", "马尔扎哈,男"};

        method(s -> System.out.print("姓名:" + s.split(",")[0]),
                s -> System.out.println(" 性别:" + s.split(",")[1]),
                array);

    }

    //定义方法,用来打印
    public static void method(Consumer<String> one, Consumer<String> two, String[] arr) {
        //遍历数组,拿到数组中的每一个元素
        for (String s : arr) {
            //打印姓名
            //one.accept(s);
            //打印性别
            //two.accept(s);
            //合并成一个Consumer
            one.andThen(two).accept(s);
        }

    }
}
<think>我们被要求解释接口函数式接口,并给出相关示例。同时,在回答后必须提出3-5个相关问题,以“§§相关问题§§”开头,且禁止换行分散。 接口(Interface)在Java中是一种引用类型,它是抽象方法的集合。一个类通过实现接口来实现接口中定义的所有抽象方法。接口也可以包含常量、默认方法、静态方法和嵌套类型。 函数式接口(Functional Interface)是Java 8引入的概念,它是一个只有一个抽象方法的接口(但可以有多个默认方法和静态方法)。函数式接口可以用lambda表达式、方法引用或构造函数引用来实现。 下面分别给出接口函数式接口的示例: 1. 普通接口示例: ```java // 定义一个普通接口 interface Animal { void eat(); // 抽象方法 void sleep(); // 另一个抽象方法 } // 实现接口 class Dog implements Animal { @Override public void eat() { System.out.println("Dog is eating"); } @Override public void sleep() { System.out.println("Dog is sleeping"); } } ``` 2. 函数式接口示例: ```java // 使用@FunctionalInterface注解标注,表明这是一个函数式接口 @FunctionalInterface interface Greeting { void sayHello(String name); // 只有一个抽象方法 // 可以有默认方法 default void defaultMethod() { System.out.println("This is a default method"); } // 也可以有静态方法 static void staticMethod() { System.out.println("This is a static method"); } } public class Main { public static void main(String[] args) { // 使用lambda表达式实现函数式接口 Greeting greeting = (name) -> System.out.println("Hello, " + name); greeting.sayHello("Alice"); // 输出:Hello, Alice // 调用默认方法 greeting.defaultMethod(); // 调用静态方法 Greeting.staticMethod(); } } ``` 函数式接口的特点: - 有且只有一个抽象方法(不包括默认方法和静态方法)。 - 可以使用@FunctionalInterface注解来标记,这样编译器会检查该接口是否符合函数式接口的条件(即只有一个抽象方法),如果不是,则会报错。 - 常见函数式接口:Runnable, Callable, Comparator, 以及Java 8在java.util.function包中提供的Predicate, Function, Consumer, Supplier等。 为什么需要函数式接口函数式接口是为了支持Lambda表达式而设计的。Lambda表达式允许我们将函数作为参数传递给方法,或者将代码本身作为数据处理,从而支持函数式编程风格。 总结: - 普通接口可以包含多个抽象方法,而函数式接口只能包含一个抽象方法。 - 函数式接口是Lambda表达式和方法引用的目标类型。 注意:如果一个接口有多个抽象方法,那么它就不是函数式接口,不能使用Lambda表达式来实现(除非使用匿名内部类)。 最后,按照要求,在回答后提出3-5个相关问题,以“§§相关问题§§”开头,且不换行分散。</think>### 接口函数式接口详解 #### 1. 接口(Interface) **定义**: 接口是Java中完全抽象的引用类型,用于定义一组相关方法的契约(无方法体),实现类必须提供这些方法的具体实现。 **核心特性**: ```java // 基础接口示例 interface Transport { // 常量(自动public static final) int MAX_SPEED = 120; // 抽象方法(自动public abstract) void start(); void stop(); // Java 8+ 默认方法 default void honk() { System.out.println("Beep beep!"); } // Java 8+ 静态方法 static void checkSpeed(int speed) { if(speed > MAX_SPEED) System.out.println("超速警告!"); } } ``` **实现与使用**: ```java class Car implements Transport { @Override public void start() { System.out.println("引擎启动"); } @Override public void stop() { System.out.println("刹车制动"); } } // 使用 Transport myCar = new Car(); myCar.start(); // 输出:引擎启动 myCar.honk(); // 输出:Beep beep! Transport.checkSpeed(150); // 输出:超速警告! ``` #### 2. 函数式接口(Functional Interface) **定义**: 特殊的接口类型,**有且仅有一个抽象方法**(可包含多个默认/静态方法),是Lambda表达式和方法引用的目标类型。 **核心特征**: - 必须用`@FunctionalInterface`注解标记 - 单一抽象方法(Single Abstract Method, SAM) - 支持Lambda表达式实现 **常见函数式接口**: | 接口 | 方法 | 用途 | |----------------------|-------------------|-------------------------| | `Runnable` | `void run()` | 无参数无返回值任务 | | `Consumer<T>` | `void accept(T t)`| 消费型操作 | | `Supplier<T>` | `T get()` | 供给型操作 | | `Function<T,R>` | `R apply(T t)` | 转换操作 | | `Predicate<T>` | `boolean test(T t)`| 条件判断 | **自定义实现**: ```java @FunctionalInterface interface StringProcessor { // 单一抽象方法 String process(String input); // 默认方法(不影响函数式接口性质) default void log() { System.out.println("处理完成"); } } public class Main { public static void main(String[] args) { // Lambda表达式实现 StringProcessor toUpper = s -> s.toUpperCase(); System.out.println(toUpper.process("hello")); // 输出:HELLO // 方法引用实现 StringProcessor reverser = Main::reverseString; System.out.println(reverser.process("world")); // 输出:dlrow } private static String reverseString(String s) { return new StringBuilder(s).reverse().toString(); } } ``` #### 3. 关键区别 | **特性** | 普通接口 | 函数式接口 | |------------------|-----------------------------|----------------------------| | **抽象方法数量** | 无限制 | 严格限制为1个 | | **Lambda支持** | 不可用 | 核心使用场景 | | **注解要求** | 不需要 | 必须用`@FunctionalInterface` | | **设计目的** | 定义行为契约 | 支持函数式编程 | | **典型用途** | 多态实现、API扩展点 | Stream操作、回调函数 | #### 4. 最佳实践 ```java // 推荐:使用内置函数式接口 List<String> names = Arrays.asList("Alice", "Bob", "Charlie"); names.stream() .filter(name -> name.length() > 4) // Predicate .map(String::toUpperCase) // Function .forEach(System.out::println); // Consumer // 自定义函数式接口场景 @FunctionalInterface interface TriFunction<A,B,C,R> { R apply(A a, B b, C c); // 处理三个参数的场景 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值