您的当前位置:首页正文

java8 四大内置函数式接口 函数式接口使用详解

2024-11-08 来源:个人技术集锦

java8 四大内置函数式接口 函数式接口使用详解

Java8是一种非常流行的编程语言,它在函数式编程方面有着很多强大的特性。其中最重要的就是函数式接口。Java8内置了四个函数式接口,这些接口可以帮助开发者轻松地编写高效的代码

Lambda表达式

Java8引入了一种新的语法:Lambda表达式。Lambda表达式是一种简洁而紧凑的函数表示方式,它可以将函数作为参数传递给方法,或者将代码本身作为数据处理。Lambda表达式的语法格式如下:

(parameters) -> expression
或
(parameters) -> { statements; }

四大内置函数式接口

1. Function接口

Function接口是Java8内置的一个函数式接口,它接受一个输入参数并返回一个结果。Function接口有一个apply方法,它接受一个参数并返回一个结果。例如,下面的代码演示了如何使用Function接口:


    @Test
    public void testFunc(){
        Function<Integer,String> converter = (num) -> {
            int term  = num+10;
            return Integer.toString(term);
        };
        String result = converter.apply(3);
        System.out.println(result);
    }

在上面的代码中,我们定义了一个Function对象converter,它将一个整数转换为字符串。然后我们调用apply方法将整数3传递给converter对象,并将结果存储在result变量中。最后,我们打印出了result变量的值。

2. Predicate接口

Predicate接口是Java8内置的另一个函数式接口,它接受一个输入参数并返回一个布尔值。Predicate接口有一个test方法,它接受一个参数并返回一个布尔值。例如,下面的代码演示了如何使用Predicate接口:

    @Test
    public void testPredicate(){
        Predicate<String> predicate = (s -> s.length() > 0);
        Boolean result = predicate.test("lwd");
        System.out.println(result);
    }

在上面的代码中,我们定义了一个Predicate对象predicate,它测试字符串是否为空。然后我们调用test方法将字符串"foo"传递给predicate对象,并将结果存储在result变量中。最后,我们打印出了result变量的值。

3. Consumer接口

Consumer接口是Java8内置的另一个函数式接口,它接受一个输入参数并不返回任何结果。Consumer接口有一个accept方法,它接受一个参数并不返回任何结果。例如,下面的代码演示了如何使用Consumer接口:

    @Test
    public void testConsumer(){
        Consumer<String> consumer = (s -> System.out.println(s));
        consumer.accept("lwd");
    }

在上面的代码中,我们定义了一个Consumer对象consumer,它将字符串打印到控制台。然后我们调用accept方法将字符串"foo"传递给consumer对象。

4. Supplier接口

Supplier接口是Java8内置的最后一个函数式接口,它不接受任何参数并返回一个结果。Supplier接口有一个get方法,它不接受任何参数并返回一个结果。例如,下面的代码演示了如何使用Supplier接口:

    @Test
    public void testSupplier(){
        Supplier<String> supplier = () -> {
            System.out.println("aaaa");
            return "qqqq";
        };
        String result = supplier.get();
        System.out.println(result);
    }

在上面的代码中,我们定义了一个Supplier对象supplier,它返回字符串"foo"。然后我们调用get方法获取supplier对象的结果,并将结果存储在result变量中。最后,我们打印出了result变量的值。

四大内置函数式接口总结

Java8提供了一些内置的函数式接口,在java.util.function包中。这些函数式接口可以用来表示不同类型的函数操作,例如:

Predicate:表示一个布尔型的函数,接受一个参数,返回一个布尔值,例如(x) -> x > 0。
Consumer:表示一个消费型的函数,接受一个参数,无返回值,例如(x) -> System.out.println(x)。
Function<T, R>:表示一个映射型的函数,接受一个参数,返回一个结果,例如(x) -> x * 2。
Supplier:表示一个供给型的函数,无参数,返回一个结果,例如() -> Math.random()。

自定义函数式接口

接口只有一个抽象方法
接口使用@FunctionalInterface注解标注
//用@FunctionalInterface注解可以让编译器检查接口是否符合函数式接口的定义,如果不符合,会报错
@FunctionalInterface
public interface TestFunctionInterface {
    void sayHello(String name);
}

    @Test
    public void testDefFunc(){
        TestFunctionInterface testFunctionInterface = s ->{
            System.out.println(s);
        };
        testFunctionInterface.sayHello("lwd");
    }


Java8函数式接口的使用场景

排序、过滤集合、条件排序、集合转化、去重复等

函数式接口使用场景

    @Test
    public void testSortLam() {
        //定义一个字符串列表
        List<String> list = Arrays.asList("Bing", "Bing", "Google", "Yahoo", "Baidu");

        //使用Lambda表达式实现Comparator接口
        //Collections.sort(list, (s1, s2) -> s1.length() - s2.length()); //按照字符串长度排序
        list.sort((s1, s2) -> s1.length() - s2.length());
        List<String> list2 = list.stream().distinct().collect(Collectors.toList());
        Set<String> sets = list.stream().collect(Collectors.toSet());
        List<String> list3 = list.stream().filter(s -> !s.equals("Bing")).collect(Collectors.toList());

        //打印排序后的列表
        System.out.println(list); //输出[Bing, Yahoo, Baidu, Google]
        System.out.println(list2);
        System.out.println(list3);
        System.out.println(sets);

        //转map并打印
        list.stream().map(item -> item+"lwd").forEach(System.out::println);

    }



    //结果
[Bing, Bing, Yahoo, Baidu, Google]
[Bing, Yahoo, Baidu, Google]
[Yahoo, Baidu, Google]
[Google, Yahoo, Baidu, Bing]
Binglwd
Binglwd
Yahoolwd
Baidulwd
Googlelwd
Process finished with exit code 0

可以看到,我们使用了filtermapforEach等方法,它们都需要传递一个函数式接口类型的参数,用来对流中的元素进行操作。我们可以使用Lambda表达式或者方法引用来实现这些函数式接口,使得代码更加简洁和清晰。

Java8函数式接口的优缺点分析对比

Java8函数式接口和Lambda表达式是Java语言发展的一个重要的进步,它们为Java开发者提供了一种新的编程风格,可以使代码更加简洁和清晰,提高了开发效率和可读性。同时,它们也为Java引入了一些新的特性和概念,例如函数式编程,方法引用,Stream API等,使得Java更加丰富和强大。

但是,Java8函数式接口和Lambda表达式也有一些缺点和限制,例如:

  • 兼容性问题:Java8函数式接口和Lambda表达式只能在Java8或更高版本的环境中运行,如果需要在低版本的环境中运行,就需要使用其他的工具或者框架来支持。
  • 性能问题:Java8函数式接口和Lambda表达式在运行时会生成一些额外的对象和方法,这可能会影响程序的性能和内存占用。虽然Java虚拟机会进行一些优化和缓存,但是仍然需要注意避免过度使用或者滥用这些特性。
  • 调试问题:Java8函数式接口和Lambda表达式在编译时会被转换为一些隐含的类和方法,这可能会导致调试时出现一些困难和混乱。例如,在断点调试时,可能会跳到一些看不懂的代码中,或者无法查看Lambda表达式中的变量值。

因此,在使用Java8函数式接口和Lambda表达式时,需要根据具体的场景和需求来选择合适的方式,避免盲目地追求新特性而忽略了其他方面的影响。

外传

? 原创不易,如若本文能够帮助到您的同学
? 支持我:关注我+点赞?+收藏⭐️
? 留言:探讨问题,看到立马回复
? 格言:己所不欲勿施于人 扬帆起航、游历人生、永不言弃!?

显示全文