Java8 新特性 函数式接口
什么是函数式接口
函数式接口是Java8引用的一个新特性,是一种特殊的接口:SAM类型的接口(Single Abstract Method)。但是它还是一个接口,只是有些特殊罢了。 函数式接口的出现主要是为了配合Java8的另一个新特性Lamdba表达式来使用。
- 接口中只有一个抽象方法
- 接口中面可以加一个注解@FunctionalInterface来检查接口中的方法是不是只有一个抽象方法
- 在接口里面可以加入 默认方法 和 静态方法
- 函数式接口也可以继承,但是继承的时候,抽象方法必须一样
- 函数式接口重写父类的的方法,并不会计入到自己的抽象方法中
自定义函数式接口
//加入这个注解是为了检测接口中是否符合函数式接口的要求
@FunctionalInterface
public interface MyFunctionInterction {
//唯一的抽象方法
void absoluMethod();
//重写Object的方法
@Override
String toString();
//默认方法
default void defaultMethod() {
System.out.println("默认方法");
}
//静态方法
static void stativMethod() {
System.out.println("静态方法");
}
}
函数式接口的简单使用
里面的默认方法可以直接使用
public class TestFunctionIntection {
public static void main(String[] args) {
TestFunctionIntection testFunctionIntection =
new TestFunctionIntection();
testFunctionIntection.test(
//Lamdba表达式的简单使用
() -> System.out.println("函数式接口里面的抽象方法"));
}
/**
* 自己定义的一个方法,并使用自定义的一个消费类型的函数式接口
* @param myFunctionInterction
*/
public void test(MyFunctionInterction
myFunctionInterction) {
//函数式接口里面的抽象方法
myFunctionInterction.absoluMethod();
//默认方法
myFunctionInterction.defaultMethod();
//静态方法
MyFunctionInterction.stativMethod();
}
}
java8里面自定义的四个核心的函数式接口
上面我自定义的一个接口,就是一个消费类型的函数式接口。其实这类接口在java.util.function里面有定义的,就是void Consumer< T >,消费类型接口,上面代码中的test方法里面的接口其实可以换成Consumer< T >接口,也可以用,下面主要就是介绍这四个函数式接口的简单使用。
下面是这四个核心接口的简单使用
public class FunctionTest {
//Consumer<T> 消费型接口
@Test
public void test1() {
Consumer<String> consumer = (x) -> System.out.println(x);
consumer.accept("消费型接口,没有返回值!");
}
//输出:消费型接口,没有返回值!
//供给型接口
@Test
public void test2() {
Supplier<String> supplier = () -> "主要的作用就是创建对象!";
String s = supplier.get();
System.out.println(s);
}
//输出:主要的作用就是创建对象!
//函数型接口
//Function<T,R> T 接收的参数,R 返回值类型
@Test
public void test3() {
Function<Integer, String> function = (x) -> x + ":为String类型";
String apply = function.apply(7);
System.out.println(apply);
}
//输出:7:为String类型
//断言型接口
@Test
public void test4() {
Predicate<Integer> predicate = (x) -> x > 10;
boolean test = predicate.test(11);
System.out.println(test);
}
//输出:true
}
Consumer 的应用
//Consumer<T> 消费型接口
@Test
public void test1() {
//定义一个消费型接口,只输出输入的内容
Consumer<String> consumer = (x) -> System.out.println(x);
//在输入的内容后面加上·--加上了默认方法·
Consumer<String> consumer2 = (x) -> System.out.println(x + "--加上了默认方法");
//执行顺序 先执行 accept 后面执行 addThen(然后)
consumer.andThen(consumer2).accept("消费型接口,没有返回值!");
}
//输出:消费型接口,没有返回值 (accept输出的值)
//输出:消费型接口,没有返回值 !--加上了默认方法 (addThen输出的值)
Consumer 的默认方法的源码:
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
其返回值这一句是重点,先是传入一个Consumer接口,然后返回一个Consumer接口,说明可以用表达式链,然后用这个特性可以把数据进一次进行加工。
(T t) -> { accept(t); after.accept(t); };这一句,返回的顺序首先是调用抽象方法,然后再调用默认方法,说明这个默认方法只可以对数据进行再加工,不能再抽象方法前面。
Supplier 的应用
//供给型接口,这个方法若以用在工厂方法中
@Test
public void test2() {
//跟据一个字符串创建对象
Supplier<String> supplier = () -> "主要的作用就是创建对象!";
//获取一个对象
String s = supplier.get();
//获取两个以象
String s1 = supplier.get();
//两个对象内容一样
System.out.println(s.equals(s1));
System.out.println(s);
//用方法引用的方式创建一个对象
Supplier<SupplierTest> testSupplier = SupplierTest::new;
//用new的方式创建一个对象
Supplier<SupplierTest> supplierTestSupplier = () -> new SupplierTest("张三");
//可以通过supplierTestSupplier 来获取一个对象,并且可以调用里面的方法
String name = supplierTestSupplier.get().getName();
System.out.println(name);
}
//输出:true
//输出:主要的作用就是创建对象!
//输出:张三
Supplier< T >接口类型就有一个方法签名。T get()方法,没有默认方法。
Function< T,R > 的应用
//默认主法addThen
//函数型接口
//Function<T,R> T 接收的参数,R 返回值类型
@Test
public void test3() {
Function<String, String> f1 = (x) -> x +"+ ";
Function<String, String> f2 = (x) -> x + "- ";
//addThen(然后的意思)执行顺序先执行f1,并且把执行后的结果作为f2的输入参数
String apply = f1.andThen(f2).apply("1");
System.out.println(apply);
}
//输出:1+ -
addThen的源码:
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
源码中最重要的一句
(V v) -> apply(before.apply(v)); 规定了执行顺序
//默认主法compose
//函数型接口
//Function<T,R> T 接收的参数,R 返回值类型
@Test
public void test3() {
Function<String, String> f1 = (x) -> x +"+ ";
Function<String, String> f2 = (x) -> x + "- ";
//addThen(然后的意思)执行顺序先执行f2,并且把执行后的结果作为f1的输入参数
String apply = f1.compose(f2).apply("1");
System.out.println(apply);
}
//输出:1- +
三个默认方法,但是最后一个用的不多,这里也就不再介绍了。
Predicate< T > 的应用
//默主方法negate 非
//断言型接口
@Test
public void test4() {
Predicate<Integer> predicate = (x) -> x > 10;
boolean test = predicate.negate().test(11);
System.out.println(test);
}
//输出:false
//断言型接口
//默认方法 or 和 and
@Test
public void test4() {
Predicate<Integer> p1 = (x) -> x > 10;
Predicate<Integer> p2 = (x) -> x < 5;
//默认方法 or 或
boolean test = p1.or(p2).test(3);
//默认方法 and 且
boolean test2 = p1.and(p2).test(3);
System.out.println(test);
System.out.println(test2);
}
//输出:true
//输出:false
函数式接口的使用
函数式接口的的使用,大部分都是在流操作里面进行,现在可以不太理解,但是可以在学习完流操作以后,再过来看,并且跟着写一遍。代码光看是没有用的。如果不写是不知道意思的。
参考的博客:浅浅的函数式接口
细节决定成败!
个人愚见,如有不对,恳请扶正!
Java8 新特性 函数式接口的更多相关文章
- Java8 新特性----函数式接口,以及和Lambda表达式的关系
这里来讲解一下Java8 新特性中的函数式接口, 以及和Lambda 表达式的关系.看到过很多不少介绍Java8特性的文章,都会介绍到函数式接口和lambda表达式,但是都是分别介绍,没有将两者的关系 ...
- java8新特性-函数式接口详细讲解及案例
一.函数式接口 1.1 概念 函数式接口在Java中是指:有且仅有一个抽象方法的接口.函数式接口,即适用于函数式编程场景的接口.而Java中的函数式编程体现就是Lambda,所以函数式接口就是可 以适 ...
- 【Java8新特性】接口中的默认方法和静态方法,你都掌握了吗?
写在前面 在Java8之前的版本中,接口中只能声明常量和抽象方法,接口的实现类中必须实现接口中所有的抽象方法.而在Java8中,接口中可以声明默认方法和静态方法,本文,我们就一起探讨下接口中的默认方法 ...
- 【Java8新特性】- 接口中默认方法修饰为普通方法
Java8新特性 - 接口中默认方法修饰为普通方法 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学 ...
- Java8的新特性--函数式接口
目录 函数式接口 什么是函数式接口 函数式接口的使用 Java8内置的四大核心函数式接口 一.Consumer:消费型接口(void accept(T t)) 二.Supplier:供给型接口(T g ...
- Java8 新特性 —— 函数式编程
本文部分摘录自 On Java 8 概述 通常,传递给方法的数据不同,结果也不同.同样的,如果我们希望方法被调用时的行为不同,该怎么做呢?结论是:只要能将代码传递给方法,那么就可以控制方法的行为. 说 ...
- Java8新特性_接口中的默认方法
默认方法由来猜想 1. Collection接口.Collections公共类. 同是操作集合,为啥要搞俩?没必要.在接口中搞一些默认实现,一个接口即搞定了. 2. Java8支持Lambda表达式 ...
- Java8新特性之接口defualt,static方法
简介 作用 Java8中接口引入了defualt,static两种方法提供默认实现,彻底打破了接口不能有默认实现的规定 static 让接口类似于工具类,提供一些静态方法 static方法不会被子类继 ...
- Java8新特性--函数式编程
在jdk8中什么是函数式接口: 1.被@FunctionalInterface注解修饰的. 2.接口里边只有一个非default的方法. 满足以上2个条件的即为函数式接口,ps:即使一个接口没有被@F ...
随机推荐
- spring事务概念与获取事务时事务传播行为源码分析
一.事务状态:org.springframework.transaction.TransactionStatus isNewTransaction 是否是新事务 hasSavepoint 是否有保存点 ...
- asp.net+jquery 制作text editor
利用jquery制作的文本编辑器,直接给源码吧,相信大家都能看懂.点此下载
- java--修饰符与常用规则
修饰符总结 修饰符 类 成员变量 成员方法 构造方法 public Y Y Y Y default Y Y Y Y protected Y Y Y private Y Y Y abstract Y Y ...
- Vue – 基础学习(4):事件修饰符
Vue – 基础学习(3):事件修饰符
- TP5.1 调用common里面自定义的常量
公共文件:\application\common.php define('cms_password', cms); 控制器引用: 调用: $aa = cms_password; dump(cms_pa ...
- pandas基础:Series与DataFrame操作
pandas包 # 引入包 import pandas as pd import numpy as np import matplotlib.pyplot as plt Series Series 是 ...
- windows下使用ssh(利用paramiko库)
环境:python3.7.3 win7 or win10 1.首先下载paramiko库 命令:pip install paramiko 2.代码: import paramiko 创建一个 ssh ...
- django环境搭建(基于anaconda环境)
环境:win7,anaconda,python3.5 1.介绍 Django特点:具有完整的封装,开发者可以高效率的开发项目,Django将大部分的功能进行了封装,开发者只需要调用即可,如此,大大的缩 ...
- mysql数据库之事务和隔离级别
事务和并发执行目的: 1.提高吞吐量,资源利用率 2.减少等待时间 连接管理器:接受请求/创建线程/认证用户/建立安全连接 并发控制:任何时候,只要有两个以上的用户试图读写同时一个文件/数据,都会带来 ...
- 团队第五次——Alpha2的发布
这个作业属于哪个课程 https://edu.cnblogs.com/campus/xnsy/2019autumnsystemanalysisanddesign/ 这个作业要求在哪里 https:// ...