как сделать фильтр / запрос по списку / карте в памяти, используя гуаву - PullRequest
2 голосов
/ 01 марта 2012

У меня есть сложные объекты

    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 лиц объектов, и у каждого есть как минимум 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"
  • .....

Короче говоря, существует несколько сценариев с различной комбинацией обоих объектов.Посоветуйте, пожалуйста, лучший способ использования гуавы для такого случая?

1 Ответ

3 голосов
/ 01 марта 2012

Вы должны использовать 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);

и т. Д.

...