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

使用函數式接口作為形參時,會為方法的封裝提供了很大的便利性,不會受到類型的約束和限制,使得方法的使用場景更加廣泛和可擴展性;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM