I had an interview yesterday where I was asked to write a function that would take in a list containing a date and the amount of money spent on that date, and to output the total amount spent per month. The data was for an energy company, so the amount spent corresponds to the amount of energy used that day.
Some conditions were:
- The list will only contain 1 years worth of data
- This list is in the order each usage/transaction occurred
- But the list can start at any point and date within the year (i.e if it started on Feb 2nd 2017, it would only contain data up till Feb 1st 2018)
They left it kind of open after that on how to proceed. I didn't manage to get it done in the interview, although I think I had the right approach.
The sample data looks like this:
(("2017-02-13", 1200.00), ("2017-02-19", 50.00), ("2017-04-10", 100.45), etc..)
My solution would output a table similar to the following:
Month-Year | Usage
--------------------------------
January-2017 | 2400.0
February-2017 | 1250.0
April-2017 | 100.45
May-2017 | 225.0
December-2017 | 460.9
January-2018 | 1550.0
My code is below. Please let me know if you think there is simpler way to do this. I thought maybe instead of a Map
, I could have another class called MonthlyUsage
, and make a list of that instead to hold the data, but I wasn't too sure how to implement that with this approach.
DailyUsage.java
package com.energy;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
public class DailyUsage {
private Date date;
private double usage;
private Calendar c = Calendar.getInstance();
public DailyUsage(String dateStr, double usage) throws ParseException {
Date formattedDate = new SimpleDateFormat("yyyy-MM-dd").parse(dateStr);
this.date = formattedDate;
this.usage = usage;
}
public int getMonth() {
c.setTime(date);
return c.get(Calendar.MONTH);
}
public String getMonthName() {
c.setTime(date);
String month = c.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault());
return month;
}
public double getUsage() {
return usage;
}
public int getYear() {
c.setTime(date);
int year = c.get(Calendar.YEAR);
return year;
}
}
EnergyCalculator.java
package com.energy;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class EnergyCalculator {
public static void main(String[] args) throws ParseException {
List<DailyUsage> dailyUsageList = populateList();
Map<String, Double> monthlyUsage = calculateMonthlyUsage(dailyUsageList);
System.out.println("Month-Year \t | \tUsage "
+ "\n--------------------------------");
for (Map.Entry<String, Double> use : monthlyUsage.entrySet()) {
System.out.println(use.getKey() + "\t | \t" + use.getValue());
}
}
protected static Map<String, Double> calculateMonthlyUsage(
List<DailyUsage> usageList) {
// Map to store month and usage
Map<String, Double> usageMonthMap = new LinkedHashMap<String, Double>();
for (DailyUsage usage : usageList) {
// SB for making unique key of month and year
StringBuilder combinedKey = new StringBuilder();
combinedKey.append(usage.getMonthName() + "-" + usage.getYear());
if (!usageMonthMap.containsKey(combinedKey.toString())) {
usageMonthMap.put(combinedKey.toString(), usage.getUsage());
}
else {
double currentUsage = usageMonthMap.get(combinedKey.toString());
currentUsage += usage.getUsage();
usageMonthMap.put(combinedKey.toString(), currentUsage);
}
}
return usageMonthMap;
}
private static List<DailyUsage> populateList() throws ParseException {
// Test data
List<DailyUsage> dailyUsageList = new ArrayList<DailyUsage>();
dailyUsageList.add(new DailyUsage("2017-01-20", 1200.00));
dailyUsageList.add(new DailyUsage("2017-01-24", 1200.00));
dailyUsageList.add(new DailyUsage("2017-02-13", 1200.00));
dailyUsageList.add(new DailyUsage("2017-02-19", 50.00));
dailyUsageList.add(new DailyUsage("2017-04-10", 100.45));
dailyUsageList.add(new DailyUsage("2017-05-19", 225.00));
dailyUsageList.add(new DailyUsage("2017-12-20", 400.50));
dailyUsageList.add(new DailyUsage("2017-12-29", 60.40));
dailyUsageList.add(new DailyUsage("2018-01-05", 700));
dailyUsageList.add(new DailyUsage("2018-01-07", 150));
dailyUsageList.add(new DailyUsage("2018-01-15", 700));
return dailyUsageList;
}
}