I am trying to read a text file and store with a hashmap. The file contains information like this:
1946-01-12;13:00:00;0.3;G
1946-01-12;18:00:00;-2.8;G
1946-01-13;07:00:00;-6.2;G
1946-01-13;13:00:00;-4.7;G
1946-01-13;18:00:00;-4.3;G
1946-01-14;07:00:00;-1.5;G
1946-01-14;13:00:00;-0.2;G
I want to store the dates as keys and then "13:00:00;0.3;G" as value, where 13:00 is time, 0.3 is temperature and G represent a quality code. I wonder if this is even possbile since many rows in the file has the same date? I already wrote a code for storing the data in a list, but now I want to store it in a map instead. My old code looks like this:
/**
* Provides methods to retrieve temperature data from a weather station file.
*/
public class WeatherDataHandler {
private List<Weather> weatherData = new ArrayList<>();
public void loadData(String filePath) throws IOException {
List<String> fileData = Files.readAllLines(Paths.get("filepath"));
for(String str : fileData) {
List<String> parsed = parseData(str);
LocalDate date = LocalDate.parse(parsed.get(0));
LocalTime time = LocalTime.parse(parsed.get(1));
double temperature = Double.parseDouble(parsed.get(2));
String quality = parsed.get(3);
//new Weather object
Weather weather = new Weather(date, time, temperature, quality);
weatherData.add(weather);
}
}
private List<String> parseData(String s) {
return Arrays.asList(s.split(";"));
}
I got stuck when implementing the hashmap. I started with some code below, but I do not know how to loop over a sequence of dates. What is the simplest way to store the data from the file in a map?
public class WeatherDataHandler {
public void loadData(String filePath) throws IOException {
Map<LocalDate, String> map =new HashMap<LocalDate, String>();
BufferedReader br = new BufferedReader(new FileReader("filepath"));
String line="";
int i=0;
while (line != null) {
line = br.readLine();
map.put(i,line);
i++;
}
String date="";
String time="";
String temperature="";
String quality="";
for(int j=0;j<map.size();j++){
if(!(map.get(j)== null)){
String[] getData=map.get(j).toString().split("\\,");
date = getData[0];
time = getData[1];
temperature = getData[2];
quality = getData[3];
}
}
}
Using the stream API you can create a map where the key is the date and the [map] value is a list.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class WeatherDataHandler {
public static void main(String[] args) {
Path path = Paths.get("filepath");
try {
Map<String, List<String>> map = Files.lines(path)
.collect(Collectors.groupingBy(line -> line.split(";", 2)[0]));
map.entrySet()
.stream()
.forEach(entry -> System.out.printf("%s = %s%n", entry.getKey(), entry.getValue()));
}
catch (IOException x) {
x.printStackTrace();
}
}
}
Method lines()
in class java.nio.file.Files
creates a stream where each stream element is a single line of the file being read.
Method split()
splits the line into a two element array (because of the second argument which is the number 2).
The first array element, i.e. the date, becomes the [map] key and the rest of the line becomes the [map] value.
Whenever a duplicate key is encountered, the value is appended to the existing value creating a list. Hence the type parameters for the map are String
for the [map] key and List<String>
for the [map] value.
Running the above code on your sample data yields:
1946-01-14 = [1946-01-14;07:00:00;-1.5;G, 1946-01-14;13:00:00;-0.2;G]
1946-01-12 = [1946-01-12;13:00:00;0.3;G , 1946-01-12;18:00:00;-2.8;G]
1946-01-13 = [1946-01-13;07:00:00;-6.2;G , 1946-01-13;13:00:00;-4.7;G, 1946-01-13;18:00:00;-4.3;G ]