Java 内存中的对象搜索优化

Java 内存中的对象搜索优化,java,android,search,optimization,collections,Java,Android,Search,Optimization,Collections,我有一个MyObjects的数组列表。MyObjects类有10多个属性,但我只需要从4个属性中搜索。用户将按下一个按钮,并能够为属性1选择值。 假设用户将选择property1Value1、property1Value2和property1Value4,然后按下按钮并选择property2值:property2Value1、property2Value5、property2Value7等等。这些是过滤器1和过滤器2。 property2Value2、property2Value3和proper

我有一个
MyObjects
的数组列表。
MyObjects
类有10多个属性,但我只需要从4个属性中搜索。用户将按下一个按钮,并能够为
属性1
选择值。 假设用户将选择
property1Value1
property1Value2
property1Value4
,然后按下按钮并选择
property2
值:
property2Value1
property2Value5
、property2Value7等等。这些是过滤器1和过滤器2。
property2Value2
property2Value3
property2Value4
对用户不可见,因为用户已使用过滤器1过滤掉。就像在进入新的过滤屏幕之前进行搜索一样。 我需要将他在每个过滤器中选择的内容存储在某个地方,因为当他返回时,我必须向他显示所选的值

我认为使用图片更容易理解,因为在易趣上也实施了类似的操作:

开始时没有筛选器:用户可以选择每个属性的所有值:

用户为类型属性选择了“Tablet”。-搜索完成,某些属性值不再可见:

选择第二个过滤器值:

按(自动)搜索,我应该在SQL中执行以下操作:

SELECT * FROM MyObjects WHERE
( (property1  = property1Value1) || (property1  = property1Value2) || (property1  = property1Value4) )
AND
(  (property2 = property2Value1) ||  (property2 = property2Value5) )
因为我在内存中有这些对象,所以我认为创建sqlLite3数据库不是一个好主意,请写出来而不是选择。在iOS实现中,我做了非常复杂的缓存算法。缓存分隔的筛选器值。一堆辅助索引持有者(最少20个),因为对于每个过滤器,我需要做一些额外的工作,这里没有提到,数据只存储一次

我害怕把这个算法改写成Android,iOS上的算法一定很简单

编辑: 基本上,我需要在Java对象搜索中重写SQL搜索

Edit2: 基于多重映射的答案


Multimap
并不比
HashMap好,您所说的基本上是索引。与您所描述的类似的方法在Java中是完全可管理的,它只需要像在Objective C中一样仔细地编码

您没有详细说明一些问题,例如是否允许多个项在其字段中具有相同的值,因此我假定它们是。在这种情况下,我会这样开始:

  • 使用Guava's,可能是
    HashMultimap
    ,其中键是要索引的属性,每个被索引的对象都将
    放入该键下的映射中
  • 当您试图搜索多个字段时,请调用
    multimap.get(property)
    以获取与该属性匹配的所有对象的
    集合
    ,并仅保留与所有属性匹配的对象:

    Set<Item> items = new Set<Items>(typeMultimap.get("tablet"));
    items.retainAll(productLineMultimap.get("Galaxy Tab"));
    // your results are now in "items"
    
    Set items=新设置(typeMultimap.get(“tablet”);
    items.retainal(productLineMultimap.get(“Galaxy选项卡”);
    //您的结果现在位于“项目”中
    
  • 如果属性列表稳定,请编写一个包装器
    索引器
    类,该类具有所有
    多映射
    的字段,并确保将对象插入到所有属性索引中或从所有属性索引中移除,并且可能为映射获取程序提供方便的包装器

它是如何执行后台SQL的MYSQL的在MyISAM表中有一个文件,其中有数据,在其他文件中有id位置

从mytable中选择*将把所有ID放入结果集中,因为没有筛选器。 因为是*将所有字段复制到id。这等同于:

ArrayList<MyObject> result = new ArrayList<MyObject>();
for(int i=0; i < listMyObjects.size(); i++){
    if(true == true){// SELECT * FROM has a hidden WHERE 1, which is always true
      result.add(listMyObjects.get(i));
    }
}

不确定这是否慢了很多,但我至少已经从第十个/一百个辅助集合、索引中逃脱了。在此之后,我将制作所需的额外内容并完成

+1谢谢,我将检查以前从未使用过的Multimap。将问题编辑得更清楚:我需要重写SQL以在集合中搜索。ebay如何处理SQLMap?您认为我的解决方案如何?如果您已经将对象保留在内存中,则使用
多重映射
比使用ID字段映射更好;您没有包装器类开销,不必手动查找对象,并且可以直接执行
收集
操作。
Multimap
几乎完全等同于
Map
,有一些额外的方便方法。这看起来像是为了获得未经证实的性能优势而进行的大量易出错的工作。我建议尝试一种简单得多的过滤机制,如果你能准确地指出经济放缓的具体位置,那么只需手动尝试。
ArrayList<String> filterByProperty1 = new ArrayList<String> ();
    ArrayList<MyObject> result = new ArrayList<MyObject>();
    for(int i=0; i < listMyObjects.size(); i++){
          MyObject curMyObject = listMyObjects.get(i);
          // lets see if bypass the filter, if filter exists  
          boolean property1Allow = false;
          boolean property2Allow = false;
          if(filterByProperty1.size() > 0){
              String theCurProperty1Value = curMyObject.getProperty1();
               if(filterByProperty1.contains(theCurPropertyValue)){
                   property1Allow = true;
               }
           }
           else{// no filter by property1: allowed to add to result
               property1Allow = true;
           }

          // do the same with property2,3,4, lazzy to write it

           if(property1Allow && property2Allow){
              result.add(theCurPropertyValue);
           }
        }
    }