Java 8: how to 'JOIN' two Maps having the same Keys? [duplicate] - java

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())));

Related

Is the error reporting in Collectors.toMap() broken? [duplicate]

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]}

Java 8 collections streaming - Convert list to Set, transforming result [duplicate]

This question already has answers here:
How can I turn a List of Lists into a List in Java 8?
(12 answers)
Closed 5 years ago.
Imaging object with following method:
class A { List<B> getIds(){...} }
Now I have an Collection of A as input;
And I want to get set of unique Ids out of it, normally you would go for:
Set<B> ids = new HashSet<>();
for(A a : input){
ids.addAll(a.getIds());
}
Is there a way to do the same in one line using stream API, like following
Set<List<B>> set = input.stream().map((a) -> a.getIds()).collect(Collectors.toSet());
but making flat set of B
You have to use flatMap
input.stream()
.map(a -> a.getIds())
.flatMap(ids -> ids.stream())
.collect(Collectors.toSet());
This will produce flat Set.

Partition and map java streams in categories [duplicate]

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()));

java streams - collect elements from map of collections using condition on the values [duplicate]

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());

How to sort a map on map values [duplicate]

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.

Categories

Resources