简体   繁体   English

JAVA 8将谓词提取为字段或方法?

[英]JAVA 8 Extract predicates as fields or methods?

What is the cleaner way of extracting predicates which will have multiple uses. 提取具有多种用途的谓词的更干净方法是什么? Methods or Class fields? 方法或类字段?

The two examples: 这两个例子:

1.Class Field 1.班级领域

void someMethod() {
    IntStream.range(1, 100)
        .filter(isOverFifty)
        .forEach(System.out::println);
}

private IntPredicate isOverFifty = number -> number > 50;

2.Method 2.方法

void someMethod() {
    IntStream.range(1, 100)
        .filter(isOverFifty())
        .forEach(System.out::println);
} 

private IntPredicate isOverFifty() {
    return number -> number > 50;
}

For me, the field way looks a little bit nicer, but is this the right way? 对我来说,野外工作的方法看起来更好一些,但这是正确的方法吗? I have my doubts. 我有疑问

Generally you cache things that are expensive to create and these stateless lambdas are not . 通常,您缓存创建起来很昂贵的东西,而这些无状态lambda则不是 A stateless lambda will have a single instance created for the entire pipeline (under the current implementation). 无状态Lambda将为整个管道(在当前实现下)创建一个实例。 The first invocation is the most expensive one - the underlying Predicate implementation class will be created and linked; 第一次调用是最昂贵的调用-将创建并链接基础Predicate实现类; but this happens only once for both stateless and stateful lambdas. 但这对于无状态和有状态的lambda只会发生一次。

A stateful lambda will use a different instance for each element and it might make sense to cache those, but your example is stateless, so I would not. 有状态的lambda将为每个元素使用不同的实例,缓存它们可能是有意义的,但是您的示例是无状态的,所以我不会。

If you still want that (for reading purposes I assume), I would do it in a class Predicates let's assume. 如果您仍然希望这样做(出于阅读目的,我假设),我将在一个Predicates类中进行假设。 It would be re-usable across different classes as well, something like this: 它也可以在不同的类之间重用,如下所示:

 public final class Predicates {
     private Predicates(){
     }

     public static IntPredicate isOverFifty() {
          return number -> number > 50;
     }
 } 

You should also notice that the usage of Predicates.isOverFifty inside a Stream and x -> x > 50 while semantically the same, will have different memory usages. 您还应该注意,Stream内部的Predicates.isOverFifty用法和x -> x > 50在语义上相同时,将具有不同的内存用法。

In the first case, only a single instance (and class) will be created and served to all clients; 在第一种情况下,将只创建一个实例(和类)并将其提供给所有客户端。 while the second ( x -> x > 50 ) will create not only a different instance, but also a different class for each of it's clients (think the same expression used in different places inside your application). 而第二个( x -> x > 50 )将不仅为其每个客户端创建一个不同的实例,而且为其创建一个不同的类(请考虑在应用程序内部不同位置使用相同的表达式)。 This happens because the linkage happens per CallSite - and in the second case the CallSite is always different. 发生这种情况是因为每个CallSite发生了链接-在第二种情况下, CallSite总是不同的。

But that is something you should not rely on (and probably even consider) - these Objects and classes are fast to build and fast to remove by the GC - whatever fits your needs - use that. 但这是您不应该依赖(甚至可能考虑)的东西-这些对象和类可以快速构建并可以通过GC快速删除-可以满足您的需要-使用它。

To answer, it's better If you expand those lambda expressions for old fashioned Java. 要回答,最好是为老式Java扩展这些lambda表达式。 You can see now, these are two ways we used in our codes. 现在您可以看到,这是我们在代码中使用的两种方式。 So, the answer is, it all depends how you write a particular code segment. 因此,答案是,这完全取决于您如何编写特定的代码段。

private IntPredicate isOverFifty = new IntPredicate<Integer>(){

 public void test(number){
  return number > 50;
 }

};


private IntPredicate isOverFifty() {
    return new IntPredicate<Integer>(){

          public void test(number){
             return number > 50;
          }

   };
}

1) For field case you will have always allocated predicate for each new your object. 1)对于现场情况,您将始终为每个新对象分配谓词。 Not a big deal if you have a few instances, likes, service. 如果您有一些实例(如赞)服务,那没什么大不了的。 But if this is a value object which can be N, this is not good solution. 但是,如果这是一个可以为N的值对象,则不是很好的解决方案。 Also keep in mind that someMethod() may not be called at all. 另外请记住,根本不会调用someMethod() One of possible solution is to make predicate as static field. 一种可能的解决方案是将谓词设为static字段。

2) For method case you will create the predicate once every time for someMethod() call. 2)对于方法案例,每次调用someMethod()时都会创建一次谓词。 After GC will discard it. GC之后将其丢弃。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM