[英]Java stream to validate int in a map
我有下面的代码,它只是根据具有数字范围的地图检查给定的数字。 方法 isWithinAnyRange 将检查数字是否在包括开始但不包括结束的范围内。
这工作正常,但我想用流简化该方法。
public static void main(String [] args)
{
Map<Integer,Integer> intMap = new HashMap<>();
intMap.put(0,2);
intMap.put(3,4);
intMap.put(6,9);
System.out.println(isWithinAnyRange(intMap,2)); //false
System.out.println(isWithinAnyRange(intMap,3)); //true
System.out.println(isWithinAnyRange(intMap,4)); //false
System.out.println(isWithinAnyRange(intMap,6)); //true
System.out.println(isWithinAnyRange(intMap,7)); //true
}
public static boolean isWithinAnyRange(Map<Integer,Integer> intMap, Integer num){
for(Map.Entry<Integer,Integer> entry: intMap.entrySet()){
if(num>=entry.getKey() && num<entry.getValue()){
return true;
}
}
return false;
}
当您的所有范围都不重叠时,例如在您的示例中,您最好使用TreeMap
:
public static void main(String [] args) {
TreeMap<Integer,Integer> intMap = new TreeMap<>();
intMap.put(0,2);
intMap.put(3,4);
intMap.put(6,9);
System.out.println(isWithinAnyRange(intMap,2)); //false
System.out.println(isWithinAnyRange(intMap,3)); //true
System.out.println(isWithinAnyRange(intMap,4)); //false
System.out.println(isWithinAnyRange(intMap,6)); //true
System.out.println(isWithinAnyRange(intMap,7)); //true
}
public static boolean isWithinAnyRange(NavigableMap<Integer,Integer> intMap, Integer num) {
Map.Entry<Integer,Integer> e = intMap.floorEntry(num);
return e != null && num < e.getValue();
}
这不仅更简单,而且比线性搜索更有效。 更正式地说,时间复杂度是 O(log n) 而不是 O(n)。
中小型范围的另一个选择是BitSet
:
BitSet bitSet = new BitSet();
bitSet.set(0,2);
bitSet.set(3,4);
bitSet.set(6,9);
System.out.println(bitSet.get(2)); //false
System.out.println(bitSet.get(3)); //true
System.out.println(bitSet.get(4)); //false
System.out.println(bitSet.get(6)); //true
System.out.println(bitSet.get(7)); //true
这甚至具有 O(1) 时间复杂度。 它存储零和最大数字之间的所有值,无论它们是否包含,但每个数字仅使用一位,例如,对于所有值都在0 .. 64
范围内的示例,单个long
值将是在幕后使用。 但是当您有非常大的范围或距离时,它不适合。 此外,当距离很小但存在负值或所有值远离零时,将需要一个偏移量来调整存储在位集中的值。
如果您只想知道条目是否匹配:
boolean isMatch =
intMap.entrySet().stream()
.anyMatch(e -> num >= e.getKey() && num < e.getValue());
如果要查找匹配的条目:
Optional<Map.Entry<Integer, Integer>> match =
intMap.entrySet().stream()
.filter(e -> num >= e.getKey() && num < e.getValue())
.findAny();
如果可能有多个匹配的条目,您可以将它们收集回地图:
Map<Integer, Integer> matches =
intMap.entrySet().stream()
.filter(e -> num >= e.getKey() && num < e.getValue())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.