2

我正在寻找用 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带有静态方法的简单类,该方法接受 a 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?

4

3 回答 3

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");

如果你碰巧使用 Guava,那么已经有一堆这样的方法了。希望这样的特性会出现在 Java-9 中。有JEP 269允许编写Set.of("AND", "NOT", "OR").

于 2015-10-31T15:38:43.770 回答
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")));

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

于 2015-10-31T14:46:36.523 回答
1

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

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

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

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

于 2015-10-31T14:46:46.177 回答