Compiler thinks final instance variable not initialised - java

My compiler is warning me that that an instance variable, a 2d int[][] array, might not have been initialised when I go to assign it.
I understand why the compiler might think that, because it is initialised in a double if statement. However the first if is on a boolean that is initialised to true, and the second if throws an exception on the else. I am confident of the logic of the program but the compiler obviously is not.
Does anyone have any tips for overcoming this kind of problem? I don't want to otherwise initialise the variable because it is meant to be final.
The variable of concern is the board variable. The below is part of a constructor for the object which contains the variable.
try {
FileReader fr = new FileReader(filename);
BufferedReader br = new BufferedReader(fr);
boolean first = true;
int lineCount = 0;
String line;
while ((line = br.readLine()) != null) {
String lineParts[] = line.split(" ");
if (first) {
if (lineParts.length == 2) {
this.xSize = Integer.parseInt(lineParts[0]);
this.ySize = Integer.parseInt(lineParts[1]);
board = new int[this.ySize][this.xSize];
first = false;
} else { throw new RuntimeException(); }
} else {
lineCount++;
if (lineParts.length == this.xSize) {
for (int i = 0; i < this.xSize; i++) {
board[lineCount][i] = Integer.parseInt(lineParts[i]);
}
} else throw new RuntimeException();
}
}
br.close();
if (lineCount != this.ySize) throw new RuntimeException();
}

Indeed, the compiler can't unravel the loop logic enough to know the final variable is initialized before use.
You'll need to move handling of the first line out of the loop — which is reasonable anyway, since the content of the loop is almost completely different for the first line and subsequent lines:
try {
FileReader fr = new FileReader(filename);
BufferedReader br = new BufferedReader(fr);
int lineCount = 0;
String line;
line = br.readLine();
if (line != null) {
String lineParts[] = line.split(" ");
if (lineParts.length == 2) {
this.xSize = Integer.parseInt(lineParts[0]);
this.ySize = Integer.parseInt(lineParts[1]);
board = new int[this.ySize][this.xSize];
} else {
throw new RuntimeException();
}
while ((line = br.readLine()) != null) {
String lineParts[] = line.split(" ");
lineCount++;
if (lineParts.length == this.xSize) {
for (int i = 0; i < this.xSize; i++) {
board[lineCount][i] = Integer.parseInt(lineParts[i]);
}
} else {
throw new RuntimeException();
}
}
}
br.close();
if (lineCount != this.ySize) throw new RuntimeException();
}
Note: This code preserves the previous code's behavior that it doesn't count the first line. I'm guessing the fact it's special includes not counting it. :-)
Side note: I'd strongly recommend using try-with-resources in that code, not only for best practices, but because you're not closing the file when you throw your exceptions:
try (
FileReader fr = new FileReader(filename);
BufferedReader br = new BufferedReader(fr);
) {
int lineCount = 0;
String line;
line = br.readLine();
if (line != null) {
String lineParts[] = line.split(" ");
if (lineParts.length == 2) {
this.xSize = Integer.parseInt(lineParts[0]);
this.ySize = Integer.parseInt(lineParts[1]);
board = new int[this.ySize][this.xSize];
} else {
throw new RuntimeException();
}
while ((line = br.readLine()) != null) {
String lineParts[] = line.split(" ");
lineCount++;
if (lineParts.length == this.xSize) {
for (int i = 0; i < this.xSize; i++) {
board[lineCount][i] = Integer.parseInt(lineParts[i]);
}
} else {
throw new RuntimeException();
}
}
}
if (lineCount != this.ySize) throw new RuntimeException();
}

Related

Is my readers and writers in this method not closing properly?

When I delete a record first before inserting a new record, I can do it, and after deleting I can add new record. But if I insert a new record first then my delete function is not working. Based on my research, it's mainly because the input/output is not closed properly but I have already done that, please take a look at my source code thank you.
Insert record
public void RegCustomer()
{
try
{
File F = new File("Customer.txt");
FileWriter fw = new FileWriter(F, true);
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter pw = new PrintWriter(bw);
//PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(F, true)));
pw.println(this.Name+","+this.CheckInDate+","+this.CheckOutDate+","+this.Floor+","+this.RoomID+","+this.ICNumber+","+this.Contact+","+this.Email);
pw.flush();
pw.close();
fw.close();
bw.close();
}
catch(Exception e)
{
}
}
Delete Record
public boolean delcus(String Target)
{
boolean success = false;
File F = new File("Customer.txt");
File Ftc = new File("Temp.txt");
try
{
FileReader fr = new FileReader(F);
BufferedReader br = new BufferedReader(fr);
PrintWriter pr = new PrintWriter(Ftc);
String line = br.readLine();
while (line!=null)
{
String[] wordsinLine = line.split(",");
if (wordsinLine[0].equals(Target))
{
}
else
{
pr.println(line);
success = true;
}
line = br.readLine();
}
if (success)
{
pr.flush();
pr.close();
br.close();
fr.close();
}
}
catch (Exception e)
{
}
F.delete();
File dump = new File("Customer.txt");
Ftc.renameTo(dump);
return success;
}
I have another method that checks for several conditions before triggering the insert method.
public int checkroom()
{
int check = 0;
int ciDay = this.CheckInDate/10000;
int ciMonth = (this.CheckInDate/100)%100;
int coDay = this.CheckOutDate/10000;
int days = coDay - ciDay;
String name;
int Dbcid;
int Dbcod;
int DbFloor;
int DbRoomID;
try
{
File F = new File("Customer.txt");
FileReader Fr = new FileReader(F);
BufferedReader Reader = new BufferedReader(Fr);
Scanner Sc = new Scanner(Reader);
Sc.useDelimiter("[,\n]");
while(Sc.hasNext())
{
name = Sc.next();
Dbcid = Sc.nextInt();
Dbcod = Sc.nextInt();
DbFloor = Sc.nextInt();
DbRoomID = Sc.nextInt();
if (days <= 7)
{
if (DbFloor == this.Floor && DbRoomID == this.RoomID)
{
int DbcidDay = Dbcid/10000;
int DbcidMonth = (Dbcid/100)%100;
int DbcodDay = Dbcod/10000;
if(ciMonth == DbcidMonth)
{
if (ciDay >= DbcidDay && ciDay < DbcodDay)
{
check = 2;
}
else if (coDay >= DbcidDay && coDay < DbcodDay)
{
check = 3;
}
else if (ciDay <= DbcidDay && coDay >= DbcodDay)
{
check = 4;
}
else
{
check = 1;
}
}
else
{
check = 1;
}
}
else
{
check =1;
}
}
else
{
check =5;
}
}
if(check > 0)
{
Sc.close();
Reader.close();
Fr.close();
}
}
catch (Exception e)
{
}
return check;
}
There are a few issues I can see:
You need to close your streams in a finally clause (or, better still, use a try-with-resource). Otherwise, if an exception is thrown that interrupts the normal program flow, your stream will not be closed immediately.
You should only close the outermost stream object (so e.g. your BufferedReader, but not the FileReader)
You are swallowing exceptions. At least do a printStackTrace() on the exceptions you catch so you can see if any are actually thrown.
Avoid methods like File.delete() that don't throw exceptions in the case of an error. Instead, use the equivalent methods on the Files.class, which throw exceptions in the event of an error.
Incidentally, although it's not an issue as such, you don't need to call flush() just before close()-- the latter automatically flushes before closing.

BufferedReader causing Java GUI to hang

I am currently working on an add-on to a rhythm game called osu! using Java. There are multiple windows involved, but after the actionPerformed event listener is invoked for one of them, it creates another window that creates an object the constructor of which calls two methods that each use a BufferedReader. However, once I click the button for the actionPerformed, the program hangs and freezes until it is terminated from task manager. Here is the actionPerformed code for the GUI window:
private void btnCreateActionPerformed(ActionEvent evt) throws IOException {
String text = textBeats.getText();
if (text == null) {
JOptionPane.showMessageDialog(contentPane, "Please enter a positive number.");
}
boolean isNumber = true;
for (char c : text.toCharArray()) {
if (!Character.isDigit(c)) {
isNumber = false;
} else if (c == '-') {
isNumber = false;
}
}
if (isNumber) {
double beats = Double.parseDouble(text);
WindowCode window = new WindowCode(drawArea, file, beats);
window.setVisible(true);
this.dispose();
} else {
JOptionPane.showMessageDialog(contentPane, "Please enter a positive number.");
}
}
And here are the two methods called when creating WindowCode:
public double[] getLastTimingPoint() {
String line;
String timings[] = new String[8];
double pointElements[] = new double[8];
boolean isTiming = false;
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(osuFile), "UTF-8"))){
while ((line = reader.readLine()) != null) {
if (line.contains("[TimingPoints]")) {
isTiming = true;
} else if (line.contains("[Colours]") || line.contains("[HitObjects]")) {
isTiming = false;
}
if (isTiming) {
if (!line.contains("[TimingPoints]") && !line.contains("[Colours]") && !line.contains("[HitObjects]") && line.length() > 0) {
timings = line.split(",");
}
}
}
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int i = 0; i < timings.length; i++) {
pointElements[i] = Double.parseDouble(timings[i]);
}
System.out.println("1");
return pointElements;
}
public double[] getLastInheritedPoint() {
String line;
String timings[] = new String[8];
double pointElements[] = new double[8];
boolean isTiming = false;
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(osuFile), "UTF-8"))) {
while ((line = reader.readLine()) != null) {
if (line.contains("[TimingPoints]")) {
isTiming = true;
}
while (isTiming) {
if (!line.contains("[TimingPoints]") && !line.contains("[Colours]") && !line.contains("-")) {
timings = line.split(",");
}
}
}
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int i = 0; i < timings.length; i++) {
pointElements[i] = Double.parseDouble(timings[i]);
}
System.out.println("2");
return pointElements;
}
I have tried to print out checkpoint numbers and it only prints "1" to the console, leading me to believe that it is the second method that is causing this. My question is if the BufferedReader affects the EDT somehow and if it does, how I should get around it.
On the second method you have this inner loop:
while (isTiming) {
if (!line.contains("[TimingPoints]") && !line.contains("[Colours]") && !line.contains("-")) {
timings = line.split(",");
}
}
If the file being read contains this string "[TimingPoints]" then variable isTiming will be set to true, and no one else resets it back to false, being trapped into an infinite loop.
You should revise that loop logic.

Using BufferedReader to read a single line in Java

I have code successfully reading from a CSV. However when I try to use fileReader to read a solo line, it makes my code stop working.
Here is my code:
try {
String line = "";
fileReader = new BufferedReader(new FileReader(filename));
while ((line = fileReader.readLine()) != null) {
String[] tokens = line.split(DELIMITER);
for (String token : tokens) {
totalData.add(token);
if (!artists.contains(token)) {
artists.add(token);
}
}
for (int l = 0; l <= 999; l++) {
lineData = fileReader.readLine();
lineArray[l] = lineData;
}
}
} finally {
fileReader.close();
}
When I try to read arrayList sizes and print data I get from the arrayLists above this code below makes it stop working:
for (int l = 0; l <= 80; l++) {
lineData = fileReader.readLine();
lineArray[l] = lineData;
}
If I comment this for loop, everything is fine. I really need this for loop, how can I edit my code to resolve this issue? Also, what is happening?
for (int l = 0; l <= 80; l++) {
lineData = fileReader.readLine();
lineArray[l] = lineData;
}
This hard code can replace a single line of code:
lineArray[i++] = line;
I corrected your code and that's what happened:
String line = "";
int i = 0;
try (BufferedReader fileReader = new BufferedReader(new FileReader(""))) {
while ((line = fileReader.readLine()) != null) {
lineArray[i++] = line;
String[] tokens = line.split(DELIMITER);
for (String token : tokens) {
totalData.add(token);
if (!artists.contains(token)) {
artists.add(token);
}
}
}
}

Null Pointer Exception Occurs only while comparison and not printing out values

public static void main(String[] args) throws FileNotFoundException, IOException {
// TODO code application logic here
BufferedReader in1 = new BufferedReader(new FileReader("595231gov_nov_13_assessed.txt"));
BufferedReader in2 = new BufferedReader(new FileReader("627231farsidetect.txt"));
String Id = null;
int count = 0;
String count_line=null;
while((count_line = in1.readLine()) != null){
if(count_line.contains("ID: "))
count ++;
}
System.out.println(count);
File1 [] File_1 = new File1[count];
in1 = new BufferedReader(new FileReader("595231gov_nov_13_assessed.txt"));
int i = 0;
String line = null;
String relation = null;
while ((line = in1.readLine()) != null && i != count){
if(line.contains("ID:")){
File_1 [i] = new File1();
File_1[i].ID = line;
}
else if(line.contains("Relation:")){
File_1[i].Relation = line;
}
else if(line.contains("Result:")){
File_1[i].Result = line;
i ++;
}
else if(line.contains("TP") || line.contains("FP") || line.contains("TN") || line.contains("FN")){
File_1[i-1].Comment = line;
}
}
line = null;
relation = null;
i =0;
int count2 = 0;
count_line=null;
while((count_line = in2.readLine()) != null){
if(count_line.contains("ID: "))
count2 ++;
}
System.out.println(count2);
in2 = new BufferedReader(new FileReader("/home/627231farsidetect.txt"));
File2 [] File_2 = new File2[count2];
while ((line = in2.readLine()) != null && i != count2){
if(line.contains("ID:")){
File_2 [i] = new File2();
File_2[i].ID = line;
}
else if(line.contains("Relation:")){
File_2[i].Relation = line;
}
else if(line.contains("Result:")){
File_2[i].Result = line;
i ++;
}
}
in1.close();
in2.close();
for (i=0; i<File_1.length - 1; i++)
{
System.out.println(File_1[i].ID);
System.out.println(File_1[i].Relation);
System.out.println(File_1[i].Result);
if(File_1[i].Comment != null)
System.out.println(File_1[i].Comment);
}
for (i=0; i<File_2.length; i++)
{
System.out.println(File_2[i].ID);
System.out.println(File_2[i].Relation);
System.out.println(File_2[i].Result);
}
for (i = 0; i < File_1.length-1; i++){
for(int j=0;j< File_2.length; i++){
if(File_1[i].ID != null && File_2[j].ID != null && File_1[i].Relation != null && File_2[j].Relation !=null){
if(File_1[i].ID.equals(File_2[j].ID) && File_1[i].Relation.equals(File_2[j].Relation)){
if(!(File_1[i].Result.equals(File_2[j].Result))){
System.out.println(File_1[i].ID);
System.out.println(File_1[i].Relation);
System.out.println(File_1[i].Result);
if(File_1[i].Comment != null)
System.out.println(File_1[i].Comment);
}
}
}
}
}
}
public static class File1{
public String ID;
public String Relation;
public String Result;
public String Comment;
public File1() {
this.Result = null;
this.ID=null;
this.Relation = null;
this.Comment = null;
}
}
public static class File2{
public String ID;
public String Relation;
public String Result;
public File2() {
this.Result = null;
this.ID=null;
this.Relation = null;
}
}
-When I just printout the values, I do not face a null pointer exception,
-But when I try and do comparison I am faced with a null pointer exception and I can't figure out why.
-NetBeans just points to the comparison statement
if(File_1[i].ID.equals(File_2[j].ID) && File_1[i].Relation.equals(File_2[j].Relation))
Something else which is unusual is that, I have assigned values for File_1 until File_1[Length] but it prints out length - 1 values. Whereas I assigned values for File_2 the same way and it prints fine. Please help. I am processing Farsi text, so there might be the possibility of weird characters, but I am pretty sure there has to be something to do with the index values.
Don't know if it was intentional or not, but in your for loop you seem to be incrementing the wrong value (i instead of j)...
for (i = 0; i < File_1.length-1; i++)
{
for(int j=0;j< File_2.length; j++)
{
if(File_1[i].ID != null && File_2[j].ID != null && File_1[i].Relation != null && File_2[j].Relation !=null)
{
if(File_1[i].ID.equals(File_2[j].ID) && File_1[i].Relation.equals(File_2[j].Relation))
{
if(!(File_1[i].Result.equals(File_2[j].Result)))
{
System.out.println(File_1[i].ID);
System.out.println(File_1[i].Relation);
System.out.println(File_1[i].Result);
if(File_1[i].Comment != null)
System.out.println(File_1[i].Comment);
}
}
}
}
}

Comparing two files in java

I am trying to compare two .txt files (i.e their contents), but when I execute this code my application goes into an infinite loop. Why?
public int compareFile(String fILE_ONE2, String fILE_TWO2)throws Exception
{
File f1 = new File(fILE_ONE2); //OUTFILE
File f2 = new File(fILE_TWO2); //INPUT
FileReader fR1 = new FileReader(f1);
FileReader fR2 = new FileReader(f2);
BufferedReader reader1 = new BufferedReader(fR1);
BufferedReader reader2 = new BufferedReader(fR2);
String line1 = null;
String line2 = null;
int flag=1;
while ((flag==1) &&((line1 = reader1.readLine()) != null)&&((line2 = reader2.readLine()) != null))
{
if (!line1.equalsIgnoreCase(line2))
flag=0;
else
flag=1;
}
reader1.close();
reader2.close();
return flag;
}
I converted your code into a main program. There is no infinite loop in this code.
I am assuming you are comparing 2 text files of a small-ish size.
import java.io.*;
public class Diff {
public static void main(String[] args) throws FileNotFoundException, IOException {
File f1 = new File(args[0]);// OUTFILE
File f2 = new File(args[1]);// INPUT
FileReader fR1 = new FileReader(f1);
FileReader fR2 = new FileReader(f2);
BufferedReader reader1 = new BufferedReader(fR1);
BufferedReader reader2 = new BufferedReader(fR2);
String line1 = null;
String line2 = null;
int flag = 1;
while ((flag == 1) && ((line1 = reader1.readLine()) != null)
&& ((line2 = reader2.readLine()) != null)) {
if (!line1.equalsIgnoreCase(line2))
flag = 0;
}
reader1.close();
reader2.close();
System.out.println("Flag " + flag);
}
}
I ran it on 2 small different text files. This is the output.
javac Diff.java && java Diff a.txt b.txt
Flag 0
If you think you have an infinite loop, the issue might be elsewhere.
The code looks good, no infinite loops. You can remove irrespective check in the code and can update the code as below:
int flag=1;
while (((line1 = reader1.readLine()) != null)&&((line2 = reader2.readLine()) != null))
{
if (!line1.equalsIgnoreCase(line2))
{
flag=0;
break;
}
}
As the return type of the method is integer than it will return 0 if different and 1 if equal.
Assuming text file inputs, an alternative implementation to the while loop:
while (true) // Continue while there are equal lines
{
line1 = reader1.readLine();
line2 = reader2.readLine();
if (line1 == null) // End of file 1
{
return (line2 == null ? 1 : 0); // Equal only if file 2 also ended
}
else if (line2 == null)
{
return 0; // File 2 ended before file 1, so not equal
}
else if (!line1.equalsIgnoreCase(line2)) // Non-null and different lines
{
return 0;
}
// Non-null and equal lines, continue until the input is exhausted
}
The first else if is not necessary, but it is included for clarity purposes. Otherwise, the above code could be simplified to:
while (true) // Continue while there are equal lines
{
line1 = reader1.readLine();
line2 = reader2.readLine();
if (line1 == null) // End of file 1
{
return (line2 == null ? 1 : 0); // Equal only if file 2 also ended
}
if (!line1.equalsIgnoreCase(line2)) // Different lines, or end of file 2
{
return 0;
}
}
The loop should be placed in a try/finally block, to assure that the readers are closed.
Above method by Jess will fail if file2 is same as file1 but has an extra line at the end.
This should work.
public boolean compareTwoFiles(String file1Path, String file2Path)
throws IOException {
File file1 = new File(file1Path);
File file2 = new File(file2Path);
BufferedReader br1 = new BufferedReader(new FileReader(file1));
BufferedReader br2 = new BufferedReader(new FileReader(file2));
String thisLine = null;
String thatLine = null;
List<String> list1 = new ArrayList<String>();
List<String> list2 = new ArrayList<String>();
while ((thisLine = br1.readLine()) != null) {
list1.add(thisLine);
}
while ((thatLine = br2.readLine()) != null) {
list2.add(thatLine);
}
br1.close();
br2.close();
return list1.equals(list2);
}
if you use java8, the code below to compare file contents
public boolean compareTwoFiles(String file1Path, String file2Path){
Path p1 = Paths.get(file1Path);
Path p1 = Paths.get(file1Path);
try{
List<String> listF1 = Files.readAllLines(p1);
List<String> listF2 = Files.readAllLines(p2);
return listF1.containsAll(listF2);
}catch(IOException ie) {
ie.getMessage();
}
}

Categories

Resources