2

我需要将键存储为不区分大小写,并且状态/状态/状态等键的所有值都合并到一个集合中。然而,问题是我需要在某个时候返回原始密钥的区分大小写版本,因此通用 CaseInsensitiveMap 不起作用。我只需要返回添加的“状态”的第一个大写字母,因此在这种情况下,我保留状态并丢弃状态/状态。

我已经查看了一些实现这种数据结构的选项,例如 Guava HashMultimap 和 Tuples,但似乎没有一个是完全正确的。

<CaseInsensitiveOriginalKey, OriginalKey, Set<Values>>

因此,例如,如果我添加一个值为 {Texas, Oklahoma} 的键“State”,它将存储为:

<state, State, {Texas, Oklahoma}>

这个想法是,如果我创建某种 .add(StATe, {Nebraska}) 那么地图,看到“状态”的不区分大小写的条目已经存在,变成:

<state, State, {Texas, Oklahoma, Nebraska}>

对于新键, .add(COLOR, {blue, red})

整体地图变为:

<state, State, {Texas, Oklahoma, Nebraska}>
<color, COLOR, {blue, red}>
  • .get(ColoR) 返回 {red, blue}
  • .getKey(coLOR) 返回颜色

关于如何最好地做到这一点的任何想法?

4

3 回答 3

2

您可以维护两个地图:

  • 一种是Map<String, Set<String>>将不区分大小写的键映射到相应的字符串集(例如"state" → {"Texas", "Oklahoma"})。

  • 另一个是Map<String, String>将不区分大小写的键映射到其对应的区分大小写的键(例如"state" → "State")。

您可以创建自己的类,将这两个映射作为私有字段,并确保在添加/删除/更新配对时它们保持同步。

于 2013-08-08T23:32:53.353 回答
2

您需要的是类似于Map<CaseInsensitiveOriginalKey, Record>whereRecord是具有原始(区分大小写)键和一组值作为属性的自定义类。

您可以使用通用Pair类而不是自定义 Record 类来逃避,但是(IMO)那将是糟糕的设计。


但是,您的要求存在问题:

但是问题是我需要原始密钥的区分大小写版本...

您的示例表明您可以拥有多个区分大小写的原始密钥版本;即您首先看到的那个(例如“State”)和后续的(例如“STate”、“state”等)。那么哪个是正确的原始密钥呢?你看到的第一个案例是……呃……垃圾?

关键是,将您看到的第一个版本视为最终/首选版本将是有问题的。你需要一些东西(或某人)来智能地找出最终版本。为此,您可能需要保留您看到的所有版本,直到(至少)您完成初始数据捕获阶段。您甚至可能需要保留他们的频率和/或他们的上下文。

于 2013-08-08T23:39:36.553 回答
0

我建议一个有几个地图的数据结构。一个是从每个(区分大小写)键到不区分大小写键的映射,另一个是从不区分大小写键到值的映射。给定一个区分大小写的键,每次访问都需要两步:从第一个映射中找到要使用的不区分大小写的键,然后将该键与第二个映射一起使用。

于 2013-08-08T23:37:54.373 回答