• JAVA8的java.util.function包


    一 概述

    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;
        }
    
    }
    

  • 相关阅读:
    发布全文检索类库外包
    给即将面试的人
    实验四 Web服务器2
    电子公文传输系统验收2功能测试
    整数范围与类型转换
    实验三电子公文传输系统1个人贡献
    socket测试
    电子公文传输系统验收4开发基础
    Web服务器1socket编程
    算法测试(课上测试)
  • 原文地址:https://www.cnblogs.com/linzhanfly/p/9686941.html
Copyright © 2020-2023  润新知