获取Java中某个范围内的键值
假设我在Java中有一个如下所示的地图:
{ 39:"39 to 41", 41:"41 to 43", 43:"43 to 45", 45:">=45" }
如果键是按排序顺序(使用treemap或linkedhashmap)。现在,如果我尝试获得> = 39和<41的值。那么我应该得到字符串“39到41”。如何有效地执行此操作?
看起来你想要的不仅仅是SortedMap
; 你想要一个NavigableMap
! 具体来说,您可以使用floorKey
操作。
这是一个例子:
NavigableMap map = new TreeMap(); 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!
请注意,还有ceilingKey
, lowerKey
, higherKey
,还有…Entry
而不是…Key
操作也返回Map.Entry
而不仅仅是K
试试Java 6 java.util.NavigableMap
。 http://download.oracle.com/javase/6/docs/api/java/util/NavigableMap.html 。
在特殊用途floorKey
/ floorEntry
。
例如: floorKey(40)
应该返回39
。 floorEntry将返回您要查找的值。
使用有序地图,您可以执行以下操作:
SortedMap head = map.headMap(value+1); if (head.isEmpty()) { return null; } else { return head.get(head.lastKey()); }
我不确定那会很容易。 一个建议是“填补空白”,即输入值40->"39 to 41"
等等。我想只有你知道地图中可能的整个数字范围才有可能。
或者mabybe覆盖了get
to to to to to to the the value是否在地图中,然后展开直到它找到了什么。 我不确定它目前的forms是否可行,因为你必须最终解析值字符串。
您可以递归查找下边界。
public String descriptionFor(int value) { String description = map.get(value); return description == null ? descriptionFor(value--) : description; }
您需要具有最小边界。
我相信你必须自己实施这样的地图。 你是对的,它必须被分类; get
的实现必须遍历键,直到找到小于或等于参数的最大键。
如果你是TreeMap
子类,那么最初看起来你可以通过简单地重写get()
方法来实现它。 但是,为了保持尽可能多的Map合约,您必须覆盖其他方法以保持一致性。
那么例如containsKey()
呢? 你的主要包含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的任何后续获取返回null
,但返回上述键35的映射 – 37或39-40。
因此,虽然您可以通过覆盖TreeMap来开始这一点,但也许Map
的整个概念并不是您想要的。 除非你需要将这种行为转移到采用Map
现有方法中,否则自己创建它作为一个独特的类可能更容易,因为它不是一个Map,就像你定义它一样。