簡體   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