I have a map of lists e.g.
HashMap exampleMap = new HashMap<String, List<Foo>>();
I want to initialise a new list if the key does not exist, I've been trying variations of putIfAbsent but have had no success so far
exampleMap.putIfAbsent('bar', () => []);
My ultimate goal is to add items to the list but the list needs to be initialised first
exampleMap['bar'].add(fooItem);
CodePudding user response:
There are a couple things wrong:
HashMap exampleMap = new HashMap<String, List<Foo>>();
This declares exampleMap
to be a HashMap<dynamic, dynamic>
. (See Why is dart wrongly inferring my generic parameter type? for an explanation why.)
The moral is: if you want to declare types explicitly, you must be explicit everywhere. You can't take half-measures. Otherwise just use var
and allow the type of the variable to be inferred from the right-hand-side.
Later when you do:
exampleMap.putIfAbsent('bar', () => []);
Because exampleMap
's static (known at compile-time) type is HashMap<dynamic, dynamic>
, nothing is known about the type for the HashMap
's values. The return type of the anonymous function (() => []
) thus cannot be inferred, and since it returns an empty list with no explicit type parameter, the List
's element type also cannot be inferred. The anonymous function therefore is compiled as a Function
that returns a List<dynamic>
.
Meanwhile, exampleMap
's runtime type is actually a HashMap<String, List<Foo>>
. When you execute the code, putIfAbsent
will fail due to the inability to safely add a List<dynamic>
where a List<Foo>
is expected.
If you fix your original declaration to use var
, then your putIfAbsent
call should work without any additional changes. If you actually do want exampleMap
's static type to be HashMap<dynamic, dynamic>
, then you alternatively could change your putIfAbsent
call to provide an explicit type for the empty List
: exampleMap.putIfAbsent('bar', () => <Foo>[])
.
I'll also point out that if you don't allow null
values in your Map
, I much prefer using ??=
over putIfAbsent
:
var exampleMap = HashMap<String, List<Foo>>();
exampleMap['bar'] ??= [];