I am trying to take an initial CSV file, pass it through a class that checks another file if it has an A or a D to then adds or deletes the associative entry to an array object.
example of pokemon.csv:
1, Bulbasaur
2, Ivysaur
3, venasaur
example of changeList.csv:
A, Charizard
A, Suirtle
D, 2
That being said, I am having a lot of trouble getting the content of my new array to a new CSV file. I have checked to see whether or not my array and class files are working properly. I have been trying and failing to take the final contents of "pokedex1" object array into the new CSV file.
Main File
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
public class PokedexManager {
public static void printArray(String[] array) {
System.out.print("Contents of array: ");
for(int i = 0; i < array.length; i++) {
if(i == array.length - 1) {
System.out.print(array[i]);
}else {
System.out.print(array[i] + ",");
}
}
System.out.println();
}
public static void main(String[] args) {
try {
//output for pokedex1 using PokemonNoGaps class
PokemonNoGaps pokedex1 = new PokemonNoGaps();
//initializes scanner to read from csv file
String pokedexFilename = "pokedex.csv";
File pokedexFile = new File(pokedexFilename);
Scanner pokescanner = new Scanner(pokedexFile);
//reads csv file, parses it into an array, and then adds new pokemon objects to Pokemon class
while(pokescanner.hasNextLine()) {
String pokeLine = pokescanner.nextLine();
String[] pokemonStringArray = pokeLine.split(", ");
int id = Integer.parseInt(pokemonStringArray[0]);
String name = pokemonStringArray[1];
Pokemon apokemon = new Pokemon(id, name);
pokedex1.add(apokemon);
}
//opens changeList.csv file to add or delete entries from Pokemon class
String changeListfilename = "changeList.csv";
File changeListFile = new File(changeListfilename);
Scanner changeScanner = new Scanner(changeListFile);
//loads text from csv file to be parsed to PokemonNoGaps class
while(changeScanner.hasNextLine()) {
String changeLine = changeScanner.nextLine();
String[] changeStringArray = changeLine.split(", ");
String action = changeStringArray[0];
String nameOrId = changeStringArray[1];
//if changList.csv file line has an "A" in the first spot add this entry to somePokemon
if(action.equals("A")) {
int newId = pokedex1.getNewId();
String name = nameOrId;
Pokemon somePokemon = new Pokemon(newId, name);
pokedex1.add(somePokemon);
}
//if it has a "D" then send it to PokemonNoGaps class to delete the entry from the array
else { //"D"
int someId = Integer.parseInt(nameOrId);
pokedex1.deleteById(someId);
}
//tests the action being taken and the update to the array
//System.out.println(action + "\t" + nameOrId + "\n");
System.out.println(pokedex1);
//*(supposedly)* prints the resulting contents of the array to a new csv file
String[] pokemonList = changeStringArray;
try {
String outputFile1 = "pokedex1.csv";
FileWriter writer1 = new FileWriter(outputFile1);
writer1.write(String.valueOf(pokemonList));
} catch (IOException e) {
System.out.println("\nError writing to Pokedex1.csv!");
e.printStackTrace();
}
}
//tests final contents of array after being passed through PokemonNoGaps class
//System.out.println(pokedex1);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
PokemonNoGaps class file:
public class PokemonNoGaps implements ChangePokedex {
private Pokemon[] pokedex = new Pokemon[1];
private int numElements = 0;
private static int id = 0;
// add, delete, search
#Override
public void add(Pokemon apokemon) {
// if you have space
this.pokedex[this.numElements] = apokemon;
this.numElements++;
// if you don't have space
if(this.numElements == pokedex.length) {
Pokemon[] newPokedex = new Pokemon[ this.numElements * 2]; // create new array
for(int i = 0; i < pokedex.length; i++) { // transfer all elements from array into bigger array
newPokedex[i] = pokedex[i];
}
this.pokedex = newPokedex;
}
this.id++;
}
public int getNewId() {
return this.id + 1;
}
#Override
public void deleteById(int id) {
for(int i = 0; i < numElements; i++) {
if(pokedex[i].getId() == id) {
for(int j = i+1; j < pokedex.length; j++) {
pokedex[j-1] = pokedex[j];
}
numElements--;
pokedex[numElements] = null;
}
}
}
public Pokemon getFirstElement() {
return pokedex[0];
}
public int getNumElements() {
return numElements;
}
public String toString() {
String result = "";
for(int i = 0; i < this.numElements; i++) {
result += this.pokedex[i].toString() + "\n";
}
return result;
}
}
Excpeted output:
1, Bulbasaur
3, Venasaur
4, Charizard
5, Squirtle
Am i using the wrong file writer? Am I calling the file writer at the wrong time or incorrectly? In other words, I do not know why my output file is empty and not being loaded with the contents of my array. Can anybody help me out?
I spotted a few issues whilst running this. As mentioned in previous answer you want to set file append to true in the section of code that writes to the new pokedx1.csv
try {
String outputFile1 = "pokedex1.csv";
FileWriter fileWriter = new FileWriter(prefix+outputFile1, true);
BufferedWriter bw = new BufferedWriter(fileWriter);
for(String pokemon : pokedex1.toString().split("\n")) {
System.out.println(pokemon);
bw.write(pokemon);
}
bw.flush();
bw.close();
} catch (IOException e) {
System.out.println("\nError writing to Pokedex1.csv!");
e.printStackTrace();
}
I opted to use buffered reader for the solution. Another issue I found is that your reading pokedex.csv but the file is named pokemon.csv.
String pokedexFilename = "pokemon.csv";
I made the above change to fix this issue.
On a side note I noticed that you create several scanners to read the two files. With these types of resources its good practice to call the close method once you have finished using them; as shown below.
Scanner pokescanner = new Scanner(pokedexFile);
// Use scanner code here
// Once finished with scanner
pokescanner.close();
String outputFile1 = "pokedex1.csv";
FileWriter writer1 = new FileWriter(outputFile1);
appears to be within your while loop so a new file will be created every time.
Either use the FileWriter(File file, boolean append) constructor or create before the loop
Related
I am trying to save each index of list as new line in text file in format below in java and read same as two separate Array List for later . I have done the saving part now i want to read it back into two separate lists
Save Formate
Class SaveLists
public class SaveLists{
private List<Integer> First= new ArrayList<>();
private List<Integer> second= new ArrayList<>();
public void save(List l) throws IOException{
try{
File f = new File ("E:\\Sample.txt");
if (!f.exists()) {
f.createNewFile();
}
FileWriter fw = new FileWriter(f.getAbsoluteFile(),true);
BufferedWriter bw = new BufferedWriter(fw);
for(Object s : l) {
bw.write(s + System.getProperty("line.separator"));
}
bw.write(System.getProperty("line.separator"));
bw.close();
}catch(FileNotFoundException e){System.out.println("error");}
}
public void ReadFromText(){
//Read from Text file and save in both lists
}
}
Class Main :
public static void main(String[] args) {
temp t = new temp();
t.First.add(1);
t.First.add(2);
t.First.add(3);
t.second.add(6);
t.second.add(5);
t.second.add(4);
t.save(t.First);
t.save(t.second);
// t.ReadFromText();
}
As both the save operations are on the same thread the lines would be written to the file in a synchronous manner. So after reading all the lines from the file we can split the lines based on the size of the input lists i.e. the first set of values would have been inserted by the 'First' list.
public void ReadFromText() {
// Read from Text file and save in both lists
List<Integer> output1 = new ArrayList<>();
List<Integer> output2 = new ArrayList<>();
try {
Path path = Path.of("D:\\Sample.txt");
List<String> inputList = Files.lines(path).collect(Collectors.toList());
for (int i = 0; i < inputList.size(); i++) {
String s = inputList.get(i);
if (!s.isEmpty()) {
if (i < First.size()) {
output1.add(Integer.valueOf(s));
} else {
output2.add(Integer.valueOf(s));
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
Here is my NameRecord constructor class:
public class NameRecord {
String firstName;
int count;
public NameRecord(String name, int count){
this.firstName = name;
this.count = count;
}
#Override
public String toString() {
return firstName + " - " + count + " registered births.";
}
public String getFirstName() {
return firstName;
}
public int getCount() {
return count;
}
}
And here is what I have so far of the actual program:
public class Names {
public final int MAX_NAMES = 3;
NameRecord[] boyNames = new NameRecord[MAX_NAMES];
String boysFile = "data/boynames.txt";
#Override
public String toString() {
String result = "";
for (NameRecord record : boyNames)
result += record + "\n";
return result;
}
public void loadNamesFromFile() {
try {
BufferedReader stream = new BufferedReader(new FileReader("Data/boysnames.txt"));
} catch (Exception e)
{
System.out.println("File not found");
}
}
}
Basically, the program reads a file and determines if the name is on the boys list or girls list txt files, and then outputs if it is on the list, and if so how many times it was used. I am only working with boys for right now to keep confusion to a minimum. My question is, in the loadNamesFromFile method, how do I add information from the file to the boyNames array. I know the NameRecord calls for the name and the count, but I'm not sure how to retrieve that information from the file and add it to the array. I have included the top three names from the file below, the name is of course the first name and the number is the number of times it was used, or count.
Jacob 29195
Michael 26991
Joshua 24950
First of all if it is possible to have your file structure like this
Jacob;29195
Michael;26991
Joshua;24950
to make it more easy to develop the solution
and now this is how you can read the file lines and store them into your tabel
public void loadNamesFromFile() {
try {
BufferedReader stream = new BufferedReader(new FileReader("Data/boysnames.txt"));
String currentLine ="";
int i = 0;
while(curentLine = stram.readLine()) {
String [] record = currentLine.split(";");
NameRecord = name = new NameRecord(record[0], Integer.parseInt(record[1]);
boyNames[i] = name;
i++;
}
} catch (Exception e)
{
System.out.println("File not found");
}
}
First of all you should add a scanner for the file in order to read what is in the file. After that u keep reading the file and add the information untill there is no more content in the file. Besides this I would use an ArrayList of NameRecord for being more flexible with the number of names.
Im assuming that the content of your file is always the same (given your example).
public class Names {
try {
ArrayList<NameRecord> boyNames = new ArrayList<>();
public void loadNamesFromFile() {
File file = new File("Data/boysnames.txt");
Scanner sc = new Scanner(file);
while(sc.hasNextLine()) {
boyNames.add(new NameRecord(sc.next(), sc.nextInt()));
}
sc.close();
}
} catch(IOException e) {
System.err.println(e);
}
}
My suggestion is to read all the contents of the file i.e., all the names, in a single String variable. Then, iterate over each word and count the number of occurrences and add the info to the array. Let's use Scanner to read the file.
I presume that the length of the array boyNames[] is equal to the number of unique names in the file.
Scanner boys = new Scanner(new File("Data/boys.txt"));
int a,i,n=0,c,b;
String con = "", x; //con holds all names
//reading the names
while(boys.hasNext())
con+= boys.next()+" ";
b = con.split(" ").length; //b = total number of names in the file
for(i=0; i<b; i++){
x = con.split(" ")[i];
if(!x.equals("*")){
c = 0; a = 0;
//counting frequency of x in con
while(con.indexOf(x, a) != -1){
c++; a = con.indexOf(x, a) + x.length() + 1;
}
//adding name and frequency to array
boyNames[n++] = new NameRecord(x, c);
con = con.replaceAll(x, "*"); //removing all instances of x from con
}
}
The boyNames[] array now stores the names and their respective frequencies in the file.
I am trying to segregate my data into multiple array list, so that I can use them later-on in my code. But I am not able to put my data in array list.
My code is about segregating the data into three array list of different Subjects (Example:Physics,chemistry) as per various filters, which you will find in my code.
Input data file:
1|150|20150328|20150406|Physics|1600|1600|2|68|92
2|152|20150328|20150406|Physics|1600|1500|2|68|89
3|153|20150328|20150406|Physics|1600|1500|2|68|60
4|155|20150328|20150406|Physics|1600|1600|2|68|72
5|161|20150328|20150406|Chemistry|1600|1600|2|68|77
Here's my code:
Public Class filter{
public static void main(String args[])
BufferedReader in= null;
BufferedWriter out= null;
String in_line;
String PrevRollNo= "";
int PrevDate= 0;
ArrayList<transaction> PhysicsList= new ArrayList<transaction>();
ArrayList<transaction> scList= new ArrayList<transaction>();
ArrayList<transaction> Chemistry= new ArrayList<transaction>();
try{
in = new BufferedReader(new FileReader(Path for input file));
File out_file= new File(Path for output file);
if(!out_file.exists())
{
(!out_file.createNewFile();
}
FileWriter fw=new FileWriter(out_file);
out= new BufferedWriter(fw);
while ((in_line=in.readline())!=null)
{
Transaction transact=new Transaction(in_line);
if(transact.RollNo.equals(PrevRollNo))
{
if(transact.subject.equals("Physics")&& transact.Prs_Date= PrevDate
{
PhysicsList.add(transact);
}
else if(transact.subject.equals("Physics")&&transact.wk_date != PrevDate}
Iterator<Transaction> it;
if(!transact.RoomNo.equals("102")&&!transact.lcl_RoomNo.equals("102");
{
it= scList.iterator();
while(it.hasnext())
{
Transaction sc= it.next();
if(sc.lcl_RoomNo.equals(transact.RoomNo) && sc.l1 equals(tansact.l1) && sc.l2 equals(transact.l2)
if(sc.marks==transact.marks)
{
transact.srsfound= true;
}
else
{
System.out.print.ln( "not found");
}
scList.remove(sc))
out.write(in_line);
break;
}}}}
Static Class Transaction
{
Public String RollNo, Subject, RoomNo, lcl_RoomNo, l1, l2;
Public int wk_date, prs_date;
Public double marks , amt;
Public boolean srcfound, tgtfound;
Public Transaction(String in_line)
{
String [] SplitData= in_line.split("\\|");
RollNo = SplitData[1];
Subject = SplitData[4]
RoomNo = SplitData[5];
lcl_RoomNo = SplitData[6];
l1 = SplitData[7];
l2 = SplitData[8];
wk_date = SplitData[3];
prs_date = SplitData[2];
marks = Double.parsedouble(SplitData[9]);
amt = Double.parsedouble(SplitData[]);
srcfound = false;
tgtfound = false;
}
Kindly help with your expertise.
Use Java 8 NIO and Streams. It will ease the job.
Files.lines(Paths.get("fileName.txt")).map(line -> {
String[] tokens = line.split("|");
//tokens contains individual elements of each line. Add your grouping logic on tokens array
}
I agree with the other answer in some ways. NIO should be used, it makes it a lot easier. However, I would avoid streams and instead use the readAllLines method like so:
try{
List<String> filecontents = new String(Files.readAllLines(file.toPath()); //file is the object to read from.
for(int i = 0; i < filecontents.size(); i++){
String line = lines.get(i);
//New code starts here
if(!line.contains("|") continue; //Ignore that line
//New code ends here
String[] array = line.split("|");
ArrayList<String> list = new ArrayList<String>();
for(int a = 0; a < array.length; a++){
String part = array[a];
list.add(part);
}
Transaction t = new Transaction(line);
if(line.contains("Physics") PlysicsList.add(t);
else if(line.contains("Chemistry") Chemistry.add(t);
else{ //Do nothing}
}
}catch(IOException e){
e.printStackTrace();
}
EDIT: I added a check in there. The reason the first and last lines may not be working is if the lines that are being parsed are not being parsed properly. See if this fixes your issue
I'm trying to get saved data in a text file to an array to use it in my code and then search this array for a string submitted from the user from the GUI , but for some reason I print out the data in the array it is all null. here's the code !!
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
public class IO {
File f = new File("DB.txt");
PrintWriter write;
Scanner input;
String[][] data;
String nameToSearch;
// search constructor
public IO(String name) {
super();
nameToSearch = name;
try {
input = new Scanner(f);
} catch (FileNotFoundException e) {
System.out.println("File not found please restart the program");
}
data = new String[linesCounter()][2];
int i = 0;
while (input.hasNext()) {
data[i][0] = input.nextLine();
data[i][1] = input.nextLine();
i++;
}
}
public IO(String name, String number) {
try {
write = new PrintWriter(new FileWriter(f, true));
} catch (IOException e) {
System.out.println("Error");
}
write.println(name);
write.println(number);
write.close();
}
int linesCounter() {
try {
input = new Scanner(f);
} catch (FileNotFoundException e) {
System.out.println("File not found please restart the program");
}
int counter = 0;
while (input.hasNext()) {
input.nextLine();
counter++;
}
return counter / 2;
}
int contactFinder() {
int i = 0;
while (input.hasNext()) {
if (data[i][0].equalsIgnoreCase(nameToSearch))
return i;
i++;
}
return -1;
}
String nameGetter() {
return data[contactFinder()][0];
}
String numGetter() {
return data[contactFinder()][1];
}
}
It looks like you read all the lines in from the file to count how many lines there are, and then when you go to read the data, you're starting from where you left off, which would be the end of the file.
It's also worth noting that you can use commons-io FileUtils to easily read all the lines from a file.
For example:
List<String> lines = FileUtils.readLines(f);
String[][] data = new String[lines.length][2];
for (int i = 0; i < lines.size(); i++) {
data[i][i % 2] = lines.get(i);
}
If you also don't want to use a (very useful) third party library, you could load up the data pretty simply with:
List<String> lines = new ArrayList<String>();
Scanner input = new Scanner(f);
while (input.hasNextLine()) {
lines.add(input.nextLine());
}
input.close();
Then go into the array population.
I would advice you to use RandomAccessFile. This has methods such as readLine() to read the line and seek(long pos) to set the file read pointer. You may use seek(0L) to restart the reading of the file.
Does anybody know how to properly read from a file an input that looks like this:
0.12,4.56 2,5 0,0.234
I want to read into 2 arrays in Java like this:
a[0]=0.12
a[1]=2
a[2]=0;
b[0]=4.56
b[1]=5
b[2]=0.234
I tried using scanner and it works for input like 0 4 5 3.45 6.7898 etc but I want it for the input at the top with the commas.
This is the code I tried:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class IFFTI {
public static int size=0;
public static double[] IFFTInputREAL= new double[100];
public static double[] IFFTInputIMAG= new double[100];
static int real=0;
static int k=0;
public static void printarrays(){
for(int k=0;k<size;k++){
System.out.print(IFFTInputREAL[k]);
System.out.print(",");
System.out.print(IFFTInputIMAG[k]);
System.out.print("\n");
}
}
public static void readIFFT(String fileName){
try {
Scanner IFFTI = new Scanner(new File(fileName));
while (IFFTI.hasNextDouble()) {
if(real%2==0){
IFFTInputREAL[k] = IFFTI.nextDouble();
real++;
}
else{
IFFTInputIMAG[k] = IFFTI.nextDouble();
real++;
k++;}
}
try{
size=k;
}catch(NegativeArraySizeException e){}
} catch (FileNotFoundException e) {
System.out.println("Unable to read file");
}
}
}
I think this will do what you want:
String source = "0.12,4.56 2,5 0,0.234";
List<Double> a = new ArrayList<Double>();
List<Double> b = new ArrayList<Double>();
Scanner parser = new Scanner( source ).useDelimiter( Pattern.compile("[ ,]") );
while ( parser.hasNext() ) {
List use = a.size() <= b.size() ? a : b;
use.add( parser.nextDouble() );
}
System.out.println("A: "+ a);
System.out.println("B: "+ b);
That outputs this for me:
A: [0.12, 2.0, 0.0]
B: [4.56, 5.0, 0.234]
You'll obviously want to use a File as a source. You can use a.toArray() if you want to get it into a double[].
You will have to read the complete line.
String line = "0.12,4.56 2,5 0,0.234"; //line variable will recieve the line read
Then.. you split the line on the commas or the spaces
String[] values = line.split(" |,");
This will result in an array like this: [0.12, 4.56, 2, 5, 0, 0.234]
Now, just reorganize the contents between the two order arrays.
Reading from a file in Java is easy:
http://www.exampledepot.com/taxonomy/term/164
Figuring out what to do with the values once you have them in memory is something that you need to figure out.
You can read it one line at a time and turn it into separate values using the java.lang.String split() function. Just give it ",|\\s+" as the delimiter and off you go:
public class SplitTest {
public static void main(String[] args) {
String raw = "0.12,4.56 2,5 0,0.234";
String [] tokens = raw.split(",|\\s+");
for (String token : tokens) {
System.out.println(token);
}
}
}
EDIT Oops, this is not what you want. I don't see the logic in the way of constructing the arrays you want.
Read the content from the file
Split the string on spaces. Create for each element of the splitted array an array.
String input = "0.12,4.56 2,5 0,0.234";
String parts[] = input.split(" ");
double[][] data = new double[parts.length][];
Split each string on commas.
Parse to a double.
for (int i = 0; i < parts.length; ++i)
{
String part = parts[i];
String doubles[] = part.split(",");
data[i] = new double[doubles.length];
for (int j = 0; j < doubles.length; ++j)
{
data[i][j] = Double.parseDouble(doubles[j]);
}
}
File file = new File("numbers.txt");
BufferedReader reader = null;
double[] a = new double[3];
double[] b = new double[3];
try {
reader = new BufferedReader(new FileReader(file));
String text = null;
if ((text = reader.readLine()) != null) {
String [] nos = text.split("[ ,]");
for(int i=0;i<nos.length/2;i++){
a[i]=Double.valueOf(nos[2*i]).doubleValue();
b[i]=Double.valueOf(nos[2*i+1]).doubleValue();
}
}
for(int i=0;i<3;i++){
System.out.println(a[i]);
System.out.println(b[i]);
}
} catch (FileNotFoundException e) {
} catch (IOException e) {
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
}
}