Reputation: 1885
I want to convert a list of dates to a map where the month is the key and the values is a list of dates with the given month.
I have the following month object, which basically is holding a month and a year int, so each month is unique.
public class Month implements Serializable, Comparable<Month> {
protected int year;
protected int month;
public Month(Date dag) {
Calendar cal = Calendar.getInstance();
cal.setTime(dag);
this.month = cal.get(Calendar.MONTH)+1; //zerobased to onebased
this.year = cal.get(Calendar.YEAR);
}
}
And now given a list of dates i try do do something like this:
public void addLedigeDage(List<Date> newLedigeDage) {
List<Date> datesPerMonth = new ArrayList<>();
Calendar cal = Calendar.getInstance();
for (Date date : newLedigeDage) {
cal.setTime(date);
Month month = new Month(date);
datesPerMonth = findAllDatesForGivenMonth(newLedigeDage, cal.get(Calendar.MONTH));
ledigeDageMap.put(month, datesPerMonth);
}
}
private List<Date> findAllDatesForGivenMonth(List<Date> newLedigeDage, int month) {
Calendar cal = Calendar.getInstance();
List<Date> datesForGivenMonth = new ArrayList<>();
for (Date date : newLedigeDage) {
if (cal.get(Calendar.MONTH) == month ) {
datesForGivenMonth.add(date);
}
}
return datesForGivenMonth;
}
But the code is not clean and not optimal, since i iterate over same dates too many times.
I am using java 1.7 and have Guava available. I cannot use a Multimap in this case, because of some architecture issues in my application.
Any suggestions on how to optimize this and make it clean?
Upvotes: 1
Views: 315
Reputation: 167
There are several problems with your code: 1st: Don't Lie in your code (Month contains month and year). Should be some more specific name.
2nd: override equals and hashcode method other wise two month object with same month and year value will be treated different by Map.
Apart from this DaveyDaveDave answer is good to go.
Upvotes: 0
Reputation: 65851
There is an elegant Java-8 solution:
List<Date> dates = Arrays.asList(new Date(10000), new Date(100000));
Map<Month, List<Date>> byMonth = dates.stream()
.collect(Collectors.groupingBy(d -> new Month(d)));
Upvotes: 2
Reputation: 10612
I think I'd do something like:
public void addLedigeDage(List<Date> newLedigeDage) {
for (Date date : newLedigeDage) {
Month month = new Month(date);
if (!ledigeDageMap.containsKey(month)) {
ledigeDageMap.put(month, new ArrayList<>());
}
ledigeDageMap.get(month).add(date);
}
}
If you wanted, you could then extract:
if (!ledigeDageMap.containsKey(month)) {
ledigeDageMap.put(month, new ArrayList<>());
}
ledigeDageMap.get(month).add(date);
as a separate method called something like addDateToMap
to be a bit cleaner.
Upvotes: 1