簡體   English   中英

generics java 中的動態數據類型

[英]Dynamic datatype in generics java

我有一個用例,客戶端正在發送 List<Function>。 任務是迭代並執行這個 function 並將其保存在 TypedSafeMap 中。 偽客戶端代碼:

Function<String, Integer> firstFn = x -> x.length();
Function<String, String> secondFn = x -> x.substring(0);

client.runTheseFunctions(Arrays.asList(firstFn, secondFn));

在代碼中的runtTheseFunctions中,任務是執行這些函數並將其保存在TypedSafeMap中,其中key是function的結果類型的數據類型,value是functions.apply()的返回值;

下面的代碼

public static void runTheseFunctions(List<Function<Employee, ?>> lst, Employee o) {
           lst.stream().forEach( x -> {
             typedSafeMap.put(????, x.apply(o));  
        //The key is nothing but the datatype of the x.apply(o).
        //How do I add this in runtime here. Generics is all compile time safety.
           });
    }
public static void runTheseFunctions(List<Function<Employee, ?>> lst, Employee o) {
    lst.stream().collect(Collectors.toMap(f -> f.apply(o).getClass(), f -> f.apply(o)));
}

您可以實現您的“runTheseFunctions”方法,如下所示:

    public static void runTheseFunctions(List<Function<Employee, ?>> lst, Employee o) {
        Map<Class<?>, Object> typedSafeMap = new HashMap<>();

        lst.stream().forEach(x -> {
            Object value = x.apply(o);
            typedSafeMap.put(value.getClass(), value);
        });

        System.out.println(typedSafeMap);
    }

這是您想要實現的目標的示例,您可以將其用於測試。 我假設一個簡單的Employee class 實現,只是為了給你一個想法:

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

class Employee {
    String name;

    public Employee(String name) {
        this.name = name;
    }

    public int length() {
        return name.length();
    }

    public String substring(int index) {
        return name.substring(index);
    }
}

public class Test {

    public static void main(String[] args) {

        Employee e = new Employee("Marco");

        Function<Employee, Integer> firstFn = x -> x.length();
        Function<Employee, String> secondFn = x -> x.substring(0);

        runTheseFunctions(Arrays.asList(firstFn, secondFn), e);

    }

    public static void runTheseFunctions(List<Function<Employee, ?>> lst, Employee o) {

        Map<Class, Object> typedSafeMap = new HashMap<>();

        lst.stream().forEach(x -> {

            Object result = x.apply(o);

            typedSafeMap.put(x.apply(o).getClass(), x.apply(o));
            // The key is nothing but the datatype of the x.apply(o).
            // How do I add this in runtime here. Generics is all compile time safety.
        });

        typedSafeMap.entrySet().forEach(entry -> System.out.println(entry.getKey() + " - " + entry.getValue()));
    }

}

這是 output:

class java.lang.String - Marco
class java.lang.Integer - 5

如果函數列表包含兩個或多個具有相同輸出類型的函數(例如:String getFirstName、String getLastName、toMap 將失敗。所以另一種選擇是:

var map = list.stream().collect(groupingBy(
    f -> f.apply(e).getClass(), 
    mapping(f -> f.apply(e), toList())
));

增強@Yonas 答案:

private static Map<?, ? extends Object> runTheseFunctions(List<Function<String, ? extends Object>> list, String o) {
    return list.stream()
            .map(f -> f.apply(o))
            .collect(Collectors.toMap(result -> result.getClass(), Function.identity()));
}

這將只調用一次f.apply(o)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM