I have this class:
class A {
private List<String> keys;
private String otherData;
private int otherDate2;
// getter and setters for each
}
For this class I have a simple list filled with some data. List<A> listOfA
.
Now I want to convert this data to a map. Map<String, List<A>>
Currently we using a bunch of methods to archive this in a very complicated way. I think, we can solve it with a simple stream()
-operation.
I tried this
// first
listOfA.stream()
.collect(Colletors.groupingBy(a -> a.getKeys()))
// produces a Map<String, List<A>>
// second
listOfA.stream()
.flatMap(a -> a.getKeys().stream())
.collect(Colletors.groupingBy(string -> string))
// produces a Map<String, List<String>>
What is the right way for this situation?
Edit: To be clear, I want a Map<String, List<A>>
.
You can group DataFrame rows into a list by using pandas. DataFrame. groupby() function on the column of interest, select the column you want as a list from group and then use Series. apply(list) to get the list for every group.
You don't need streams for this. It's easier this way:
Map<String, List<A>> result = new HashMap<>();
listOfA.forEach(a -> a.getKeys().forEach(key ->
result.computeIfAbsent(key, k -> new ArrayList<>()).add(a)));
This iterates outer and inner lists and fills a Map
using computeIfAbsent
, which creates an empty list if there is still no value for the given key, then A
instances are simply added to the corresponding list.
The first code will group by Map<List<String>, List<A>>
and not Map<String, List<A>>
.
The second code makes no sense : you group strings by themselves...
A simple way would be creating the set of all possible key-A couples.
You could use a Map
for each couple but it looks like an overhead.SimpleImmutableEntry
that represents a key and value suits better.
Once you get the whole couples, you can easily group A elements by key.
You could try something like :
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toList;
// ...
List<A> listOfA = new ArrayList<>();
listOfA.add(new A(Arrays.asList("1", "2"), "foo1", 1));
listOfA.add(new A(Arrays.asList("2", "3"), "foo2", 2));
listOfA.add(new A(Arrays.asList("3", "4"), "foo3", 3));
Map<String, List<A>> map =
listOfA.stream()
.flatMap(a -> a.keys.stream()
.map(k -> new SimpleImmutableEntry<>(k, a)))
.collect(groupingBy(e -> e.getKey(), mapping(e -> e.getValue(), toList())));
map.forEach((k, v) -> System.out.println("key=" + k + ", value=" + v + "\n"));
Output :
key=1, value=[A [keys=[1, 2], otherData=foo1, otherDate2=1]]
key=2, value=[A [keys=[1, 2], otherData=foo1, otherDate2=1], A [keys=[2, 3], otherData=foo2, otherDate2=2]]
key=3, value=[A [keys=[2, 3], otherData=foo2, otherDate2=2], A [keys=[3, 4], otherData=foo3, otherDate2=3]]
key=4, value=[A [keys=[3, 4], otherData=foo3, otherDate2=3]]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With