zoukankan      html  css  js  c++  java
  • Map结合Function函数式接口的巧妙之处

    需求:在给定 List 集合中,需根据不同的算法规则,选取计算方式并返回结果;

    例如:[1, 2, 3, 4, 5] List 集合中都是 Integer 类型数据,根据提供的算法规则,sum 求和,min 求最小值,max 求最大值等;

    使用场景:需要根据指定 key,选取不同的逻辑处理方式;

    一、使用枚举类实现

    (1)定义枚举类DataEnum,需实现指定的计算接口,根据不同的算法规则【使用枚举类中默认的 name 属性】,来选取不同的算法计算方式;

    (2)代码如下:

    // 计算方式接口定义
    public interface Icalculate {
    
        // 计算方式
        Integer calculate(List<Integer> datas);
    
    }
    
    // 定义枚举类,实现接口
    public enum DataEnum implements Icalculate {
    
        SUM{
            @Override
            public Integer calculate(List<Integer> datas) {
                return datas.stream().reduce(0, (element1, element2) -> element1 + element2);
            }
        },
    
        MIN{
            @Override
            public Integer calculate(List<Integer> datas) {
                Optional<Integer> min = datas.stream().min(Comparator.comparingInt(o -> o));
                return min.orElse(null);
            }
        },
    
        MAX{
            @Override
            public Integer calculate(List<Integer> datas) {
                Optional<Integer> max = datas.stream().max(Comparator.comparingInt(o -> o));
                return max.orElse(null);
            }
        };
    
        // 根据算法规则,获取指定的计算方式【挪用了枚举类继承Enum中的name属性】
        public static DataEnum of(String name) {
            Optional<DataEnum> dataEnum = Arrays.stream(DataEnum.values()).filter(element -> element.name().equalsIgnoreCase(name)).findAny();
            return dataEnum.orElse(null);
        }
    
    }
    
    枚举类实现

    (3)测试样例及结果

    public class DataEnumTest {
    
        public static void main(String[] args) {
            DataEnum dataEnum = DataEnum.of("max");
            if (!Objects.isNull(dataEnum)) {
                List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
                System.out.println("max = " + dataEnum.calculate(list));
            }
        }
    
    }
    结果:max = 5
    测试样例及结果

    二、使用Map结构结合Function实现【常用】

    (1)定义FunctionUtil工具类,结合Java8的Function函数式接口实现;

    (2)代码实现:

    public class FunctionUtil {
    
        // 定义Map结构,key: 算法规则,value: 存放指定的计算方式
        private static Map<String, Function<List<Integer>, Integer>> calculateMap = new HashMap<>();
    
        // 静态代码块,初始化Map结构,定义指定算法规则的计算方式
        static {
            calculateMap.put("SUM", list -> list.stream().reduce(0, Integer::sum));
            calculateMap.put("MIN", data -> data.stream().min(Comparator.comparingInt(o -> o)).orElse(null));
            calculateMap.put("MAX", data -> data.stream().max(Comparator.comparingInt(o -> o)).orElse(null));
        }
    }

    (3)测试样例和结果:

    public class Test {
    
        public static void main(String[] args) {
            List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
            Integer min = FunctionUtil.calculateMap.get("MIN").apply(list);
            Integer max = FunctionUtil.calculateMap.get("MAX").apply(list);
            Integer sum = FunctionUtil.calculateMap.get("SUM").apply(list);
            System.out.println("min = " + min + ", max = " + max + ", sum = " + sum);
    
        }
    
    }
    结果:min = 1, max = 5, sum = 15
    测试样例及结果

    三、Java8 的函数式接口之 Function 使用

    (1)常见的函数式接口集合,供参考:详解JAVA8函数式接口{全}

    1、Consumer<T>   :消费型接口    void accept(T t);
    
    2、Supplier<T>   :供给型接口    T get();
    
    3、Function<T,R> :函数型接口    R apply(T t);
    
    4、Predicate<T>  :断言型接口    boolean test(T t);

    (2)举例使用 Function 作为参数使用

    public class FunctionTest {
    
        // 提供一个 Function 入参泛型方法【适用于不同的数据类型】
        private static <T, R> R calculate(T t, Function<T, R> function) {
            return function.apply(t);
        }
    
        public static void main(String[] args) {
            Function<List<Integer>, Integer> sumFunc = list -> list.stream().reduce(0, Integer::sum);
            Integer sum = FunctionTest.calculate(Arrays.asList(1, 2, 3, 4, 5), sumFunc);
            
            Function<List<Integer>, Integer> maxFunc = list -> list.stream().max(Comparator.comparingInt(o -> o)).orElse(null);
            Integer max = FunctionTest.calculate(Arrays.asList(1, 2, 3, 4, 5), maxFunc);
    
            Function<List<Integer>, Integer> minFunc = list -> list.stream().min(Comparator.comparingInt(o -> o)).orElse(null);
            Integer min = FunctionTest.calculate(Arrays.asList(1, 2, 3, 4, 5), minFunc);
    
            System.out.println("sum = " + sum + ", min = " + min + ", max = " + max);
        }
    
    }
    
    结果:sum = 15, min = 1, max = 5

    使用函数式接口作为形参时,会为方法的封装提供了很大的便利性,不会受到类型的约束和限制,使得方法的使用场景更加广泛和可扩展性;

  • 相关阅读:
    在CentOS 7上安装Docker
    VMware虚拟机上安装CentOS 7
    5、Linux的常用命令
    3.Linux 系统目录结构
    2、Linux的关机方式
    zepto callback
    解callback嵌套
    debugger 调试的一些经验
    Chrome Timeline的指标说明:Blocked、Connect、Send、Wait、Receive
    jquery ajax promise
  • 原文地址:https://www.cnblogs.com/blogtech/p/13501765.html
Copyright © 2011-2022 走看看