Reputation: 25022
I am trying to create a map
from a Java
stream
. I am able to do this easily with javascript
and am trying to create the same thing in Java
. Here is my data structure:
var slips = [
{
original: 'Y',
lines: [
{
detailLines: {
detailLineId: 111
}
},
{
detailLines: {
detailLineId: 222
}
}
]
},
{
original: 'N',
lines: [
{
detailLines: {
detailLineId: 333
}
},
{
detailLines: {
detailLineId: 444
}
}
]
}
]
Here is how I did it in javascript
var test = slips.reduce((acc, slip) => {
slip.lines.map(line => line.detailLines.detailLineId)
.map(arr => acc[arr] = slip.original);
return acc;
}, {});
to get my result of
{
'111': 'Y',
'222': 'Y',
'333': 'N',
'444': 'N'
}
How do I do this using the Java 8 Stream api? The slips
above really is just a POJO
. I converted it to a JSON
object to do figure it out in js
. The real structure of the Objects are
class Slip {
private Boolean original;
private List<Line> lines;
}
class Line {
private List<DetailLine> detailLines;
}
class DetailLine {
private Long detailLine;
}
So what I have started with the Java
is
Map<Long, Boolean> results = slips.stream().reduce(new Map<Long, Boolean>, ...)
Upvotes: 1
Views: 7384
Reputation: 168
Here is a working example
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<DetailLine> detailedLines1 = new ArrayList<DetailLine>();
detailedLines1.add(new DetailLine(111l));
detailedLines1.add(new DetailLine(222l));
List<DetailLine> detailedLines2 = new ArrayList<DetailLine>();
detailedLines2.add(new DetailLine(333l));
detailedLines2.add(new DetailLine(444l));
Line line1 = new Line(detailedLines1);
Line line2 = new Line(detailedLines2);
List<Line> lines1 = new ArrayList<Line>();
lines1.add(line1);
List<Line> lines2 = new ArrayList<Line>();
lines2.add(line2);
List<Slip> slips = new ArrayList<Slip>();
slips.add(new Slip(true, lines1));
slips.add(new Slip(false, lines2));
Map<Long, Boolean> myResult = new HashMap<>();
slips.stream().map(
slip ->
slip.getLines().stream().map(
line -> line.getDetailLines().stream().map(deadLine -> deadLine.getDetailLine()).collect(Collectors.toList())
).flatMap(Collection::stream)
.map(l -> new AbstractMap.SimpleEntry<>(l, slip.getOriginal()))
).flatMap(l -> l).forEach(System.out::println);
}
}
Output
111=true
222=true
333=false
444=false
Upvotes: 0
Reputation: 93842
For me, it looks like a line object contains a single detail line and not a list.
class Slip {
private Boolean original;
private List<Line> lines;
}
class Line {
private DetailLine detailLine;
}
class DetailLine {
private Long detailLineId;
}
Assuming each detail line id is unique, you might use flatMap
to create the necessary mappings id -> Boolean, and simply collects them into a map.
import java.util.AbstractMap.SimpleEntry;
import static java.util.stream.Collectors.toMap;
...
Map<Long, Boolean> results =
slips.stream()
.flatMap(s -> s.getLines().stream().map(l -> new SimpleEntry<>(l.getDetailLine().getDetailLineId(), s.getOriginal())))
.collect(toMap(SimpleEntry::getKey, SimpleEntry::getValue))
If you indeed have the structure you claimed, you should flatMap
twice:
.flatMap(s -> s.getLines().stream().flatMap(l -> l.getDetailLine().stream().map(dl -> new SimpleEntry<>(dl.getDetailLineId(), s.getOriginal()))))
Upvotes: 2