在TreeMap中获取其String键以模式开头的值

时间:2012-05-22 23:25:37

标签: java string treemap

我有一个带有字符串的Treemap作为键。我想获得其键以字符串搜索开头的所有值。

我认为我需要做的是:

myTreeMap.subMap(search.concat(X1),true,search.concat(X2),true);

其中X1和X2是可能的最高和最低的字符。

有更好的方法吗?如果没有,X1和X2是什么?

提前致谢。

4 个答案:

答案 0 :(得分:0)

Hmmmm。我会说你应该myTreeMap.subMap(search, true, search2, false) search2没有连接,而是“递增”。毕竟,如果X2只是一个角色,那么您的实施将会错过search.concat(X2).concat(X2)

答案 1 :(得分:0)

问题在于您尝试进行的部分密钥搜索。

myTreeMap.subMap(search.concat(X1), true, search.concat(X2), true);

假设您有一些键/值对:

fooBar - >一些价值 fooBage - >其他一些价值 barBear - >耗尽价值观念 barTender - >另一个值

现在你要找到所有“foo *”,在这个例子中是fooBar和fooBage。密钥被视为单个令牌,在这种情况下恰好是一个字符串。无法将密钥视为部分密钥。甚至说你想要“fooA”通过“fooZ”也不会让你成为fooBar或者fooBage。

如果你创建了密钥类(我称之为FractionalKey),并覆盖了equals方法,那么你可以将equals定义为“some regex”,或“整个事物,或者只是第一部分”等。这个问题是如果equals返回true,那么哈希码也必须相等,这会破坏我认为的规则。

我认为这是您唯一的选择,然后搜索您想要的密钥列表。

答案 2 :(得分:0)

基本上你需要按字典顺序排列下一个前缀作为第二个边界:

public <T> Map<String, T> subMapWithKeysThatAreSuffixes(String prefix, NavigableMap<String, T> map) {
    if ("".equals(prefix)) return map;
    String lastKey = createLexicographicallyNextStringOfTheSameLenght(prefix);
    return map.subMap(prefix, true, lastKey, false);
}

String createLexicographicallyNextStringOfTheSameLenght(String input) {
    final int lastCharPosition = input.length()-1;
    String inputWithoutLastChar = input.substring(0, lastCharPosition);
    char lastChar = input.charAt(lastCharPosition) ;
    char incrementedLastChar = (char) (lastChar + 1);
    return inputWithoutLastChar+incrementedLastChar;
}

答案 3 :(得分:0)

由于我对上述答案的编辑因太原创而被拒绝,我会在此处发布。这个答案修复了拼写错误并处理原始没有的int溢出。

public <T> Map<String, T> subMapWithKeysThatAreSuffixes(String prefix, NavigableMap<String, T> map) {
    if ("".equals(prefix)) return map;
    String lastKey = createLexicographicallyNextStringOfTheSameLength(prefix);
    return map.subMap(prefix, true, lastKey, false);
}

String createLexicographicallyNextStringOfTheSameLength(String input) {
    final int lastCharPosition = input.length()-1;
    String inputWithoutLastChar = input.substring(0, lastCharPosition);
    char lastChar = input.charAt(lastCharPosition);
    char incrementedLastChar = (char) (lastChar + 1);
    // Handle int/char overflow.  This wasn't done above.
    if (incrementedLastChar == ((char) 0)) return input+incrementedLastChar;
    return inputWithoutLastChar+incrementedLastChar;
}