繁体   English   中英

用于验证映射中的 int 的 Java 流

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM