Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用guava对内存中的列表/地图进行过滤/查询_Java_Collections_Guava - Fatal编程技术网

Java 如何使用guava对内存中的列表/地图进行过滤/查询

Java 如何使用guava对内存中的列表/地图进行过滤/查询,java,collections,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;

我有复杂的物体

    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;
    }
班级人员{
整数id;
字符串fname;
字符串名称;
//……还有更多的属性
列出地址;
}
班级地址{
弦街1号;
弦街2号;
字符串城市;
字符串状态;
拉链;
}
我有大约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”的对象
简而言之,两个对象的不同组合存在多个场景。
请建议在这种情况下使用番石榴的最佳方法?

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

例如:

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
公共类PersonLastNameEqualsPredicate实现谓词{
私有字符串personName;
公共PersonNameEqualsPredicate(字符串personName){this.personName=personName;}
公共布尔应用(Person p){返回this.personName.equals(p.getLName());}
}
公共类PersonStreet1EqualsPredicate实现谓词{
私有字符串street1Name;
public PersonStreet1EqualsPredicate(字符串street1Name){this.street1Name=street1Name;}
公共布尔应用(个人p){
对于(地址a:p.getAddresses()){
if(street1Name.equals(a.getStreet1())返回true;
}
返回false;
}
}
//根据需要添加额外的谓词
每个场景项需要一个谓词。然后需要根据需要调整它们:

一,

Predicate peopleNamedZoik=新的PersonLastNamePredicate(“zoik”);
二,

谓词peopleNamedMarkandLivingXYZStreet=谓词和(新PersonLastNamePredicate(“smark”)、新PersonStreet1EqualPredicate(“xyz”);
三,

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

那么这仅仅是一个问题

一,

列出myLongPersonList=。。。;
Iterable zoikPeople=Iterables.filter(myLongPersonList,peopleNamedZoik);
二,

列出myLongPersonList=。。。;
Iterable zoikPeople=Iterables.filter(myLongPersonList,PeopleNamedMarkandLivingXYzStreet);

等等。

谢谢你的回答。只有一个问题,在应用谓词时,我不想每次应用谓词时都迭代到30K对象。有什么方法可以在第一次迭代时构建映射/索引,然后在处理它们时查询这些对象?类似于步骤1:构建索引或映射步骤2:myFilteredObjects=someListOrMap.get(场景定义)我对番石榴不太熟悉,所以可能会对它有很多期望:D,请随意纠正我。thax很多。过早优化?你确定你在乎吗?30000不是很多迭代,特别是如果他们已经在memory@rst:您得到了一个lazy iterable,因此在那一刻,实际上还没有迭代任何内容。然后您可以使用o使用临时集合来实际迭代和存储它们。最好使用guava的静态构造函数,如List.newArrayList(Iterable),因为它们支持获取iterables。为什么不构建复杂谓词?
Predicate<Person> peopleNamedZoik = new PersonLastNamePredicate("zoik");
Predicate<Person> peopleNamedSmarkAndLivingInXyzStreet = Predicates.and(new PersonLastNamePredicate("smark"), new PersonStreet1EqualsPredicate("xyz"));
List<Person> myLongPersonList = ...;
Iterable<Person> zoikPeople = Iterables.filter(myLongPersonList, peopleNamedZoik);
List<Person> myLongPersonList = ...;
Iterable<Person> zoikPeople = Iterables.filter(myLongPersonList, peopleNamedSmarkAndLivingInXyzStreet);