获取Java中某个范围内的键的值

获取Java中某个范围内的键的值,java,map,range-map,Java,Map,Range Map,假设我有一个Java地图,它看起来像这样: { 39:"39 to 41", 41:"41 to 43", 43:"43 to 45", 45:">=45" } 如果键是按顺序排序的(使用treemap或linkedhashmap)。现在如果我尝试获取>=39和的值,我不确定这是否容易。一个建议是“填补空白”,即输入一个值40->“39到41”等。我想只有当你知道地图上可能的全部数字范围时,这才可能实现 或者可能是覆盖get以检查值是否在映射中,并向外扩展直到找到某个值。我不确

假设我有一个Java地图,它看起来像这样:

{ 
 39:"39 to 41",
 41:"41 to 43",
 43:"43 to 45",
 45:">=45"
}

如果键是按顺序排序的(使用treemap或linkedhashmap)。现在如果我尝试获取>=39和的值,我不确定这是否容易。一个建议是“填补空白”,即输入一个值
40->“39到41”
等。我想只有当你知道地图上可能的全部数字范围时,这才可能实现


或者可能是覆盖
get
以检查值是否在映射中,并向外扩展直到找到某个值。我不确定在它当前的伪装下这是否可能,因为您必须解析值字符串。

您可以递归地查找下边界

public String descriptionFor(int value) {
    String description = map.get(value);
    return description == null ? descriptionFor(value--) : description;
}

您需要有一个最小边界。

对于排序地图,您可以这样做:

SortedMap<Integer,String> head = map.headMap(value+1);
if (head.isEmpty()) {
    return null;
} else {
    return head.get(head.lastKey());
}
SortedMap head=map.headMap(值+1);
if(head.isEmpty()){
返回null;
}否则{
返回head.get(head.lastKey());
}

我相信,您必须自己实现这样一个映射。你是对的,它必须被分类;
get
的实现必须遍历这些键,直到找到小于或等于参数的最大键

如果您将
TreeMap
子类化,那么最初看起来您可以通过简单地重写
get()
方法来实现这一点。但是,为了尽可能多地维护映射契约,您必须覆盖其他方法以实现一致性

例如,
containsKey()
?您的main是否包含
40
的映射?如果返回
false
,则客户端可以根据此信息决定不调用
get()
;出于这些原因(以及正式定义),您必须返回
true
。但是这样就很难确定地图是否“真的包含”给定的地图;如果您希望在不覆盖任何已存在内容的情况下执行诸如更新之类的操作

remove()
方法可能也很棘手。从我对界面的理解来看

// Calling map.remove "Removes the mapping for a key from this map if it is present."
map.remove(x);

// Now that the mapping is removed, I believe the following must hold
assert map.get(x) == null;
assert map.containsKey(x);
在这里始终如一地行动是非常棘手的。例如,如果您有一个35-40的映射,并且您调用
remove(38)
,那么据我所知,对于键38的任何后续get,您必须返回
null
,但对于键35-37或39-40,您必须返回上述映射



因此,虽然您可以通过覆盖TreeMap来开始这一点,但是
Map
的整个概念可能并不是您想要的。除非您需要将此行为插入到采用
Map
的现有方法中,否则您可以更轻松地将其创建为一个独特的类,因为它不是一个完全符合您定义它的方式的映射。

尝试Java 6
Java.util.NavigableMap

特殊用途
floorKey
/
floorrentry


例如:
floorKey(40)
应该返回
39
。FloorRentry将返回您正在查找的值。

看起来您需要的不仅仅是一个;你想要一个!具体来说,您可以使用该操作

下面是一个例子:

    NavigableMap<Integer,String> map =
        new TreeMap<Integer, String>();

    map.put(0, "Kid");
    map.put(11, "Teens");
    map.put(20, "Twenties");
    map.put(30, "Thirties");
    map.put(40, "Forties");
    map.put(50, "Senior");
    map.put(100, "OMG OMG OMG!");

    System.out.println(map.get(map.floorKey(13)));     // Teens
    System.out.println(map.get(map.floorKey(29)));     // Twenties
    System.out.println(map.get(map.floorKey(30)));     // Thirties
    System.out.println(map.floorEntry(42).getValue()); // Forties
    System.out.println(map.get(map.floorKey(666)));    // OMG OMG OMG!
导航地图=
新树映射();
map.put(0,“Kid”);
地图放置(11,“青少年”);
地图放置(20,“20”);
地图放置(30,“30”);
地图放置(40,“四十”);
地图出售(50,“高级”);
地图。放(100,“天哪,天哪!”;
System.out.println(map.get(map.floorKey(13));//青少年
System.out.println(map.get(map.floorKey(29));//二十几岁
System.out.println(map.get(map.floorKey(30));//三十岁
System.out.println(map.floorEntry(42.getValue());//四十多岁
System.out.println(map.get(map.floorKey(666));//天哪天哪天哪!

请注意,还有
ceilingKey
lowerKey
higherKey
,还有
…Entry
而不是
…Key
操作,它返回一个
映射。Entry
而不仅仅是
K

你的意思是
我不知道的可能的重复项,显然这里也没有人。很酷!所有人都为标准运行时间欢呼!有时我觉得我懂Java,然后我遇到了这样的事情,我的思想被吹走了。