I need to be able to compare entries of a file - Java - java

`import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Dokimi {
private static String line;
public static void main (String[] args) throws IOException
{
int x = 0;
BufferedReader br = new BufferedReader(new FileReader("src/film.txt"));
line = br.readLine();
String[] filmline = new String [1000];
while (line != null) {
line = br.readLine();
filmline[x] = line;
x++;
}
br.close();
for (int i = 0; i<x; i++) // after many tries the last change I made is this. This is the testing class.
{
String [] arr = filmline[i].split(": ");
if ( i == x-1) // I know it isn't the best, maybe not even good but I tried many things and had nothing to lose.
{
for ( String ss : arr) {
String test = ss;
if (test.equals("Dancing With The Dogs "))
{
System.out.println("gotcha!");
}
}
}
}
}
}`So, I have a text file with the attributes of some movies. For example :
"film id : 1 film title : Pirates Of Hawai film category : action , comedy film description : A pirate from Hawai drinks rum and goes on an adventure to find more rum."
(every entry in one line) and each time a user is trying to add a new entry I have to make sure the film isn't already on the file. I tried the slpit method (by using ":" and erasing "film id" etc) and StringTokenizer but it only worked on ONE and specified by me line, and not in a loop so that it could read the whole file.

As per here
Change your line a bit to add a ":":
"film id : 1 : film title : Pirates Of Hawai : film category : action , comedy : film description : A pirate from Hawai drinks rum and goes on an adventure to find more rum."
You can try this approach and compare with yours: (use existsfilm to verify if it already exists before add)
public void showAllFilms(){
ArrayList<String[]> films = getFilms();
for(String[] film : films){
System.out.println("id "+film[0]+"\ntitle "+film[1]);
}
}
public existsFilm(String filmName){
ArrayList<String[]> films = getFilms();
for(String[] film : films){
if(film[1].equals(filmName)){
return true;
}
}
return false;
}
public ArrayList<String[]> getFilms(){
ArrayList<String[]> filmList = new ArrayList();
int lineRead = 0;
try{
File file = new File("yourfile.txt");
BufferedReader br = new BufferedReader(new FileReader(file)));
String line;
while ((line = br.readLine()) != null) {
String[] data = line.split(":");
if(data.length > 0){
filmList.add(new String[]{data[1],data[3],data[5],data[7]});
}
lineRead++;
}
}catch(Exception ex){
System.out.println("Error reading line "+lineRead);
ex.printStackTrace(); //very ugly using this (common is logging it)
}
return filmList;
}

Don't use StringTokenizer, it's legacy, and should be supported for maintenance reasons, but not be implemented in new code.
Considering the tokens differ each time, you may want to run over the String and using substring here and there, that is, assuming each line contains the same tokens.
Or, change your input in:
"1*Pirates Of Hawaiaction , comedyA pirate from Hawai drinks rum and
goes on an adventure to find more rum."
This way, all tokens are identical, and you will be able to use the split method.

Related

Search String only prints out searches without characters attached

I’m new to java and I am working on a project. I am trying to search a text file for a few 4 character acronyms. It will only show or output when it’s just the 4 characters and nothing else. If there is a space or another character attached to it won’t display it… I have tried to make it show the whole line, but have yet to be successful.
The contents of text file:
APLM
APLM12345
ABC0
ABC0123456
CSQV
CSQVABCDE
ZIAU
ZIAUABCDE
The output in console:
APLM
ABC0
CSQV
ZIAU
My Code:
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
public class searchPdfText
{
public static void main(String args[]) throws Exception
{
int tokencount;
FileReader fr = new FileReader("TextSearchTest.txt");
BufferedReader br = new BufferedReader(fr);
String s = "";
int linecount = 0;
ArrayList<String> keywordList = new ArrayList<String>(Arrays.asList("APLM", "ABC0", "CSQV", "ZIAU" ));
String line;
while ((s = br.readLine()) != null)
{
String[] lineWordList = s.split(" ");
for (String word : lineWordList)
{
if (keywordList.contains(word))
{
System.out.println(s);
break;
}
}
}
}
}
If you take a look at the documentation for ArrayList.contains you will see that it only returns true if your keyword contains the provided string from your file. As such, your code is correct when it only outputs the exact matches found for those provided strings in keywordList.
Instead, if you want to get matches when a part of the provided string contains a keyword, consider iterating through the input and matching it the other way around:
while ((s = br.readLine()) != null) {
String[] lineWordList = s.split(" ");
for (String word : lineWordList) {
// JAVA 8
keywordList.stream().filter(e -> word.contains(e)).findFirst()
.ifPresent(e -> System.out.println(word));
// JAVA <8
for (String keyword : keywordList) {
if (word.contains(keyword)) {
System.out.println(s);
break;
}
}
}
}
Additionally, you may consider following Oracle's Java Naming Conventions with regards to your class name. Each word in your class name should be capitalized. For example, you class might be better named SearchPdfText.
You just need to change your while code for the output you want:
while ((s = br.readLine()) != null) {
if (s.length() == 4){
System.out.println(s);
}
}
If you want only that 4 specific values just create a method to check it like:
public static boolean hasIt(String text){
String [] list = { "APLM", "ABC0", "CSQV", "ZIAU" };
for ( String s : list ){
if (s.equals(text)){
return true;
}
}
return false;
}
And your while to:
while ((s = br.readLine()) != null) {
if (hasIt(s)){
System.out.println(s);
}
}

best way to search and print the specific block of strings from file?

what is the best way to print the specific lines of strings from file?
for example:
file.txt
Id : 123
car : toyota
model : 1998
Id : 129
car : merecdes
model :2007
at console:
Enter ID to search specific car and model:
123
ID : 123
car: Toyota
model : 1998
code:
/* skipped the "write file" portion of the code */
trying to implement: "Read the id and print car and name" according to the example
File mfile = new File("Employee.txt");
Scanner scan = new Scanner(mfile);
int firstline=0; //
String thisLine = null;
LineNumberReader m = new LineNumberReader(new FileReader(mfile));
// LineNumberReader lnr = new LineNumberReader(new FileReader(new File("Employee")));
BufferedReader br = new BufferedReader(m);
while(scan.hasNextLine()){
/* myEmployee.getID();
myEmployee.getName();
myEmployee.getAge();
*/
String line = scan.nextLine();// check next line
String s = null;
firstline++;
if(firstline==1)
{
System.out.println(line);
String line2 = scan.nextLine();
firstline++;
if(s== "Name"){
System.out.println(line2);
}
}
}
scan.close();
Pseudo code: //the code is self-explanatory.
while(EOF) {
String data = readLine();
if(data.contains(inputId)) {
//here record gets started
System.out.println(data);
String recordData;
while((recordData = readLine()) != '\n'){
System.out.println(recordData)
}
break;
}
}
You have to retrieve the line first. Then by using split() method you ca get what you want.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Read {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("someFile"));
try {
String line = br.readLine();
while (line != null) {
if(line.contains("String 1")) {
// ...
} else if (line.contains("String 2")) {
// ...
}
line = br.readLine();
String[] columns = line.split(" ");
System.out.println("ID: "+ columns[0] );
System.out.println("Car : "+ columns[1] );
System.out.println("Model : "+ columns[2] );
}
} finally {
br.close();
}
}
}
First of all, may I know if the file format could be change? All things would become simple if the records are stored like:
Id,car,model
123,toyota,1988
129,merecdes,2007
if not, then ignore this point...
I think you could use a HashMap to store the car info by reading every 4 lines, then you can get a single car by HashMap.get(Id).

How to find certain words in a text file, then find numbers in Java?

I have the following text file (answers.txt):
Problem A: 23|47|32|20
Problem B: 40|50|30|45
Problem C: 5|8|11|14
Problem D: 20|23|25|30
What I need is something that will read the problem that I tell it(Problem A, Problem B), then read the numbers after it, which are separated by the lines, and print it out like this:
Answers for Problem A: a.23 b.47 c.32 d.20
Does anyone know how this can be done? I've been stuck on it for a while.
Read the lines one by one, split the lines at " " first. The you will get an array with three parts "Problem", "A:" and "23|47|32|20". Then split the third part at "|" so you will get a second array with four parts "23,"47","32","20".
Combine all to get the output you want.
If you want info on how to read lines from a file, or spilt strings then there are billions of tutorials online on how to do that so I wont go into detail on how its done. IM sure you can find them.
Check out this code!
It assumes that you have such file format:
Problem A:
23|7|32|20
Problem B:
40|50|30|45
Problem C:
5|8|11|14
Problem D:
20|23|25|30
because you wrote "numbers after it, which are separated by the lines"
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
public class Demo {
public static void main(String[] args) throws FileNotFoundException {
Scanner sc = new Scanner(new File("answers.txt"));
List<String> dataList = new ArrayList<String>();
while(sc.hasNextLine()){
dataList.add(sc.nextLine());
}
System.out.println(dataList);
Map<String,String> map = new HashMap<String,String>();
for(int i=0;i<dataList.size();i=i+2){
map.put(dataList.get(i),dataList.get(i+1));
}
for(Entry<String,String> en:map.entrySet()){
System.out.println(en.getKey()+" : "+en.getValue());
}
String problemC = map.get("Problem C:");
String splitted[] = problemC.split("\\|");
System.out.println("Get me problem C: "+String.format("a:%s, b:%s, c:%s, d:%s",splitted[0],splitted[1],splitted[2],splitted[3]));
}
}
Hope this helps!
public static void main(String args[])
{
BufferedReader br = new BufferedReader(new FileReader(new File("answers.txt")));
String lineRead = null;
String problem = "Problem A";//Get this from user Input
List<String> numberData = new ArrayList<String>();
while((lineRead = br.readLine())!=null)
{
if(lineRead.contains(problem))
{
StringTokenizer st = new StringTokenizer(lineRead,":");
String problemPart = st.nextToken();
String numbersPart = st.nextToken();
st = new StringTokenizer(lineRead,"|");
while(st.hasMoreTokens())
{
String number = st.nextToken();
System.out.println("Number is: " + number);
numberData.add(number);
}
break;
}
}
System.out.println("Answers for " + problem + " : " + numberData );
}
Read the lines one by one, split the lines with :. The you will get an array with two parts "Problem A:" and "23|47|32|20". Then split the second part at "|" so you will get a second array with four parts "23,"47","32","20".
Combining all this you will get the output you want.
Cheers!
Use java.util.Scanner and you can filter the integers in the file.
Scanner s = new Scanner (new File ("answers.txt")).useDelimiter("\\s+");
while (s.hasNext()) {
if (s.hasNextInt()) { // check if next token is integer
System.out.print(s.nextInt());
} else {
s.next(); // else read the next token
}
}
Do you know how to read line by line ? If not , chect it How to read a large text file line by line in java?
To sub your string data there have many ways to do. You can sub as you wish. Here for my code..
String data = yourReader.readLine();
String problem = data.substring("Problem".length(), data.indexOf(":"));
System.err.println("Problem is " + problem);
data = data.substring(data.indexOf(":") + 2, data.length());
String[] temp = data.split("\\|");
for (String result : temp) {
System.out.println(result);
}
Assuming there are always four possible answers as in your Example:
// read complete file in fileAsString
String regex = "^(Problem \\w+): (\\d+)\\|(\\d+)\\|(\\d+)\\|(\\d+)$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(fileAsString);
//and so on, read all the Problems using matcher.find() and matcher.group(int) to get the parts
// put in a Map maybe?
// output the one you want...
I might suggest creating a simple data type for the purpose of organization:
public class ProblemAnswer {
private final String problem;
private final String[] answers;
public ProblemAnswer(String problem, String[] answers) {
this.problem = problem;
this.answers = new String[answers.length];
for (int i = 0; i < answers.length; i++) {
this.answers[i] = answers[i];
}
}
public String getProblem() {
return this.problem;
}
public String[] getAnswers() {
return this.answers;
}
public String getA() {
return this.answers[0];
}
public String getB() {
return this.answers[1];
}
public String getC() {
return this.answers[2];
}
public String getD() {
return this.answers[3];
}
}
Then the reading from the text file would look something like this:
public void read() {
Scanner s = new Scanner("answers.txt");
ArrayList<String> lines = new ArrayList<String>();
while (s.hasNext()) {
lines.add(s.nextLine());//first separate by line
}
ProblemAnswer[] answerKey = new ProblemAnswer[lines.size()];
for (int i = 0; i < lines.size(); i++) {
String[] divide = lines.get(i).split(": "); //0 is the problem name, 1 is the list
//of answers
String[] answers = divide[1].split("|"); //an array of the answers to a given
//question
answerKey[i] = new ProblemAnswer(divide[0], answers); //add a new ProblemAnswer
//object to the key
}
}
Now that leaves you with an answer key with ProblemAnswer objects which is easily checked
with a simple .equals() comparison on the getProblem() method, and whatever index is matched, you have all the answers neatly arranged right within that same object.

Reading from file and splitting the data in Java

I'm trying to read data from a .txt file. The format looks like this:
ABC, John, 123
DEF, Mark, 456
GHI, Mary, 789
I am trying to get rid of the commas and put the data into an array or structure (structure most likely).
This is the code I used to to extract each item:
package prerequisiteChecker;
import java.util.*;
import java.io.*;
public class TestUnit {
public static void main(String[]args){
try {
FileInputStream fstream = new FileInputStream("courses.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
while ((strLine = br.readLine()) != null) {
String[] splitOut = strLine.split(", ");
for (String token : splitOut)
System.out.println(token);
}
in.close();
} catch (Exception e){
System.err.println("Error: " + e.getMessage());
}
}
}
At one point I had a print line in the "while" loop to see if the items would be split. They were. Now I'm just at a loss on what to do next. I'm trying to place each grouping into one structure. For example: ID - ABC. First Name - John. Room - 123.
I have a few books on Java at home and tried looking around the web. There is so much out there, and none of it seemed to lead me in the right direction.
Thanks.
Michael
create a class that looks something like this:
class structure {
public String data1;
public String data2;
public String data3;
}
This will form your basic data structure that you can use to hold the kind of data you have mentioned in your question. Now, you might want to follow proper object oriented methods like declaring all your fields as private, and writting getters and setters. you can find more on there here ... http://java.dzone.com/articles/getter-setter-use-or-not-use-0
Now, just outside your while loop, create an ArrayList like this: ArrayList<structure> list = new ArrayList<structure>(); This will be used to hold all the different rows of data that you will parse.
Now, in your while loop do something like this:
structure item = new structure();//create a new instance for each row in the text file.
item.data1 = splitOut[0];
item.data2 = splitOut[1];
item.data3 = splitOut[2];
list.add(item);
this will basically take the data that you parse in each row, put in the data structure that you declared by creating a new instance of it for each new row that is parsed. this finally followed by inserting that data item in the ArrayList using the list.add(item) in the code as shown above.
I would create a nice structure to store your information. I'm not sure if how you want to access the data, but here's a nice example. I'll go off of what you previously put. Please note that I only made the variables public because they're final. They cannot change once you make the Course. If you want the course mutable, create getters and setters and change the instance variables to private. After, you can use the list to retrieve any course you'd like.
package prerequisiteChecker;
import java.util.*;
import java.io.*;
public class TestUnit {
public static void main(String[] args) {
try {
FileInputStream fstream = new FileInputStream("courses.txt");
// use DataInputStream to read binary NOT text
// DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
List<Course> courses = new LinkedList<Course>();
while ((strLine = br.readLine()) != null) {
String[] splitOut = strLine.split(", ");
if (splitOut.length == 3) {
courses.add(new Course(splitOut[0], splitOut[1],
splitOut[2]));
} else {
System.out.println("Invalid class: " + strLine);
}
}
in.close();
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
}
public static class Course {
public final String _id;
public final String _name;
public final String _room;
public Course(String id, String name, String room) {
_id = id;
_name = name;
_room = room;
}
}
}
public class File_ReaderWriter {
private static class Structure{
public String data;
}
public static void main(String[] args) throws IOException{
String allDataString;
FileInputStream fileReader = new FileInputStream ("read_data_file.txt");
DataInputStream in = new DataInputStream(fileReader);
BufferedReader bufferReader = new BufferedReader(new InputStreamReader(in));
String[] arrayString = {"ID - ", " NAME - ", " ROOM - "};
int recordNumber = 0;
Structure[] structure = new Structure[10];
for (int i = 0; i < 10; i++)
structure[i] = new Structure();
while((allDataString = bufferReader.readLine()) != null){
String[] splitOut = allDataString.split(", ");
structure[recordNumber].data = "";
for (int i = 0; i < arrayString.length; i++){
structure[recordNumber].data += arrayString[i] + splitOut[i];
}
recordNumber++;
}
bufferReader.close();
for (int i = 0; i < recordNumber; i++){
System.out.println(structure[i].data);
}
}
}
I modify your given code. It works. Try it and if any query then ask.

Java : Resizing a multidimensional array

I have a multidimensional array built from Strings that is initially created with the size [50][50], this is too big and now the array is full of null values, I am currently trying to remove these said null values, I have managed to resize the array to [requiredSize][50] but cannot shrink it any further, could anyone help me with this? I have scoured the internet for such an answer but cannot find it.
Here is my complete code too (I realise there may be some very unclean parts in my code, I am yet to clean anything up)
import java.io.*;
import java.util.*;
public class FooBar
{
public static String[][] loadCSV()
{
FileInputStream inStream;
InputStreamReader inFile;
BufferedReader br;
String line;
int lineNum, tokNum, ii, jj;
String [][] CSV, TempArray, TempArray2;
lineNum = tokNum = ii = jj = 0;
TempArray = new String[50][50];
try
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Please enter the file path of the CSV");
String fileName = in.readLine();
inStream = new FileInputStream(fileName);
inFile = new InputStreamReader(inStream);
br = new BufferedReader(inFile);
StringTokenizer tok,tok2;
lineNum = 0;
line = br.readLine();
tokNum = 0;
tok = new StringTokenizer(line, ",");
while( tok.hasMoreTokens())
{
TempArray[tokNum][0] = tok.nextToken();
tokNum++;
}
tokNum = 0;
lineNum++;
while( line != null)
{
line = br.readLine();
if (line != null)
{
tokNum = 0;
tok2 = new StringTokenizer(line, ",");
while(tok2.hasMoreTokens())
{
TempArray[tokNum][lineNum] = tok2.nextToken();
tokNum++;
}
}
lineNum++;
}
}
catch(IOException e)
{
System.out.println("Error file may not be accessible, check the path and try again");
}
CSV = new String[tokNum][50];
for (ii=0; ii<tokNum-1 ;ii++)
{
System.arraycopy(TempArray[ii],0,CSV[ii],0,TempArray[ii].length);
}
return CSV;
}
public static void main (String args[])
{
String [][] CSV;
CSV = loadCSV();
System.out.println(Arrays.deepToString(CSV));
}
}
The CSV file looks as follows
Height,Weight,Age,TER,Salary
163.9,46.8,37,72.6,53010.68
191.3,91.4,32,92.2,66068.51
166.5,51.1,27,77.6,42724.34
156.3,55.7,21,81.1,50531.91
It can take any size obviously but this is just a sample file.
I just need to resize the array so that it will not contain any null values.
I also understand a list would be a better option here but it is not possible due to outside constraints. It can only be an multi dimensional array.
I think you need 3 changes to your program
After your while loop lineNum will be 1 more than the number of lines in the file so instead of declaring CSV to String[tokNum][50] declare it as CSV = new String[tokNum][lineNum-1];
tokNum will be the number of fields in a row so your for loop condition should be ii<tokNum rather than ii<tokNum-1
The last parameter for your arraycopy should be lineNum-1
i.e. the modified code to build your CSV array is:
CSV = new String[tokNum][lineNum-1];
for (ii=0; ii<tokNum ;ii++)
{
System.arraycopy(TempArray[ii],0,CSV[ii],0,lineNum-1);
}
and the output will then be:
[[Height, 163.9, 191.3, 166.5, 156.3], [Weight, 46.8, 91.4, 51.1, 55.7],
[Age, 37, 32, 27, 21], [TER, 72.6, 92.2, 77.6, 81.1],
[Salary, 53010.68, 66068.51, 42724.34, 50531.91]]
Notice that you don't really need to handle the first line of the file separately from the others but that is something you can cover as part of your cleanup.
10 to 1 this is a homework assignment. However, it looks like you've put somethought into it.
Don't make the TempArray variable. Make a "List of List of Strings". Something like:
List<List<String>> rows = new ArrayList<ArrayList<String>>();
while(file.hasMoreRows()) { //not valid syntax...but you get the jist
String rowIText = file.nextRow(); //not valid syntax...but you get the jist
List<String> rowI = new ArrayList<String>();
//parse rowIText to build rowI --> this is your homework
rows.add(rowI);
}
//now build String[][] using fully constructed rows variable
Here's an observation and a suggestion.
Observation: Working with (multidimensional) arrays is difficult in Java.
Suggestion: Don't use arrays to represent complex data types in Java.
Create classes for your data. Create a List of people:
class Person {
String height; //should eventually be changed to a double probably
String weight; // "
//...
public Person( String height, String weight /*, ... */ ) {
this.height = height;
this.weight = weight;
//...
}
}
List<Person> people = new ArrayList<Person>();
String line;
while ( (line = reader.nextLine()) != null ) {
String[] records = line.split(",");
people.add(new Person (records[0], records[1] /*, ... */));
}

Categories

Resources