Java 支持布尔查询的内存中数据结构

Java 支持布尔查询的内存中数据结构,java,data-structures,boolean-logic,Java,Data Structures,Boolean Logic,我需要将数据存储在内存中,将一个或多个键字符串映射到一个对象,如下所示: "green", "blue" -> object1 "red", "yellow" -> object2 myMap["green"] -> obj1 myMap["blue"] -> obj1 myMap["red"] -> obj2 myMap["yellow"] -> obj2 因此,在Java中,数据结构可能实现: Map<Set<String>, V&g

我需要将数据存储在内存中,将一个或多个键字符串映射到一个对象,如下所示:

"green", "blue" -> object1
"red", "yellow" -> object2
myMap["green"] -> obj1
myMap["blue"] -> obj1
myMap["red"] -> obj2
myMap["yellow"] -> obj2
因此,在Java中,数据结构可能实现:

Map<Set<String>, V>
我在Java中工作,所以理想的解决方案是一个现成的Java库。然而,如果必要的话,我愿意从头开始实施


有人有什么想法吗?如果可能的话,我宁愿避免内存中数据库的开销,我希望在速度上可以与HashMap相媲美(或者至少达到相同的数量级)。

我想说,最简单的方法就是简单地进行递归过滤和切分,例如,当计算
X和Y
时,其中
X
已计算为空集

但是,映射需要从标记(如“红色”或“蓝色”)到对象集


递归的基本情况(解析原子标记)是在此映射中进行简单的查找<代码>和将使用交集、使用联合等实现。

标准是否符合位图索引:?

查看。它们有很多很棒的东西,您可以使用它们,特别是用于执行强大的基于集合的逻辑的类

例如,如果您的值存储在HashMap中(如另一个答案所示),如下所示:

"green", "blue" -> object1
"red", "yellow" -> object2
myMap["green"] -> obj1
myMap["blue"] -> obj1
myMap["red"] -> obj2
myMap["yellow"] -> obj2
然后要检索匹配的结果:
(“红色”或“绿色”)而不是“蓝色”
,可以执行以下操作:

析取(CollectionUtils.union(myMap.get(“红色”)、myMap.get(“绿色”)、myMap.get(“蓝色”))


事实上,我喜欢这个问题,因此我按照我先前回答的精神实施了一个完整的解决方案:

这是一个简单的解决方案,不是线程安全的,而是一个有趣的好起点,我想

编辑:根据要求进行一些细化


有关用法,请参阅单元测试

有两个接口,
DataStructure
Query
。DataStructure的行为有点像一个映射(在我的实现中,它实际上与一个内部映射一起工作),但它也提供了可重用和不可变的查询对象,可以像这样组合:

    Query<String> combinedQuery = 
    structure.and(
                    structure.or(
                            structure.search("blue"), 
                            structure.search("red")
                    ),
                    structure.not(
                            structure.search("green")
                    )
    );
查询组合查询=
结构。及(
结构或(
结构。搜索(“蓝色”),
结构。搜索(“红色”)
),
结构。不是(
结构。搜索(“绿色”)
)
);
(搜索标记为(蓝色或红色)而非绿色的对象的查询)。此查询是可重用的,这意味着只要背景地图发生更改,其结果就会更改(有点像ITunes智能播放列表)

查询对象已经是线程安全的,但备份映射不是,因此这里有一些改进的空间。此外,查询可以缓存其结果,但这可能意味着必须扩展接口以提供清除方法(有点像Wicket模型中的分离方法),这不会很好

至于许可:如果有人想要这个代码,我很乐意把它放在SourceForge上等等


Sean

您可以将字符串键映射到二进制常量,然后使用位移位生成适当的掩码。

我确实认为某种类型的数据库解决方案是您的最佳选择。SQL轻松支持通过

(X and Y) and not Z

这也很有效

Google Collections看起来是一种获取底层结构的简单方法,然后将其与静态过滤器相结合以获得所需的查询行为

建筑业会像这样发展

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()
valueFilter=/…生成谓词
Set result=Maps.filterValues(smminInstance.asMap(),valueFilter).keySet()

你可以做任何复杂的构建谓词的工作,但是有一些方法可能足以完成包含/不包含样式的查询。

我没有找到满意的解决方案,所以我决定编写自己的解决方案,并将其作为开源(LGPL)项目发布,找到它。

在你的示例中,“green”是吗“映射到object1?或者只是“绿色”和“蓝色”映射到object1?“绿色”和“蓝色”类似于object1上的“标记”-然后您可以通过对这些标记的布尔查询来选择对象。“绿色”也可以映射到一些
object3
?我认为这还不够,因为它只允许一个绿色对象,一个蓝色对象等。只是快速(非功能性!)CollectionUtils中一些工具和实用程序的示例。我现在正在玩它,很快就会回答-有趣的问题!有趣的是,我并没有看到一个更早的答案——你能详细介绍一下它的基本原理吗?你会考虑把你的代码放在开源许可证(例如LGPL)上吗?我删除了我之前的答案,抱歉。我会在回答中详细说明。一些想法:它似乎创建了很多中间数组列表——我想知道如果没有这些,它是否可以完成(可能返回一个懒惰的Iterable而不是集合)。缓存中间结果将非常有趣。我还想知道一些启发式方法,用于确定应该以何种方式处理参数以获得最大效率。您所看到的只是一个概念证明,30分钟的编码时间。但我已经在谷歌代码()上创建了一个项目,如果你(或其他任何人)对此做出贡献,我会很高兴,我也会很高兴在这里详细阐述你的评论。