gpt4 book ai didi

java - Java 8 中字段名称的硬链接(hard link)

转载 作者:行者123 更新时间:2023-12-01 12:10:48 25 4
gpt4 key购买 nike

例如我有一些实体 - 产品

 public class Product {
...
private String name;
private int count;
private Product associatedProduct;
...
// GETTERS & SETTERS

}

我还有产品查找器,可以通过过滤器查找产品:

 public interface Finder<T> {

Set<T> find(Filter... filters);

}

现在我可以执行以下代码:

      Finder<Product> finder = ...;
// find all products with name 'cucumber'
Set<Product> finder.find(Filter.equals("name", "cucumber"));

我们不喜欢这段代码,因为我应该有指向字段名称“name”的“软”链接,并且我不能在打印错误或任何其他错误的情况下出现编译时异常。

出于这个原因,我创建了代码生成器,它生成属性的静态链接。

生成的类如下所示:

      public final class $Product {
private final String context;
// some factory is used to instance creation
$PostEntity() {this.context = "";}
$PostEntity(String context) {this.context = context;}
public String name() { return context + "name";}
public String count() { return context + "count";}
public String associatedProduct() { return context + "associatedProduct";}
public $Product associatedProductDot() { return new $Product( this.context + "associatedProduct.");}

}

现在我可以做以下事情:

      Set<Product> finder.find(Filter.equals(Links.PRODUCT.name() , "cucumber"));
//or
Set<Product> finder.find(Filter.equals(Links.PRODUCT.associatedProductDot().name() , "cucumber"));

它就像一种魅力,我很高兴。

我知道使用代理对象的替代方法,但它在运行时增加了额外的开销,并在代码中添加了一些神奇的时刻,所以这个变体不适合我。

最后是我的问题:

有更优雅的方法使用 java 8 来实现此功能吗?

最佳答案

Java 8 拥有您需要的一切:

public static <C,P> Predicate<C> byProperty(Function<C,P> f, P value) {
return component->Objects.equals(f.apply(component), value);
}
public static <C> Set<C> find(Collection<? extends C> c, Predicate<? super C> p) {
return c.stream().filter(p).collect(Collectors.<C>toSet());
}

标准interface用于过滤的名称为 Predicate 上面的第一个方法允许您创建任意 Predicate s 用于匹配组件类型的属性 C 。第二种方法展示了如何获得 Set Collection 中的匹配组件使用 Stream API。然后你可以像这样使用它:

List<Product> list;

Set<Product> set=find(list, byProperty(Product::getName, "foo"));

Set<Product> set=find(list, byProperty(Product::getCount, 42));

请注意,这是类型安全的并且包含 compile-time checked references (your “hard links”)到您的属性(property)。与您所要求的唯一区别是它们引用 getter 方法而不是字段名称,因为 a) 不支持字段引用,b) 您的字段是 private无论如何。

<小时/>

请注意,您可以通过另一个工厂来增强这些方法,从而提供值谓词而不是常量:

public static <C,P> Predicate<C> matchProp(
Function<C,P> f, Predicate<? super P> value) {
return component->value.test(f.apply(component));
}

这允许使用以下用例:

    Set<Product> set=find(list, matchProp(Product::getCount, count -> count>100));

           参见 Lambda Expressions

    Set<Product> set=find(list, matchProp(Product::getName, String::isEmpty));

关于java - Java 8 中字段名称的硬链接(hard link),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27300245/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com