Reputation: 13
I've spent a while researching problems similar to mine, and am now stuck with my code. I have implemented a basic CSV file reader, but I'm stuck in processing the input
Current Result:
Source [medium = go bio , values = 5]
Source [medium = go bio , values = 5]
Source [medium = metal sink , values = 2]
Source [medium = go bio , values = 5]
Source [medium = metal sink , values = 3]
Done
But what I want is something like this.
Output:
[medium = go bio , values = 15]
[medium = metal sink , values = 5]
The contents of my text file.
go,bio,5
go,bio,5
metal,sink,2
go,bio,5
metal,sink,3
And this is my code:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.FileReader;
import java.util.HashMap;
public class CVSReader {
public static void main(String[] args) {
CVSReader obj = new CVSReader();
obj.run();
}
public void run() {
String csvFile = "file2.txt";
BufferedReader br = null;
String line;
String cvsSplitBy = ",";
String[] source;
try {
//HashMap here
HashMap<String, String> hash = new HashMap<>();
HashMap<String, Integer> hash2 = new HashMap<>();
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
// comma separator here
source = line.split(cvsSplitBy);
hash.put(source[0], source[0]);
hash.put(source[1], source[1]);
hash.put(source[2], source[2]);
System.out.println("Source [medium = " + hash.get(source[0]) + " " +
hash.get(source[1]) + " , values = " + hash.get(source[2]) + "]");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("Done");
}
}
Upvotes: 1
Views: 92
Reputation: 201439
First, you need a Map<String, Integer>
to add your entries with the same key. Build the key, parse the value from your line
, and if it's already in the Map
add the current value to your parsed value. Then store the value back in the Map
. I would also prefer a try-with-resources
close. Finally, iterate the Map.entrySet()
. Something like,
String csvFile = "file2.txt";
String cvsSplitBy = "\\s*,\\s*"; // <-- adds support for white space(s)
// before or after the comma.
try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
Map<String, Integer> hash = new HashMap<>();
String line;
while ((line = br.readLine()) != null) {
String[] source = line.split(cvsSplitBy);
String medium = source[0] + " " + source[1]; // <-- the key
int val = Integer.parseInt(source[2]); // <-- the value
if (hash.containsKey(medium)) { // <-- is the key in Map?
val += hash.get(medium); // <-- yes, add the value.
}
hash.put(medium, val); // <-- store the value back in the Map.
}
// Iterate the entry set, display the "medium" and value.
for (Map.Entry<String, Integer> entry : hash.entrySet()) {
System.out.printf("Source [medium = %s , values = %d]%n",
entry.getKey(), entry.getValue());
}
} catch (IOException e) { // <-- FileNotFoundException is a sub-class.
e.printStackTrace();
}
System.out.println("Done");
Which I ran with your provided text file, and got (as requested)
Source [medium = metal sink, values = 5] Source [medium = go bio, values = 15] Done
Upvotes: 1