Reputation: 37
I have a separated .txt file in which there is a list of "students" with their own mark on the side that goes from 0 to 10, here is an example on how the .txt looks like:
Mark 2
Elen 3
Luke 7
Elen 9
Jhon 5
Mark 4
Elen 10
Luke 1
Jhon 1
Jhon 7
Elen 5
Mark 3
Mark 7
What I want to do is calculating the Average of each student (expressed in double
) so that the output would look like this:
Mark: 4.0
Elen: 6.75
Luke: 4.0
Jhon: 4.33
Here is what I've come up with, for now I've only managed to use Properties
to list the student names without repetition, but the number shown on the side of each one of them is obviously the last one the program finds.
I've included it on a button actionlistener as I'm implementing a GUI, by pressing the button the output shown above is append
in a TextArea
:
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent d) {
try {
File file = new File("RegistroVoti.txt");
FileInputStream fileInput = new FileInputStream(file);
Properties properties = new Properties();
properties.load(fileInput);
fileInput.close();
Enumeration enuKeys = properties.keys();
while (enuKeys.hasMoreElements()) {
String key = (String) enuKeys.nextElement();
String value = properties.getProperty(key);
l1.append(key + ": " + value + "\n");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
I was thinking to use Collectors
to calculate the average, but I actually don't know how to implement it...
Any help is appreciated!
Thanks in advance!
Upvotes: 3
Views: 1104
Reputation: 1738
The way I like to do this kind of thing is using Map
s and List
s.
To read the lines from the file, I'm fond of the nio
way of reading, so I would do
List<String> lines = Files.readAllLines(Paths.get("RegistroVoti.txt"));
Then, you can make a HashMap
<String,
List
<Integer>>
, which will store each person's name and a list of the numbers associated with them:
HashMap<String, List<Integer>> studentMarks = new HashMap<>();
Then, using a for each loop, go through each of the lines and add each number to the hash map:
for (String line : lines) {
String[] parts = line.split(" ");
if (studentMarks.get(parts[0]) == null) {
studentMarks.put(parts[0], new ArrayList<>());
}
studentMarks.get(parts[0]).add(Integer.parseInt(parts[1]));
}
Then, you can go through each entry in the map and calculate the average of the associated list:
for (String name : studentMarks.keySet()) {
System.out.println(name + " " + studentMarks.get(name).stream().mapToInt(i -> i).average().getAsDouble());
}
(Note that this is a Java 8 stream solution; you could just as easily write a for
loop to calculate it in earlier versions)
For more information on some of the things I've used, see:
Hope this helps!
Edit A complete solution:
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent d) {
try {
List<String> lines = Files.readAllLines(Paths.get("RegistroVoti.txt"));
Map<String, List<Integer>> studentMarks = new HashMap<>();
for (String line : lines) {
String[] parts = line.split(" ");
if (studentMarks.get(parts[0]) == null) {
studentMarks.put(parts[0], new ArrayList<>());
}
studentMarks.get(parts[0]).add(Integer.parseInt(parts[1]));
}
for (String name : studentMarks.keySet()) {
System.out.println(name + " " + studentMarks.get(name).stream().mapToInt(i -> i).average().getAsDouble());
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
Upvotes: 4