How do I get my array out of try/catch block? - java

I've been kicking this code around for a while and I think I know what the general problem is, I can't figure out how to correct it. I'm getting the following error:
C:\Documents and Settings\Joe King\My Documents\418.85A Java\Project5>javac Project5.java
Project5.java:408: error: variable boatNames might not have been initialized
boatArray1 = new Boat[boatNames.length];
^
1 error
The problem is my boatNames array is in a try/catch block and I think this is isolating it from the rest of the code. How can I get the boatNames array out of the try/catch block?
My code is as follows:
class Project5{
public static void main(String[] args){
String[] boatNames;
Boat[] boatArray1;
Boat[] boatArray2;
String result = " ";
String name = null;
char firstChar;
char firstLetter;
char secondLetter;
int totalRead;
int i;
int j;
int k;
int l;
int m;
Path inPath = Paths.get("C:/Documents and Settings/Joe King/My Documents/418.85A Java/Projects/Input").resolve("Boat Names.txt");
if(!Files.exists(inPath)){
System.out.println(inPath + " does not exist. Terminating the program.");
System.exit(1);
}
try(BufferedReader fileIn = Files.newBufferedReader(inPath, Charset.forName("UTF-16"))){
totalRead = 0;
while(fileIn.readLine() != null){
name = fileIn.readLine();
++totalRead;
name = null;
}
boatNames = new String[totalRead];
for(i = 0 ; i < boatNames.length ; ++i){
name = fileIn.readLine();
boatNames[i] = name;
name = null;
}
}catch(IOException e){
System.err.println("Error writing file: " + inPath);
e.printStackTrace();
}
Path outPath = Paths.get("C:/Documents and Settings/Joe King/My Documents/418.85A Java/Projects/Output").resolve("Fleet Registry.txt");
try{
Files.createDirectories(outPath.getParent());
}catch(IOException e){
System.err.println("Error creating directory: " + outPath.getParent());
e.printStackTrace();
System.exit(1);
}
boatArray1 = new Boat[boatNames.length];
if(boatNames.length > 0){
try(BufferedWriter fileOut = Files.newBufferedWriter(outPath, Charset.forName("UTF-16"))){
for(j = 0 ; j < boatNames.length ; j++){
String delimiters = "[. ,]";
int limit = -1;
String[]tokens = boatNames[j].split(delimiters, limit);
for(k = 0 ; k < tokens.length ; ++k){
firstChar = tokens[k].charAt(0);
firstChar = Character.toUpperCase(firstChar);
char[] tokenArray = tokens[k].toCharArray();
String text = new String(tokenArray, 1, (tokenArray.length - 1) );
tokens[k] = firstChar + text;
result = result + tokens[k] + " ";
if(k != tokens.length - 1){
continue;
}else{
result = result.trim();
boatNames[k] = result;
result = " ";
}
}
firstLetter = boatNames[j].charAt(0);
if((firstLetter == 'B') || (firstLetter == 'C') || (firstLetter == 'N')){
boatArray1[j] = new RaceBoat();
}else{
boatArray1[j] = new SailBoat();
}
boatArray1[j].christenBoat(boatNames[j]);
}
System.out.println("\n");
for(l = 0 ; l < boatNames.length ; ++l){
secondLetter = Character.toUpperCase(boatNames[l].charAt(1));
if((secondLetter == 'A') || (secondLetter == 'E')){
if(l > 0){
fileOut.newLine();
}
fileOut.write(boatArray1[l].goFast());
}else{
if(l > 0){
fileOut.newLine();
}
fileOut.write(boatArray1[l].goSlow());
}
fileOut.newLine();
fileOut.write(boatArray1[l].launchBoat());
fileOut.newLine();
fileOut.write(boatArray1[l].whatIsBoatState());
fileOut.newLine();
}
boatArray2 = new Boat[3];
boatArray2[0] = new SailBoat();
boatArray2[1] = new RaceBoat("Endurance", true);
boatArray2[2] = new RaceBoat(false);
for(m = 0 ; m < boatArray2.length ; ++m){
fileOut.newLine();
fileOut.write(boatArray2[m].toString());
fileOut.newLine();
fileOut.write(boatArray2[m].launchBoat());
fileOut.newLine();
fileOut.write(boatArray2[m].whatIsBoatState());
fileOut.newLine();
}
fileOut.newLine();
fileOut.write("There are " + Boat.boatCount + " boats in the fleet this morning.");
}catch(IOException e){
System.err.println("Error writing outPath: " + outPath);
e.printStackTrace();
}
}else{
System.out.println("\n\n\nArgh!... you forgot to enter ship names scalawag!" +
"\n\n\n\tPlease try again!");
}
System.out.println("\nThe Fleet Registry is completed, press ENTER to continue.\n");
try{
System.in.read();
} catch(IOException e){
return;
}
}
}
Thank you everyone, I've entered the following:
if(boatNames != null){
boatArray1 = new Boat[boatNames.length];
if(boatNames.length > 0){
try(BufferedWriter fileOut = Files.newBufferedWriter(outPath, Charset.forName("UTF-16"))){
for(j = 0 ; j < boatNames.length ; j++){
String delimiters = "[. ,]";
int limit = -1;
String[]tokens = boatNames[j].split(delimiters, limit);
for(k = 0 ; k < tokens.length ; ++k){
firstChar = tokens[k].charAt(0);
firstChar = Character.toUpperCase(firstChar);
char[] tokenArray = tokens[k].toCharArray();
String text = new String(tokenArray, 1, (tokenArray.length - 1) );
tokens[k] = firstChar + text;
result = result + tokens[k] + " ";
if(k != tokens.length - 1){
continue;
}else{
result = result.trim();
boatNames[k] = result;
result = " ";
}
}
firstLetter = boatNames[j].charAt(0);
if((firstLetter == 'B') || (firstLetter == 'C') || (firstLetter == 'N')){
boatArray1[j] = new RaceBoat();
}else{
boatArray1[j] = new SailBoat();
}
boatArray1[j].christenBoat(boatNames[j]);
}
System.out.println("\n");
for(l = 0 ; l < boatNames.length ; ++l){
secondLetter = Character.toUpperCase(boatNames[l].charAt(1));
if((secondLetter == 'A') || (secondLetter == 'E')){
if(l > 0){
fileOut.newLine();
}
fileOut.write(boatArray1[l].goFast());
}else{
if(l > 0){
fileOut.newLine();
}
fileOut.write(boatArray1[l].goSlow());
}
fileOut.newLine();
fileOut.write(boatArray1[l].launchBoat());
fileOut.newLine();
fileOut.write(boatArray1[l].whatIsBoatState());
fileOut.newLine();
}
boatArray2 = new Boat[3];
boatArray2[0] = new SailBoat();
boatArray2[1] = new RaceBoat("Endurance", true);
boatArray2[2] = new RaceBoat(false);
for(m = 0 ; m < boatArray2.length ; ++m){
fileOut.newLine();
fileOut.write(boatArray2[m].toString());
fileOut.newLine();
fileOut.write(boatArray2[m].launchBoat());
fileOut.newLine();
fileOut.write(boatArray2[m].whatIsBoatState());
fileOut.newLine();
}
fileOut.newLine();
fileOut.write("There are " + Boat.boatCount + " boats in the fleet this morning.");
}catch(IOException e){
System.err.println("Error writing outPath: " + outPath);
e.printStackTrace();
}
}else{
System.out.println("\n\n\nArgh!... you forgot to enter ship names scalawag!" +
"\n\n\n\tPlease try again!");
}
System.out.println("\nThe Fleet Registry is completed, press ENTER to continue.\n");
try{
System.in.read();
} catch(IOException e){
return;
}
}
Now I'm getting the following error:
C:\Documents and Settings\Joe King\My Documents\418.85A Java\Project5>java Project5
Exception in thread "main" java.lang.NullPointerException
at Project5.main(Project5.java:424)
This doesn't make sense to me, in order to get to line 424 the boatNames array cannot be null because the length of boatNames was used several times before line 424. What am I missing?
Thanks

The variable is out of the try/catch, otherwise the compile error would be different. The problem is that the initialization is inside the try block, so that code after the try can't be sure the variable was initialized.
There are two ways to deal with this:
Initialize the variable when you declare it. Just using this would be enough:
String[] boatNames = null;
Move all the code that uses the variable inside the try block. This is often a good strategy, but only if your methods are small. In your case, I wouldn't recommend this, as your method is much too long. Now, if you could break your code up into shorter methods, then limiting the scope of the variable to a single try block would make good sense.

Before the try/catch block, initialize the array like this:
String[] boatNames = null;

You have declared your array outside try block
String[] boatNames;
It will be initialized under first try block
boatNames = new String[totalRead];
Issue is here boatArray1 = new Boat[boatNames.length];
Reason, your compiler has no way to know if boatNames initialization will be successful as there might be an exception and initialization will fail.
As part of your declaration you can do this:
String[] boatNames = null; // This will fix your immediate problem
but doing this may lead you to NullPointerException since your File read can fail.
To solve this do a null check on your array before you use it.
if(boatNames == null){
// I am not going to go further or will take corrective measures here
}

The compiler here considers the possibility that an exception might be raised in the try block even before boatNames is initialized hence it gives the compiler error might not have been initialized. The might is important here!
The ideal solution here would be to tweak your code structure and put
boatArray1 = new Boat[boatNames.length];
in the same try block!

Related

Java, Spring Boot: Question about numberformatexception

this NumberFormatException is driving me insane. I cannot seem to find any reason for the exception.
For context i am running a maven built spring boot application as a jar when the error occurs. It is running without errors inside the ide.
The error message:
java.lang.NumberFormatException: For input string: "9150287"
The piece of code producing the error message:
String substring = st.substring(indexLastAddedString + 1, i).trim();
System.out.println("Substring to be parsed: " + substring);
number = Integer.parseInt(substring);
So far i tried every method of parsing the string to integer.
I also logged the string and tried different strings.
//Edit
Here is the minimal reproducible example:
File file = new File("somefile.txt");
BufferedReader br = new BufferedReader(new FileReader(file));
String st;#
int numberOfSemicolon = 0;
int indexLastAddedString = 0;
String description = "";
int adressNumber = -1;
int number = 0;
while ((st = br.readLine()) != null) {
for(int i = 0; i < st.length(); i++) {
if(st.charAt(i) == ';') {
numberOfSemicolon++;
}
//add the description of project
if(st.charAt(i) == ';' && numberOfSemicolon == 1) {
description = st.substring(indexLastAddedString,i).replace("\""," ");
indexLastAddedString = i;
}
//add the adresNumber of project
if(st.charAt(i) == ';' && numberOfSemicolon == 2) {
String identifier = st.substring(indexLastAddedString+1, i);
adressNumber = customers.get(identifier) == null ? -1 : customers.get(identifier).getId();
indexLastAddedString = i;
}
//add the belegnumber of project
if(st.charAt(i) == ';' && numberOfSemicolon == 3) {
String substring = st.substring(indexLastAddedString + 1, i).trim();
System.out.println("Substring to be parsed: " + substring);
try {
} catch (NumberFormatException er) {
er.printStackTrace();
}
number = Integer.parseInt(substring);
projects.add(new Project(number,description, adressNumber));
indexLastAddedString = i+1;
numberOfSemicolon = 0;
}
}
}
The text file contains data in the following format (as an example):
projectdescription;adressNumber;projectNumber;

How to write into csv sheet with below mentioned specific format

We need to get below format
Redemption Reference Code|Status|Delivery company|Shipper Tracking Number|Comments
2006995040|Shipped|USPS|ABCD12345|Order SHIPPED
2006995042|Cancelled|||INVALID Address
2006995048|Ordered|USPS|ABCD12345|Order SHIPPED
I am using below code
private void accumulateOrdersFromPlacement(){
int count = 0;
for (int i = 0; i < orderIds.size(); i++) {
if (count == 0) {
outPutLineData.add(orderIds.get(i));
outPutLineData.add("Cancelled");
outPutLineData.add("");
outPutLineData.add(" ");
outPutLineData.add(" ");
cancelledStatusLineItems.add(orderIds.get(i));
count++;
} else if (count == 1) {
outPutLineData.add(orderIds.get(i));
outPutLineData.add("Shipped");
if (outPutLineData.contains("Shipped")) {
outPutLineData.add("USPS");
outPutLineData.add("order SHIPPED");
outPutLineData.add("");
}
shippedStatusLineItems.add(orderIds.get(i));
count++;
} else if (count == 2) {
outPutLineData.add(orderIds.get(i));
outPutLineData.add("No Longer Available");
outPutLineData.add("");
outPutLineData.add(" ");
outPutLineData.add(" ");
count++;
nlaStatusLineItems.add(orderIds.get(i));
} else if (count == 3) {
outPutLineData.add(orderIds.get(i));
outPutLineData.add("Ordered");
outPutLineData.add("");
outPutLineData.add(" ");
outPutLineData.add(" ");
orderedStatusLineItems.add(orderIds.get(i));
count = 0;
}
}
I am using below code for file creation. This is the detailed coding . This has more readability to understand code.Here i got confused about the code.We are taking order id count andbased on that this code is working.
private File createFile(final File directory) {
FileWriter fw = null;
File tempFile = null;
try {
directory.mkdir();
tempFile = new File(".//FidelityFulfillment//" + generateFileName(countyThreeLetterCode, "FidelityFulfillment", ".csv", date));
logReport(GenericConstants.NEW_LINE + "Fulfillment file creating:", tempFile.getName());
fw = new FileWriter(tempFile, true);
try (BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile, true))) {
writer.write(generateHeaderLine());
writer.newLine();
for (int y = 1; y < outPutLineData.size(); y++) {
if (y % 5 < 4) {
writer.write(outPutLineData.get(y-1) + fieldSeperator);
logReport(outPutLineData.get(y - 1) + fieldSeperator);
}
else {
writer.write(outPutLineData.get(y-1));
logReport(outPutLineData.get(y));
}
if (y % 5 == 0) {
writer.newLine();
logReport("newline");
}
}
writer.close();
} catch (final IOException e) {
e.printStackTrace();
final String err = "Unable to write file due to : " + e;
logReport(GenericConstants.NEW_LINE + "Unable to create temp local File");
} finally {
fw.close();
}
}catch (Exception e){
e.printStackTrace();
}
return tempFile;
}
Getting response as
Redemption Reference Code|Status|Delivery company|ShipperTrackingNumber|Comments
2006964032|Cancelled|| |
newline
2006964034|Shipped|USPS||
newline
2006964036|No Longer Available||
Last line one pipline is getting missing
First, you loop in a strange way :
for (int y = 1; y < outPutLineData.size(); y++) {
In general, we start at 0.
But you tried to correct that with the condition :
if (y % 5 < 4) {
//System.out.print("size:"+y);
writer.write(outPutLineData.get(y-1) + fieldSeperator);
logReport(outPutLineData.get(y - 1) + fieldSeperator);
}
else {
//System.out.print("size noseperator:"+y);
writer.write(outPutLineData.get(y-1));
logReport(outPutLineData.get(y));
}
Instead, simply use an iterator to read the values, then on read the correct amount of values :
Iterator<String> it = outPutLineData.iterator();
while(it.hasNext()){
for (int j = 0; j < columnCount; ++j) {
writer.write(it.next());
if( j < columnCount - 1)
writer.write(fieldSeperator);
}
writer.newLine();
}
Example with a StringBuilder to print in console :
int columnCount = 2;
String fieldSeperator = "|";
List<String> list = Arrays.asList("foo", "1", "bar", "2");
Iterator<String> it = list.iterator();
//Safe guard !
if(list.size() % columnCount != 0)
throw new RuntimeException("The list does have the correct amount of data");
while(it.hasNext()){
for (int j = 0; j < columnCount; ++j) {
sb.append( it.next() );
if( j < columnCount - 1)
sb.append(fieldSeperator );
}
System.out.println(sb.toString());
sb.setLength(0);
}
foo|1
bar|2
Use a POJO
You are using a List<String> to hold the values, you need to know how many column you need to read to get the value. Instead, use a POJO :
public class Redemption{
String redemptionReference;
String code;
String status;
String deliveryCompany;
String shipperTrackingNumber;
String comments;
}
And create the instance in your first loop :
List<Redemption> list...
That way, you just need to iterate each instance to build your row :
for(Redemption r: list){
writer.write(r.getRedemptionReference() + fieldSeperator);
...
writer.write(r.getComments());
writer.newLine();
}
Of course, you need to use getter and setter but this is just to show what you should do.
CSV API
Big warning, writing your own CSV writer is dangerous. If you have a comment like "This is a | character". You will end up with a line like :
2006995040|Shipped|USPS|This is a | character|Order SHIPPED
That one column to many... because you should have
2006995040|Shipped|USPS|"This is a | character"|Order SHIPPED
But you are not checking that case, and this is only one case. Using a CSV API is safer and simpler.
See Any good library to read and write csv files?

How to step reader.readLine() in two for cycles ?

I am reading data from a txt file. I want to create new objects from every ten lines and "." indicates that the current object doesn't have any more data lines (I work with two types of object("Nemfuggetlen" and "fuggetlen"), "fuggetlen" has 9 and "Nemfuggetlen" has 7 lines, "." separates their data lines).
The problem is: when I read two "Nemfuggetlen" objects in a row, it works fine, but if I read "fuggetlen" after "Nemfuggetlen" it makes "-------" to the next object first data lines, when it shouldn't. For "Nemfuggetlen" object it should fill the last 3 lines of "adatok" string array with "-------" and step to the next object.
int sorokszama = 0;
input.mark(300);
while((s = input.readLine()) !=null){
sorokszama++;
System.out.println("Sorok szama : " + sorokszama);
input.reset();
for(int h = 0; h < sorokszama/10; h++){
for(int i = 0;(s = input.readLine()) !=null; i++) {
if(i < 10){
if(!(".".equals(s))) {
adatok[i] = s;
System.out.println(adatok[i]);
}
else {
adatok[i] = "-------";
System.out.println(adatok[i]);
break;
}
}
}
if("Ferfi".equals(adatok[2])){
nem = true;
}
else {
nem = false;
}
if("Van".equals(adatok[4])){
tamogato = true;
}
else{
tamogato = false;
}
if("-------".equals(adatok[7])){ //A kepviselo nem fuggetlen
k = new Nemfuggetlen(adatok[0], Integer.parseInt(adatok[1]), nem, adatok[4], new Kerulet (Integer.parseInt(adatok[5])), adatok[6]);
}
if("-------".equals(adatok[9])){ // A kepviselo fuggetlen
k = new Fuggetlen(adatok[0], Integer.parseInt(adatok[1]), nem, adatok[4], new Kerulet (Integer.parseInt(adatok[5])),tamogato, adatok[7], Integer.parseInt(adatok[8]));
}
kepviselok.add(k);
//System.out.println(kepviselok.get(0));
}
System.out.println("Kepviselok szama : " + sorokszama/10);
for(int i = 0; i < kepviselok.size(); i++) {
System.out.println((i+1) + ". tag : " + kepviselok.get(i));
}
input.close();

How to implement find text mechanism in JTextPane?

I want to implement Find mechanism (like text editors or word) in my JTextPane.
I want it to have next / previous options (up/down arrows) and highlighting to all the words it found.
Is there a simple way to do so?
I am not an expert, I found the following code working:-
public static void GetTextToFindAndFind(String textToFind, int ignorecase, int findCounter){
// findCounter = 0 or 1. 0 represents find and 1 represents findCounter.
String Current2 = textPane.getText();
if(findCounter ==0){
if(textToFind == null){
optionPane.showMessageDialog(null, "Please Enter Text.", "Error", 0);
}
else if(textToFind.isEmpty()){
optionPane.showMessageDialog(null, "Please Enter Text.", "Error", 0);
}
else{
// Use any Character. But I a suggest to use a character from an Encrypted file.
Replacer = "¥";
CurrentText = textPane.getText();
if(ignorecase==1){
CurrentText = CurrentText.toLowerCase();
textToFind = TextToFind.toLowerCase();
}
int counter = 0;
readtext = new StringReader(CurrentText);
readBuffer = new BufferedReader(readtext);
try {
String Line = readBuffer.readLine();
int found = 0;
while(Line!=null || found != 1){
if(Line.contains(TextToFind)){
Line = null;
found = 1;
}
if(Line!=null){
Line = readBuffer.readLine();
counter = counter + 1;
}
}
if(found == 1){
textPane.setSelectionStart(CurrentText.indexOf(textToFind) - counter);
textPane.setSelectionEnd(CurrentText.indexOf(textToFind) + textToFind.length() - counter);
int counter2 = 1;
while(counter2!=textToFind.length()){
Replacer = Replacer + "¥";
counter2 = counter2 + 1;
}
CurrentText = CurrentText.replaceFirst(textToFind, Replacer);
findCounter = 1;
}
else{
optionPane.showMessageDialog(null, "No Matches.", "Message", 0);
}
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch(NullPointerException e){
optionPane.showMessageDialog(null, "No Matches.", "Message", 0);
}
}
}
else{
int counter = 0;
readtext = new StringReader(CurrentText);
readBuffer = new BufferedReader(readtext);
try {
String Line = readBuffer.readLine();
int found = 0;
while(Line!=null || found != 1){
if(Line.contains(textToFind)){
Line = null;
found = 1;
}
if(Line!=null){
Line = readBuffer.readLine();
counter = counter + 1;
}
}
if(found == 1){
textPane.setSelectionStart(CurrentText.indexOf(textToFind) - counter);
textPane.setSelectionEnd(CurrentText.indexOf(textToFind) + textToFind.length() - counter);
CurrentText = CurrentText.replaceFirst(textToFind, Replacer);
}
else{
optionPane.showMessageDialog(null, "No Matches.", "Message", 0);
}
}
catch(IOException e){
e.printStackTrace();
} catch(NullPointerException e){
optionPane.showMessageDialog(null, "No Matches.", "Message", 0);
}
}
}
There's a JFindReplace tool. You can disable replace and just have find. Apart from that I don't know how good it is.
Link: http://www.javalobby.org/java/forums/t19015.html

Adding commas to output

This is what it does:
2,
4,
6,
8,
10
I would like for it to be horizontal:
2, 4, 6, 8, 10
try {
PrintWriter fout = new PrintWriter(new BufferedWriter(new FileWriter("numbers.dat")));
for(int i = start; i <= 100; i = i + 2) {
fout.println(i+",");
}
Another attempt
for(int i = start; i <= 100; i += 2)
System.out.print(i + (i > 98 ? "\n" : ", "));
In the write() method:
for(int i = start; i <= 100; i = i + 2) {
if (i > start) {
fout.print(",");
}
fout.println(i);
}
Then when you call output(), it will display as comma separated list. And for screen display
while((outputline = fin.readLine()) != null) {
System.out.print(outputline + " ");
}
System.out.println();
Alternatively, skip saving the comma in the file and displaying will be as follows
int count = 0;
while((outputline = fin.readLine()) != null) {
if (count > 0)
System.out.print(", ");
System.out.print(outputline);
count++;
}
System.out.println();
If you mean to do it on printing to your .dat file:
for(int i = start; i <= 100; i = i + 2) {
fout.print(i);
if(i < 100) {
fout.print(", ");
} else {
fout.println();
}
}
If it is when printing to the system output after reading your file, try this:
try {
BufferedReader fin = new BufferedReader(new FileReader("numbers.dat"));
String outputline = "";
StringBuilder result = new StringBuilder();
while((outputline = fin.readLine()) != null) {
result.append(outputline).append(", ");
}
int length = result.length();
result.delete(length - 2, length);
System.out.println(result);
fin.close();
}
This uses a StringBuilder to build up your result and then removes the last , when it is done.
Here is a very basic example of what you could do:
int max=11;
for(int i = 0; i < max; i += 2){
System.out.print(i);
if(i < max-2){
System.out.print(", ");
}
}
fout.println(i + ", ");
System.out.println(outputline + ", ");
This will give you commas after all the numbers but it looks like you don't need one after the final number.
You will have to remove the last comma either by using indexOf or checking for the last iteration of your loop.

Categories

Resources