0

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

我认为用图片更容易理解,因为在 ebay 上实现了类似的功能:

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

用户选择“平板电脑”作为类型属性。- 搜索完成,一些属性值不再可见:

药片

选择第二个过滤器值:

标签类型

按(自动)搜索我应该在 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 的回答。

Multimap并不比 a 好HashMap<String, <ArrarList<Integer>> ,其中键是属性 ( property2Value3) 的值,而值是 my ArrayList<MyObjects>(1,2,3,4,5...100)的索引列表

需要在每个过滤器上建立,每个过滤器值HashMap<String, <ArrarList<Integer>>都比我所在的位置要好,iOS...可能少了一些辅助集合。

任何想法?

4

2 回答 2

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包含所有 s 字段的包装类,Multimap并确保将对象插入到所有属性索引中并从所有属性索引中删除,并且可能具有用于映射 getter 的便利包装器。
于 2013-10-27T02:36:16.153 回答
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);
           }
        }
    }

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

于 2013-10-27T03:27:50.457 回答