文章目录
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
可以看到,我们使用了filter
,map
,forEach
等方法,它们都需要传递一个函数式接口类型的参数,用来对流中的元素进行操作。我们可以使用Lambda表达式或者方法引用来实现这些函数式接口,使得代码更加简洁和清晰。
Java8函数式接口的优缺点分析对比
Java8函数式接口和Lambda表达式是Java语言发展的一个重要的进步,它们为Java开发者提供了一种新的编程风格,可以使代码更加简洁和清晰,提高了开发效率和可读性。同时,它们也为Java引入了一些新的特性和概念,例如函数式编程,方法引用,Stream API等,使得Java更加丰富和强大。
但是,Java8函数式接口和Lambda表达式也有一些缺点和限制,例如:
- 兼容性问题:Java8函数式接口和Lambda表达式只能在Java8或更高版本的环境中运行,如果需要在低版本的环境中运行,就需要使用其他的工具或者框架来支持。
- 性能问题:Java8函数式接口和Lambda表达式在运行时会生成一些额外的对象和方法,这可能会影响程序的性能和内存占用。虽然Java虚拟机会进行一些优化和缓存,但是仍然需要注意避免过度使用或者滥用这些特性。
- 调试问题:Java8函数式接口和Lambda表达式在编译时会被转换为一些隐含的类和方法,这可能会导致调试时出现一些困难和混乱。例如,在断点调试时,可能会跳到一些看不懂的代码中,或者无法查看Lambda表达式中的变量值。
因此,在使用Java8函数式接口和Lambda表达式时,需要根据具体的场景和需求来选择合适的方式,避免盲目地追求新特性而忽略了其他方面的影响。
外传
😜 原创不易,如若本文能够帮助到您的同学
🎉 支持我:关注我+点赞👍+收藏⭐️
📝 留言:探讨问题,看到立马回复
💬 格言:己所不欲勿施于人 扬帆起航、游历人生、永不言弃!🔥