#1617 Map.get returns default value for existing key if value is null

tonsky Thu 18 Aug 2011

If value === null, Map.get behaves like there’s no such key in a map:

>>> [1:null].containsKey(1)
true
>>> [1:null].get(1, "not_found")
not_found

Expected:

>>> [1:null].get(1, "not_found")
null

brian Thu 18 Aug 2011

Promoted to ticket #1617 and assigned to brian

That is probably kind of like #1356 - although it will be important to avoid a double lookup in get. But can maybe check if get returns null and default is non-null, then do the extra containsKey lookup.

tonsky Thu 18 Aug 2011

Hi brian,

while thinking about avoiding double lookup and your solution I actually implemented it:

diff --git a/src/sys/java/fan/sys/Map.java b/src/sys/java/fan/sys/Map.java
--- a/src/sys/java/fan/sys/Map.java
+++ b/src/sys/java/fan/sys/Map.java
@@ -79,14 +79,18 @@
   {
     Object val = map.get(key);
     if (val != null) return val;
-    return this.def;
+    return this.def == null 
+      ? null 
+      : (map.containsKey(key) ? null : this.def);
   }
 
   public final Object get(Object key, Object def)
   {
     Object val = map.get(key);
     if (val != null) return val;
-    return def;
+    return def == null 
+      ? null 
+      : (map.containsKey(key) ? null : def);
   }
 
   public final boolean containsKey(Object key)
diff --git a/src/testSys/fan/MapTest.fan b/src/testSys/fan/MapTest.fan
--- a/src/testSys/fan/MapTest.fan
+++ b/src/testSys/fan/MapTest.fan
@@ -343,6 +343,8 @@
 
     verifyEq(m["a"], "A")
     verifyEq(m["b"], null)
+    verifyEq(m.get("b", "def"), null)
+    verifyEq(m.get("c", "def"), "def")
 
     keys := Str[,]
     vals := Str?[,]

brian Wed 24 Aug 2011

Ticket resolved in 1.0.60

changeset

Login or Signup to reply.