内存中的对象搜索优化

时间:2013-10-27 02:19:45

标签: java android search optimization collections

我有一个MyObjects的ArrayList。 MyObjects类有10个以上的属性,但我只需要搜索4个属性。用户将按下按钮,并可以选择property1的值。 假设用户将选择property1Value1property1Value2property1Value4,而不是按下按钮,将选择property2值:property2Value1,{ {1}},property2Value7等。那些是filter1和filter2。 用户无法看到property2Value5property2Value2property2Value3,因为他已使用filter1过滤掉了。就像在进入新的过滤器屏幕之前进行搜索一样。 我需要存储他在每个过滤器中选择的内容,因为当他向后导航时,我必须向他显示所选的值。

我觉得用图片更容易理解,因为在ebay上实现类似:

开头没有过滤器:用户可以为每个属性选择所有值: no filters

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

tablet

选择第二个过滤器值:

tabtype

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

property2Value4

因为我在内存中有对象,所以我认为创建一个sqlLite3数据库不是一个好主意,写出比select。在iOS实现中,我做了非常复杂的缓存算法。缓存过滤器值分开。一个辅助索引持有者的loooooot(最小20),因为对于每个过滤器我需要一些额外的工作,这里没有提到,只存储了一次数据。

我害怕将该算法重写为Android,iOS上的内容必须简单易懂。

修改: 基本上我需要在Java对象搜索中重写SQL搜索。

EDIT2 : 根据Multimap的答案。

SELECT * FROM MyObjects WHERE ( (property1 = property1Value1) || (property1 = property1Value2) || (property1 = property1Value4) ) AND ( (property2 = property2Value1) || (property2 = property2Value5) ) 并不比Multimap好 其中键是property(HashMap<String, <ArrarList<Integer>>)的值,值是我property2Value3的索引列表(1,2,3,4,5 ... 100)

需要在每个过滤器上建立,每个过滤器值都为ArrayList<MyObjects>,而不是我在哪里,iOS ...可能只有少量辅助集合。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

你所谈论的基本上是索引。与您描述的类似的方法在Java中是完全可管理的,它只需要在Objective C中进行相同的仔细编码。

你没有详细说明是否允许多个项目在其字段中具有相同的值,所以我认为它们是。在这种情况下,我就是这样开始的:

  • 使用Guava的Multimap,可能是HashMultimap,其中键是索引属性,每个被索引的对象都会put进入该键下的地图。
  • 当您尝试搜索多个字段时,请调用multimap.get(property)以获取与该属性匹配的所有对象中的Collection,并仅保留与所有属性匹配的对象:

    Set<Item> items = new Set<Items>(typeMultimap.get("tablet"));
    items.retainAll(productLineMultimap.get("Galaxy Tab"));
    // your results are now in "items"
    
  • 如果您的属性列表是稳定的,请编写一个包含所有Indexer字段的包装器Multimap,并确保将对象插入到所有属性索引中并从中删除,并且可能有地图吸气剂的便利包装。

答案 1 :(得分:0)

如何执行场景背后的SQL的MYSQL? - 在MyISAM表中有一个文件,他有数据,在其他文件中有id位置。

SELECT * FROM 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));
    }
}

如果是过滤器,则应该有一个过滤器列表:

ArrayList<String> filterByProperty1 = new ArrayList<String> ();

在过滤器界面我会添加一些字符串property1Value1property1Value2 ....搜索算法将是:

    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);
           }
        }
    }

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

相关问题