Reputation: 2881
Generally I've been quite a fan of using List.of / Arrays.asList, but unfortunately they don't accept nulls. The usecase I most often stumble upon this, is when dealing with DB calls, and parameters are abstracted to be passed via list. So it always have to be of certain length for any given procedure, and optional values are given as nulls.
I found Why does Map.of not allow null keys and values? which mentions List.of, but mainly talks about maps. And in the case of maps, I agree -- ambiguity of .get
seems troublesome (key missing, or value intentionally null?), but this doesn't seem to apply to a list. If you get a null from a list, then you know for sure someone intentionally had put it there.
Some people might say "use optional", but I strongly believe it should be reserved for return types, and others seem to agree Uses for Optional
having an Optional in a class field or in a data structure, is considered a misuse of the API
What is the intended clean, standard solution? Does it really boil down to "use boilerplaty ArrayList initialization without these nice shorthand syntaxes" or "write your own util methods"?
Upvotes: 0
Views: 70
Reputation: 103018
Generally I've been quite a fan of using List.of / Arrays.asList, but unfortunately they don't accept nulls
This is incorrect:
List<String> list = Arrays.asList("a", "b", null);
String nullRef = list.get(2);
System.out.println(nullRef);
Works fine. List.of
indeed doesn't accept null
refs.
Some people might say "use optional"
Yeah, ignore those people.
What is the intended clean, standard solution?
Clean is a weaselword that is generally best read as: "I like it personally but am unwilling to just say that it's a taste preference" - it means nothing. You can't argue about taste, after all.
The standard solution, that is borderline objective language, we can work with that.
I think your API design that takes a list of db values is the problem. Presumably, you've written your own abstraction layer for this.
I'm having a hard time imaginine DB abstraction APIs where 'list of objects that includes null refs' is the right call.
If you're trying to weave prepared statement 'parameters', this would appear to be a nice API for that, and doesn't require lists at all:
db.select()
.append("SELECT a, b FROM c INNER JOIN d ON c.e = d.f ")
.append("WHERE (signup IS NULL OR signup < ?) ", LocalDate.now())
.append("AND LEFT(username, ?) = ?", 2, "AA")
.query()
If you're trying to abstract an insert/merge/upsert statement, you need some way of linking values with the column name that the value is a value for. This would suggest an API along the lines of:
db.insert("tableName")
.mergeOn("key", key)
.mergeOn("date", someDate)
.put("value", value)
.exec();
You can also re-use Map.of
for this purpose, in which case 'I want the db to use the default value for this column' is done by simply not including that key/value pair in your map, thus sidestepping your needs to put null
in such a map.
Perhaps if you show your specific API use-case, more insights can be provided.
If your question boils down to:
"I want to put null
refs and use List.of
, what is the standard clean way to do that"
then the answer is a rather obvious: There is nothing - as that does not work.
There is no --shut-up-List.of--let-me-add-nulls
command line switch.
Upvotes: 3