具有任何匹配属性的对象的JAVA 8筛选器列表



我的要求是通过匹配任何属性的字符串来过滤对象列表。例如,假设Contact类有三个属性:街道、城市、电话。

我知道java流过滤器是如何工作的,我必须将输入字符串与每个属性进行比较,如下所示:

contactList.stream().filter(contact -> contact.getStreet().equals("dubai") || 
contact.getCity().equals("dubai") || .......).collect(Collectors.toList());

但是,如果一个类有20多个属性,并且列表大小为80000以上,则将每个属性与输入字符串进行比较会影响性能。所以我的问题是,Java或任何其他库是否支持用任何匹配的属性过滤列表?如下所示:

contactList.stream().filter(contact -> contact.anyProperty.equals("dubai").collect(Collectors.toList());

有人能帮我吗,谢谢。

您可以使用findAny。一旦找到候选人,这将立即结束:

Optional<Contact> contact = contactList.stream().filter(contact -> contact.getStreet().equals("dubai") || 
contact.getCity().equals("dubai") || .......).findAny();

或者,如果您只需要一个信息(如果存在这样的对象(,请使用anyMatch:

boolean exists = contactList.stream().anyMatch(contact -> contact.getStreet().equals("dubai") || 
contact.getCity().equals("dubai") || .......);

您可以通过使用反射读取所有类属性来解决此问题

通过重写toString((方法并检查toString的结果是否包含输入字符串

一种可能的方法是用所需的属性覆盖toString(),并使用它来检查它是否包含单词

contactList.stream()
.filter(contact -> contact.toString().contains("dubai"))
.collect(Collectors.toList());

您可能还想使用Pattern来匹配确切的单词。

我有一个使用Gson和JSON的项目,当我读到你的问题时,我首先想到的是:

  1. 将您的列表转换为JsonObject的JsonArray=>您可以轻松获得每个JsonObject(联系人对象的属性列表(的密钥集
  2. 在该列表中筛选,找到所有值为"dubai"的JsonObject

我想,阻止您的问题的代码已经解决了。

contactList.stream().anyMatch(contact -> contactMacther(contact,"dubai"));
private boolean contactMacther(Contact contact, String match){
return contact.getStreet().equalsIgnoreCase(match) ||
contact.getCity().equalsIgnoreCase(match);

您可以创建提取属性的函数列表,而不是在您的过滤方法中使用它:

List<Function<Contact, Object>> getPrperties = Arrays.asList(
Contact::getStreet, 
Contact::getCity
// other
);
contactList.stream()
.filter(contact -> getPrperties.stream()
.map(f -> f.apply(contact))
.anyMatch("dubai"::equals)
)
.collect(Collectors.toList();

或者你可以提取测试方法:

BiFunction<Contact, String, Boolean> test = (contact, values) ->
getPrperties.stream().map(f -> f.apply(contact)).anyMatch(values::equals);
List<Person> collect = contactList.stream()
.filter(contact -> test.apply(contact, "dubai"))
.collect(Collectors.toList());

最新更新