How to check for duplicate String in a java String array - java

I am trying to find duplicates values from the first column 0 in array that's been loaded in a string and split, and then throw an exception when this is found.
Here is my code.
public void loadTrueFalseQuestions() throws Exception {
try {
Scanner input = new Scanner(new FileInputStream(TRUE_FALSE_FILE));
while (input.hasNextLine()) {
line = input.nextLine();
String[] split = line.split(",");
int chapterNumber = Integer.parseInt(split[1]);
String correctAnswer = (split[3]);
String questionID = (split[0]);
if (split.length != TRUE_FALSE_FIELDS) {
throw new Exception();
} else if ((!correctAnswer.matches("TRUE")) & (!correctAnswer.matches("FALSE"))) { //throw new Exception();
} else if (true) {
}
}
} catch (FileNotFoundException e) {
System.out.println("Could not open a file.");
System.exit(0);
}
}
This is the CSV file.
TF001,8,Java allows an instance of an abstract class to be instantiated.,FALSE
TF001,8,Downcasting should be used only in situations where it makes sense.,TRUE
TF003,9,The throw operator causes a change in the flow of control.,TRUE
TF004,9,When an exception is thrown the code in the surrounding try block continues executing
and then the catch block begins execution.,FALSE
I'm not sure how to go about it. I cannot get past the logic. I'm trying an if statement and contains(questionID) string method, but not sure how to combine these two. (if that makes sense).
Appreciate any advice.

I use a hash map and put the key field as the key in the hash map. You can check if you already put the key in the hash and if so do something because you already have it.
public void loadTrueFalseQuestions() throws Exception {
try {
Scanner input = new Scanner(new FileInputStream(TRUE_FALSE_FILE));
Map<String, String> myHash = new HashMap<>();
while (input.hasNextLine()) {
line = input.nextLine();
String[] split = line.split(",");
int chapterNumber = Integer.parseInt(split[1]);
String correctAnswer = (split[3]);
String questionID = (split[0]);
if (myHash.containsKey(questionID)) {
// what to do here?
} else {
myHash.put(questionID, line);
}
}
} catch (FileNotFoundException e) {
System.out.println("Could not open a file.");
System.exit(0);
}
}

Related

Why I could not save the contents of a file after reading it twice?

Already fixed. Thanks for Mas & ruhul for observing my bugs.
I was trying to read a text file twice, named stationary.txt. The contents of the file has three columns such as the amount, the name of product and the total price.
What I am trying to do first is by averaging each product's price by reading line by line. Then I closed the Buffered and then open it again and read. The second reading takes a variable average and compares each product's price line by line. If line 1 is over the average, then write it into dearer.txt, otherwise write it into cheap.txt
Here is the stationary.txt
1 Highlighter 5.99
2 Pen 9.00
3 Eraser 5.00
4 DrawingPin 2.75
5 Highlighter 10.99
6 FountainPen 20.50
7 Pencil 14.50
Below is the source code
import java.util.*;
import java.io.*;
public class Ques {
public static void main(String[] args) throws FileNotFoundException {
double average = 0;
File inFile = new File("stationary.txt");
FileReader fileReader = new FileReader(inFile);
BufferedReader bufReader = new BufferedReader(fileReader);
File outFilel = new File("dearer.txt");
FileOutputStream outFileStreaml = new FileOutputStream(outFilel);
PrintWriter outStream1 = new PrintWriter(outFileStreaml);
File outFile2 = new File("cheap.txt");
FileOutputStream outFileStream2 = new FileOutputStream(outFile2);
PrintWriter outStream2 = new PrintWriter(outFileStream2);
computeAverage(bufReader, outStream1, outStream2, average);
}
public static void computeAverage(BufferedReader bufReader, PrintWriter outStream1, PrintWriter outStream2, double average) {
String line = "";
double mark = 0;
double sum = 0;
int count = 0;
try {
bufReader.readLine();
while ((line = bufReader.readLine()) != null) {
String [] data = line.split(" ");
mark = Double.parseDouble(data[2]);
sum += mark;
count++;
}
average = sum / count;
compareMark(outStream1, outStream2, average);
} catch (NumberFormatException | IOException e) {
System.out.println(e);
} finally {
if (bufReader != null) {
try {
bufReader.close();
} catch ( IOException e) {
e.printStackTrace();
}
}
}
}
public static void compareMark(PrintWriter outStream1, PrintWriter outStream2, double average) throws FileNotFoundException {
File inFile = new File("stationary.txt");
FileReader fileReader = new FileReader(inFile);
BufferedReader bufReader = new BufferedReader(fileReader);
String line = " ";
double sum = 0;
double mark = 0;
int count = 0;
try {
double ave = (double) Math.round(average * 100) / 100;
System.out.println("another " + ave);
bufReader.readLine();
while ((line = bufReader.readLine()) != null) {
System.out.println(line);
String [] data = line.split(" ");
mark = Double.parseDouble(data[2]);
if (mark > ave) {
System.out.println("Over");
outStream1.write(line);
} else {
System.out.println("Less");
outStream2.write(line);
}
}
} catch (IOException e) {
System.out.println(e);
} catch (NumberFormatException ex) {
System.out.println(ex);
} finally {
if (bufReader != null) {
try {
bufReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
The source code is perfectly working, just that I received 0 bytes of both files after executing reading twice (first, doing average and last, doing comparison). Why is that? what am I doing wrong here?
Thank you for your kind help.
Your code is not correct and does not compile. But the main flaws are the following:
Your Double.parseDouble(data[2]) shouldn't work with your 4th line of data. Better use Double.parseDouble(data[data.length - 1])
Remove the readLine()-calls in front of the while-loop.
Write the lines including a line separator.
Close the OutStreams
The Data File that you have provided have the columns seperated by a space. As the 2nd Column has data which contains spaces, the convertion of data[2] to double will trigger an exception. Which will make the program to close the buffers and exit.
Use Commas to seperate column data.
Use better exception handling to find exceptions easily.
All you need is to close those output stream. As you are using bufferredWriter and not flushing it after each write you need to close those output-stream. which will write back those lines or datas into the file. Here is an example how you can do it:
Example 1: using flush().
....
outStream1.write(line);
outStream1.flush();
} else {
System.out.println("Less");
outStream2.write(line);
outStream2.flush();
}
Example 2: most efficient (either way you need to close those buffer too like bufReader.close())
...
} catch (IOException e) {
System.out.println(e);
} catch (NumberFormatException ex) {
System.out.println(ex);
} finally {
// add try catch.
outStream2.close();
outStream1.close();
if (bufReader != null ... ) {
try {
bufReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
As requested, an example using List
First a class to hold the stationary data, must be completed:
public class Stationary {
private final int id; // or String if desired
private final String name;
private final double mark; // BigDecimal would be better for money
public Stationary(int id, String name, double mark) {
// TODO error checking
this.id = id;
...
}
public int getId() {
return id;
}
... // TODO other getters
// TODO equals, hashCode, toString
}
and to read the file:
public List<Stationary> read(File file) {
List<Stationary> list= new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
// TODO parse line into id, name, mark
list.add(new Stationary(id, name, mark);
}
}
return list;
}
now the list can be used as needed, e.g. average:
List<Stationary> stationaries = read(STATIONARY_FILE);
...
for (Stationary stationary : stationaries) {
sum += stationary.getMark();
count += 1;
}
...
streams not used to keep it simple

Duplicate local variable error with Scanner object and while loop

When passing in a Scanner object in java and using a while loop to access each line, an error says I have a duplicate local variable ("fileContents" in the very first line).
static Map<String, Integer> countCategories(Scanner fileContents) {
HashMap<String, Integer> categoryCount = new HashMap<String, Integer>();
while (fileContents.hasNext()) {
String line = fileContents.nextLine();
String[] lineItems = line.split(",");
String category = lineItems[2]; // specified position in CSV file
if (categoryCount.get(category) == null) {
categoryCount.put(category, 1);
} else {
categoryCount.put(category, categoryCount.get(category) + 1);
}
}
To further expound on this, I'm just organizing information from a file, and I'm new to Java. Am I even doing this HashMap right, or should I be formatting this method and/or the hash map created inside in an entirely different way?
As requested, the rest of my main:
public class PA2Main {
public static void main(String[] args) {
try {
String fileName = args[0];
Scanner fileContents = new Scanner(new File(fileName)); // temp var
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// recreate fileContents to use outside of try/catch
String fileName = args[0];
Scanner fileContents = new Scanner(new File(fileName));
HashMap<String, Integer> organizedCategories = countCategories(fileContents); // call function
if (args.length > 1) {
if (!"LOCATION".equals(args[1]) || !"CATCOUNT".equals(args[1])) {
System.out.println("Invalid Command");
} else {
//process commands
if (args[1].equals("CATCOUNT")) {
}
if (args[1].equals("LOCATION")) {
// organize info in fi
}
}
}
}
Formatting is a little weird, but I hope that makes sense. Obviously, I haven't done a lot with the rest of the program and this isn't very clean. The error message just states: Duplicate local variable fileContents
And a "quick fix" is renaming it.
You can't have two variables with the same name in a class most of the time, and especially if the scope of them is the same like it is here with both in the same method. Even if the type of the object was different, the compiler would have no way to differentiate and pick which one you want to use so it won't compile.
In the code you provided, we can see that you used declared 2 Scanner objects with the same name which will cause the error every single time you try this.
public static void main(String[] args) {
try {
String fileName = args[0];
*** Scanner fileContents = new Scanner(new File(fileName));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String fileName = args[0];
*** Scanner fileContents = new Scanner(new File(fileName));
HashMap<String, Integer> organizedCategories = countCategories(fileContents);
if (args.length > 1) {
if (!"LOCATION".equals(args[1]) || !"CATCOUNT".equals(args[1])) {
System.out.println("Invalid Command");
} else {
if (args[1].equals("CATCOUNT")) {
}
if (args[1].equals("LOCATION")) {
}
}
}
To fix this error generally, you could just rename one of the variables, but in your case, I don't think that having 2 Scanner objects is even necessary.
The try-catch clause should be used specifically for the lines of your code that have an actual possibility of throwing an exception, in this case initializing the scanner.
A cleaner way to write your code with this in mind would be
public static void main (String[] args) {
String fileName = args[0];
Scanner fileContents;
try {
fileContents = new Scanner(new File(fileName));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
HashMap<String, Integer> organizedCategories = countCategories(fileContents);
if (args.length > 1) {
if (!"LOCATION".equals(args[1]) || !"CATCOUNT".equals(args[1])) {
System.out.println("Invalid Command");
} else {
if (args[1].equals("CATCOUNT")) {
}
if (args[1].equals("LOCATION")) {
}
}
}
}

[ JAVA ]Reading one line with Scanner and store every entry in a String. Than read the scond line and do the same

I've a CSV FIle with 2 lines of data. The first line is the heading and the second line is data associated with the heading. ( First heading = data from first heading ..etc.) I want to store each entry in a ArrayList. i want to use ; and " as a sc.useDelimiter. This is my whole code:
public class CsvScanner {
private static Scanner sc;
ArrayList<String> names = new ArrayList<String>();
ArrayList<String> values = new ArrayList<String>();
String namesAdd;
String valuesAdd;
public void scanFile() {
try {
sc = new Scanner(Gui.selectedFile);
sc.useDelimiter("[;\n]");
while (sc.hasNextLine()) {
namesAdd = sc.nextLine();
names.add(namesAdd);
// System.out.println(names);
}
CreateLog.startLog();
} catch (Exception e) {
System.out.println("error");
}
try {
while (sc.hasNextLine()) {
valuesAdd = sc.nextLine();
values.add(valuesAdd);
// System.out.println(values);
}
} catch (Exception e) {
System.out.println("error v2");
}
EDIT: i got it Running, but i cant make it stop on the END of the first line..

Using try/catch for files in java

I'm having issues with using try-catch blocks in java. I'm writing a method that reads a user input file and prints it out to the console. This is what I have -
static Scanner input = new Scanner(System.in);
public static String readingFiles(String fileout) {
boolean find = false;
while(!find) {
try {
File f = new File(input.nextLine());
Scanner scan = new Scanner(f);
} catch (FileNotFoundException e) {
System.out.println("File Not Found.");
}
}
ArrayList<String> list = new ArrayList<String>();
while (input.hasNext())
{
list.add(input.nextLine());
}
String output = list.toString();
return output;
}
It just seems like a mess and I have no idea what to do with it at this point. I had it working a few times, in that it would output what the file said but then if I purposefully entered the wrong file name it would loop "file not found" endlessly and I couldn't figure out how to return the loop to the beginning so the user could input a different file name.
Now it just does nothing even when i enter the correct file name, it returns nothing until i press enter again and it'll return file not found.
I call it using this in my main menu method -
case 1:
System.out.println("You chose Read File. Enter your file name: ");
System.out.println(Question4.readingFiles(input.nextLine()));
pressEnter();
break;
edit: I now have this, which works but only prints the first line of my file?
public static String readingFiles(String fileout) {
boolean find = false;
String result = "";
while (!find) {
try {
File read = new File(fileout);
Scanner check = new Scanner(read);
result = check.nextLine();
find = true;
check.close();
} catch (FileNotFoundException e) {
System.out.println("File Not Found. Please try again.");
break;
}
}
return result;
}
Check the following code.
public static void readFiles() throws Exception {
int i = 1;
BufferedReader reader = null;
Scanner input = null;
boolean fileFound = true;
while(i <= 5){
System.out.print("Enter a file name::::");
input = new Scanner(System.in);
if(input.hasNextLine()){
try {
File f = new File(input.nextLine());
reader = new BufferedReader(new FileReader(f));
String str = null;
while((str = reader.readLine()) != null){
System.out.println(str);
}
} catch (FileNotFoundException e) {
System.out.println("File Not Found");
fileFound = false;
i++;
continue;
} catch (IOException e) {
System.out.println("IOException");
i++;
continue;
} catch (Exception e) {
System.out.println("Some Other Exception");
i++;
continue;
} finally{
if(fileFound)
reader.close();
}
}
i++;
}
}
Please note this method will read files 5 times. If you want to change it, you can pass an int parameter to the method and accordingly change the first while condition. Ensure you give complete path of the file with escape characters. For example, if file location is 'C:\abc.txt', you need to input 'C:\\abc.txt'. Else, it will display 'File Not Found' in console.
public class readingFiles {
public static String readingFiles(String fileout) {
try {
//find a file with the same name as the value of "fileout"
File f = new File(fileout);
Scanner scan = new Scanner(f);
//create a list to hold the file output
ArrayList<String> list = new ArrayList<String>();
//loop through the output line by line and add to the list
while (scan.hasNext())
{
list.add(scan.nextLine());
}
//convert the list into a String value to pass back to the caller
String output = list.toString();
scan.close();
return output;
} catch (FileNotFoundException e) {
//if file is not found, return a value of -1
System.out.println("File Not Found.");
return("-1");
}
}
Okay a few things:
Your first while loop is unnecessary. I think you are trying to loop through files in the folder to look for a specific file name. However the Scanner scan = new Scanner(f); line already does this.
The reason your code infinitely prints "File not found." is because you never set the find condition to true to exit the loop.
You never use the fileout value you pass into the method. And your code asks the user for the filename input twice (once in the main method, once in the readingFiles method).
Using a list, then converting to String results in an output of [line1, line2, line3, etc] not sure if this is what you want.
As for why your second attempt prints only the first line, You have removed the while loop which loops through the file reading every line, therefore it only reads one line before stopping.

Method to find string inside of the text file. Then getting the following lines up to a certain limit

So this is what I have so far :
public String[] findStudentInfo(String studentNumber) {
Student student = new Student();
Scanner scanner = new Scanner("Student.txt");
// Find the line that contains student Id
// If not found keep on going through the file
// If it finds it stop
// Call parseStudentInfoFromLine get the number of courses
// Create an array (lines) of size of the number of courses plus one
// assign the line that the student Id was found to the first index value of the array
//assign each next line to the following index of the array up to the amount of classes - 1
// return string array
}
I know how to find if a file contains the string I am trying to find but I don't know how to retrieve the whole line that its in.
This is my first time posting so If I have done anything wrong please let me know.
You can do something like this:
File file = new File("Student.txt");
try {
Scanner scanner = new Scanner(file);
//now read the file line by line...
int lineNum = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
lineNum++;
if(<some condition is met for the line>) {
System.out.println("ho hum, i found it on line " +lineNum);
}
}
} catch(FileNotFoundException e) {
//handle this
}
Using the Apache Commons IO API https://commons.apache.org/proper/commons-io/ I was able to establish this using FileUtils.readFileToString(file).contains(stringToFind)
The documentation for this function is at https://commons.apache.org/proper/commons-io/javadocs/api-2.4/org/apache/commons/io/FileUtils.html#readFileToString(java.io.File)
Here is a java 8 method to find a string in a text file:
for (String toFindUrl : urlsToTest) {
streamService(toFindUrl);
}
private void streamService(String item) {
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
stream.filter(lines -> lines.contains(item))
.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
When you are reading the file, have you considered reading it line by line? This would allow you to check if your line contains the file as your are reading, and you could then perform whatever logic you needed based on that?
Scanner scanner = new Scanner("Student.txt");
String currentLine;
while((currentLine = scanner.readLine()) != null)
{
if(currentLine.indexOf("Your String"))
{
//Perform logic
}
}
You could use a variable to hold the line number, or you could also have a boolean indicating if you have passed the line that contains your string:
Scanner scanner = new Scanner("Student.txt");
String currentLine;
int lineNumber = 0;
Boolean passedLine = false;
while((currentLine = scanner.readLine()) != null)
{
if(currentLine.indexOf("Your String"))
{
//Do task
passedLine = true;
}
if(passedLine)
{
//Do other task after passing the line.
}
lineNumber++;
}
This will find "Mark Sagal" in Student.txt. Assuming Student.txt contains
Student.txt
Amir Amiri
Mark Sagal
Juan Delacruz
Main.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
final String file = "Student.txt";
String line = null;
ArrayList<String> fileContents = new ArrayList<>();
try {
FileReader fReader = new FileReader(file);
BufferedReader fileBuff = new BufferedReader(fReader);
while ((line = fileBuff.readLine()) != null) {
fileContents.add(line);
}
fileBuff.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println(fileContents.contains("Mark Sagal"));
}
}
I am doing something similar but in C++. What you need to do is read the lines in one at a time and parse them (go over the words one by one). I have an outter loop that goes over all the lines and inside that is another loop that goes over all the words. Once the word you need is found, just exit the loop and return a counter or whatever you want.
This is my code. It basically parses out all the words and adds them to the "index". The line that word was in is then added to a vector and used to reference the line (contains the name of the file, the entire line and the line number) from the indexed words.
ifstream txtFile;
txtFile.open(path, ifstream::in);
char line[200];
//if path is valid AND is not already in the list then add it
if(txtFile.is_open() && (find(textFilePaths.begin(), textFilePaths.end(), path) == textFilePaths.end())) //the path is valid
{
//Add the path to the list of file paths
textFilePaths.push_back(path);
int lineNumber = 1;
while(!txtFile.eof())
{
txtFile.getline(line, 200);
Line * ln = new Line(line, path, lineNumber);
lineNumber++;
myList.push_back(ln);
vector<string> words = lineParser(ln);
for(unsigned int i = 0; i < words.size(); i++)
{
index->addWord(words[i], ln);
}
}
result = true;
}
Here is the code of TextScanner
public class TextScanner {
private static void readFile(String fileName) {
try {
File file = new File("/opt/pol/data22/ds_data118/0001/0025090290/2014/12/12/0029057983.ds");
Scanner scanner = new Scanner(file);
while (scanner.hasNext()) {
System.out.println(scanner.next());
}
scanner.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
if (args.length != 1) {
System.err.println("usage: java TextScanner1"
+ "file location");
System.exit(0);
}
readFile(args[0]);
}
}
It will print text with delimeters

Categories