Java8:如何使用lambda表达式将所选字段的值从一个对象复制到另一个对象

时间:2018-02-20 14:50:05

标签: java lambda java-8

我正在尝试理解java8的新功能:forEach和lambda表达式。

尝试重写此功能:

public <T extends Object> T copyValues(Class<T> type, T source, T result)
        throws IllegalAccessException
{
    for(Field field : getListOfFields(type)){
        field.set(result, field.get(source));
    }
    return result;
}

使用lambda。

我认为它应该是这样的,但不能正确:

() -> {
     return getListOfFields(type).forEach((Field field) -> {
            field.set(result, field.get(source));
     });
};

2 个答案:

答案 0 :(得分:5)

循环可以替换为

getListOfFields(type).forEach((field) -> field.set(result, field.get(source)));

但是,forEach方法调用没有返回值,因此您仍然需要

return result;

分开。

完整的方法:

public <T extends Object> T copyValues(Class<T> type, T source, T result)
        throws IllegalAccessException
{
    getListOfFields(type).forEach((field) -> field.set(result, field.get(source)));
    return result;
}
编辑,我没有注意到异常的问题。您必须捕获异常并抛出一些未经检查的异常。例如:

public <T extends Object> T copyValues(Class<T> type, T source, T result)
{
    getListOfFields(type).forEach (
      (field) -> {
        try {
            field.set(result, field.get(source));
        } catch (IllegalAccessException ex) {
            throw new RuntimeException (ex);
        }
    });
    return result;
}

答案 1 :(得分:1)

您可以通过以下方式使用功能:

@FunctionalInterface
interface CopyFunction<T> {
    T apply(T source, T result) throws Exception;
}

public static <T> CopyFunction<T> createCopyFunction(Class<T> type) {
    return (source, result) -> {
        for (Field field : getListOfFields(type)) {
            field.set(result, field.get(source));
        }
        return result;
    };
}

然后:

A a1 = new A(1, "one");
A a2 = new A(2, "two");
A result = createCopyFunction(A.class).apply(a1, a2);

CopyFunction功能界面与BinaryOperator几乎相同,只是BinaryOperator不会抛出异常。如果要处理函数中的异常,可以使用BinaryOperator代替。