将字段名称/类型作为参数传递给Java中的方法

use*_*342 2 java oop design-patterns java-8

我有一个LocalizedAttributes列表

public class LocalizedAttribute<T> {
    T value;
    Locale locale;
}
Run Code Online (Sandbox Code Playgroud)

我有一个存储本地化属性列表的类;

public class A {
    .
    .
    private List<LocalizedAttribute> localizedAttributes;
}
Run Code Online (Sandbox Code Playgroud)

我有一堂课,里面有一些与书本有关的信息。

public class B {
    private String title;
    private String summary;
    private List<String> authors;
    private List<Map<String, String>> publisherRoles;
}
Run Code Online (Sandbox Code Playgroud)

我创造了一堆书

B bookRelatedInfo1 = new B(); ///fill in values;
B bookRelatedInfo2 = new B(); ///fill in values;
B bookRelatedInfo3 = new B(); ///fill in values;
Run Code Online (Sandbox Code Playgroud)

我将此添加到A类的对象中

A.setLocalizedAttributes(ImmutableList.of(
            new LocalizedAttribute(bookRelatedInfo1, new Locale("US")),
            new LocalizedAttribute(bookRelatedInfo2, new Locale("DE")),
            new LocalizedAttribute(bookRelatedInfo3, new Locale("JP"))
))
Run Code Online (Sandbox Code Playgroud)

现在,我想提取本地化标题的列表,并分别进行摘要。

getLocalizedTitles(List<LocalizedAttribute> localizedAttributes) {
    return localizedAttributes.stream()
        .map(localizedAttribute -> {
            Locale locale = localizedAttribute.getLocale();
            B b = (B) localizedAttribute.getValue();
            return new LocalizedAttribute(b.getTitle(), locale);
        })
        .collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我想获取摘要列表,则需要再次编写完全相同的方法b.getTitle,以此类推。有没有更清洁的方法可以做到这一点?

Era*_*ran 5

您可以将传递Function<B,T>给该方法:

<T> List<LocalizedAttribute<T>> getLocalizedAttributes(List<LocalizedAttribute<B>> localizedAttributes, Function<B,T> mapper) {
    return localizedAttributes.stream()
        .map(localizedAttribute -> {
            Locale locale = localizedAttribute.getLocale();
            B b = localizedAttribute.getValue();
            return new LocalizedAttribute<T>(mapper.apply(b), locale);
        })
        .collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)

可以简化为:

<T> List<LocalizedAttribute<T>> getLocalizedAttributes(List<LocalizedAttribute<B>> localizedAttributes, Function<B,T> mapper) {
    return localizedAttributes.stream()
        .map(la -> new LocalizedAttribute<T>(mapper.apply(la.getValue()), la.getLocale()))
        .collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以将其称为:

List<LocalizedAttribute<String>> titleList = getLocalizedAttributes(list,B::getTitle);
Run Code Online (Sandbox Code Playgroud)

要么

List<LocalizedAttribute<String>> summaryList = getLocalizedAttributes(list,B::getSummary);
Run Code Online (Sandbox Code Playgroud)

  • @ user1692342如果将方法List &lt;LocalizedAttribute &lt;B &gt;&gt;(而不是原始的List &lt;LocalizedAttribute&gt;)传递给方法,则不必将getValue()强制转换为B。(假设getValue()的返回类型为T而不是Object)。 (2认同)