java 获取Java中某个范围内键的值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3519901/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get values for keys within a range in Java
提问by Emil
Suppose I have a map in Java which looks like this:
假设我有一张 Java 地图,如下所示:
{
39:"39 to 41",
41:"41 to 43",
43:"43 to 45",
45:">=45"
}
If the keys are in sorted order(either using treemap or linkedhashmap).Now if i try to get a value which is >=39 and <41.Then I should get the String "39 to 41".How do I do this efficiently?
如果键按排序顺序(使用树图或链接哈希图)。现在,如果我尝试获取 >=39 和 <41 的值。那么我应该得到字符串“39 到 41”。我如何有效地做到这一点?
回答by polygenelubricants
It looks like you want more than a SortedMap; you want a NavigableMap! Specifically you can use the floorKeyoperation.
看起来你想要的不仅仅是一个SortedMap; 你想要一个NavigableMap!具体可以使用floorKey操作。
Here's an example:
下面是一个例子:
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!
Note that there are also ceilingKey, lowerKey, higherKey, and also …Entryinstead of …Keyoperations as well which returns a Map.Entry<K,V>instead of just the K.
请注意,还有ceilingKey, lowerKey, higherKey, and also …Entryinstead of…Key操作返回 aMap.Entry<K,V>而不仅仅是K。
回答by helios
Try Java 6 java.util.NavigableMap. http://download.oracle.com/javase/6/docs/api/java/util/NavigableMap.html.
试试 Java 6 java.util.NavigableMap。http://download.oracle.com/javase/6/docs/api/java/util/NavigableMap.html。
In special use floorKey/floorEntry.
特殊用途floorKey/ floorEntry.
By example: floorKey(40)should return 39. floorEntry would return the value you are looking for.
例如:floorKey(40)应该返回39. floorEntry 将返回您正在寻找的值。
回答by Maurice Perry
With a sorted map, you could do something like that:
使用排序的地图,您可以执行以下操作:
SortedMap<Integer,String> head = map.headMap(value+1);
if (head.isEmpty()) {
return null;
} else {
return head.get(head.lastKey());
}
回答by Andrzej Doyle
You'd have to implement such a map yourself, I believe. You're right that it would have to be sorted; the implementation of getwould have to iterate through the keys until it finds the largest key that is less than or equal to the argument.
我相信你必须自己实现这样的地图。你是对的,它必须被排序;的实现get必须遍历键,直到找到小于或等于参数的最大键。
If you subclass TreeMapit would initially appear that you can get this working via simply overriding the get()method. However, to maintain as much of the Map contract as possible you'll have to override other methods for consistency.
如果您子类化TreeMap,最初看起来您可以通过简单地覆盖该get()方法来使其工作。但是,为了尽可能多地维护 Map 契约,您必须覆盖其他方法以保持一致性。
And what about e.g. containsKey()? Does your main contain a mapping for 40? If you return false, then a client can decide not to call get()based on this information; for these reason (and the formal definition) you have to return true. But then it makes it hard to determine whether the map "really contains" a given mapping; if you're looking to do something such as update without overwriting anything that already exists.
例如containsKey()呢?你的主要包含一个映射40吗?如果您 return false,则客户端可以get()根据此信息决定不调用;由于这些原因(以及正式定义),您必须返回true. 但是这样就很难确定地图是否“真正包含”了给定的映射;如果您希望在不覆盖任何已存在的内容的情况下执行更新等操作。
The remove()method might be tricky too. From my reading of the interface,
这个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);
Acting consistently here would be verytricky. If you have a mapping from 35-40 for example, and you call remove(38), then as I understand it you'd have to return nullfor any subsequent gets for the key 38, but return the aforementioned mapping for keys 35-37 or 39-40.
在这里始终如一地表演会非常棘手。例如,如果您有 35-40 的映射,并且您调用remove(38),那么据我所知,您必须返回null键 38 的任何后续获取,但返回键 35-37 或 39-40 的上述映射.
So while you can make a start on this by overriding TreeMap, perhaps the whole concept of Mapis not quite what you want here. Unless you need this behaviour to slot into existing methods that take Map, it might be easier to create it yourself as a distinct class since it's not quitea Map, the way you're defining it.
因此,虽然您可以通过覆盖 TreeMap 来开始这一点,但也许这里的整个概念Map并不是您想要的。除非您需要将此行为插入到 take 的现有方法中Map,否则将它自己创建为一个独特的类可能会更容易,因为它不像您定义它的方式那样完全是 Map。
回答by Noel M
I'm not sure that's going to be easy. One suggestion would be to "fill in the gaps", ie put in a value 40->"39 to 41"etc etc. I suppose that will only be possible if you know the whole range of numbers possible in the map.
我不确定这会很容易。一个建议是“填补空白”,即输入一个值40->"39 to 41"等。我想只有当您知道地图中可能出现的整个数字范围时,这才有可能。
Or mabybe something that overrides the getto check to see if the value is in the map, and expanding out until it finds something. I'm not sure that's going to be possible in its current guise, as you'd have to end up parsing the value strings.
或者 mabybe 覆盖的东西,get以检查该值是否在地图中,并扩展直到找到某些东西。我不确定以目前的形式是否可行,因为您最终必须解析值字符串。
回答by hhbarriuso
You can recursively look for lower boundary.
您可以递归查找下限。
public String descriptionFor(int value) {
String description = map.get(value);
return description == null ? descriptionFor(value--) : description;
}
You will need to have a minimum boundary.
您将需要有一个最小边界。

