I am trying to count the frequency of all dates from a text file. The dates are stored in parsed.get(0) but when I print the frequency I get this output:
1946-01-12: 1
1946-01-12: 1
1946-01-12: 1
1946-01-13: 1
1946-01-13: 1
1946-01-13: 1
1946-01-14: 1
1946-01-14: 1
1946-01-14: 1
1946-01-15: 1
instead of
1946-01-12: 3
1946-01-13: 3
1946-01-14: 3
1946-01-15: 1
I guess it is because I have to store the dates like ("1946-01-12", "1946-01-12", "1946-01-12", "1946-01-12", "1946-01-13", "1946-01-13",...). If I just print parsed.get(0) I get
1946-01-12
1946-01-12
1946-01-12
1946-01-13
1946-01-13
1946-01-13
1946-01-14
1946-01-14
1946-01-14
1946-01-15`
How can I solve it based on my code below?
private static List<WeatherDataHandler> weatherData = new ArrayList<>();
public void loadData(String filePath) throws IOException {
//Read all data
List<String> fileData = Files.readAllLines(Paths.get("filePath"));
System.out.println(fileData);
for(String str : fileData) {
List<String> parsed = parseData(str);
LocalDate dateTime = LocalDate.parse(parsed.get(0));
WeatherDataHandler weather = new WeatherDataHandler(dateTime, Time, temperature, tag);
weatherData.add(weather);
List<String> list = Arrays.asList(parsed.get(0));
Map<String, Long> frequencyMap =
list.stream().collect(Collectors.groupingBy(Function.identity(),
Collectors.counting()));
for (Map.Entry<String, Long> entry : frequencyMap.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
Based on how I think this is working I would do it as follows. Comments included to explain additional logic. The main idea is to do as much inside your main loop as possible. Creating the frequenceyMap
outside the loop with a stream
is additional and unnecessary work.
private static List<WeatherDataHandler> weatherData =
new ArrayList<>();
public void loadData(String filePath) throws IOException {
// Read all data
List<String> fileData =
Files.readAllLines(Paths.get("filePath"));
System.out.println(fileData);
// Pre-instantiate the freqency map.
Map<String, Long> frequencyMap = new LinkedHashMap<>();
for (String str : fileData) {
List<String> parsed = parseData(str);
LocalDate dateTime =
LocalDate.parse(parsed.get(0));
WeatherDataHandler weather = new WeatherDataHandler(
dateTime, Time, temperature, tag);
weatherData.add(weather);
// Ensure dateTime is a string. This may not have the desired
// format for date but that can be corrected by you
String strDate = dateTime.toString();
// Use the compute method of Map. If the count is null,
// initialize it to 1, otherwise, add 1 to the existing value.
frequencyMap.compute(strDate,
(date, count) -> count == null ? 1 : count + 1);
}
for (Map.Entry<String, Long> entry : frequencyMap
.entrySet()) {
System.out.println(
entry.getKey() + ": " + entry.getValue());
}
}
You can also print the map as follows:
frequencyMap.forEach((k,v)->System.out.println(k + ": " + v));
Finally, the above could have been simplified a few places like using Files.lines(path)
to create a stream. But as you are also writing this to a WeatherDataHandler
list and wanted to keep your structure, I did not use that feature.