I receive a List of Object arrays,
List<Object[]> rawRows = service.getRows();
Any particular value can be obtained as e.g.
(Date)((Object[])rawRows.get(i))[3] // In each item, Array Element #3 is a certain Date
I need to map this to a List<Report>
for a POJO which has specific fields defined for each value:
public class Report {
private String abbreviation;
private String username;
private Integer recallid;
private Date recalldate;
// ... + getters/setters
// Constructor
public Report (String abbreviation, String username, Integer recallid, Date recalldate, ...)
{
}
}
I'm stumped on the following: How would I specify the index in this Lamba expression to map to my new List<Report>
?
List<Report> detailReports = rawRows.stream().map(obj -> new Report(
(String)((Object[])rawRows.get(0))[0], // I'm hard-coding (0) but need "i"
(String)((Object[])rawRows.get(0))[1], // I'm hard-coding (0) but need "i"
(Integer)((Object[])rawRows.get(0))[2],// I'm hard-coding (0) but need "i"
(Date)((Object[])rawRows.get(0))[3], // I'm hard-coding (0) but need "i"
//...
)).collect(Collectors.toList());
My goal is to have a List<Report>
with all the array elements mapped to the POJO per object exactly per the specified sequence. But there's no i
index for me to track. In this example I'm hard-coding 0
as the rawRow
to get from the original List.
First, change your lambda from
obj -> new Report((String)((Object[])rawRows.get(0))[0] ...
to
obj -> new Report((String) obj[0] ...
obj
is the lambda parameter, and in the map()
function will take on the value of each item in rawRows
.
Next, I would really recommend converting the lambda into a separate, named function. This would have signature public Report rawRowToReport(Object[] rawRow)
and would hold all your indexing logic, instead of writing it in the lambda body.
The reason for this is, as you've noticed, "there's no i
index for me to track": this is because the indexing being done by i
is into the raw row itself. It's really just the deserialization logic for whatever is in the Object[]
. This sort of logic should be encapsulated in its own method (or ideally class) which only deals with serializing and/or deserializing. Outside users (like your Stream
) delegate the nitty gritty to that class or method. Ultimately, the Stream
only handles the process of iterating over the data and applying filters and transforms. It doesn't know what those filters and transforms require.
rawRows.stream().map(this::rawRowToReport).collect(Collectors.toList());