Java8: как скопировать значения выбранных полей из одного объекта в другой с помощью лямбда-выражения

Я пытаюсь понять новые функции java8: foreach и лямбда-выражения.

попытка переписать эту функцию:

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

используя лямбда.

Я думаю, что это должно быть что-то вроде этого, но не может сделать это правильно:

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

2 ответов


вы можете использовать функции следующим образом:

@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 не исключение. Если вы хотите обрабатывать исключения в функции, вы можете использовать .


цикл может быть заменен на

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

EDIT, я не заметил проблему с исключением. Вам придется поймать исключение и выбросить некоторое непроверенное исключение. Например:

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