Выбор нужного сеттера
Задача заключается в следующем:
есть некий класс SearchParam который обернут декораторами @Getter и @Setter. Допустим, что у нас есть экземпляр данного класса filter и некий объект inputName, который содержит в себе две переменные (String ident = "name", String value = "Jhon"); как, зная то, что ident имеет строковое значение name, которое абсолютно всегда совпадает с названием одной из переменных объекта класса SearchParam, вызвать нужный сеттер (тут стоит учитывать, что SearchParam может содержать различные переменные, нас должно беспокоить только то, что название переменной будет "100%" совпадать с ident)?
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class SearchParam {
private Long id;
private String name;
private String comment;
}
Ответы (2 шт):
Предположим, что класс, которым является объект inputName, выглядит следующим образом:
@Getter
@AllArgsConstructor
static class Input {
private String ident;
private Object value;
}
Тогда можно создать map, в которой:
- Ключ - это имя поля, которое необходимо засетить
- Значение - логика, по которой будет сетиться поле
Например:
Map<String, BiConsumer<Object, SearchParam>> searchParamSetters = new HashMap<>();
searchParamSetters.put("id", (input, searchParam) -> searchParam.setId((Long) input));
searchParamSetters.put("name", (input, searchParam) -> searchParam.setName((String) input));
searchParamSetters.put("comment", (input, searchParam) -> searchParam.setComment((String) input));
SearchParam searchParam = new SearchParam();
Input nameInput = new Input("name", "Johnny");
searchParamSetters.get(nameInput.getIdent()).accept(nameInput.getValue(), searchParam);
Минус данного подхода в том, что для каждого нового поля в классе SearchParam необходимо будет иметь соответствующее значение в мапе.
Так же следует подумать о том, что делать случае, когда в мапе нет значения для Input.ident
Для решения своей задачи воспользовался отражениями в Java, классом Method.
private void bindDataToFilter () {
Method method;
for (Map.Entry<String, String> entry : filterTextFields.entrySet()) {
String key = entry.getKey(); //Название переменной экземпляра
String value = entry.getValue(); //Значение, которое должно попасть в key
String methodName = "set" + StringUtils.capitalize(key);
try {
method = filter.getClass().getMethod(methodName, String.class);
method.invoke(filter, value);
} catch (SecurityException | NoSuchMethodException ignored) { } catch (IllegalAccessException |
InvocationTargetException e) {
e.printStackTrace();
}
}
}