Storing values from a Hash Map into a Text File - java

I have created a class that allows the user to create and store compounds into a Hash Map and now I want to create another class that allows me to take the values stored in that Hash Map and save them into a text file. I'm not sure if this is needed, but here is the code for the first class that I created containing the Hash Map:
package abi;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
public class ChemicalComp {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
Map<String, String> data = new HashMap<String, String>();
while(true){
String readinput=br.readLine();
if(readinput.equals(""))
break;
String input = readinput.replaceAll("\"", "");
String array[]=input.split(", ");
String compound=array[0];
String formula="";
for(int i=1;i<array.length;i++){
if(!array[i].equals("1")){
formula+=array[i];
}
}
data.put(compound, formula);
}
if(!data.isEmpty()) {
#SuppressWarnings("rawtypes")
Iterator it = data.entrySet().iterator();
while(it.hasNext()) {
#SuppressWarnings("rawtypes")
Map.Entry obj = (Entry) it.next();
System.out.println(obj.getKey()+":"+obj.getValue());
}
}
}
}
I'm not too familiar with text files, but I have done some research and this is what I've gotten so far. I know its pretty basic and that I will probably need some type of getter method, but I'm not sure where to incorporate it into what I have. Here is what I have for the class containing the text file:
package abi;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.IOException;
public class CompoundManager {
private String path;
private boolean append_to_file = false;
public CompoundManager(String file_path) {
path = file_path;
}
public CompoundManager(String file_path, boolean append_value){
path = file_path;
append_to_file = append_value;
}
public void WriteToFile (String textLine) throws IOException{
FileWriter Compounds = new FileWriter(path, append_to_file);
PrintWriter print_line = new PrintWriter (Compounds);
print_line.printf("%s" + "%n", textLine);
print_line.close();
}
}

I can't understand what your program does but you can use a buffered writer for it.
Just create a try-catch block and wrap a filewriter in a bufferedwriter like this :
try (BufferedWriter br = new BufferedWriter(new FileWriter(new File("filename.txt"))))
{
for (Map.Entry<Integer, String> entry : map.entrySet()) {
int key = entry.getKey();
String value = entry.getValue();
br.write(key + ": " + value);
br.newLine();
}
} catch (Exception e) {
printStackTrace();
}

Related

How to sort both numbers and name at the same time

Currently, I'm at the point where I have only sorted the names within the file but I want to also make it so that ages can be sort. Another problem would be trying to get names that are the same but have different ages to sort. Right now my code looks something like this:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class MultiKey {
public static void main(String[] args) {
File textFile = new File("H:\\Names_ages.txt");
FileReader in;
BufferedReader readFile;
String lineOfText;
try {
in = new FileReader(textFile);
readFile = new BufferedReader(in);
BufferedReader reader = new BufferedReader(new FileReader(textFile));
List<String> results = new ArrayList<String>();
while ((lineOfText = readFile.readLine()) != null) {
results.add(lineOfText);
}
Collections.sort(results);
System.out.println(results);
readFile.close();
in.close();
} catch (FileNotFoundException e){
System.out.println("File does not exist or could not be found");
System.err.println("FileNotFoundException: "+ e.getMessage());
} catch (IOException e){
System.out.println("Problem reading file");
System.err.println("IOException: " + e.getMessage());
}
}
}
Logic:
Create a separate holder for the attributes you want to have the sorting on.
Apply Comparator on that Person object.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class MultiKey {
public static void main(String[] args) {
File textFile = new File("H:\\Names_ages.txt");
FileReader in;
BufferedReader readFile;
String lineOfText;
try {
in = new FileReader(textFile);
readFile = new BufferedReader(in);
BufferedReader reader = new BufferedReader(new FileReader(textFile));
List<Person> results = new ArrayList<Person>();
while ((lineOfText = readFile.readLine()) != null) {
//split here the line into name and age separate variables basedon delimiter available between them.
Person p = new Person(name,age);
results.add(p);
}
order(results);
System.out.println(results);
readFile.close();
in.close();
} catch (FileNotFoundException e){
System.out.println("File does not exist or could not be found");
System.err.println("FileNotFoundException: "+ e.getMessage());
} catch (IOException e){
System.out.println("Problem reading file");
System.err.println("IOException: " + e.getMessage());
}
}
}
private static void order(List<Person> persons) {
Collections.sort(persons, new Comparator<Person>() {
public int compare(Object o1, Object o2) {
String x1 = ((Person) o1).getName();
String x2 = ((Person) o2).getName();
int sComp = x1.compareTo(x2);
if (sComp != 0) {
return sComp;
} else {
Integer x1 = ((Person) o1).getAge();
Integer x2 = ((Person) o2).getAge();
return x1.compareTo(x2);
}
}});
}
public class Person{
private String name;
private int age;
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return this.age;
}
public vois setAge(int age){
this.age = age;
}
}
Typical Approach would be:
Parse each line and create an encapsulation object for it
(in your example a class "Person" with two fields for "name" and "age")
How you do this parsing depends on the format of the lines in the file
e.g. you can use String.split(",") for this, if the values in the line
are separated by comma.
Add the encapsulation objects to a list and then e.g. sort using
a Comparator. Use java.util.Collections.sort(Comparator).
Of course, with that list of encapsulation objects you can do much more very easily, e.g. find Persons with same Name but different Ages.
You can use the thenComparing to chain Comparators
Comparator<String> byName = Comparator.comparing(s -> s.split(" ")[0]);
Comparator<String> byAge = Comparator.comparingInt(s -> Integer.parseInt(s.split(" ")[1]));
try (BufferedReader br = new BufferedReader(new FileReader("filePath"))) {
List<String> sorted = br.lines().sorted(byName.thenComparing(byAge)).collect(Collectors.toList());
return sorted;
} catch (IOException e) {
e.printStackTrace();
}
If more than one space also expected try pattern \\s+ instead of white space
or we can create a Comparator like below instead of creating two Comparators
Comparator<String> c = Comparator.<String, String> comparing(s -> s.split("\\s+")[0])
.thenComparingInt(s -> Integer.parseInt(s.split("\\s+")[1]));

static method returns empty hashmap

I have some code where there are 2 classes, A and and util class with static methods B. The class B has a static method called by A. This static method returns a hashmap (); Although the map is properly built by the static method in clas B, the map is empty when i call this method of B from A. Any thoughts?
the following is the static method from class B which correctly build the map.
package fileutils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import com.google.common.io.Files;
public class JarFileUtils {
//Returns the sql queries as a MAP
public static Map<String, String> getSQLs(String jarFileFullPath){
Map<String, String> sqlData = new HashMap<String, String>();
try {
JarFile jarFile = new JarFile(jarFileFullPath);
Enumeration enumeration = jarFile.entries();
while (enumeration.hasMoreElements()){
sqlData = getSqlDataHelper(enumeration.nextElement(), jarFile);
}
jarFile.close();
} catch (IOException e) {
e.printStackTrace();
}
return sqlData;
}
//Helper to fetch SQL info
private static Map<String, String> getSqlDataHelper(Object obj, JarFile jarFile)
{ Map<String, String> sqls = new HashMap<String, String>();
JarEntry entry = (JarEntry)obj;
String path = "/"+entry.getName();
if(Files.getFileExtension(path).equalsIgnoreCase("sql")){
InputStream input;
try {
input = jarFile.getInputStream(entry);
sqls.put(Files.getNameWithoutExtension(path), readSqlFile(input));
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println(sqls.toString());
return sqls;
}
//Reads the given SQL file
private static String readSqlFile(InputStream input) throws IOException {
InputStreamReader isr = new InputStreamReader(input);
BufferedReader reader = new BufferedReader(isr);
StringBuilder sqlQuery = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sqlQuery.append(line);
sqlQuery.append("\n");
}
reader.close();
return sqlQuery.toString();
}
}
the following is where i call the above static method from class A. the size of this map is zero for some reason.
//Get the list of SQLs in the jar file
Map<String,String> sqlsExtracted = JarFileUtils.getSQLs(currentProjectFullPath);
System.out.println("size = "+currentProjectFullPath+" = "+sqlsExtracted.size());
please advise,
thanks!
Adding my comment as a possible answer, since it might point to the problem.
getSQLs() is going through each entry in the jar file, but only returns the result of the last entry. Perhaps the last entry doesn't contain any sql files?

Saving Vectors In Java

How would I go about saving a String Vector to a file every time it is edited?
So let's say I have usernames in a vector, after I add or delete a username I'd like it to save that vector so if the program is closed, it will show the most recent elements.
This should help you get started.
As JB Nizet said, you should use an ArrayList.
I also went ahead and used Java 7 autocloseable functionality, which ensures you close file handles appropriately.
Of course, you will need to validate your input, and you will want to take care about what you persist. I suspect that you will soon want to consider a better storage strategy, however, this will get you started.
In addition, since this is acting like a collection, you should add hashcode and equals. For brevity sake, I did not add those.
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
public class PersistedCollection {
private static final String NEWLINE_SEPARATOR = System.getProperty("line.separator");
private final List<String> values;
private final File file;
public PersistedCollection(File file) {
this.values = new ArrayList<>();
this.file = file;
}
public void add(String value) {
// You should validate this value. Remove carriage returns, make sure it meets your value specifications.
values.add(value);
persist();
}
public void remove(String value) {
values.remove(value);
persist();
}
private void persist() {
// Using Java 7 autocloseable to ensure that the output stream is closed, even in exceptional circumstances.
try (OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(this.file), 8192); Writer writer = new PrintWriter(outputStream)) {
for (String value : values) {
writer.append(value);
writer.append(NEWLINE_SEPARATOR);
}
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("PersistedCollection [values=");
builder.append(values);
builder.append(", file=");
builder.append(file);
builder.append("]");
return builder.toString();
}
public static void main(String[] arguments) {
PersistedCollection persistedCollection = new PersistedCollection(new File("/tmp/test.txt"));
persistedCollection.add("jazeee");
persistedCollection.add("temporary user");
persistedCollection.add("user402442");
persistedCollection.add("JB Nizet");
persistedCollection.remove("temporary user");
System.out.println(persistedCollection);
}
}
Another solution would be to create a class where you add all the methods required to read from a file of usernames (one username per line). Then you can refer to this class from anywhere (as the modifier is public) and call the methods such that you will add or remove usernames from that file.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.io.File;
public class Test {
private static BufferedWriter bw;
private static ArrayList<String> vector=new ArrayList<String>();
private static String everything;
//add an username
public static void add(String x){
vector.add(x);
}
//remove an username
public static void remove(String x){
vector.remove(x);
}
//update the file with the new vector of usernames
public static void updateToFile() throws IOException{
File username = new File("/home/path/to/the/file");
FileWriter fw = new FileWriter(username.getAbsoluteFile());
bw= new BufferedWriter(fw);
for (String x:vector){
bw.write(x.toString());
bw.write("\n");
}
bw.close();
}
//you call this method to initialise your vector of usernames
//this implies that you already have a file of usernames
//one username per line
public static void setUsername() throws IOException{
vector=new ArrayList<String>();
BufferedReader br = new BufferedReader(new FileReader("/home/path/to/the/file"));
try {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
everything = sb.toString();
} finally {
br.close();
}
String lines[] = everything.split("\\r?\\n");
for (String x:lines){
vector.add(x);
}
}
//print your usernames in the console
public static void printUsers(){
for (String User:vector){
System.out.println(User);
}
}
}
Then it gets as easy as this:
import java.io.IOException;
public class MainTest {
public static void main(String[] args) throws IOException{
Test.setUsername();
Test.printUsers();
Test.add("username5");
Test.remove("username2");
System.out.println("// add username5; remove username2");
Test.printUsers();
System.out.println("// file has been updated with the new state");
Test.updateToFile();
System.out.println("// veryfing update");
Test.setUsername();
Test.printUsers();
}
}
The output:
(this first 4 users is what I have in the file)
username1
username2
username3
username4
// add username5; remove username2
username1
username3
username4
username5
// file has been updated with the new state
// verifying update
username1
username3
username4
username5

File always seems to be empty

Ok, I'm really confused by some code I wrote. It's a DataSetter (didn't know a better name for it...), and has methods to change the data in my data file (data.txt). This data has the following format: #key=value (eg. #version=1.0). Now, I tried to run this line of code:
new DataSetter().setValue("version", "1.1");
It just clears the file. That's pretty much all it does. Now, I think it clears the file because it makes a new File, which is completely empty but has the same name. Here's my code:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
/**
* This class contains methods to set specific data in the data.txt file. <br>
* The data is rewritten every time a new value is set.
*
* #author Casper van Battum
*
*/
public class DataSetter {
private static final File DATA_FILE = new File("resources/data.txt");
private static final String lineFormat = "#%s=%s";
private FileOutputStream out;
private DataReader reader = new DataReader();
private HashMap<String, String> dataMap = reader.getDataMap();
private Scanner scanner;
public DataSetter() {
try {
out = new FileOutputStream(DATA_FILE, false);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void setValue(String key, String newValue) {
openDataFile();
String oldLine = String.format(lineFormat, key, dataMap.get(key));
dataMap.put(key, newValue);
String newLine = String.format(lineFormat, key, newValue);
try {
replace(oldLine, newLine);
} catch (IOException e) {
e.printStackTrace();
}
closeDataFile();
}
private void replace(String oldLine, String newLine) throws IOException {
ArrayList<String> tmpData = new ArrayList<String>();
while (scanner.hasNextLine()) {
String currentLine = scanner.nextLine();
tmpData.add((currentLine == oldLine) ? newLine : currentLine);
}
out.write(new String().getBytes());
String sep = System.getProperty("line.separator");
StringBuffer sb = new StringBuffer();
for (String string : tmpData) {
sb.append(string + sep);
}
FileWriter writer = new FileWriter(DATA_FILE);
String outString = sb.toString();
writer.write(outString);
writer.close();
}
private void openDataFile() {
try {
scanner = new Scanner(DATA_FILE);
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
}
private void closeDataFile() {
scanner.close();
}
}
So after running the setValue() method, I just have an empty file...
Im really out of idea's on how to solve this...
You are truncating your data file with the
new FileOutputStream(DATA_FILE, false)
so no nothing is written when you go to output your the elements in the tmpData ArrayList read from Scanner.
ArrayList<String> tmpData = new ArrayList<String>();
while (scanner.hasNextLine()) {
String currentLine = scanner.nextLine(); // never gets called
...
}
The typical strategy for updating a text file is to create a temporary file with old file's contents (File#renameTo), write the data to file, then delete the temporary file after closing any open streams to the file being read.

read 7 columns from .csv file in java?

I am new to Java. Can anybody suggest to me how to read a CSV file with 7 columns?
Here is my code:
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class main {
public static Map<String,String> map1 = null;
public static Map<String,String> map2 = null;
public static void main(String[] args) {
try {
readFileandPopulate();
for (Map.Entry<String, String> entry : map1.entrySet()) {
System.out.println("Key : " + entry.getKey() + " Value : "
+ entry.getValue()+" address :"+map2.get(entry.getKey()));
//insert into DB
}
} catch (Exception e) {//Catch exception if any
e.printStackTrace();
System.err.println("Error: " + e.getMessage());
}
}
public static void readFileandPopulate() throws Exception {
FileInputStream fstream = new FileInputStream("/Users/Desktop/Pattern Recognition/DataSetR/1a19.csv");
// Use DataInputStream to read binary NOT text.
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
map1 = new HashMap<String,String>();
while ((strLine = br.readLine()) != null) {
System.out.println(strLine);
String temp[] = strLine.split(",");
map1.put(temp[0], temp[1]);
}
in.close();
System.out.println("done 1");
}
}
Is there any method to just read few columns and delete remaining data or can I store all values in array and use index of array to calculate one equation using values?
I would recommend using a CSV parser, such as http://opencsv.sourceforge.net/. Then you could do the following:
CSVReader reader = new CSVReader(new FileReader(filePath), ',');
List<String[]> rows= reader.readAll();
for (String[] row : rows)
{
for (int i = 0; i < numColumnsToParse; i++)
{
//do something with row[i]
}
}
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import au.com.bytecode.opencsv.CSVReader;
public class ReadCSV
{
public static void main(String[] args) throws IOException
{
String[] row = null;
String csvFilename = "C:/Users/Hussain/Desktop/data.csv";
CSVReader csvReader = new CSVReader(new FileReader(csvFilename));
List content = csvReader.readAll();
for (Object object : content)
{
row = (String[]) object;
System.out.println("value in row 7 ===>>>"+row[6]);
}
csvReader.close();
}
}
you can add the jar from here

Categories