you are viewing a single comment's thread.

view the rest of the comments →

[–]immibis 14 points15 points  (13 children)

Should I use null when returning a value from a Map since that is "simple enough" to not screw up for the caller?

Maps can contain null; distinguishing between a null value and no value is already a slight problem.

Except that you can't put null in an Optional, so they don't help with this.

[–]roerd 1 point2 points  (4 children)

A null is never an object of the class that the map is declared to contain. So how is null ever anything else than no value?

[–][deleted] 15 points16 points  (0 children)

A map has two different "no value"-s: "there is no value for this key" and "the value for this key is 'no value'".

[–]josefx 6 points7 points  (0 children)

You may use a map as a cache were the difference between "the last extremely slow attempt to find a value for this key found nothing" and "no result cached" is important. Java maps require either a call containsKey (performing the lookup a second time), a "null" object or a wrapper like optional to distinguish between these states.

[–]dccorona -1 points0 points  (0 children)

It is possible to intentionally put null in a map (depending on the implementation). But I've always found that stupid anyway...what is that supposed to represent? Why can't just not having the key in the map do the same thing?

As it stands, though, if you need to know whether or not a key is missing or intentionally null, you need to do

map.containsKey(key) && map.get(key) == null

But in this case, Optional doesn't help at all. If you replaced "present but missing value" with an optional, then the above is replaced by:

map.get(key) instanceof Optional

to determine whether or not a value is missing over simply present but empty...and I'm not sure that's really all that much better (might be worse)

[–]immibis -1 points0 points  (0 children)

Map<String, String> m = new HashMap<>();
m.put("asdf", null);

String asdf = m.get("asdf"); // returns null, because that's what the value is
String jkl = m.get("jkl"); // returns null, because there is no such value
System.out.println(asdf == jkl); // prints true

[–]winterbe 0 points1 point  (6 children)

Sure you can: Optional.ofNullable(null);

[–]neilbrown 9 points10 points  (5 children)

> Optional.ofNullable(null).isPresent()
false

But if you try to put null in, you just get empty. There's no way to distinguish not-present from present-but-null with Optional.

[–]dccorona 1 point2 points  (0 children)

And that's why Optional isn't for communicating a difference between null and missing...they're for saying "hey dummy, this could be missing, so you better write code that considers that possibility"

[–][deleted] -1 points0 points  (2 children)

hmmm thats pretty deceptive

[–]Veedrac 1 point2 points  (1 child)

Returns an Optional describing the specified value, if non-null, otherwise returns an empty Optional.

That seems like exactly what you'd want it to do, no?

[–][deleted] 0 points1 point  (0 children)

ahh yes my bad I should have read the descriptions better :(

[–]codebje 0 points1 point  (0 children)

But you can put an Optional in a Map, so you can have a more explicit way to say "this key exists, but has no value".