一 概述

name type description
Consumer Consumer< T > 接收T对象,不返回值
Predicate Predicate< T > 接收T对象并返回boolean
Function Function< T, R > 接收T对象,返回R对象
Supplier Supplier< T > 提供T对象(例如工厂),不接收值
UnaryOperator UnaryOperator< T > 接收T对象,返回T对象
BiConsumer BiConsumer<T, U> 接收T对象和U对象,不返回值
BiPredicate BiPredicate<T, U> 接收T对象和U对象,返回boolean
BiFunction BiFunction<T, U, R> 接收T对象和U对象,返回R对象
BinaryOperator BinaryOperator< T > 接收两个T对象,返回T对象

参考:https://blog.csdn.net/huo065000/article/details/78964382

二 Consumer

1 作用

  • 消费某个对象

2 使用场景

  • Iterable接口的forEach方法需要传入Consumer,大部分集合类都实现了该接口,用于返回Iterator对象进行迭代。

3 设计思想

  • 开发者调用ArrayList.forEach时,一般希望自定义遍历的消费逻辑,比如:输出日志或者运算处理等。
  • 处理逻辑留给使用者,使用灵活多变。
  • 多变的逻辑能够封装成一个类(实现Consumer接口),将逻辑提取出来

PASS:Javascript能够将函数传递给另一个函数,这应该算是函数式编程的一个体现,java的function包中的类也是类似的。

public interface Iterable<T> {
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
}

4 DEMO

public class ConsumerTest {

    public static void main(String[] args) {
ArrayList<Employee> employees = new ArrayList<>();
String[] prefix = {"A", "B"};
for (int i = 1; i <= 10; i++)
employees.add(new Employee(prefix[i % 2] + i, i * 1000));
employees.forEach(new SalaryConsumer());
employees.forEach(new NameConsumer());
} static class Employee {
private String name;
private int salary; public Employee() {
this.salary = 4000;
} public Employee(String name, int salary) {
this.name = name;
this.salary = salary;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getSalary() {
return salary;
} public void setSalary(int salary) {
this.salary = salary;
} @Override
public String toString() {
return new StringBuilder()
.append("name:").append(name)
.append(",salary:").append(salary)
.toString();
}
} // 输出需要交税的员工
static class SalaryConsumer implements Consumer<Employee> { @Override
public void accept(Employee employee) {
if (employee.getSalary() > 2000) {
System.out.println(employee.getName() + "要交税了.");
}
} } // 输出需要名字前缀是‘A’的员工信息
static class NameConsumer implements Consumer<Employee> { @Override
public void accept(Employee employee) {
if (employee.getName().startsWith("A")) {
System.out.println(employee.getName() + " salary is " + employee.getSalary());
}
} }
}

三 Predicate

1 作用

  • 判断对象是否符合某个条件

2 使用场景

​ ArrayList的removeIf(Predicate):删除符合条件的元素

​ 如果条件硬编码在ArrayList中,它将提供无数的实现,但是如果让调用者传入条件,这样ArrayList就可以从复杂和无法猜测的业务中解放出来。

3 设计思想

  • 提取条件,让条件从处理逻辑脱离出来,解耦合

4 DEMO

// employee.getSalary() > 2000 提取成一个条件类
class SalaryConsumer implements Consumer<Employee> {
@Override
public void accept(Employee employee) {
// 自行传入本地的最低交税工资
if (new SalaryPredicate(2000).test(employee)) {
System.out.println(employee.getName() + "要交税了.");
}
}
} class SalaryPredicate implements Predicate<Employee>{
private int tax; public SalaryPredicate(int tax) {
this.tax = tax;
} @Override
public boolean test(Employee employee) {
return employee.getSalary() > tax;
}
}

三 Function

1 作用

  • 实现一个”一元函数“,即传入一个值经过函数的计算返回另一个值。

2 使用场景

  • V HashMap.computeIfAbsent(K , Function<K, V>) // 简化代码,如果指定的键尚未与值关联或与null关联,使用函数返回值替换。
  • <R> Stream<R> map(Function<? super T, ? extends R> mapper); // 转换流

3 设计思想

  • 一元函数的思想,将转换逻辑提取出来,解耦合

4 DEMO

public static void main(String[] args) {
ArrayList<Employee> employees = new ArrayList<>();
String[] prefix = {"B", "A"};
for (int i = 1; i <= 10; i++)
employees.add(new Employee(prefix[i % 2] + i, i * 1000));
int[] expenses = ListToArray(employees, new EmployeeToExpenses());// 公司对单个员工的支出数组
int[] incomes = ListToArray(employees, new EmployeeToIncome()); // 单个员工的收入数组
System.out.println("社保+公积金+税=" + (sum(expenses) - sum(incomes)) + "元");
} private static int[] ListToArray(List<Employee> list, Function<Employee, Integer> function) {
int[] ints = new int[list.size()];
for (int i = 0; i < ints.length; i++)
ints[i] = function.apply(list.get(i));
return ints;
} private static int sum(int[] salarys) {
int sum = 0;
for (int i = 0; i < salarys.length; i++)
sum += salarys[i];
return sum;
} // 公司支出
static class EmployeeToExpenses implements Function<Employee, Integer> { @Override
public Integer apply(Employee employee) {
// 假设公司公积金和社保为工资的20%
return Double.valueOf(employee.getSalary() * (1 + 0.2)).intValue();
} } // 员工实际到手工资
static class EmployeeToIncome implements Function<Employee, Integer> { @Override
public Integer apply(Employee employee) {
// 假设员工薪水 * 80% 为到手工资
return Double.valueOf(employee.getSalary() * (1 - 0.2)).intValue();
} }

四 Supplier

1 作用

  • 创建一个对象(工厂类)

2 使用场景

  • Optional.orElseGet(Supplier<? extends T>):当this对象为null,就通过传入supplier创建一个T返回。

3 设计思想

  • 封装工厂创建对象的逻辑

4 DEMO

public static void main(String[] args) {
// 生成固定工资的员工
Supplier<Employee> supplier = () -> new Employee();
Employee employee1 = supplier.get();
employee1.setName("test1");
Employee employee2 = supplier.get();
employee2.setName("test2");
System.out.println("employee1:" + employee1);
System.out.println("employee2:" + employee2);
}

五 UnaryOperator

1 作用

  • UnaryOperator继承了Function,与Function作用相同
  • 不过UnaryOperator,限定了传入类型返回类型必需相同

2 使用场景

  • List.replaceAll(UnaryOperator) // 该列表的所有元素替换为运算结算元素
  • Stream.iterate(T,UnaryOperator) // 重复对seed调用UnaryOperator来生成元素

3 设计思想

  • 一元函数的思想,将同类转换逻辑提取出来,解耦合

4 DEMO

public static void main(String[] args) {
ArrayList<Employee> employees = new ArrayList<>();
String[] prefix = {"B", "A"};
for (int i = 1; i <= 10; i++)
employees.add(new Employee(prefix[i % 2] + i, i * 1000));
System.o
ut.println("公司进行薪资调整...");
salaryAdjustment(employees,new SalaryAdjustment(4000));
employees.forEach(System.out::println);
} static void salaryAdjustment(List<Employee> list, UnaryOperator<Employee> operator) {
for (int i = 0; i < list.size(); i++) {
list.set(i, operator.apply(list.get(i)));
}
} static class SalaryAdjustment implements UnaryOperator<Employee> {
private int salary; public SalaryAdjustment(int salary) {
this.salary = salary;
} @Override
public Employee apply(Employee employee) {
employee.setSalary(salary);
return employee;
} }

JAVA8的java.util.function包的更多相关文章

  1. JAVA8的java.util.function包 @FunctionalInterface

    1 函数式接口java.util.function https://www.cnblogs.com/CobwebSong/p/9593313.html 2 JAVA8的java.util.functi ...

  2. Function接口 – Java8中java.util.function包下的函数式接口

    Introduction to Functional Interfaces – A concept recreated in Java 8 Any java developer around the ...

  3. 深入学习Java8 Lambda (default method, lambda, function reference, java.util.function 包)

    Java 8 Lambda .MethodReference.function包 多年前,学校讲述C#时,就已经知道有Lambda,也惊喜于它的方便,将函数式编程方式和面向对象式编程基于一身.此外在使 ...

  4. 函数式接口java.util.function

    什么是函数式接口 为什么要用函数式接口 java.util.function和其他的函数式接口 lamdba表达式 方法引用 流 Stream 1 什么是函数式接口 用@FunctionInterfa ...

  5. [Java 基础] 使用java.util.zip包压缩和解压缩文件

    reference :  http://www.open-open.com/lib/view/open1381641653833.html Java API中的import java.util.zip ...

  6. java.util.concurrent包

    在JavaSE5中,JUC(java.util.concurrent)包出现了 在java.util.concurrent包及其子包中,有了很多好玩的新东西: 1.执行器的概念和线程池的实现.Exec ...

  7. java.util.concurrent包API学习笔记

    newFixedThreadPool 创建一个固定大小的线程池. shutdown():用于关闭启动线程,如果不调用该语句,jvm不会关闭. awaitTermination():用于等待子线程结束, ...

  8. 《java.util.concurrent 包源码阅读》 结束语

    <java.util.concurrent 包源码阅读>系列文章已经全部写完了.开始的几篇文章是根据自己的读书笔记整理出来的(当时只阅读了部分的源代码),后面的大部分都是一边读源代码,一边 ...

  9. 《java.util.concurrent 包源码阅读》02 关于java.util.concurrent.atomic包

    Aomic数据类型有四种类型:AomicBoolean, AomicInteger, AomicLong, 和AomicReferrence(针对Object的)以及它们的数组类型, 还有一个特殊的A ...

随机推荐

  1. Pytest权威教程19-编写钩子(Hooks)方法函数

    目录 编写钩子(Hooks)函数 钩子函数验证和执行 firstresult: 遇到第一个有效(非None)结果返回 hookwrapper:在其他钩子函数周围执行 钩子(Hooks)函数排序/调用示 ...

  2. ansible-playbook--jia使用

    #cat jia.yml - hosts: test-gfs user: dev gather_facts: true vars: PORT: "3306" MESAGE: &qu ...

  3. ubuntu之路——day17.4 卷积神经网络示例

    以上是一个识别手写数字的示例 在这个示例中使用了两个卷积-池化层,三个全连接层和最后的softmax输出层 一般而言,CNN的构成就是由数个卷积层紧跟池化层再加上数个全连接层和输出层来构建网络. 在上 ...

  4. x3d

    目录 3d format introduction x3d resources open source C++ implementations file formats 1. Feature matr ...

  5. Mockito 的用法

    本文为博主原创,转载请注明出处: Mockito 是一个基于MIT协议的开源java测试框架. Mockito区别于其他模拟框架的地方主要是允许开发者在没有建立“预期”时验证被测系统的行为.对于moc ...

  6. Ubuntu宝塔面板设置网站 Apache Server API为Apache 2.0 Handler模式

    用过宝塔面板(https://www.bt.cn)的谁用谁知道:  以下来自官网的介绍: “宝塔Linux面板是提升运维效率的服务器管理软件,支持一键LAMP/LNMP/集群/监控/网站/FTP/数据 ...

  7. Hive的两种操作模式

    Hive的客户端操作 Hive的客户端操作 通过JDBC操作Hive 通过Thrift操作Hive 通过JDBC操作Hive 首先 Hive 启动远程服务 hive --service hiveser ...

  8. IDEA快捷键无法使用

    IDEA快捷键无法使用 觉得有用的话,欢迎一起讨论相互学习~Follow Me 今天新换了一台主机,但是很奇怪的是自己的IDEA快捷键使用不了了,以为是主机还是硬件的问题,最终解决后,发现是软件之间的 ...

  9. Centos7安装文件传输软件rz sz

    一直使用Xshell的xftp传输文件,谁知道忽然无法正常使用. 于是,决定用户rz进行传输 安装步骤也比较简单 1.首先安装第三方源(以下源比默认源包含更多安装包,建议添加该源使用) yum ins ...

  10. go 代码玩耍

    //小游戏 num := rand.Intn() var input int fmt.Println("请输入数字") fmt.Scanf("%d", & ...