Java Map computeIfAbsent issue

Multi tool use
So I found a curiosity with Java's Map computeIfAbsent
(using java8) method and I hope someone can tell me why this is happening as I can not really follow the logic behind that issue.
So, I have a Map with a key (obviously) and the value is a list and I use the computeIfAbsent to create a new list when a key is not set yet. Now when I use an Integer as key I can use the following:
List<Object> list = map.computeIfAbsent(1, ArrayList::new);
But when I use a String as key trying to use
List<Object> list = map.computeIfAbsent("key", ArrayList::new);
I get the error that The method computeIfAbsent(String, Function<? super String,? extends List<Object>>) in the type Map<String,List<Object>> is not applicable for the arguments (String, ArrayList::new)
. Is there just the implementation missing? Using a String key I have to use the method like that, which is then working again.
List<Object> list = map.computeIfAbsent("key", k -> new ArrayList<>());
Maybe someone can enlighten me about that. Thanks :)
java java-8 functional-programming
add a comment |
So I found a curiosity with Java's Map computeIfAbsent
(using java8) method and I hope someone can tell me why this is happening as I can not really follow the logic behind that issue.
So, I have a Map with a key (obviously) and the value is a list and I use the computeIfAbsent to create a new list when a key is not set yet. Now when I use an Integer as key I can use the following:
List<Object> list = map.computeIfAbsent(1, ArrayList::new);
But when I use a String as key trying to use
List<Object> list = map.computeIfAbsent("key", ArrayList::new);
I get the error that The method computeIfAbsent(String, Function<? super String,? extends List<Object>>) in the type Map<String,List<Object>> is not applicable for the arguments (String, ArrayList::new)
. Is there just the implementation missing? Using a String key I have to use the method like that, which is then working again.
List<Object> list = map.computeIfAbsent("key", k -> new ArrayList<>());
Maybe someone can enlighten me about that. Thanks :)
java java-8 functional-programming
As a side note, Guava'sMultiMap
already implements what you're looking for.
– chrylis
Dec 19 '18 at 7:28
and its worth mentioning the type ofmap
used in the code for clarity of the question
– nullpointer
Dec 19 '18 at 7:46
I'm pretty sure this is a duplicate, but it's hard to find :-/
– Marco13
Dec 19 '18 at 22:14
Ah, there it is: stackoverflow.com/q/35296734/3182664 - any objections to close this one as a duplicate of the other?
– Marco13
Dec 19 '18 at 22:16
add a comment |
So I found a curiosity with Java's Map computeIfAbsent
(using java8) method and I hope someone can tell me why this is happening as I can not really follow the logic behind that issue.
So, I have a Map with a key (obviously) and the value is a list and I use the computeIfAbsent to create a new list when a key is not set yet. Now when I use an Integer as key I can use the following:
List<Object> list = map.computeIfAbsent(1, ArrayList::new);
But when I use a String as key trying to use
List<Object> list = map.computeIfAbsent("key", ArrayList::new);
I get the error that The method computeIfAbsent(String, Function<? super String,? extends List<Object>>) in the type Map<String,List<Object>> is not applicable for the arguments (String, ArrayList::new)
. Is there just the implementation missing? Using a String key I have to use the method like that, which is then working again.
List<Object> list = map.computeIfAbsent("key", k -> new ArrayList<>());
Maybe someone can enlighten me about that. Thanks :)
java java-8 functional-programming
So I found a curiosity with Java's Map computeIfAbsent
(using java8) method and I hope someone can tell me why this is happening as I can not really follow the logic behind that issue.
So, I have a Map with a key (obviously) and the value is a list and I use the computeIfAbsent to create a new list when a key is not set yet. Now when I use an Integer as key I can use the following:
List<Object> list = map.computeIfAbsent(1, ArrayList::new);
But when I use a String as key trying to use
List<Object> list = map.computeIfAbsent("key", ArrayList::new);
I get the error that The method computeIfAbsent(String, Function<? super String,? extends List<Object>>) in the type Map<String,List<Object>> is not applicable for the arguments (String, ArrayList::new)
. Is there just the implementation missing? Using a String key I have to use the method like that, which is then working again.
List<Object> list = map.computeIfAbsent("key", k -> new ArrayList<>());
Maybe someone can enlighten me about that. Thanks :)
java java-8 functional-programming
java java-8 functional-programming
edited Dec 19 '18 at 7:29
asked Dec 19 '18 at 7:27
Fussel
64313
64313
As a side note, Guava'sMultiMap
already implements what you're looking for.
– chrylis
Dec 19 '18 at 7:28
and its worth mentioning the type ofmap
used in the code for clarity of the question
– nullpointer
Dec 19 '18 at 7:46
I'm pretty sure this is a duplicate, but it's hard to find :-/
– Marco13
Dec 19 '18 at 22:14
Ah, there it is: stackoverflow.com/q/35296734/3182664 - any objections to close this one as a duplicate of the other?
– Marco13
Dec 19 '18 at 22:16
add a comment |
As a side note, Guava'sMultiMap
already implements what you're looking for.
– chrylis
Dec 19 '18 at 7:28
and its worth mentioning the type ofmap
used in the code for clarity of the question
– nullpointer
Dec 19 '18 at 7:46
I'm pretty sure this is a duplicate, but it's hard to find :-/
– Marco13
Dec 19 '18 at 22:14
Ah, there it is: stackoverflow.com/q/35296734/3182664 - any objections to close this one as a duplicate of the other?
– Marco13
Dec 19 '18 at 22:16
As a side note, Guava's
MultiMap
already implements what you're looking for.– chrylis
Dec 19 '18 at 7:28
As a side note, Guava's
MultiMap
already implements what you're looking for.– chrylis
Dec 19 '18 at 7:28
and its worth mentioning the type of
map
used in the code for clarity of the question– nullpointer
Dec 19 '18 at 7:46
and its worth mentioning the type of
map
used in the code for clarity of the question– nullpointer
Dec 19 '18 at 7:46
I'm pretty sure this is a duplicate, but it's hard to find :-/
– Marco13
Dec 19 '18 at 22:14
I'm pretty sure this is a duplicate, but it's hard to find :-/
– Marco13
Dec 19 '18 at 22:14
Ah, there it is: stackoverflow.com/q/35296734/3182664 - any objections to close this one as a duplicate of the other?
– Marco13
Dec 19 '18 at 22:16
Ah, there it is: stackoverflow.com/q/35296734/3182664 - any objections to close this one as a duplicate of the other?
– Marco13
Dec 19 '18 at 22:16
add a comment |
2 Answers
2
active
oldest
votes
The mapping function - Function<? super K, ? extends V> mappingFunction
- maps a key to a value, so when the key is Integer
, ArrayList::new
works, since ArrayList
has a constructor that takes an int (the initial capacity). On the other hand, it doesn't have a constructor that takes a String
.
Since the key probably shouldn't affect the initial capacity of the ArrayList
, you should not use a method reference here (in both cases). Use lambda expression.
To make it clearer:
List<Object> list = map.computeIfAbsent(1, ArrayList::new);
behaves similar to:
List<Object> list = map.computeIfAbsent(1, k -> new ArrayList<>(k));
so it will create an ArrayList
with initial capacity of 1.
On the other hand:
List<Object> list = map.computeIfAbsent("key", ArrayList::new);
behaves similar to:
List<Object> list = map.computeIfAbsent("key", k -> new ArrayList<>(k));
where k
is a String
, so it doesn't pass compilation.
And more specifically,1 -> ArrayList::new
does not in fact produce a list with the value1
inserted.
– chrylis
Dec 19 '18 at 7:30
So when usingArrayList::new
the given key is inserted into the list? That in my example I'd have a List with the value 1 already in it?
– Fussel
Dec 19 '18 at 7:33
@chrylis did the OP expect such behavior (1 being inserted into the List)? I didn't see that mentioned in the question.
– Eran
Dec 19 '18 at 7:33
1
@Fussel the key will not be part of the list either way, but you are correct to use lambda expressions in both cases (Integer and String key). No, theList
beingList<String>
makes no difference, since the key is not added to the List, it is passed to theArrayList
constructor (which doesn't work for Strings, since ArrayList has no constructor that accepts a String).
– Eran
Dec 19 '18 at 7:45
2
@Fussel If you replace1
with 1 billion you might get a memory error since Java will try to allocate an array that has the capacity of storing 1 billion elements. Note that capacity != actual elements. An emptyArrayList
can consume an arbitrary amount of memory depending on the capacity.
– Giacomo Alzetta
Dec 19 '18 at 15:08
|
show 2 more comments
Your second attempt
List<Object> list = map.computeIfAbsent("key", ArrayList::new);
would actually be equal to
List<Object> list = map.computeIfAbsent("key", k -> new ArrayList<>(k));
and since ArrayList
has no constructor taking a String as a parameter, it doesn't work. The first example works as it creates a list with one element.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53846428%2fjava-map-computeifabsent-issue%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
The mapping function - Function<? super K, ? extends V> mappingFunction
- maps a key to a value, so when the key is Integer
, ArrayList::new
works, since ArrayList
has a constructor that takes an int (the initial capacity). On the other hand, it doesn't have a constructor that takes a String
.
Since the key probably shouldn't affect the initial capacity of the ArrayList
, you should not use a method reference here (in both cases). Use lambda expression.
To make it clearer:
List<Object> list = map.computeIfAbsent(1, ArrayList::new);
behaves similar to:
List<Object> list = map.computeIfAbsent(1, k -> new ArrayList<>(k));
so it will create an ArrayList
with initial capacity of 1.
On the other hand:
List<Object> list = map.computeIfAbsent("key", ArrayList::new);
behaves similar to:
List<Object> list = map.computeIfAbsent("key", k -> new ArrayList<>(k));
where k
is a String
, so it doesn't pass compilation.
And more specifically,1 -> ArrayList::new
does not in fact produce a list with the value1
inserted.
– chrylis
Dec 19 '18 at 7:30
So when usingArrayList::new
the given key is inserted into the list? That in my example I'd have a List with the value 1 already in it?
– Fussel
Dec 19 '18 at 7:33
@chrylis did the OP expect such behavior (1 being inserted into the List)? I didn't see that mentioned in the question.
– Eran
Dec 19 '18 at 7:33
1
@Fussel the key will not be part of the list either way, but you are correct to use lambda expressions in both cases (Integer and String key). No, theList
beingList<String>
makes no difference, since the key is not added to the List, it is passed to theArrayList
constructor (which doesn't work for Strings, since ArrayList has no constructor that accepts a String).
– Eran
Dec 19 '18 at 7:45
2
@Fussel If you replace1
with 1 billion you might get a memory error since Java will try to allocate an array that has the capacity of storing 1 billion elements. Note that capacity != actual elements. An emptyArrayList
can consume an arbitrary amount of memory depending on the capacity.
– Giacomo Alzetta
Dec 19 '18 at 15:08
|
show 2 more comments
The mapping function - Function<? super K, ? extends V> mappingFunction
- maps a key to a value, so when the key is Integer
, ArrayList::new
works, since ArrayList
has a constructor that takes an int (the initial capacity). On the other hand, it doesn't have a constructor that takes a String
.
Since the key probably shouldn't affect the initial capacity of the ArrayList
, you should not use a method reference here (in both cases). Use lambda expression.
To make it clearer:
List<Object> list = map.computeIfAbsent(1, ArrayList::new);
behaves similar to:
List<Object> list = map.computeIfAbsent(1, k -> new ArrayList<>(k));
so it will create an ArrayList
with initial capacity of 1.
On the other hand:
List<Object> list = map.computeIfAbsent("key", ArrayList::new);
behaves similar to:
List<Object> list = map.computeIfAbsent("key", k -> new ArrayList<>(k));
where k
is a String
, so it doesn't pass compilation.
And more specifically,1 -> ArrayList::new
does not in fact produce a list with the value1
inserted.
– chrylis
Dec 19 '18 at 7:30
So when usingArrayList::new
the given key is inserted into the list? That in my example I'd have a List with the value 1 already in it?
– Fussel
Dec 19 '18 at 7:33
@chrylis did the OP expect such behavior (1 being inserted into the List)? I didn't see that mentioned in the question.
– Eran
Dec 19 '18 at 7:33
1
@Fussel the key will not be part of the list either way, but you are correct to use lambda expressions in both cases (Integer and String key). No, theList
beingList<String>
makes no difference, since the key is not added to the List, it is passed to theArrayList
constructor (which doesn't work for Strings, since ArrayList has no constructor that accepts a String).
– Eran
Dec 19 '18 at 7:45
2
@Fussel If you replace1
with 1 billion you might get a memory error since Java will try to allocate an array that has the capacity of storing 1 billion elements. Note that capacity != actual elements. An emptyArrayList
can consume an arbitrary amount of memory depending on the capacity.
– Giacomo Alzetta
Dec 19 '18 at 15:08
|
show 2 more comments
The mapping function - Function<? super K, ? extends V> mappingFunction
- maps a key to a value, so when the key is Integer
, ArrayList::new
works, since ArrayList
has a constructor that takes an int (the initial capacity). On the other hand, it doesn't have a constructor that takes a String
.
Since the key probably shouldn't affect the initial capacity of the ArrayList
, you should not use a method reference here (in both cases). Use lambda expression.
To make it clearer:
List<Object> list = map.computeIfAbsent(1, ArrayList::new);
behaves similar to:
List<Object> list = map.computeIfAbsent(1, k -> new ArrayList<>(k));
so it will create an ArrayList
with initial capacity of 1.
On the other hand:
List<Object> list = map.computeIfAbsent("key", ArrayList::new);
behaves similar to:
List<Object> list = map.computeIfAbsent("key", k -> new ArrayList<>(k));
where k
is a String
, so it doesn't pass compilation.
The mapping function - Function<? super K, ? extends V> mappingFunction
- maps a key to a value, so when the key is Integer
, ArrayList::new
works, since ArrayList
has a constructor that takes an int (the initial capacity). On the other hand, it doesn't have a constructor that takes a String
.
Since the key probably shouldn't affect the initial capacity of the ArrayList
, you should not use a method reference here (in both cases). Use lambda expression.
To make it clearer:
List<Object> list = map.computeIfAbsent(1, ArrayList::new);
behaves similar to:
List<Object> list = map.computeIfAbsent(1, k -> new ArrayList<>(k));
so it will create an ArrayList
with initial capacity of 1.
On the other hand:
List<Object> list = map.computeIfAbsent("key", ArrayList::new);
behaves similar to:
List<Object> list = map.computeIfAbsent("key", k -> new ArrayList<>(k));
where k
is a String
, so it doesn't pass compilation.
edited Dec 19 '18 at 7:36
answered Dec 19 '18 at 7:29


Eran
279k37452537
279k37452537
And more specifically,1 -> ArrayList::new
does not in fact produce a list with the value1
inserted.
– chrylis
Dec 19 '18 at 7:30
So when usingArrayList::new
the given key is inserted into the list? That in my example I'd have a List with the value 1 already in it?
– Fussel
Dec 19 '18 at 7:33
@chrylis did the OP expect such behavior (1 being inserted into the List)? I didn't see that mentioned in the question.
– Eran
Dec 19 '18 at 7:33
1
@Fussel the key will not be part of the list either way, but you are correct to use lambda expressions in both cases (Integer and String key). No, theList
beingList<String>
makes no difference, since the key is not added to the List, it is passed to theArrayList
constructor (which doesn't work for Strings, since ArrayList has no constructor that accepts a String).
– Eran
Dec 19 '18 at 7:45
2
@Fussel If you replace1
with 1 billion you might get a memory error since Java will try to allocate an array that has the capacity of storing 1 billion elements. Note that capacity != actual elements. An emptyArrayList
can consume an arbitrary amount of memory depending on the capacity.
– Giacomo Alzetta
Dec 19 '18 at 15:08
|
show 2 more comments
And more specifically,1 -> ArrayList::new
does not in fact produce a list with the value1
inserted.
– chrylis
Dec 19 '18 at 7:30
So when usingArrayList::new
the given key is inserted into the list? That in my example I'd have a List with the value 1 already in it?
– Fussel
Dec 19 '18 at 7:33
@chrylis did the OP expect such behavior (1 being inserted into the List)? I didn't see that mentioned in the question.
– Eran
Dec 19 '18 at 7:33
1
@Fussel the key will not be part of the list either way, but you are correct to use lambda expressions in both cases (Integer and String key). No, theList
beingList<String>
makes no difference, since the key is not added to the List, it is passed to theArrayList
constructor (which doesn't work for Strings, since ArrayList has no constructor that accepts a String).
– Eran
Dec 19 '18 at 7:45
2
@Fussel If you replace1
with 1 billion you might get a memory error since Java will try to allocate an array that has the capacity of storing 1 billion elements. Note that capacity != actual elements. An emptyArrayList
can consume an arbitrary amount of memory depending on the capacity.
– Giacomo Alzetta
Dec 19 '18 at 15:08
And more specifically,
1 -> ArrayList::new
does not in fact produce a list with the value 1
inserted.– chrylis
Dec 19 '18 at 7:30
And more specifically,
1 -> ArrayList::new
does not in fact produce a list with the value 1
inserted.– chrylis
Dec 19 '18 at 7:30
So when using
ArrayList::new
the given key is inserted into the list? That in my example I'd have a List with the value 1 already in it?– Fussel
Dec 19 '18 at 7:33
So when using
ArrayList::new
the given key is inserted into the list? That in my example I'd have a List with the value 1 already in it?– Fussel
Dec 19 '18 at 7:33
@chrylis did the OP expect such behavior (1 being inserted into the List)? I didn't see that mentioned in the question.
– Eran
Dec 19 '18 at 7:33
@chrylis did the OP expect such behavior (1 being inserted into the List)? I didn't see that mentioned in the question.
– Eran
Dec 19 '18 at 7:33
1
1
@Fussel the key will not be part of the list either way, but you are correct to use lambda expressions in both cases (Integer and String key). No, the
List
being List<String>
makes no difference, since the key is not added to the List, it is passed to the ArrayList
constructor (which doesn't work for Strings, since ArrayList has no constructor that accepts a String).– Eran
Dec 19 '18 at 7:45
@Fussel the key will not be part of the list either way, but you are correct to use lambda expressions in both cases (Integer and String key). No, the
List
being List<String>
makes no difference, since the key is not added to the List, it is passed to the ArrayList
constructor (which doesn't work for Strings, since ArrayList has no constructor that accepts a String).– Eran
Dec 19 '18 at 7:45
2
2
@Fussel If you replace
1
with 1 billion you might get a memory error since Java will try to allocate an array that has the capacity of storing 1 billion elements. Note that capacity != actual elements. An empty ArrayList
can consume an arbitrary amount of memory depending on the capacity.– Giacomo Alzetta
Dec 19 '18 at 15:08
@Fussel If you replace
1
with 1 billion you might get a memory error since Java will try to allocate an array that has the capacity of storing 1 billion elements. Note that capacity != actual elements. An empty ArrayList
can consume an arbitrary amount of memory depending on the capacity.– Giacomo Alzetta
Dec 19 '18 at 15:08
|
show 2 more comments
Your second attempt
List<Object> list = map.computeIfAbsent("key", ArrayList::new);
would actually be equal to
List<Object> list = map.computeIfAbsent("key", k -> new ArrayList<>(k));
and since ArrayList
has no constructor taking a String as a parameter, it doesn't work. The first example works as it creates a list with one element.
add a comment |
Your second attempt
List<Object> list = map.computeIfAbsent("key", ArrayList::new);
would actually be equal to
List<Object> list = map.computeIfAbsent("key", k -> new ArrayList<>(k));
and since ArrayList
has no constructor taking a String as a parameter, it doesn't work. The first example works as it creates a list with one element.
add a comment |
Your second attempt
List<Object> list = map.computeIfAbsent("key", ArrayList::new);
would actually be equal to
List<Object> list = map.computeIfAbsent("key", k -> new ArrayList<>(k));
and since ArrayList
has no constructor taking a String as a parameter, it doesn't work. The first example works as it creates a list with one element.
Your second attempt
List<Object> list = map.computeIfAbsent("key", ArrayList::new);
would actually be equal to
List<Object> list = map.computeIfAbsent("key", k -> new ArrayList<>(k));
and since ArrayList
has no constructor taking a String as a parameter, it doesn't work. The first example works as it creates a list with one element.
answered Dec 19 '18 at 7:30


Jan Gassen
1,69011531
1,69011531
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53846428%2fjava-map-computeifabsent-issue%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
ISo8cbbEs8z4hwWmOuZ yq9 Y3q mN94Mbra,1SjIqvB n7W 5ph9WrtPKYaNO,QudC miXEOHeGtpdTbEsiVXNGNYT,v6Xq 0C 6178D6xn
As a side note, Guava's
MultiMap
already implements what you're looking for.– chrylis
Dec 19 '18 at 7:28
and its worth mentioning the type of
map
used in the code for clarity of the question– nullpointer
Dec 19 '18 at 7:46
I'm pretty sure this is a duplicate, but it's hard to find :-/
– Marco13
Dec 19 '18 at 22:14
Ah, there it is: stackoverflow.com/q/35296734/3182664 - any objections to close this one as a duplicate of the other?
– Marco13
Dec 19 '18 at 22:16