Best way to process strings in Java - java

I want make a game of life clone using text files to specify my starting board, then write the finished board to a new text file in a similar format. E.g. load this:
Board in:
wbbbw
bbbbb
wwwww
wbwbw
bwbwb
from a file, then output something like this:
Board out:
wbbbw
bbbbb
wwwww
wwwww
bwbwb
I do this by making a 2D array (char[][] board) of characters, reading the file line by line into a string, and using String.charAt() to access each character and store it in the array.
Afterward, I convert each element of board (i.e., board[0], board[1], etc.), back to a string using String.valueOf(), and write that to a new line in the second file.
Please tell me I'm an idiot for doing this and that there is a better way to go through the file -> string -> array -> string -> file process.

You can use String.toCharArray() for each line while reading the file.
char[][] board = new char[5][];
int i = 0;
while((line = buffRdr.readLine()) != null) {
board[i++] = line.toCharArray();
}
And while writing either String.valueOf() or java.util.Arrays.toString().
for(int i=0; i<board.length; i++) {
//write Arrays.toString(board[i]);
}

// Remember to handle whitespace chars in array
char[] row = "wbbbw bbbbb wwwww wbwbw bwbwb".toCharArray()
Everything else seems good.

Why not use an already existing text format such as JSON instead of inventing your own?
There are tons of JSON parsers out there that can read and write two dimensional arrays.
You get both the benefit of easy reading directly from the file(as with your original method) and the benefit of not having to parse an annoying string format.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
public class GameOfLife
{
private String mFilename;
private ArrayList<String> mLines;
public GameOfLife(String filename)
{
mFilename = filename;
read();
}
public char get(int x, int y)
{
String line = mLines.get(y);
return line.charAt(x);
}
public void set(char c, int x, int y)
{
String line = mLines.get(y);
String replacement = line.substring(0, x) + c + line.substring(x + 1, line.length());
mLines.set(y, replacement);
}
private void read()
{
mLines = new ArrayList<String>();
try
{
BufferedReader in = new BufferedReader(new FileReader(mFilename));
String line = in.readLine();
while (line != null)
{
mLines.add(line);
line = in.readLine();
}
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
private void write()
{
try
{
BufferedWriter out = new BufferedWriter(new FileWriter(mFilename));
for (String line : mLines)
{
out.write(line + "\n");
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}

Related

Split a string with a space in Java, when a space occurs?

I'm trying to extract data from a CSV file, in which I have the following example CSV
timestamp, Column1,column2,column3
2019-05-07 19:17:23,x,y,z
2019-03-30 19:41:33,a,b,c
etc.
currently, my code is as follows:
public static void main(String[]args){
String blah = "file.csv";
File file = new File(blah);
try{
Scanner iterate = new Scanner(file);
iterate.next(); //skips the first line
while(iterate.hasNext()){
String data = iterate.next();
String[] values = data.split(",");
Float nbr = Float.parseFloat(values[2]);
System.out.println(nbr);
}
iterate.close();
}catch (FileNotFoundException e){
e.printStackTrace();
}
}
However, my code is giving me an error
java.lang.ArrayIndexOutOfBoundsException: Index 3 is out of bounds for length 3
My theory here is the split is the problem here. As there is no comma, my program thinks that the array ends with only the first element since there's no comma on the first element (I've tested it with the timestamp column and it seems to work, however, I want to print the values in column 3)
How do I use the split function to get the column1, column2, and column3 values?
import java.util.*;
import java.util.*;
import java.io.*;
public class Sample
{
public static void main(String[] args)
{
String line = "";
String splitBy = ",";
try
{ int i=0;
String file="blah.csv";
BufferedReader br = new BufferedReader(new FileReader(file));
int iteration=0;
while ((line = br.readLine()) != null) //returns a Boolean value
{ if(iteration < 1) {
iteration++;
continue;} //skips the first line
String[] stu = line.split(splitBy);
String time=stu[3];
System.out.println(time);
}
}
catch (IOException e)
{
e.printStackTrace();
}} }
Try this way by using BufferedReader
Input:
timestamp, Column1,column2,column3
2019-05-07 19:17:23,x,y,z
2019-03-30 19:41:33,a,b,c
2019-05-07 19:17:23,x,y,a
2019-03-30 19:41:33,a,b,f
2019-05-07 19:17:23,x,y,x
2019-03-30 19:41:33,a,b,y
Output for this above code is:
z
c
a
f
x
y
A few suggestions:
Use Scanner#nextLine and Scanner#hasNextLine.
Use try-with-resources statement.
Since lines have either whitespace or a comma as the delimiter, use the regex pattern, \s+|, as the parameter to the split method. The regex pattern, \s+|, means one or more whitespace characters or a comma. Alternatively, you can use [\s+,] as the regex pattern.
Demo:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
String blah = "file.csv";
File file = new File(blah);
try (Scanner iterate = new Scanner(file)) {
iterate.nextLine(); // skips the first line
while (iterate.hasNextLine()) {
String line = iterate.nextLine();
String[] values = line.split("[\\s+,]");
System.out.println(Arrays.toString(values));
}
}
}
}
Output:
[2019-05-07, 19:17:23, x, y, z]
[2019-03-30, 19:41:33, a, b, c]

Is there any in built function in Java to remove unwanted data from extracted data

I extracted some text from a text file but now I want only some specific words from that text.
What I have tried is read from that text file and I have searched by using keyword:
FileReader fr = new
FileReader("D:\\PDFTOEXCEL\\Extractionfrompdf.txt");
BufferedReader br = new BufferedReader(fr);
String s;
String keyword = "dba COPIEFacture ";
while ((s = br.readLine()) != null) {
if (s.contains(keyword)) {
System.out.println(s);
I got Output like this: dba COPIEFacture du 28/05/2018 n° 10077586115Récapitulatif de vote facture
But I want only 28/05/2018 This so please help me
You'll need to use String manipulation methods.
It's difficult to know the best way to do it without seeing other outputs, but you could probably use split() and indexOf() to retrieve the date.
There are other, probably more complex, methods. For example, here's a StackOverflow answer about retrieving dates from strings using a regex pattern.
This will do the trick.
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
FileReader fr;
String keyword = "dba COPIEFacture du ";
String textToFind = "28/05/2018"; // The length usually will not
// change.You can use value
// 10(length) instead
StringBuilder sb = new StringBuilder();
try {
fr = new FileReader("D:\\PDFTOEXCEL\\Extractionfrompdf.txt");
int i;
while ((i = fr.read()) != -1) {
sb.append((char) i);
}
int start = sb.indexOf(keyword) + keyword.length();
int end = start + textToFind.length();
System.out.print(sb.substring(start, end)); //output: 28/05/2018
fr.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Java StringTokenizer assistance

So, I have a separate program that requires a string of numbers in the format: final static private String INITIAL = "281043765"; (no spaces) This program works perfectly so far with the hard coded assignment of the numbers. I need to, instead of typing the numbers in the code, have the program read a txt file, and assign the numbers in the file to the INITIAL variable
To do this, I'm attempting to use StringTokenizer. My implementation outputs [7, 2, 4, 5, 0, 6, 8, 1, 3]. I need it to output the numbers without the "[]" or the "," or any spaces between each number. Making it look exactly like INITIAL. I'm aware I probably need to put the [] and , as delimiters but the original txt file is purely numbers and I don't believe that will help. Here is my code. (ignore all the comments please)
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class test {
//public static String num;
static ArrayList<String> num;
//public static TextFileInput myFile;
public static StringTokenizer myTokens;
//public static String name;
//public static String[] names;
public static String line;
public static void main(String[] args) {
BufferedReader reader = null;
try {
File file = new File("test3_14.txt");
reader = new BufferedReader(new FileReader(file));
num = new ArrayList<String>();
while ((line = reader.readLine())!= null) {
myTokens = new StringTokenizer(line, " ,");
//num = new String[myTokens.countTokens()];
while (myTokens.hasMoreTokens()){
num.add(myTokens.nextToken());
}
}
System.out.println(num);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
You are currently printing the default .toString() implementation of ArrayList. Try this instead:
for (String nbr : num) {
System.out.print(nbr)
}
To get rid of the brackets, you have to actually call each item in the ArrayList. Try this just below your System.out.println
for(String number : num)
System.out.print(number);
System.out.println("");
Can you also provide sample input data?
Try Replacing space and , with empty string
line = StringUtils.replaceAll(line, “,” , “”);
line = StringUtils.replaceAll(line, “ “, “”);
System.out.println(line);

reading in CSV file, arrayindex out of bounds error

I'm attempting to read in a csv file, I've created a test file with 9 entries and their value, but my code won't read past the second line , it says the file isn't found past the second key, I've tried tweeking it as much as possible, can someone help me? sample input would include something like this but in a csv file (so each in a new line, I'm new here and still learning to edit text here):
Diego,2
Maria,2
Armando,5
Ken, 1
public static void main(String[] args) {
HashMap<String, Integer> h = new HashMap<String, Integer>(511);
try
{
Scanner readIn = new Scanner (new File ("test1.csv") );
System.out.println("I'm here 1");
while ( readIn.hasNext() )
{
System.out.print(readIn.next());// for testing purposes only
System.out.println("Check 2"); // for testing purposes only
String line = readIn.nextLine();
String str[] = line.split(",");
for (int i = 0; i < str.length ; i++)
{
String k = str[0];
int v = Integer.parseInt(str[1]);
h.insert(k , v);
}
System.out.println(h.toString());
}
readIn.close();
}
catch (ArrayIndexOutOfBoundsException ob)
{
System.out.println(" - The file wasn't found." );
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
A call to next() or nextLine() should be preceeded with the call to hasNext().But in you code you have checked if hasNext() returns true in the while loop,and then invoked both next() and nextLine() inside the loop.
You can modify your code as below:
while ( readIn.hasNext() )
{
String line = readIn.nextLine();
String str[] = line.split(",");
for (int i = 0; i < str.length ; i++)
{
String k = str[0];
int v = Integer.parseInt(str[1]);
h.put(k , v);
}
System.out.println(h.toString());
}
Your for loop isn't actually serving a purpose. You will notice that you never actually reference i in the loop. Prior to the OP's answer I believe you were trying to split on a string that didn't have a comma, but your code assumes that one will be there and hence the out of bounds exception. This relates to why I was telling you that the println() was problematic.
As far as your question about hasNext(), this is the only way you will know that you can read another line from the file. If you try to read past the end you will run into problems.
Rather writing code to read CSV file on your own. I'd suggest you to use standard libraries like Apache Commons CSV. It provides more methods to deal with CSV, Tab separated file, etc...
import java.io.FileReader;
import java.util.List;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;
public class SO35859431 {
public static void main(String[] args) {
String filePath = "D:\\user.csv";
try {
List<CSVRecord> listRecords = CSVFormat.DEFAULT.parse(new FileReader(filePath)).getRecords();
for (CSVRecord csvRecord : listRecords) {
/* Get record using index/position */
System.out.println(csvRecord.get(0));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
First there is no such insert() method in HashMap class.The correct one is put(k, v) & in while loop it should be hasNext(). Follow is my code alternate the BufferedReader.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package read;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Scanner;
/**
*
* #author Isuru Rangana Jr
*/
public class Read {
/**
* #param args the command line arguments
*/
public static void main(String args[]) throws FileNotFoundException, IOException {
HashMap<String, Integer> h = new HashMap<String, Integer>();
try {
BufferedReader readIn = new BufferedReader(new FileReader(new File("test.csv")));
while (readIn.ready()) {
String line = readIn.readLine();
String str[] = line.split(",");
for (int i = 0; i < str.length; i++) {
String k = str[0];
int v = Integer.parseInt(str[1]);
h.put(k, v);
}
System.out.println(h.toString());
}
readIn.close();
} catch (ArrayIndexOutOfBoundsException ob) {
System.out.println(" - The file wasn't found.");
}
}
}

search range data on CSV file using java

I'm trying to get selective data from .csv file using java.
for example:
CSV file contains:
Blue, 03/11/2014, 13:00, 10
pink, 04/11/2014, 14:00, 15
Red, 03/11/2014, 15:00, 50
I want to create a program in java which will allow users to select what info they want from that file.
I've been working on the example below but only able to print strings and not the dates/intergers:
package csv;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Arrays;
import java.util.Scanner;
public class ReadCVS {
public static void main(String[] args) {
ReadCVS obj = new ReadCVS();
obj.run();
}
public void run() {
String csvFile = "GeoIPCountryWhois.csv";
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
File file = new File("GeoIPCountryWhois.csv");
Scanner in = null;
try {
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
// use comma as separator
String[] colour = line.split(cvsSplitBy);
//System.out.println(country[0]+ country[1] + country[2]+ country[3]);
for (int i = 0; i < colour.length; i++) {
if (colour[i].equals("Pressure")) {
System.out.println(colour[0] + colour[1] + colour[2] + colour[3]); //Matching the string and printing.
}
}
}
} 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");
}
}
Any help/tips will be appreciated!
thanks
I would recommend using 3rd party library for parsing the csv file. This lets you focus on the essence of what you are trying to do, instead of getting hung up on file parsing. Have a look at, for example Apache Commons CSV. This would let your code look like this:
Reader in = new FileReader("GeoIPCountryWhois.csv");
DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
Iterable<CSVRecord> records = CSVFormat.EXCEL.parse(in);
for (CSVRecord record : records) {
String colour = record.get(0);
Date date = df.parse(record.get(1));
String timeString = record.get(2);
Integer value = Integer.parseInt(record.get(3));
// do what you want with the values here.
}
Notice how this does some additional parsing, such as parsing the Date and the Integer. This will let you more easily filter those columns because you can do comparisons.
If you don't want third party dependencies, you could do something similar to what you have:
DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
while ((line = br.readLine()) != null) {
// use comma as separator
String[] columns = line.split(cvsSplitBy);
// extract the columns.
String colour = columns[0].trim();
Date date = df.parse(columns[1].trim());
String time = columns[2].trim();
Integer otherValue = Integer.parseInt(columns[3].trim());
// filter on the colour column.
if(colour.equals("Red")) {
System.out.printf("colour = %s, date = %s, time = %s, val = %d\n", colour, df.format(date), time, otherValue);
}
}
Note how this code is calling String.trim() on all of the columns. This is in case there is extra whitespace around the column after splitting the line. For example, "a, b, c".split(",") would result in the String array {"a", " b", " c"} which has an extra space in " b" and " c". This is probably the source of the bug you have where you can only filter on the first column.
As a third option, which is sort of overkill, you could use CsvJdbc. This provides a JDBC interface to sql files, which you can then execute SQL queries over. I've never used this library but it looks interesting. Given that you are trying to filter CSV files.

Categories

Resources