JDK库是否提供了lambda'invoker'实用程序类?

时间:2015-10-31 14:36:00

标签: java lambda java-8 static-initializer

我希望用lambdas替换对独立的独立静态初始化函数的需求。例如我想替换像这样的东西......

class Foo {
    private static final Set<String> keywords = keywords();

    private static Set<String> keywords() {
        HashSet<String> s = new HashSet<>();
        s.add("AND");
        s.add("NOT");
        s.add("OR");
        return Collections.unmodifiableSet(s);
    }
}

用于调用在类加载时定义的lambda的东西。请注意,我的目标不是懒洋洋地调用它。

目前,我已经使用静态方法创建了一个简单的Initializer类,该方法接受Supplier,调用它并返回值。

Initializer上课

public class Initializer {
    public static <T> T init(Supplier<T> initializer) {
        return initializer.get();
    }    
}

然后在另一个班级:

import static com.whatever.Initializer.init;

class Foo {
    private static final Set<String> keywords = init(() -> {
        HashSet<String> s = new HashSet<>();
        s.add("AND");
        s.add("NOT");
        s.add("OR");
        return Collections.unmodifiableSet(s);
    });
}

标准Java库中是否存在某些东西,以便我不需要提供自己的Initializer类,或者是否有某种方法可以简单地定义然后就地执行lambda?

3 个答案:

答案 0 :(得分:2)

你可以直接施放lambda并调用它:

private static final Set<String> KEYWORDS = ((Supplier<Set<String>>) () -> {
    Set<String> result = new HashSet<>();
    ...
    return Collections.unmodifiableSet(result);
}).get();

或者您可以使用现有的快捷方式:

private static final Set<String> KEYWORDS = 
    Collections.unmodifiableSet(new HashSet<>(Arrays.asList("AND", "NOT", "OR")));

但是,调用方法的原始代码非常易读。我不会改变它。

答案 1 :(得分:2)

我会编写一个特殊的实用方法来完成整个链:

public class Sets {
    public static <T> Set<T> of(T... elements) {
        return Collections.unmodifiableSet(new HashSet<>(Arrays.asList(elements)));
    }
}

并在必要时使用它:

private static final Set<String> KEYWORDS = Sets.of("AND", "NOT", "OR");

如果您碰巧使用番石榴,那么已经有bunch of such methods。希望这样的功能将出现在Java-9中。有JEP 269可以写Set.of("AND", "NOT", "OR")

答案 2 :(得分:1)

正如@zeroflagL所提到的,你不需要在这个地方使用lambdas。您可以使用以下命令在一行中初始化keywords

Collections.unmodifiableSet(new HashSet<String>(Arrays.asList("AND", "NOT", "OR")));

但这不是那么漂亮。否则,使用static块有什么问题?它是为这些东西而创建的。

但如果您不想使用它,我认为没有标准方法。你必须使用你的初始化器。