How to parse a form of csv file in java - java

I am trying to parse a rather special-formatted file by using scanner with delimiter, but I am rather new to regex. The format:
"MARY","PATRICIA","LINDA","BARBARA","ELIZABETH","JENNIFER",...
Currently, I am using this delimiter and code below:
static void readNames(String[] names) {
try {
Scanner sc = new Scanner(new File("names.txt")).useDelimiter(",");
int count = 0;
while(sc.hasNext()) {
names[count] = sc.next();
count ++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
However, this gives me quotes around the String which is not what I want.
Then, I tried to the following delimiter:
String delimiter = " "," ";
Which I quickly realised is not recognised as a String due to the amount of quotation marks.
This is edited after I got my answer, but is there any way to do it the way I intended in the second delimiter, by using the "," as the delimiter?

Based upon the data given in your post, I think you can use this pattern ","|"
Following is the kind of code you can write,
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(new FileInputStream("filename.txt"));
sc.useDelimiter(Pattern.compile("\",\"|\""));
while(sc.hasNext()) {
System.out.println(sc.next());
}
sc.close();
}

If you just want a java written helpful csv parser. I wrote a pretty nice one recently:
public static Iterable<String[]> parseCSV(final InputStream stream) throws IOException {
return new Iterable<String[]>() {
#Override
public Iterator<String[]> iterator() {
return new Iterator<String[]>() {
static final int UNCALCULATED = 0;
static final int READY = 1;
static final int FINISHED = 2;
int state = UNCALCULATED;
ArrayList<String> value_list = new ArrayList<>();
StringBuilder sb = new StringBuilder();
String[] return_value;
public void end() {
end_part();
return_value = new String[value_list.size()];
value_list.toArray(return_value);
value_list.clear();
}
public void end_part() {
value_list.add(sb.toString());
sb.setLength(0);
}
public void append(int ch) {
sb.append((char) ch);
}
public void calculate() throws IOException {
boolean inquote = false;
while (true) {
int ch = stream.read();
switch (ch) {
default: //regular character.
append(ch);
break;
case -1: //read has reached the end.
if ((sb.length() == 0) && (value_list.isEmpty())) {
state = FINISHED;
} else {
end();
state = READY;
}
return;
case '\r':
case '\n': //end of line.
if (inquote) {
append(ch);
} else {
end();
state = READY;
return;
}
break;
case ',': //comma
if (inquote) {
append(ch);
} else {
end_part();
break;
}
break;
case '"': //quote.
inquote = !inquote;
break;
}
}
}
#Override
public boolean hasNext() {
if (state == UNCALCULATED) {
try {
calculate();
} catch (IOException ex) {
}
}
return state == READY;
}
#Override
public String[] next() {
if (state == UNCALCULATED) {
try {
calculate();
} catch (IOException ex) {
}
}
state = UNCALCULATED;
return return_value;
}
};
}
};
}
You would typically process this quite helpfully like:
for (String[] csv : parseCSV(stream)) {
//<deal with parsed csv data>
}
Generally it wraps a csv stream parser in an iterable so you can use the special java for loops. So you feed it a stream and it'll give you a for loop of arrays of strings, which is typically going to be the best way you'd want that data.
If you rather want understanding, you'll need to better phrase your question with additional information that makes it clear what you think you need and why, because most of your post doesn't make much sense.

Related

Java: How do I prevent duplicates from being added to ArrayList using conditional statement?

I'm nearly finished with a program that gathers the user's inputs (keywords) and displays them. I have it functioning in that regard but I also need to prevent duplicate keywords from being added to the List using a conditional if statement. I know I'm on the right track, but having trouble wrapping my mind around the syntax and use of a boolean to compare the entered keyword with the existing ArrayList.
I know there are methods such as Hash/Set but I'd like to be able to do it with the conditional statement before I move onto other techniques. Every answer I've found in the search seems to explain the use of Hash.
Thanks!
UPDATE: Iv'e edited my code to what I currently have based on #Jacob 's answer and this is what I was looking for, so thanks for the response. But it's still not removing duplicates, it's like it's not checking the array and skipping right to alreadyExists == false conditional statement. Or am I not comparing the values correctly?
import java.util.*;
public class KeywordData {
private ArrayList<Keyword> keywords = new ArrayList<Keyword>();
public void create() {
InputHelper inputHelper = new InputHelper();
String prompt = "";
boolean isTrue = true;
while (isTrue) {
prompt = inputHelper.getUserInput("Enter a string, otherwise type 'n' to exit:");
if (!prompt.equals("n")) {
Keyword keyword = new Keyword();
keyword.setUserKeyword(prompt);
boolean alreadyExists = false;
for (Keyword keyword1 : keywords) {
if (keyword1.equals(keyword)) {
alreadyExists = true;
}
}
if (alreadyExists == false) {
keywords.add(keyword);
} else {
System.out.println("You already added that word");
}
} else {
break;
}
}
}
public void displayKeywords() {
System.out.println();
System.out.println("********** Your unique user keywords **********");
for (Keyword keyword : keywords) {
keyword.display();
}
System.out.println();
}
}
This is how I did it, I showed my whole program because I changed some of your custom classes to just strings, and didn't really know what those custom classes did.
import java.util.*;
import java.io.Console;
public class KeywordData {
private ArrayList<String> keywords = new ArrayList<String>();
Scanner reader = new Scanner(System.in);
public void create() {
String prompt = "";
boolean isTrue = true;
while (isTrue) {
System.out.println("Enter a string, otherwise type 'n' to exit:");
prompt = reader.next();
if (!prompt.equals("n")) {
boolean alreadyExists = false;
for (String keyword1 : keywords) {
if (keyword1.equals(prompt)) {
alreadyExists = true;
}
}
if (alreadyExists == false) {
keywords.add(prompt);
}else {
System.out.println("You already added that word");
}
} else {
break;
}
}
}
public void displayKeywords() {
System.out.println();
System.out.println("********** Your unique user keywords **********");
for (String keyword : keywords) {
System.out.println(keyword);
}
}
public static void main(String[] args) {
KeywordData kd = new KeywordData();
kd.create();
kd.displayKeywords();
}
}
But the easier way to check is like this
if (!prompt.equals("n")) {
if (keywords.contains(prompt)) {
System.out.println("You already added that word");
}else {
keywords.add(prompt);
}
} else {
break;
}

What is supertype?

import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.util.*;
//star my method lab
public class Method extends JPanel {
//two array lists that I am going to use.
ArrayList<String> english = new ArrayList<>();
ArrayList<String> french = new ArrayList<>();
//bring text file as an array
public void loadEnglishWords() {
//input my file
String filename = "english.txt";
File f = new File(filename);
try {
Scanner s = new Scanner(f);
//scan all array line by line
while (s.hasNextLine()) {
String line = s.nextLine();
english.add(line);
}
} catch (FileNotFoundException e) { //wrong file name makes error massage pop up
String errorMessage = "Wrong!";
JOptionPane.showMessageDialog(null, errorMessage, "Wrong!",JOptionPane.ERROR_MESSAGE);
}
}
//same array job with English to compare
public void loadFrenchWords() {
String filename = "french.txt";
File f = new File(filename);
try {
Scanner s = new Scanner(f);
while (s.hasNextLine()) {
String line = s.nextLine();
french.add(line);
}
} catch (FileNotFoundException e) {
String errorMessage = "Wrong!";
JOptionPane.showMessageDialog(null, errorMessage, "Wrong!",JOptionPane.ERROR_MESSAGE);
}
}
//check each line to parallel my arrays to get to same position
public String lookup(String word){
for (int i = 0; i < english.size();i++) {
if (word.equals(english.get(i))) {
return french.get(i);
}
}
//wrong values in arrays
return "No match found";
}
//infinite loop to run my program until get the result
public void mainLoop() {
while (true) {
//pop-up box to ask English words
String tmp = JOptionPane.showInputDialog("Please Enter an English Word!");
//store the result in variable r
String r = lookup(tmp);
String a;
//
if (r == ("No match found")) {
a = "Write a Right Word!";
} else {
a = "The French word is : " + r + ". Play agian?";
}
//asking want to play more or not
int result;
result = JOptionPane.showConfirmDialog(null,a,"RESULT!",JOptionPane.YES_NO_OPTION);
//doens't want to play then shut down
if (result == JOptionPane.NO_OPTION) {
break;
}
}
}
//make all things run in order
#Override
public void init() {
loadEnglishWords();
loadFrenchWords();
mainLoop();
}
}
//My problem is that everytime I compile this program the error message would be:
"Method.java:88: error: method does not override or implement a method from a supertype
#Override
^
1 error"
//This program is to translate french words to english words using arraylist
I`m using a .txt file for my set of english and french words and have it run through arraylist to translate
//In my program I need to use a JPanel or pop-up box to ask the user to input the word that they wish to translate
//Please note that I am a beginner with Java, please somebody help me and point out on where I got it wrong so I can change it. Thank you so much!
What the error is saying is that in line 88, you are using the #Override to redefine a method named init from parent class JPanel. But because JPanel is what it is (i.e. a part of Java), it does not have init method, you can not redefine it, hence the error. Most likely, you should just remove the #Override, which will mean you want to add a new method instead of redefining it.
Inheritance is a mechanism where you take an existing class and modify it according to your needs. In your case, your class is named Method and it extends (inherits from) JPanel, so JPanel is the supertype of your class.
If you're just beginning, go read and educate yourself on object-oriented concepts. There are many tutorials, including YouTube videos. Happy learning!
Aside from what was previously mentioned, you need to change a few things:
public void init() { should be public static void main(String args[]) {
Then you need to make your methods static, i.e.
public static void loadEnglishWords() {
Also, the arrayLists need to also be static
And one other thing, you should compare with .equals() and not ==
I've re-written your code slightly and now it should work:
static ArrayList<String> english = new ArrayList<>();
static ArrayList<String> french = new ArrayList<>();
//bring text file as an array
public static void loadEnglishWords() {
//input my file
try {
Scanner s = new Scanner(new File("english.txt"));
//scan all array line by line
while (s.hasNextLine()) {
String line = s.next();
english.add(line);
}
} catch (FileNotFoundException e) { //wrong file name makes error massage pop up
String errorMessage = "Wrong!";
JOptionPane.showMessageDialog(null, errorMessage, "Wrong!", JOptionPane.ERROR_MESSAGE);
}
}
//same array job with English to compare
public static void loadFrenchWords() {
try {
Scanner s = new Scanner(new File("french.txt"));
while (s.hasNextLine()) {
String line = s.nextLine();
french.add(line);
}
} catch (FileNotFoundException e) {
String errorMessage = "Wrong!";
JOptionPane.showMessageDialog(null, errorMessage, "Wrong!", JOptionPane.ERROR_MESSAGE);
}
}
//check each line to parallel my arrays to get to same position
public static String lookup(String word) {
for (int i = 0; i < english.size(); i++) {
if (word.equals(english.get(i))) {
return french.get(i);
}
}
//wrong values in arrays
return "No match found";
}
//infinite loop to run my program until get the result
public static void mainLoop() {
while (true) {
//pop-up box to ask English words
String tmp = JOptionPane.showInputDialog("Please Enter an English Word!");
//store the result in variable r
String r = lookup(tmp);
String a;
//
if (r.equals("No match found")) {
a = "Write a Right Word!";
} else {
a = "The French word is : " + r + ". Play agian?";
}
//asking want to play more or not
int result;
result = JOptionPane.showConfirmDialog(null, a, "RESULT!", JOptionPane.YES_NO_OPTION);
//doens't want to play then shut down
if (result == JOptionPane.NO_OPTION) {
break;
}
}
}
//make all things run in order
public static void main(String args[]) {
loadEnglishWords();
loadFrenchWords();
mainLoop();
}
}

How would I search for a user determined word and count the occurrences in a text file using java?

I've gotten to a point where I can read the file and output the actual text in the file but i'm not quite sure on how to proceed with searching for a specific word and displaying the word count.
There are many ways. If you're reading the file line-by-line, you can using the method indexOf on the String class to search each line for the text. You'd need to call it repeatedly to move through the line looking for additional occurrences.
See documentation on indexOf at:
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#indexOf(java.lang.String,%20int)
As I understand your question, if you are reading the text line after line you can use recursivity to count how many occurences of the word appear in the same line:
The following method counts how many times a word appears in the same line
private static int numberOfLineOccurences;
public static int countNumberOfTimesInALine(String line, String word) {
if (line.indexOf(word) == -1) {
return numberOfLineOccurences;
} else {
numberOfLineOccurences++;
if (line.indexOf(word) + word.length() > line.length() -1 ) {
return numberOfLineOccurences;
}
return countNumberOfTimesInALine(
line.substring(line.indexOf(word) + word.length()), word );
}
}
In order to keep track of the first occurence of my word in my file along with the number of occurence I created a WordInfo class like this:
class WordInfo {
private int firstOccurenceLineNumber;
private int firstOccurenceColumnNumber;
private String word;
private int numberOfOccurences;
public String getWord() {
return word;
}
public int getNumberOfOccurences() {
return numberOfOccurences;
}
public WordInfo(String word) {
this.word = word;
}
public void upOccurrence() {
numberOfOccurences++;
}
public void upOccurrence(int numberOfTimes) {
numberOfOccurences+= numberOfTimes;
}
public int getFirstOccurenceLineNumber() {
return firstOccurenceLineNumber;
}
public void setFirstOccurenceLineNumber(int firstOccurenceLineNumber) {
this.firstOccurenceLineNumber = firstOccurenceLineNumber;
}
public int getFirstOccurenceColumnNumber() {
return firstOccurenceColumnNumber;
}
public void setFirstOccurenceColumnNumber(int firstOccurenceColumnNumber) {
this.firstOccurenceColumnNumber = firstOccurenceColumnNumber;
}
}
Now I can create my searchWord method. I give him the word to look for, the fileName and a WordInfo object to fill as input parameters
public static boolean searchWord(String word, String filePath, WordInfo wInfo) throws IOException {
boolean result = false;
boolean firstOccurenceFound = false;
int lineNumber = 0;
BufferedReader reader = new BufferedReader(new FileReader(new File(filePath)));
String line = null;
while ( (line = reader.readLine()) != null) {
lineNumber++;
numberOfLineOccurences= 0;
if (line.indexOf(word) != -1) {
if (!result) {
result = true;
}
if (!firstOccurenceFound) {
firstOccurenceFound = true;
wInfo.setFirstOccurenceLineNumber(lineNumber);
wInfo.setFirstOccurenceColumnNumber(line.indexOf(word) + 1);
}
wInfo.upOccurrence(countNumberOfTimesInALine(line, word));
}
}
reader.close();
return result;
}
Here is an illustration and the result below
I have the following content in a file called DemoFile.txt
And I test the code using the following main method (I am looking for the word conceptfor example):
public static void main(String[] args) throws IOException {
WordInfo wInfo = new WordInfo("concept");
if ( searchWord("concept", FILE_PATH, wInfo)) {
System.out.println("Searching for " + wInfo.getWord());
System.out.println("First line where found : " + wInfo.getFirstOccurenceLineNumber());
System.out.println("First column found: " + wInfo.getFirstOccurenceColumnNumber());
System.out.println("Number of occurrences " + wInfo.getNumberOfOccurences());
}
}
And I obtain the following results:

My Java Program won't Compile

As I just stated above this program won't compile. In my IDE, TextPad, it gives me 2 errors in the createArray method. It says that both a right bracket and semicolon are expected in my return statement when I indeed have them there. Could someone help me out here?
public class Driver
{
private static int size;
private static String somePromptMessage;
private static boolean validInput;
private static String userData;
public static void main(String[] args) throws IOException
{
validInput = false;
BufferedReader keyboard;
keyboard = new BufferedReader(new InputStreamReader(System.in));
int result;
do
{
somePromptMessage = "Enter an integer";
System.out.println(somePromptMessage);
String userData;
userData = keyboard.readLine();
System.out.println(createArray(10));
try
{
result = Integer.parseInt(userData);
}
catch(NumberFormatException nfe)
{
System.out.println("Value entered is invalid, try again");
}
}
while(!validInput);
{
return result;
}
}
public static void print(int[]x)
{
System.out.println("The array contains" + size + "elements");
for(int i = 0; i<x.length; i++)
{
System.out.println(x[i]);
}
}
private static int[] createArray(int size)
{
return int[size];
}
You're missing the enclosing } for the class, but I'll assume that one is a copy-paste issue.
The actual problem I see is that you want
return new int[size];
instead of
return int[size];
in your createArray function.
I see an extra simi-colon here:
while(!validInput);
{
return result;
}
Update: It was brought to my attention that this is actually a do while so why the extra braces around the return statement?
remove braces after while across return result; as it is do-while:
do
{
somePromptMessage = "Enter an integer";
System.out.println(somePromptMessage);
String userData;
userData = keyboard.readLine();
System.out.println(createArray(10));
try
{
result = Integer.parseInt(userData);
}
catch(NumberFormatException nfe)
{
System.out.println("Value entered is invalid, try again");
}
}
while(!validInput);
return result;

Java returns impossible random numbers

Here is the code:
import java.lang.*;
import java.io.*;
class string
{
public static void main(String[] args)
{
try
{
boolean go = true;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuffer inp = new StringBuffer(br.readLine());
System.out.println(inp.reverse());
inp.reverse();
int leng = inp.length();
inp.setLength(leng+100);
int x = 0;
StringBuffer res = inp;
William bill = new William();
res=bill.will(x+1, leng, res);
while(x<leng-1 && go)
{
if(inp.charAt(x)==' ' && go)
{
res=bill.will(x+1, leng, res);
go = bill.bob();
}
x=x+1;
}
System.out.println(res);
}
catch (IOException uhoh)
{
System.out.println("You entered something wrong.");
System.exit(1);
}
}
}
class William
{
public boolean go;
public William()
{
this.go=true;
}
public StringBuffer will(int start, int len, StringBuffer input)
{
char cur = input.charAt(start-1);
input.delete(start-1, start-1);
int x = start;
boolean happy=true;
while(x<len && happy)
{
if(x==len-2)
{
this.go=false;
input.insert(cur, x+1);
x=x+2;
happy=false;
}
else if(input.charAt(x)==' ')
{
input.insert(cur, x);
x=x+1;
happy=false;
}
else
{
x=x+1;
}
}
return input;
}
public boolean bob()
{
return this.go;
}
}
It is supposed to return the reverse of the input (it does that without error) and the input in an altered form of pig latin. tI houlds ookl ikel hist ("It should look like this"). But instead, it returns the original StringBuffer with a bunch of random numbers on the end. Two notable patterns in the error include the increase in the numbers as the number of letters increases, as well as overflow errors when short strings are inputted.
You have the arguments to StringBuffer.insert() backwards. It's (offset, char)
try
input.insert(x+1, cur); instead of input.insert(cur, x+1);
(and same for input.insert(cur, x))

Categories