This question already has answers here:
How to get the key in Collectors.toMap merge function?
(3 answers)
Collectors.toMap with same keys(print same key)
(2 answers)
Alternative for throwingMerger in Java 8
(1 answer)
Why does Collectors.toMap report value instead of key on Duplicate Key error?
(7 answers)
Closed 4 years ago.
List<String> strings = Arrays.asList("3","55","3");
Map<String,Integer> map = strings
.stream()
.collect(Collectors.toMap(s ->s, s -> s.length()));
returns
java.lang.IllegalStateException: Duplicate key 1
where I would expect Duplicate key 3
This was fixed in Java 9. Now the error message is correct:
java.lang.IllegalStateException: Duplicate key 3 (attempted merging values 1 and 1)
Seems, like this was a bug in JDK 8 but is no longer the case as of JDK 9. Reason one being that I cannot replicate it on JDK 9 and reason two this link provided by #Zircon derives about the issue and it being fixed as of JDK 9.
Seems like there have been several posts about this issue, another link being:
https://bugs.openjdk.java.net/browse/JDK-8040892
which itself is a duplicate of few other posts.
Yes it's a bug but there is another way of converting this into a map which is by using identity function:
List<String> strings = Arrays.asList("3","55","3");
Map<String, List<String>> map = strings.stream()
.collect(Collectors.toMap(Function.identity(), Arrays::asList));
By doing this you will get correct error which is
java.lang.IllegalStateException: Duplicate key [3]
For array with unique values
List<String> strings = Arrays.asList("3","55","4");
result would be
{55=[55], 3=[3], 4=[4]}
Related
This question already has answers here:
Java 8 Comparator comparing doesn't chain
(2 answers)
How do I get Comparator.comparing to correctly infer type parameters?
(2 answers)
Very confused by Java 8 Comparator type inference
(4 answers)
comparing and thenComparing gives compile error
(1 answer)
Comparator.reversed() does not compile using lambda
(4 answers)
Closed 3 years ago.
I have a list of Strings with two characters and want to sort by first character ascending and second character descending, for example "S1", "T1", "T2" should be sorted to "S1", "T2", "T1".
Seemed simple enough:
strings.sort(Comparator.comparing(code -> code.substring(0,1))
.thenComparing(code -> code.substring(1,2).reversed()));
After typing out the first part
strings.sort(Comparator.comparing(code -> code.substring(0,1))
Anything is still okay, autocomplete tells me about substring (Intellij), but when I add
.thenComparing(code -> code.substring(1,2).reversed()));
Somehow Java doesn't know anymore that it's working with Strings and gives me the error
Cannot resolve method 'substring' in 'Object'
for the .substring method calls on both.
Same happens when using stream().sorted()
This question already has answers here:
Join two maps by key
(3 answers)
Closed 4 years ago.
I have two Maps, both sharing the same keys, .
Map<Long/*JOIN.ID*/, Long/*Temp ID*/> tempIDsMap;
Map<Long/*JOIN.ID*/, Long/*Real ID*/> realIDsMap;
What I want to get (maybe using Java 8 Stream API and avoiding loops) is the JOIN of these maps on the JOIN.ID keys, to get a new Map like below:
Map<Long/*Temp ID*/. Long/*Real ID*/> realIDsByTempMap;
Use Collectors.toMap:
Map<Long,Long> realIDsByTempMap =
tempIDsMap.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getValue,
e -> realIDsMap.get(e.getKey())));
This question already has an answer here:
Partition java streams in categories [duplicate]
(1 answer)
Closed 5 years ago.
This question is a sort-of follow-up to Partition java streams in categories
I have a stream<A>, where
class A {
String category();
String data();
}
I would like to get a map<String, list<String>>, where the original stream is partitioned into sublists based on the value of category(), and then mapped to only extract the data(). It is pretty trivial to have it implemented using a for loop, but is it possible to get a more elegant solution harnessing java streams?
EXAMPLE:
Given {[a, xyz], [a, zyx], [b, abc]}, I would like to get a map:
a -> {xyz, zyx}
b -> {abc}
You need a slightly different groupBy
stream.collect(Collectors.groupingBy(A::getCategory,
Collectors.mapping(A::data, Collectors.toList()));
This question already has answers here:
Java - using Map how to find matching Key when Values are stored a List of strings
(4 answers)
Closed 6 years ago.
I have a Map. Let's say
Map>
I want to collect all the long values (keys)
when at least one myObj answers
myObj.isEnabled=false
using java stream.
I tried
map.entrySet().stream().filter(entry->entry.getValue().stream().filter(x->!x.isEnabled())).findAny().collect()
List<Long> keys = map.entrySet()
.stream()
.filter(e -> e.getValue().stream().anyMatch(o -> !o.isEnabled()))
.map(Map.Entry::getKey)
.collect(Collectors.toList());
This question already has answers here:
Sorting HashMap by values [duplicate]
(12 answers)
Closed 9 years ago.
I have a java Map
Map<String , String>
The map is like following
olah : 3
vola : 2
sola : 5
jingle : 9
i want to sort the map on the value string like sort on 3,2,5,9 for example...is there any efficient way possible.
I also want to know what difference it will make if i put a map with same values but
like
Map<String , long>
Does it improve any performance...?
See: Sort a Map<Key, Value> by values (Java)
Something like
Map<String , long>
is not possible because Java Collections can not store primitive types. If you want to do that, you can use fastutil http://fastutil.di.unimi.it/ or trove http://trove.starlight-systems.com/. Memory consumption will be better, since no Long objects are created.