Link to home
Start Free TrialLog in
Avatar of gudii9
gudii9Flag for United States of America

asked on

mapAB Challlenge

Hi,

I am working on below challenge.
http://codingbat.com/prob/p107259
Psedo code:
1. check if mp has a and b as key
2. if yes append keys and values and return map

I wrote my code as below and passing all tests
public Map<String, String> mapAB(Map<String, String> map) {
  if(map.containsKey("a")&&map.containsKey("b") ){
    map.put("ab",map.get("a")+map.get("b"));
  }
  return map;
}

Open in new window


Any improvements or alternate approaches?      

please advise
Avatar of zzynx
zzynx
Flag of Belgium image

Nothing to improve here. It just works as it should.
Looks fine.  I can't see any obvious problems/inefficiencies.
In the current case it's almost correct (A grade). Cause the task does not specify whether the value can be null or not.

As concurrent access to the map is possible, cause it's not excluded by the task, the optimal solution is (A+):

public synchronized Map<String, String> mapAB(Map<String, String> map) {
  if(map.containsKey("a") && map.containsKey("b") ){
    map.put("ab", map.get("a" ) + map.get("b"));
  }
  
  return map;
}

Open in new window


When the value cannot be null, then the following is better, cause it performs slightly better for the normal Map classes:

public synchronized Map<String, String> mapAB(Map<String, String> map) {
  String a = map.get("a");
  String b = map.get("b");
  if(a != null && b != null)
  {
    map.put("ab", a + b);
  }
  
  return map;
}

Open in new window

Avatar of gudii9

ASKER

if a or b are null map.get("a" ) or map.get("b") gives null pointer exception? please advise
Test it.
Avatar of gudii9

ASKER

public Map<String, String> mapAB(Map<String, String> map) {
  if(map.containsKey(null)&&map.containsKey("b") ){
    map.put("ab",map.get("a")+map.get("b"));
  }
  return map;
}

Open in new window

'
like above?
passing a as null in the a place?

Expected      Run            
mapAB({"b": "There", "a": "Hi"}) → {"b": "There", "a": "Hi", "ab": "HiThere"}      {"b": "There", "a": "Hi"} missing: "ab": "HiThere"      X      
mapAB({"a": "Hi"}) → {"a": "Hi"}      {"a": "Hi"}      OK      
mapAB({"b": "There"}) → {"b": "There"}      {"b": "There"}      OK      
mapAB({"c": "meh"}) → {"c": "meh"}      {"c": "meh"}      OK      
mapAB({"b": "bbb", "c": "ccc", "a": "aaa", "ab": "nope"}) → {"b": "bbb", "c": "ccc", "a": "aaa", "ab": "aaabbb"}      {"b": "bbb", "c": "ccc", "a": "aaa", "ab": "nope"}      X      
mapAB({"b": "bbb", "c": "ccc", "ab": "nope"}) → {"b": "bbb", "c": "ccc", "ab": "nope"}      {"b": "bbb", "c": "ccc", "ab": "nope"}      OK
>> if a or b are null map.get("a" ) or map.get("b") gives null pointer exception
If you're talking about the String variables with the names 'a' and 'b' the above statement is incorrect.
Avatar of gudii9

ASKER

>> if a or b are null map.get("a" ) or map.get("b") gives null pointer exception
If you're talking about the String variables with the names 'a' and 'b' the above statement is incorrect.

yes. i have to pass Strings only right for this method? how do i test with null in this case to see NPE throws or some other exception throws?
ste5an was talking about the situation where the value stored for the key "a" (or "b") is null.
(However, you can't test that on the codingbat website, since you don't have control over the tests)
In that case your code would lead to a NPE.
To avoid that you could write:

public Map<String, String> mapAB(Map<String, String> map) {
  if (map.containsKey("a") && map.containsKey("b")) {
      if (map.get("a")==null && map.get("b")==null) {
          map.put("ab", null);
      } else {
          map.put("ab", (map.get("a")==null ? "" : map.get("a")) + (map.get("b")==null ? "" : map.get("b")));
      }
  }
  return map;
}

Open in new window

Avatar of gudii9

ASKER

i will test in eclipse probably to recreate NPE
Avatar of gudii9

ASKER

package test;

import java.util.Map;

public class TestMap {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("--->"+mapAB({"b": "There", "a": "Hi"}));

	}

	
	public static Map<String, String> mapAB(Map<String, String> map) {
		  if (map.containsKey("a") && map.containsKey("b")) {
		      if (map.get("a")==null && map.get("b")==null) {
		          map.put("ab", null);
		      } else {
		          map.put("ab", (map.get("a")==null ? "" : map.get("a")) + (map.get("b")==null ? "" : map.get("b")));
		      }
		  }
		  return map;
		}
}

Open in new window


above code in eclipse gives error at line 9


Multiple markers at this line
      - Syntax error, insert ")" to complete MethodInvocation
      - The method mapAB(Map<String,String>) in the type TestMap is not applicable for the
       arguments ()
      - Syntax error, insert ";" to complete BlockStatements
      - Syntax error, insert "}" to complete Block


please advise on how to fix it
By using map.get("xyz") in the codebat lab.
Avatar of gudii9

ASKER

public Map<String, String> mapAB(Map<String, String> map) {
  if(map.containsKey("a")&&map.containsKey("b") ){
    map.put("ab",map.get("xyz")+map.get("b"));
  }
  return map;
}


//map.get("xyz") 

Open in new window


like abobve
Expected      Run            
mapAB({"b": "There", "a": "Hi"}) → {"b": "There", "a": "Hi", "ab": "HiThere"}      {"b": "There", "a": "Hi", "ab": "nullThere"}      X      
mapAB({"a": "Hi"}) → {"a": "Hi"}      {"a": "Hi"}      OK      
mapAB({"b": "There"}) → {"b": "There"}      {"b": "There"}      OK      
mapAB({"c": "meh"}) → {"c": "meh"}      {"c": "meh"}      OK      
mapAB({"b": "bbb", "c": "ccc", "a": "aaa", "ab": "nope"}) → {"b": "bbb", "c": "ccc", "a": "aaa", "ab": "aaabbb"}      {"b": "bbb", "c": "ccc", "a": "aaa", "ab": "nullbbb"}      X      
mapAB({"b": "bbb", "c": "ccc", "ab": "nope"}) → {"b": "bbb", "c": "ccc", "ab": "nope"}      {"b": "bbb", "c": "ccc", "ab": "nope"}      OK      
Correct for more than half the tests

Your progress graph for this problem

SOLUTION
Avatar of ste5an
ste5an
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gudii9

ASKER

i wonder what is wrong with my eclipse class?
Avatar of gudii9

ASKER

what are arguments for method mapAB??
is it below  single map with key, value both as string??

Map<String, String> map

??

is  it two string or other map ?
You shouldn't write:
System.out.println("--->"+mapAB({"b": "There", "a": "Hi"}));

Open in new window

but
Map<String, String> map = new HashMap();
map.put("b", "There");
map.put("a", "Hi");
System.out.println("--->"+mapAB(map));

Open in new window


On codingbat this
{"b": "There", "a": "Hi"}
is just a notation for a map containing the keys "b" and "a" having the resp. values "There" and "Hi".
In java code you create such a map this way:

Map<String, String> map = new HashMap();
map.put("b", "There");
map.put("a", "Hi");

Open in new window

Avatar of gudii9

ASKER

package test;
import java.util.HashMap;
import java.util.Map;
public class TestMap {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//System.out.println("--->"+mapAB({"b": "There", "a": "Hi"}));
		Map<String, String> map = new HashMap();
		map.put("b", "There");
		map.put("a", "Hi");
		System.out.println("--->"+mapAB(map));
	}	
	public static Map<String, String> mapAB(Map<String, String> map) {
		  if (map.containsKey("a") && map.containsKey("b")) {
		      if (map.get("a")==null && map.get("b")==null) {
		          map.put("ab", null);
		      } else {
		          map.put("ab", (map.get("a")==null ? "" : map.get("a")) + (map.get("b")==null ? "" : map.get("b")));
		      }
		  }
		  return map;
		}
}
/*You shouldn't write:
System.out.println("--->"+mapAB({"b": "There", "a": "Hi"}));
but
Map<String, String> map = new HashMap();
map.put("b", "There");
map.put("a", "Hi");
System.out.println("--->"+mapAB(map));
On codingbat this{"b": "There", "a": "Hi"}
is just a notation for a map containing the keys "b" and "a" having the resp. values "There" and "Hi".
In java code you create such a map this way:

Map<String, String> map = new HashMap();
map.put("b", "There");
map.put("a", "Hi")
*/

Open in new window


above give correct output
--->{a=Hi, ab=HiThere, b=There}
Avatar of gudii9

ASKER

package test;
import java.util.HashMap;
import java.util.Map;
public class TestMap {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//System.out.println("--->"+mapAB({"b": "There", "a": "Hi"}));
		Map<String, String> map = new HashMap();
		map.put("b", null);
		map.put("a", "Hi");
		System.out.println("--->"+mapAB(map));
	}	
	public static Map<String, String> mapAB(Map<String, String> map) {
		  if (map.containsKey("a") && map.containsKey("b")) {
		      if (map.get("a")==null && map.get("b")==null) {
		          map.put("ab", null);
		      } else {
		          map.put("ab", (map.get("a")==null ? "" : map.get("a")) + (map.get("b")==null ? "" : map.get("b")));
		      }
		  }
		  return map;
		}
}
/*You shouldn't write:
System.out.println("--->"+mapAB({"b": "There", "a": "Hi"}));
but
Map<String, String> map = new HashMap();
map.put("b", "There");
map.put("a", "Hi");
System.out.println("--->"+mapAB(map));
On codingbat this{"b": "There", "a": "Hi"}
is just a notation for a map containing the keys "b" and "a" having the resp. values "There" and "Hi".
In java code you create such a map this way:

Map<String, String> map = new HashMap();
map.put("b", "There");
map.put("a", "Hi")
*/

Open in new window


above gave below output

--->{a=Hi, ab=Hi, b=null}


bsically i am passing b value as null and got output ab=Hi

Is that is how i have to tests null here?
Avatar of gudii9

ASKER

As concurrent access to the map is possible,

what is meaning of concurrent access to map?



When the value cannot be null, then the following is better, cause it performs slightly better for the normal Map classes:

public synchronized Map<String, String> mapAB(Map<String, String> map) {
  String a = map.get("a");
  String b = map.get("b");
  if(a != null && b != null)
  {
    map.put("ab", a + b);
  }
 
  return map;
}

do you mean instead of above as below( i.e instead of cannot it is can???)

When the value can be null, then the following is better, cause it performs slightly better for the normal Map classes:

public synchronized Map<String, String> mapAB(Map<String, String> map) {
  String a = map.get("a");
  String b = map.get("b");
  if(a != null && b != null)
  {
    map.put("ab", a + b);
  }
 
  return map;
}
Avatar of gudii9

ASKER

package test;
import java.util.HashMap;
import java.util.Map;
public class TestMap {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//System.out.println("--->"+mapAB({"b": "There", "a": "Hi"}));
		Map<String, String> map = new HashMap();
		map.put("b", [b]null);[/b]
		map.put("a", "Hi");
		System.out.println("--->"+mapAB(map));
	}	
	public static Map<String, String> mapAB(Map<String, String> map) {
		  if (map.containsKey("a") && map.containsKey("b")) {
		      if (map.get("a")==null && map.get("b")==null) {
		          map.put("ab", null);
		      } else {
		          map.put("ab", (map.get("a")==null ? "" : map.get("a")) + (map.get("b")==null ? "" : map.get("b")));
		      }
		  }
		  return map;
		}
}
/*You shouldn't write:
System.out.println("--->"+mapAB({"b": "There", "a": "Hi"}));
but
Map<String, String> map = new HashMap();
map.put("b", "There");
map.put("a", "Hi");
System.out.println("--->"+mapAB(map));
On codingbat this{"b": "There", "a": "Hi"}
is just a notation for a map containing the keys "b" and "a" having the resp. values "There" and "Hi".
In java code you create such a map this way:

Map<String, String> map = new HashMap();
map.put("b", "There");
map.put("a", "Hi")
*/

Open in new window


what is difference between passing Null as above and passing "" as value as below
package test;
import java.util.HashMap;
import java.util.Map;
public class TestMap {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//System.out.println("--->"+mapAB({"b": "There", "a": "Hi"}));
		Map<String, String> map = new HashMap();
		map.put("b"[b], ""[/b]);
		map.put("a", "Hi");
		System.out.println("--->"+mapAB(map));
	}	
	public static Map<String, String> mapAB(Map<String, String> map) {
		  if (map.containsKey("a") && map.containsKey("b")) {
		      if (map.get("a")==null && map.get("b")==null) {
		          map.put("ab", null);
		      } else {
		          map.put("ab", (map.get("a")==null ? "" : map.get("a")) + (map.get("b")==null ? "" : map.get("b")));
		      }
		  }
		  return map;
		}
}
/*You shouldn't write:
System.out.println("--->"+mapAB({"b": "There", "a": "Hi"}));
but
Map<String, String> map = new HashMap();
map.put("b", "There");
map.put("a", "Hi");
System.out.println("--->"+mapAB(map));
On codingbat this{"b": "There", "a": "Hi"}
is just a notation for a map containing the keys "b" and "a" having the resp. values "There" and "Hi".
In java code you create such a map this way:

Map<String, String> map = new HashMap();
map.put("b", "There");
map.put("a", "Hi")
*/

Open in new window

Is that is how i have to tests null here?
Yes.

what is difference between passing Null as above and passing ""
"" is just the empty string and won't lead to NPExceptions like null will.
Avatar of gudii9

ASKER

what is difference between passing Null as above and passing ""
"" is just the empty string and won't lead to NPExceptions like null will.
below code did not gave NPE even i used Null as value right?
when it gives null vlaue gives NPE where as "" wont give??
package test;
import java.util.HashMap;
import java.util.Map;
public class TestMap {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//System.out.println("--->"+mapAB({"b": "There", "a": "Hi"}));
		Map<String, String> map = new HashMap();
		map.put("b", null);
		map.put("a", "Hi");
		System.out.println("--->"+mapAB(map));
	}	
	public static Map<String, String> mapAB(Map<String, String> map) {
		  if (map.containsKey("a") && map.containsKey("b")) {
		      if (map.get("a")==null && map.get("b")==null) {
		          map.put("ab", null);
		      } else {
		          map.put("ab", (map.get("a")==null ? "" : map.get("a")) + (map.get("b")==null ? "" : map.get("b")));
		      }
		  }
		  return map;
		}
}
/*You shouldn't write:
System.out.println("--->"+mapAB({"b": "There", "a": "Hi"}));
but
Map<String, String> map = new HashMap();
map.put("b", "There");
map.put("a", "Hi");
System.out.println("--->"+mapAB(map));
On codingbat this{"b": "There", "a": "Hi"}
is just a notation for a map containing the keys "b" and "a" having the resp. values "There" and "Hi".
In java code you create such a map this way:

Map<String, String> map = new HashMap();
map.put("b", "There");
map.put("a", "Hi")
*/

Open in new window

>> below code did not gave NPE even i used Null as value right?
Right. That's because you avoid NPE by checking for it:
if (map.get("a")==null && map.get("b")==null) {

Open in new window

If you wouldn't do that check, you would have an NPE.
Avatar of gudii9

ASKER

i see line 15

 if (map.get("a")==null && map.get("b")==null) {
Avatar of gudii9

ASKER

If you wouldn't do that check, you would have an NPE.

you mean like below throws NPE?

package test;
import java.util.HashMap;
import java.util.Map;
public class TestMap {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//System.out.println("--->"+mapAB({"b": "There", "a": "Hi"}));
		Map<String, String> map = new HashMap();
		map.put("b", null);
		map.put("a", "Hi");
		System.out.println("--->"+mapAB(map));
	}	
	public static Map<String, String> mapAB(Map<String, String> map) {
		  if (map.containsKey("a") && map.containsKey("b")) {
		     // if (map.get("a")==null && map.get("b")==null) {
		         // map.put("ab", null);
		      //} else {
		          map.put("ab", (map.get("a")==null ? "" : map.get("a")) + (map.get("b")==null ? "" : map.get("b")));
		     // }
		  }
		  return map;
		}
}
/*You shouldn't write:
System.out.println("--->"+mapAB({"b": "There", "a": "Hi"}));
but
Map<String, String> map = new HashMap();
map.put("b", "There");
map.put("a", "Hi");
System.out.println("--->"+mapAB(map));
On codingbat this{"b": "There", "a": "Hi"}
is just a notation for a map containing the keys "b" and "a" having the resp. values "There" and "Hi".
In java code you create such a map this way:

Map<String, String> map = new HashMap();
map.put("b", "There");
map.put("a", "Hi")
*/

Open in new window


i still did not get NPE rather i got below meaningful output to my eyes??

--->{a=Hi, ab=Hi, b=null}
Avatar of gudii9

ASKER

public Map<String, String> mapAB(Map<String, String> map) {
  if(map.containsKey("a")&&map.containsKey("b") ){
    map.put("ab",map.get("xyz")+map.get("b"));
  }
  return map;
}


//map.get("xyz") 

Open in new window


i modified as below which fixed all tests
public Map<String, String> mapAB(Map<String, String> map) {
  if(map.containsKey("a")&&map.containsKey("b") ){
   String x= map.get("a")+map.get("b");
   map.put("ab",x);
  }
  return map;
}

Open in new window


looks like i have to keep key a and key b and additionally key ab
Avatar of gudii9

ASKER

no sorting comes here based on keys or values??
>> i still did not get NPE
That's because of
map.put("ab", (map.get("a")==null ? "" : map.get("a")) + (map.get("b")==null ? "" : map.get("b")));

Open in new window

which also checks for null
Avatar of gudii9

ASKER

package test;
import java.util.HashMap;
import java.util.Map;
public class TestMap {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//System.out.println("--->"+mapAB({"b": "There", "a": "Hi"}));
		Map<String, String> map = new HashMap();
		map.put("b", null);
		map.put("a", "Hi");
		System.out.println("--->"+mapAB(map));
	}	
	public static Map<String, String> mapAB(Map<String, String> map) {
		  if (map.containsKey("a") && map.containsKey("b")) {
		     // if (map.get("a")==null && map.get("b")==null) {
		         // map.put("ab", null);
		      //} else {
		          //map.put("ab", (map.get("a")==null ? "" : map.get("a")) + (map.get("b")==null ? "" : map.get("b")));
		          map.put("ab", map.get("a")+ map.get("b"));
		          
		     // }
		  }
		  return map;
		}
}
/*You shouldn't write:
System.out.println("--->"+mapAB({"b": "There", "a": "Hi"}));
but
Map<String, String> map = new HashMap();
map.put("b", "There");
map.put("a", "Hi");
System.out.println("--->"+mapAB(map));
On codingbat this{"b": "There", "a": "Hi"}
is just a notation for a map containing the keys "b" and "a" having the resp. values "There" and "Hi".
In java code you create such a map this way:

Map<String, String> map = new HashMap();
map.put("b", "There");
map.put("a", "Hi")
*/

Open in new window

above alsoe did not throw NPE
i got below output

--->{a=Hi, ab=Hinull, b=null}


how to tweak my code to see NPE??
Replace
map.put("b", null);
map.put("a", "Hi");

Open in new window

resp.
map.put("ab", map.get("a")+ map.get("b"));

Open in new window

by
map.put("b", "Hi");
map.put("a", null);

Open in new window

resp.
map.put("ab", map.get("a").concat(map.get("b")));

Open in new window

Avatar of gudii9

ASKER

what is meaning of resp.
Avatar of gudii9

ASKER

package test;
import java.util.HashMap;
import java.util.Map;
public class TestMap {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//System.out.println("--->"+mapAB({"b": "There", "a": "Hi"}));
		Map<String, String> map = new HashMap();
		map.put("b", null);
		map.put("a", "Hi");
		System.out.println("--->"+mapAB(map));
	}	
	public static Map<String, String> mapAB(Map<String, String> map) {
		  if (map.containsKey("a") && map.containsKey("b")) {
		     // if (map.get("a")==null && map.get("b")==null) {
		         // map.put("ab", null);
		      //} else {
		          //map.put("ab", (map.get("a")==null ? "" : map.get("a")) + (map.get("b")==null ? "" : map.get("b")));
		         // map.put("ab", map.get("a")+ map.get("b"));
			  map.put("ab", map.get("a").concat(map.get("b")));
		          
		     // }
		  }
		  return map;
		}
}
/*You shouldn't write:
System.out.println("--->"+mapAB({"b": "There", "a": "Hi"}));
but
Map<String, String> map = new HashMap();
map.put("b", "There");
map.put("a", "Hi");
System.out.println("--->"+mapAB(map));
On codingbat this{"b": "There", "a": "Hi"}
is just a notation for a map containing the keys "b" and "a" having the resp. values "There" and "Hi".
In java code you create such a map this way:

Map<String, String> map = new HashMap();
map.put("b", "There");
map.put("a", "Hi")
*/

Open in new window

above throwed NPE


Exception in thread "main" java.lang.NullPointerException
      at java.lang.String.concat(String.java:2027)
      at test.TestMap.mapAB(TestMap.java:20)
      at test.TestMap.main(TestMap.java:11)


why below line did not throw NPE
map.put("ab", map.get("a")+ map.get("b"));

where as below line throwed NPE??

        map.put("ab", map.get("a").concat(map.get("b")));

please advise
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gudii9

ASKER

The '+' operator concatenates the toString() representation of the two arguments.
And toString() representation of a null object is "null".
So that doesn't lead to a NPE

i got it. thank you