I have a Set<DateCount>
which I create using the following code. This creates a set of 7 DateCount
objects with an initial count of 0, one for each day of the current week starting from the current day.
// Create an initial Set of DateCount objects for the current week with counts of 0
Set<DateCount> dateCounts = IntStream.range(0, DAYS_IN_WEEK)
.mapToObj(idx -> new DateTime().withTimeAtStartOfDay().plusDays(idx))
.map(dt -> new DateCount(dt.toDate(), 0L))
.collect(toSet());
I have a List<Object[]>
which is returned from a database repository. Each Object[]
in the list has a BigDecimal
at index 0 and a Long
at index 1. The BigDecimal
is actually a date, something like 20141001
. What I'm wondering is if there is a way I can update the dateCounts
set using this data in a Stream fashion. Right now, I'm doing the following which just iterates over the list of object arrays and creates new DateCount
objects that are then added to the dateCounts
set. The DateCount
class has a custom equals()
and hashCode()
method to ensure the dateCounts
set contains only a single DateCount
instance for any given date.
data.stream()
.forEach(obj -> {
DateTime date = null;
try {
date = (sdf == null) ? new DateTime(obj[0]) : new DateTime(sdf.parse(obj[0].toString()));
dateCounts.add(new DateCount(date.toDate(), (Long) obj[1]));
} catch (ParseException e) {
e.printStackTrace();
}
});
On a side note, I'm wondering if there's also a way to avoid doing a try/catch in my lambda expression just for parsing a String
to a Date
.
Update -- This is what I've come up with so far. It doesn't seem natural though to stream over the List<Object[]>
within the .map call, not sure if there's a better way. I introduced my own Tuple<X, Y>
class because working with an Object[]
in streams doesn't work very well given there's no accessor methods. Also in the last 2 lines, I'm creating a TreeSet
with a Comparator
so that I can sort the data by date. I don't feel that's the best approach, but I tried calling sorted()
and making DateCount
implement Comparable
which seems to work fine, but as soon as the collect(toSet())
method is called, the sorting goes out the window. I assume that's the nature of it being a streamed call. I'm curious if there's a way to sort it though before the collect method call and retain the sort after calling collect.
Set<DateCount> dateCounts = IntStream.range(0, DAYS_IN_WEEK)
.mapToObj(idx -> new Tuple<>(new DateTime().withTimeAtStartOfDay().plusDays(idx).toDate(), 0L))
.map(t -> {
Tuple<String, Long> d = data.stream()
.map(arr -> new Tuple<>(arr[0].toString(), (Long) arr[1]))
.filter(tuple -> sdf.format(t.getX()).equals(tuple.getX()))
.findFirst().orElse(new Tuple<>(sdf.format(t.getX()), 0L));
return new DateCount(DateTime.parse(d.getX(), DateTimeFormat.forPattern("yyyyMMdd")).toDate(), d.getY());
})
.collect(toSet());
TreeSet<DateCount> set = new TreeSet<>((a, b) -> a.compareTo(b));
set.addAll(dateCounts);