Mar*_*gro 4 java predicate guava
最近,我一直在使用谓词和番石榴实用程序.我创建了一个Utils.class,我存储了一些我在代码的不同部分使用的谓词.因此,这个问题已经出现,我们(我和我的同事)没有就此达成一致.
将谓词放在实用程序类中的正确方法或"良好实践方式"是什么?作为用大写字母或静态方法定义它的常量?接下来,我写一个例子:
public final class Utils {
public static final Predicate<Element> IS_SPECIAL = new Predicate<Element>() {
@Override
public boolean apply(Element elem) {
return elem.special;
}
};
public static Predicate<Element> isSpecial() {
return new Predicate<Element>() {
@Override
public boolean apply(Element elem) {
return elem.special;
}}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,番石榴提供了一些预测谓词,它提供了一个返回谓词的方法,但其他的libreries也提供它们作为常量.
有两种观点:API和实现.
关于API,使用方法,解决的办法是多比别人更灵活.它允许在不关心代码的情况下更改实现,这意味着您的代码不会受到隐藏在方法后面的任何更改的影响.
关于实现,人们通常使用枚举.枚举优于常数的优点很多:
new Predicate<Element>每几行.然而,这些枚举的性质使得在编译的类中不可能具有相同的内容.所以在这里,它在源代码级别上纯粹更好.当然,这就是你想要的,因为你实际上是在编写源代码.这是我将如何做的一个例子.(是的,我甚Utils至会Elements根据最近的Java默认惯例重命名).
public final class Elements {
private static enum ElementPredicate implements Predicate<Element> {
SPECIAL {
@Override public boolean apply(Element e) { return e.special; }
}
}
public static Predicate<Element> isSpecial() {
return ElementPredicate.SPECIAL;
}
private Elements() {}
}
Run Code Online (Sandbox Code Playgroud)
最后,请注意,如果你使用Java 8,你应该坚持使用lambda机制,就像Louis Wasserman在问题评论中提到的那样.但是由于lambas在你的例子中不可用,因为你不是从方法中直接检索特殊而是直接从字段中检索特殊的,所以不幸的是,这个建议是无效的.但是,如果您有isSpecial()方法Element,则可以直接在代码中编写谓词,如下所示:
Stream<T> stream = ... ;
stream
.filter(Element::isSpecial)
Run Code Online (Sandbox Code Playgroud)
我可能会这样做...
public final class Utils {
private static final Predicate<Element> IS_SPECIAL = new Predicate<Element>() {
@Override
public boolean apply(Element elem) {
return elem.special;
}
};
public static Predicate<Element> isSpecial() {
return IS_SPECIAL;
}
}
Run Code Online (Sandbox Code Playgroud)
这样您就可以将其称为方法,但不会每次都实例化谓词...
正如其他答案所指出的,两种解决方案之间存在差异:静态常量实例化单个对象,但此对象永远不会被垃圾收集,而该方法每次调用时都会实例化一个新对象.但是,性能上的差异可以忽略不计:谓词的内存占用量非常小,而垃圾收集器擅长收集短期对象.
由于灵活性,我仍然会选择方法解决方案:如果需要,您可以重构方法以返回(私有)静态变量而不会破坏任何旧代码.但是公共静态变量保持公共静态变量.
| 归档时间: |
|
| 查看次数: |
1890 次 |
| 最近记录: |