java - 如何使用 Guava 对内存列表/映射进行过滤/查询

标签 java collections guava

我有复杂的对象

    class Person{
        Integer id;
        String fname;
        String lname;
        //..... there are more attributes
        List<Address> addresses;
    }
    class Address{
        String street1;
        String street2;
        String city;
        String state;
        String zip;
    }

我有大约 30000 个 Person 对象,每个对象至少有 200-500 个子对象(地址)。现在我拥有所有这些内存,并且有不同的场景(20-30 个场景),我必须根据场景中可用的过滤器查询/过滤对象。例如。

  • scen1 -> 获取所有具有 lname = 'zoik' 的对象
  • scen2 -> 获取所有具有 lname = 'smark' 且 address.street1 = "xyz"的对象
  • scen3 -> 获取所有具有 lname = 'smark' 和 address.street1 = "xyz"和 address.street1 = "pqr"的对象(记住每个对象都有多个地址,所以我需要具有满足上述条件的两个地址的对象) .)
  • scen4 -> 获取所有具有 fname= "smith"且 lname = 'smark' 且 address.city="Los Angeles"的对象
  • ......

简而言之,两个对象的不同组合存在多种场景。 请建议在这种情况下使用 Guava 的最佳方法?

最佳答案

您应该将 Iterables.filter(Iterable, Predicate)Predicate 结合使用。

示例:

public class PersonLastNameEqualsPredicate implements Predicate<Person> {
  private String personName;
  public PersonNameEqualsPredicate (String personName) {this.personName= personName;}
  public boolean apply(Person p) { return this.personName.equals(p.getLName()); }
}

public class PersonStreet1EqualsPredicate implements Predicate<Person> {
  private String street1Name;
  public PersonStreet1EqualsPredicate (String street1Name) {this.street1Name = street1Name;}
  public boolean apply(Person p) {
    for (Address a: p.getAddresses()) {
      if (street1Name.equals(a.getStreet1()) return true;
    }
    return false;
  }
}

// Extra predicates as you need them

每个场景项需要一个谓词。然后您需要根据需要对其进行调制:

1.

Predicate<Person> peopleNamedZoik = new PersonLastNamePredicate("zoik");

2.

Predicate<Person> peopleNamedSmarkAndLivingInXyzStreet = Predicates.and(new PersonLastNamePredicate("smark"), new PersonStreet1EqualsPredicate("xyz"));

3.

在这里,您应该调整您的街道谓词,以立即检查所有街道名称是否包含您的所有期望。

那么这只是一个问题

1.

List<Person> myLongPersonList = ...;
Iterable<Person> zoikPeople = Iterables.filter(myLongPersonList, peopleNamedZoik);

2.

List<Person> myLongPersonList = ...;
Iterable<Person> zoikPeople = Iterables.filter(myLongPersonList, peopleNamedSmarkAndLivingInXyzStreet);

等等。

关于java - 如何使用 Guava 对内存列表/映射进行过滤/查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9520073/

相关文章:

java - 为什么显示 "Error: Could not find or load main class addstudent.AddStudent"

java - Map内部如何输入重复的key?

java - 在任何标准库中是否有帮助程序类实现对 boolean 集合的逻辑操作?

java - 如何根据谓词有效地将对象从一个 Java 集合传输到另一个集合?

java - 如何配置 Guava 缓存以在读取后删除项目?

java - 根据 id 返回列表的元素

java - Iterables.partition() 生成的 Spliterator 没有按预期运行?

java - 将文件输入添加到树形图

java - 当前线程的范围 'request' 不活动 - websocket 版本

java - `copy(List<? super T> dest, List<? extends T> src) ` 和 `copy(List<T> dest, List<? extends T> src)` 之间的差异