我需要将数据存储在内存中,我将一个或多个键字符串映射到对象,如下所示:
"green", "blue" -> object1
"red", "yellow" -> object2
因此,在Java中,数据结构可能会实现:
Map<Set<String>, V>
我需要能够有效地接收对象列表,其中字符串匹配一些布尔标准,例如:
("red" OR "green") AND NOT "blue"
我在Java工作,所以理想的解决方案是现成的Java库。但是,如果有必要,我愿意从头开始实施。
有人有什么想法吗?如果可能的话,我宁愿避免使用内存数据库的开销,我希望能有一些与HashMap相当的速度(或至少相同的数量级)。
答案 0 :(得分:6)
实际上,我喜欢这个问题,所以我按照我之前的答案精神实施了一个完整的解决方案:
一个简单的解决方案,不是线程安全或任何东西,但我觉得很有趣,也是一个很好的起点。
编辑:根据要求进行一些详细说明
请参阅单元测试以了解使用情况。
有两个界面DataStructure<K,V>
和Query<V>
。 DataStructure的行为有点像地图(在我的实现中它实际上与内部映射一起工作),但它也提供了可重用和不可变的查询对象,可以像这样组合:
Query<String> combinedQuery =
structure.and(
structure.or(
structure.search("blue"),
structure.search("red")
),
structure.not(
structure.search("green")
)
);
(查询标记为(蓝色或红色)和非绿色的对象的查询)。此查询是可重复使用的,这意味着只要更改了支持映射,它的结果就会发生变化(类似于ITunes智能播放列表)。
查询对象已经是线程安全的,但支持映射不是,因此这里有一些改进空间。此外,查询可以缓存它们的结果,但这可能意味着必须扩展接口以提供清除方法(有点像Wicket模型中的分离方法),这不会很漂亮。
至于许可:如果有人想要这个代码,我会很乐意把它放在SourceForge等......
肖恩
答案 1 :(得分:1)
标准是否适合位图索引:http://en.wikipedia.org/wiki/Bitmap_index?
答案 2 :(得分:0)
我想说最简单的方法就是简单地做一个递归过滤和切割器,例如评估X AND Y
,其中X
被评估为空集。
然而,映射需要从标记(例如“红色”或“蓝色”)到对象集。
递归的基本情况(解析原子标记)将是此映射中的简单查找。 AND
将使用intersection,OR
使用union实现,等等。
答案 3 :(得分:0)
查看Apache Commons - Collections project。他们有很多很棒的东西你可以使用,特别是CollectionUtils类来执行强大的基于集合的逻辑。
例如,如果您的值存储在HashMap中(如另一个答案所示),如下所示:
myMap["green"] -> obj1
myMap["blue"] -> obj1
myMap["red"] -> obj2
myMap["yellow"] -> obj2
然后检索匹配的结果:("red" or "green") and not "blue
您可能会这样做:
CollectionUtils.disjunction(CollectionUtils.union(myMap.get(“red”),myMap.get(“green”)),myMap.get(“blue”))
答案 4 :(得分:0)
您可以将字符串键映射到二进制常量,然后使用位移来生成适当的掩码。
答案 5 :(得分:0)
我真的认为某种类型的数据库解决方案是您最好的选择。 SQL轻松支持通过
查询数据(X and Y) and not Z
答案 6 :(得分:0)
答案 7 :(得分:0)
Google Collections SetMultimap看起来像是获取底层结构的简单方法,然后将其与Maps静态过滤器结合使用,以获得所需的查询行为。
施工会像
那样smmInstance.put(from1,to1);
smmInstance.put(from1,to2);
smmInstance.put(from2,to3);
smmInstance.put(from3,to1);
smmInstance.put(from1,to3);
//...
查询看起来像
valueFilter = //...build predicate
Set<FromType> result = Maps.filterValues(smmInstance.asMap(),valueFilter).keySet()
你可以做任何花哨的构建谓词,但是Predicates有一些方法可能足以包含/不包含样式查询。
答案 8 :(得分:0)
我无法找到满意的解决方案,因此我决定自己制作并将其作为开源(LGPL)项目发布,找到它here。