1. Function接口

/**
* function 接口测试
* function 函数只能接受一个参数,要接受两个参数,得使用BiFunction接口
*/
public class FunctionTest { @Test
public void Test (){
FunctionTest test = new FunctionTest();
// System.out.println(test.compute(4, x->x*2));
System.out.println(test.compute(2, v -> v * 3, v -> v * v));
System.out.println(test.compute2(2, v -> v * 3, v -> v * v)); System.out.println(test.compute3(2,3, (a, b)-> a+b)); System.out.println(test.compute4(2, 3, (a, b) -> a + b, a -> a * a));
} /**
* function的第一个参数是输入, 第二个参数是输出
* @param a
* @param function
* @return
*/
public int compute(int a, Function<Integer, Integer> function) {
int result = function.apply(a);
return result;
} /**
* compose 组合, 先执行传入的参数方法,再执行本身的方法
* @param a 输入
* @param func1 本身方法
* @param func2 传入的参数方法
* @return
*/
public int compute(int a, Function<Integer, Integer> func1, Function<Integer, Integer> func2) {
return func1.compose(func2).apply(a);
} /**
* andThen 方法,先执行自己的方法,再执行传入的参数方法
* @param a
* @param func1 本身方法
* @param func2 传入的参数方法
* @return
*/
public int compute2(int a, Function<Integer, Integer> func1, Function<Integer, Integer> func2) {
return func1.andThen(func2).apply(a);
} /**
* biFunction接口可传入两个参数
* @param a
* @param b
* @param biFunction
* @return
*/
public int compute3(int a, int b, BiFunction<Integer, Integer, Integer> biFunction) {
return biFunction.apply(a, b);
} /**
* biFunction只有一个andThen方法(参数还是Function),因为他只返回一个值,不能返回两个值
* @param a
* @param b
* @param biFunction
* @param function
* @return
*/
public int compute4(int a, int b, BiFunction<Integer, Integer, Integer> biFunction, Function<Integer, Integer> function) {
return biFunction.andThen(function).apply(a,b);
}
}
// 模仿Function接口, 接受一个参数, 返回一个值
@FunctionalInterface
interface FakeInterface<J, R> {
R fuck(J t);
} public class MyTest {
public String myTest(Integer a, FakeInterface<Integer, String> fakeInterface) {
System.out.println("执行我的fakeInterface中的方法, 传入一个参数");
String s = fakeInterface.fuck(a);
return s;
} public static void main(String[] args) {
MyTest myTest = new MyTest();
String s = myTest.myTest(5, x -> String.valueOf(x));
System.out.println(s);
}
}

2. BiFunction接口

public class PersonTest {

    @Test
public void test1() {
Person p1 = new Person("zhangsan", 20);
Person p2 = new Person("lisi", 30);
Person p3 = new Person("wangwu", 40);
List<Person> persons = Arrays.asList(p1, p2, p3);
PersonTest test = new PersonTest();
List<Person> result = test.getPersonByAge(30, persons);
result.forEach(x-> System.out.println(x.getUsername()));
} @Test
public void test2() {
Person p1 = new Person("zhangsan", 20);
Person p2 = new Person("lisi", 30);
Person p3 = new Person("wangwu", 40);
List<Person> persons = Arrays.asList(p1, p2, p3);
PersonTest test = new PersonTest();
List<Person> result = test.getPersonByAge2(30, persons, (age, personList) -> {
return personList.stream().filter(p->p.getAge() > age).collect(Collectors.toList());
});
result.forEach(x-> System.out.println(x.getUsername()));
} /**
* 强行使用lamboda来写代码
* @param age
* @param persons
* @return
*/
public List<Person> getPersonByAge(int 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);
} /**
* 不预先定义函数操作
* @param age
* @param persons
* @param biFunction 函数操作由用户传入,更加灵活
* @return
*/
public List<Person> getPersonByAge2(int age, List<Person> persons, BiFunction<Integer, List<Person>, List<Person>> biFunction) {
// 执行函数操作
return biFunction.apply(age, persons);
}

3. Predicate接口

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate; /**
* predicate接口, 是一个根据给定参数来决定返回bool值的判断式函数式接口
*/
public class PredicateTest { @Test
public void Test1() {
Predicate<String> predicate = p->p.length() > 5;
System.out.println(predicate.test("hello"));
} // 接口的简单练习
@Test
public void Test2() {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
PredicateTest predicateTest = new PredicateTest();
System.out.println("打印出偶数: ");
predicateTest.conditionFilter(list, item->(item & 1) == 0);
System.out.println("---------------------------");
System.out.println("打印出奇数: ");
predicateTest.conditionFilter(list, item->(item & 1) == 1);
System.out.println("---------------------------");
predicateTest.conditionFilter(list, x->true);
System.out.println("----------------------------");
System.out.println("打印:, 大于5,并且偶数: ");
predicateTest.conditionAndFilter(list, x -> x > 5, x -> (x & 1) == 0);
System.out.println("----------------------------");
} /**
* 函数式编程的一大特点就是将行为提到方法外面,由用户传入
* 调用时动态传入动作,更高层次的抽象化
* @param list
* @param predicate
*/
public void conditionFilter(List<Integer> list, Predicate<Integer> predicate) {
// 将通过条件判断的数字打印出来
for (Integer i : list) {
if (predicate.test(i)) {
System.out.println(i);
}
}
} /**
* predicate接口的 与 运算, 打印出符合两个条件的结果
同理, 可理解predict中的其他逻辑运算
* @param list
* @param p1
* @param p2
*/
public void conditionAndFilter(List<Integer> list, Predicate<Integer> p1, Predicate<Integer> p2) {
for (Integer i : list) {
if (p1.and(p2).test(i)) {
System.out.println(i);
}
}
} /**
* Predicate.isEqual() 方法用于判断两个参数是否相同, 依据就是 Objects#equals(Object, Object)}.
* 这个方法不怎么好理解, 说白了,就是调用传入参数的equals方法,
* 得到其方法的引用,而这个引用又刚好符合Predict函数的格式,可以作为Predict来使用
* @param object
* @return
*/
public Predicate<String> isEqual(Object object) {
return Predicate.isEqual(object);
} @Test
public void Test3() {
PredicateTest predicateTest = new PredicateTest();
System.out.println(predicateTest.isEqual("test").test("test")); // true
System.out.println(predicateTest.isEqual("test").test("test2")); // false
System.out.println(predicateTest.isEqual(null).test("test")); // false
System.out.println(predicateTest.isEqual(null).test(null)); //true
}
}

4. Supplier接口

@Data
public class Student {
private String name = "zhangsan";
private Integer age = 20;
}
/**
* Supplier接口, 不接受参数, 返回一个结果
* 常用于 工厂
*
*/
public class SupplierTest { // 最简单例子
@Test
public void Test() {
Supplier<String> supplier = () -> "hello world";
System.out.println(supplier.get());
} /**
* 利用supplier生产学生
*/
@Test
public void Test2() {
Supplier<Student> supplier = ()->new Student();
System.out.println(supplier.get().toString()); // 更进一步, 调用Student的构造方法, 叫做构造方法的引用
// 不接受参数, 返回Student对象,符合函数式接口的要求
// 编译器会去Student找不带参数, 返回Student的构造方法
Supplier<Student> supplier2 = Student::new;
System.out.println(supplier2.get().toString());
}
}

5. Consumer接口

接收一个参数, 不返回值, 但可能改变传入的参数,通过这个改变的副作用来实现业务,list.forEach中就是一个Consumer接口作为参数

list.forEach(x->System.out.println(x));

default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
public class MyTest {
public void myTest2(Integer a, Consumer<Integer> consumer) {
consumer.accept(a);
} public static void main(String[] args) {
MyTest myTest = new MyTest();
myTest.myTest2(5, x-> {
System.out.println("可以操作x,但没有返回值");
});
}
}

jdk8中几个核心的函数式接口笔记的更多相关文章

  1. 乐字节-Java8核心特性实战之函数式接口

    什么时候可以使用Lambda?通常Lambda表达式是用在函数式接口上使用的.从Java8开始引入了函数式接口,其说明比较简单:函数式接口(Functional Interface)就是一个有且仅有一 ...

  2. Java8内置的四大核心函数式接口

    package java_8; import org.junit.Test; import java.util.ArrayList; import java.util.Arrays; import j ...

  3. Java8新特性(一)——Lambda表达式与函数式接口

    一.Java8新特性概述 1.Lambda 表达式 2. 函数式接口 3. 方法引用与构造器引用 4. Stream API 5. 接口中的默认方法与静态方法 6. 新时间日期 API 7. 其他新特 ...

  4. Java 8 特性 —— 函数式接口

    函数式接口 概述:接口中只有一个抽象方法. 函数式接口,即适用于函数式编程场景的接口.而 Java 中的函数式编程体现就是 Lambda,所以函数式接口就是可以适用于 Lambda 使用的接口.只有确 ...

  5. JAVA8之函数式接口

    由于JDK8已经发布一段时间了,也开始逐渐稳定,未来使用JAVA语言开发的系统会逐渐升级到JDK8,因为为了以后工作需要,我们有必要了解JAVA8的一些新的特性.JAVA8相对JAVA7最重要的一个突 ...

  6. Java8 新特性 函数式接口

    什么是函数式接口   函数式接口是Java8引用的一个新特性,是一种特殊的接口:SAM类型的接口(Single Abstract Method).但是它还是一个接口,只是有些特殊罢了.  函数式接口的 ...

  7. java8学习之Supplier与函数式接口总结

    Supplier接口: 继续学习一个新的函数式接口--Supplier,它的中文意思为供应商.提供者,下面看一下它的javadoc: 而具体的方法也是相当的简单,就是不接受任何参数,返回一个结果: 对 ...

  8. JDK8中Stream使用解析

    JDK8中Stream使用解析 现在谈及JDK8的新特新,已经说不上新了.本篇介绍的就是Stream和Lambda,说的Stream可不是JDK中的IO流,这里的Stream指的是处理集合的抽象概念『 ...

  9. Java8 函数式接口 @FunctionalInterface以及常用Consumer<T>、Supplier<T>、Function<T, R>、Predicate<T>总结

    首先看看什么是Lambda 表达式 Lambda是一个匿名函数,我们可以把Lambda表达式理解为一段可以传递的代码(将代码像数据一样传递):最简单的Lambda表达式可由逗号分隔的参数列表.-> ...

随机推荐

  1. 洛谷 P3049 Landscaping ( 贪心 || DP)

    题意 : 有n块土地,每块有A[i]泥土,现把其改造成B[i]泥土,有3种操作:(1)花费X向任意土地增加1泥土:(2)花费Y向任意土地减少1泥土:(3)花费Z*|i-j|把土地i的1泥土运到土地j. ...

  2. 2019hdu多校 AND Minimum Spanning Tree

    题目链接:Click here 题目大意:两个点之间的边权为编号按位与的值,求最小生成树,方案要字典序最小 Solution: 一道不难的构造题,每个点连向他取反后的lowbit值,这样边权为0,若l ...

  3. Spring Data Jpa (四)注解式查询方法

    详细讲解声明式的查询方法 1 @Query详解 使用命名查询为实体声明查询是一种有效的方法,对于少量查询很有效.一般只需要关心@Query里面的value和nativeQuery的值.使用声明式JPQ ...

  4. Oracle--表有LONG类型复制或导数报ORA00990

    SYS@racdb1> create table siebel.S_ORG_EXT_201707101650 as select * from siebel.S_ORG_EXT where 1= ...

  5. 快速找到oracle的alert日志

    https://jingyan.baidu.com/article/f3ad7d0fe5d31309c3345b9b.html

  6. mysql 字符串字段中查找非ascii字符

    select * from tabel_name where field_name not regexp "^[ -~]*$"

  7. C# Setting.settings . 用法 2 使用配置文件(.settings、.config)存储应用程序配置

    引言 我不知大家早先是如何保存应用程序配置,以备下次打开时使用的,反正我开始学.Net的时候就去研究序列化,以二进制或XML格式的序列化来保存应用程序配置.这样每次都要建立单独的配置类,并书写读写配置 ...

  8. 解决保存快照失败后redis无法写入的问题( Redis is configured to save RDB snapshots)

    MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Com ...

  9. 阶段3 1.Mybatis_11.Mybatis的缓存_3 mybatis一对一实现延迟加载

    不用骨架创建项目 复制一对多的代码src下的代码到我们刚才创建的项目里面 把依赖信息复制过来 这里原来实现的功能是立即加载的功能.sql语句是一次性查询的两个表关联的查询. 调整代码 删除Accoun ...

  10. Jmeter接口测试系列之保存断言结果到文件

    在执行完接口测试用例后,我们需要将失败的用例结果统一保存到文件中,可以使用“断言结果”组件,并定制输出内容. 1.配置断言结果组件输出 (1.在文件名中配置需要保存的文件路径和文件名: (2.勾选仅日 ...