UPDATE: sorry for misleading some of you, here is more detailed code:
I'm trying to parse String[] array to int[] array. I take String from JTextArea, make String[] and then int[].
array1String="asd, lala, 22";
array2String="1,2,3";
String [] arr1 = array1String.split(",");
String [] arr2 = array2String.split(",");
int[] array1 = new int[arr1.length];
for (int i=0; i<arr1.length; i++) {
try {
array1[i] = Integer.parseInt(arr1[i]);
} catch (Exception ex) {
resultLabel.setText(ex.getMessage());
}
}
int[] array2 = new int[arr2.length];
for (int i=0; i<arr2.length; i++) {
try {
array2[i] = Integer.parseInt(arr2[i]);
} catch (Exception ex) {
resultLabel.setText(ex.getMessage());
}
}
the parseInt() method interprets any gibberish as a "0". So instead of getting an exception, I get every int[] member corresponding to gibberish String[] member as a ZERO. But that's not what I want. I want to catch the exception to pass the message to the JLabel. I don't want it to happily eat any nonsense and make it "0". Am i missing something? I suspect that is not how this is supposed to work.
result arrays look like the
array1 [0,0,22]
array2 [1,2,3].
And nothing goes to Label, as if exception never happened. By i didn't change the code, only handling the exception changed.
The code setting the text of the JLabel is missing, but I guess it's after the try-catch-block and will simply use the value of x, which is 0 by default. The preferable solution to this problem is to update the text inside the try-catch-block like this:
try{
int x = ...
resultLabel.setText("" + x);
}catch(Exception ex){
resultLabel.setText(ex.getMessage());
}
In general, if generating data might throw an exception is recommended to process the data inside the try-catch-block the data is produced in.
EDIT:
There's one simple problem with this code: int doesn't have any properties like an undefined value. The simplest approach to this would be to use an Integer[] instead and null as undefined-value:
Integer x;
try{
x = ...;
}catch(Excpetion ex){
resultLabel.setText(ex.getMessage());
x = null;
}
The default value for int is 0. Since you get an exception and nothing is assigned to x, you get 0
Firstly, if you are using int x = Integer.parseInt(str); in TRY block then it means your x becomes local variable of your TRY block and you cannot use it outside of TRY, not even in CATCH block. So, the in case of exception, question of x=0 will not even come because x would have lost its scope.
And if you are declaring x outside of TRY block (so that you can use it inside CATCH or outside TRY block) then you have initialize it (ofcourse with value as 0 or -1) then x=0 or x=-1 should be expected value of x
Your concern:
I want to catch the exception to pass the message to the JLabel.
Consider below approach, where you are catching the exception, computing the error message and then passing/setting into your label field etc.
Advantage of this approach as opposed to other is that you need to have duplicate code of resultLabel.setText(), you are updating your labelMessage with either success message or failure message and using it.
Please feel free to let me know if this doesn't completely address your concern.
String labelMessage = null;
String str = "asd";
try {
int x = Integer.parseInt(str);
labelMessage = //Whatever you want...
} catch (NumberFormatException e) {
e.printStackTrace();
labelMessage = "Error message = " + e.getMessage(); // OR some other menaingful message you want
}
//Set to you label field...
Related
I have a homework question I need help with
We have been given a text file containing one word per line, of a story.
We need to read this file into an array, perform a sort on the array and then perform a binary search.
The task also says I'll need to use an overload method, but I'm unsure where
I have a bubble sort, that I've tested on a small array of characters which works
public static void bubbleV1String(String[]numbers)
{
for(int i = 0; i < numbers.length-1; i++)
{
for(int j = 0; j < numbers.length-1; j++)
{
if(numbers[j] .compareTo(numbers[j+1])>0)
{
String temp = numbers[j+1];
numbers[j+1] = numbers[j];
numbers[j] = temp;
}
}
}
}`
And my binary search which I've tested on the same small array
public static String binarySearch(int[] numbers, int wanted)
{
ArrayUtilities.bucketSort(numbers);
int left = 0;
int right = numbers.length-1;
while(left <= right)
{
int middle = (left+right)/2;
if (numbers[middle] == wanted)
{
return (wanted + " was found at position " + middle);
}
else if(numbers[middle] > wanted)
{
right = middle - 1;
}
else
{
left = middle + 1;
}
}
return wanted + " was not found";
}
Here is my code in an app class to read in a file and sort it
String[] myArray = new String[100000];
int index = 0;
File text = new File("threebears.txt");
try {
Scanner scan = new Scanner(text);
while(scan.hasNextLine() && index < 100000)
{
myArray[index] = scan.nextLine();
index++;
}
scan.close();
} catch (IOException e) {
System.out.println("Problem with file");
e.printStackTrace();
}
ArrayUtilities.bubbleV1String(myArray);
try {
FileWriter outFile = new FileWriter("sorted1.txt");
PrintWriter out = new PrintWriter(outFile);
for(String item : myArray)
{
out.println(item);
}
out.close();
} catch (IOException e) {
e.printStackTrace();
}
When I go to run the code, I get a null pointer exception and the following message
Exception in thread "main" java.lang.NullPointerException
at java.base/java.lang.String.compareTo(Unknown Source)
at parrayutilities.ArrayUtilities.bubbleV1String(ArrayUtilities.java:129)
at parrayutilities.binarySearchApp.main(binarySearchApp.java:32)
Line 129 refers to this line of code of my bubblesort
if(numbers[j] .compareTo(numbers[j+1])>0)
And line 32 refers to the piece of code where I call the bubblesort
ArrayUtilities.bubbleV1String(myArray);
Does anyone know why I'm getting a null pointer exception when I've tested the bubblesort on a small string array? I'm thinking possibly something to do with the overloaded method mentioned earlier but I'm not sure
Thanks
You are creating an array of length 100000 and fill the lines as they are read. Initially all elements will be null and after reading the file quite a number of them is likely to still be null. Thus when you sort the array numbers[j] will eventually be a null element and thus calling compareTo(...) on that will throw a NullPointerException.
To fix that you need to know where in the array the non-null part ends. You are already tracking the number of read lines in index so after reading the file that would be the index of the first null element.
Now you basically have 2 options:
Pass index to bubbleV1String() and do for(int i = 0; i < index-1; i++) etc.
Make a copy of the array after reading the lines and before sorting it:
String[] copy = new String[index];
StringSystem.arrayCopy(myArray,0,copy,0,index);
//optional but it can make the rest of the code easier to handle: replace myArray with copy
myArray = copy;
Finally you could also use a List<String> which would be better than using arrays but I assume that's covered by a future lesson.
It seems that you have some null values in your numbers array. Try to debug your code (or just print array's content) and verify what you have there. Hard to tell anything not knowing what is in your input file.
Method overloading is when multiple functions have the same name but different parameters.
e.g. (taken from wikipedia - function overloading)
// volume of a cube
int volume(const int s)
{
return s*s*s;
}
// volume of a cylinder
double volume(const double r, const int h)
{
return 3.1415926*r*r*static_cast<double>(h);
}
Regarding your null pointer exception, you've created an array of size 100000, but it's likely you haven't read in enough information to fill that size. Therefore some of the array is empty when you try to access it. There are multiple ways you can go about this, off the top of my head that includes array lists, dynamic arrays or even moving the contents of the array to another one, once you know the size of the contents (however this is inefficient).
This is my first UVa submission so I had a few problems in the way. The biggest hurdle that took my time so far was probably getting all the formats correctly (I know, shouldn't have been too hard but I kept getting runtime error without knowing what that actually meant in this context). I did finally get past that runtime error, but I still get "Wrong answer."
Listed below are the things I've done for this problem. I've been working on this for the last few hours, and I honestly thought about just dropping it altogether, but this will bother me so much, so this is my last hope.
Things I've done:
considered int overflow so changed to long at applicable places
got the whole list (1-1000000) in the beginning through memorization for computation time
submitted to uDebug. Critical input and Random input both show matching output.
submitted to to UVa online judge and got "Wrong Answer" with 0.13~0.15 runtime.
Things I'm not too sure about:
I think I read that UVa doesn't want its classes to be public. So I left mine as class Main instead of the usual public class Main. Someone from another place mentioned that it should be the latter. Not sure which one UVa online judge likes.
input. I used BufferedReader(new InputStreaReader (System.in)) for this. Also not sure if UVa online judge likes this.
I thought my algorithm was correct but because of "Wrong answer," I'm not so sure. If my code is hard to read, I'll try to describe what I did after the code.
Here is my code:
class Main {
public static int mainMethod(long i, int c, List<Integer> l) {
if (i==1)
return ++c;
else if (i%2==0) {
if (i<1000000&&l.get((int)i)!=null)
return l.get((int)i)+c;
else {
c++;
return mainMethod(i/2, c, l);
}
}
else {
if (i<1000000&&l.get((int)i)!=null)
return l.get((int)i)+c;
else {
c++;
return mainMethod(i*3+1, c, l);
}
}
}
public static int countMax(int x, int y, List<Integer> l) {
int max=0;
if (x>y) {
int temp = x;
x= y;
y = temp;
}
for (int i=x; i<=y; i++) {
if (l.get(i)>max)
max = l.get(i);
}
return max;
}
public static void main(String[] args) {
List<Integer> fixed = Arrays.asList(new Integer[1000000]);
for (long i=1; i<1000000; i++) {
fixed.set((int)i, mainMethod(i,0,fixed));
}
String s;
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while ((s = br.readLine())!=null) {
int x = -1;
int y = -1;
for (String split : s.split("\\s+")) {
if (!split.equals("\\s+") && x==-1) {
x = Integer.parseInt(split);
} else if (!split.equals("\\s+") && x!=-1) {
y = Integer.parseInt(split);
}
}
if (x!=-1&&y!=-1)
System.out.println(Integer.toString(x) + " " + Integer.toString(y) + " " + Integer.toString(countMax(x,y,fixed)));
}
} catch (IOException e) {
} catch (NumberFormatException e) {
}
}
}
I apologize for generic names for methods and variables. mainMethod deals with memorization and creating the initial list. countMax deals with the input from the problem (15 20) and finding the max length using the list. The for loop within the main method deals with potential empty lines and too many spaces.
So my (if not so obvious) question is, what is wrong with my code? Again, this worked perfectly fine on uDebug's Random Input and Critical Input. For some reason, however, UVa online judge says that it's wrong. I'm just clueless as to where it is. I'm a student so I'm still learning. Thank you!
Haven't spotted your error yet, but a few things that may make it easier to spot.
First off:
int goes to 2^31, so declaring i in mainMethod to be long is unnecessary. It also states in the problem specification that no operation will overflow an int, doesn't it? Getting rid of the extraneous longs (and (int) casts) would make it easier to comprehend.
Second:
It's probably clearer to make your recursive call with c + 1 than ++c or doing c++ before it. Those have side effects, and it makes it harder to follow what you're doing (because if you're incrementing c, there must be a reason, right?) What you're writing is technically correct, but it's unidiomatic enough that it distracts.
Third:
So, am I missing something, or are you never actually setting any of the values in the List in your memoization function? If I'm not blind (which is a possibility) that would certainly keep it from passing as-is. Wait, no, definitely blind - you're doing it in the loop that calls it. With this sort of function, I'd expect it to mutate the List in the function. When you call it for i=1, you're computing i=4 (3 * 1 + 1) - you may as well save it.
I'm trying to read the ex2data2.txt which contains dataset with 3 columns. I want to store it in my x array and y array. but it is not working. it cannot read the text file. the location of text file is in my src folder along with my codes.
double[][] x = new double[180][1];
double[][] y = new double[180][0];
try{
BufferedReader br=new BufferedReader(new FileReader("ex2data2.txt"));
String words[]=new String[2];
String line=null;
int i = 0;
while((line=br.readLine())!=null){
words=line.split(",");
//double[i] y = Double.parseDouble(words);
x[i][0] = Double.parseDouble(words[0]);
x[i][1] = Double.parseDouble(words[1]);
y[i][0] = Double.parseDouble(words[2]);
i++;
}
br.close();
}
catch(Exception e){
System.err.println("Error: Target File Cannot Be Read");
}
You should put the file in the top, parent project folder. not in src/.
Edit : I have run this, for proof...
Accessing file, read all the data.
java.lang.NumberFormatException: For input string: "43 323 33" this I have put in that file
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1241)
at java.lang.Double.parseDouble(Double.java:540)
at com.rem.so.Rem.main(Rem.java:18)
Next run
java.lang.ArrayIndexOutOfBoundsException: 1
at com.rem.so.Rem.main(Rem.java:19)
After correcting this..
double[][] x = new double[180][2];
double[][] y = new double[180][1];
it is now done.
Please find the screenshot where I have put the file...
double[][] y = new double[180][0];
That's probably not what you wanted. The second dimension is zero so you wont be able to put anything in that array. The second dimension needs to be at least 1.
catch(Exception e){
System.err.println("Error: Target File Cannot Be Read");
}
Any developer writing this code should be immediately fired.
Never catch an Exception, but perform proper and specific error handling. Catch the most precise error to handle (e.g. FileNotFoundException), avoid catching errors that you do not know how to handle. If in doubt, rethrow the error, so that an outer error handler can process it. Always log the error, unless it is expected to happen.
Then you would be getting a more precise error message. But you opted to ignore the actual error e.
REALLY REALLY read a Java book or tutorial, in particular the section on proper exception handling. You are making your own live difficult by discarding the error the way you have been doing it.
An exception is almost never something you should ignore. You are required to handle them for a reason! (In fact, there are also "unchecked" exception, where you are not required to do so. Which makes it even more obvious that here, you need to handle them properly.)
Three Rules for Effective Exception Handling (java.net)
Your error most likely is an ArrayOutOfBoundsException (which you should not have caught!)
double[][] x = new double[180][1];
double[][] y = new double[180][0];
this is too small. you probably need
double[][] x = new double[180][2];
double[][] y = new double[180][1];
I am rather new in Java and I can't seem to get around the error message
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.ArrayList.elementData(ArrayList.java:371)
at java.util.ArrayList.get(ArrayList.java:384)
at djurfarm.Animals.huntCatMouse(Animals.java:213)
at djurfarm.Djurfarm.main(Djurfarm.java:24)
Java Result: 1
I know what it means, that the index somewhere is below or above what it should be, but I can't for the life of me figure out why this is happening. Maybe it's because I've stared myself blind and won't see where the logic fails. Any help would be greatly appreciated. Here is the code for the method:
public void huntCatMouse() {
while (!CatList.isEmpty()) {
for (int i = 0 ; i < CatList.size(); i++) {
try {
TimeUnit.MILLISECONDS.sleep(500);
int slump = MouseList.size() - 1;
int num = CatList.size() - 1;
Cat CatRemover = CatList.get(num);
Mouse aMouse = MouseList.get(slump);
if (aMouse.getStrength().equals(false)) {
System.out.println("En katt fångar en mus.");
CatList.remove(CatRemover);
MouseList.remove(aMouse);
} else if (aMouse.getStrength().equals(true)) {
System.out.println("En mus lyckas fly från en katt.");
CatList.remove(CatRemover);
MouseList.remove(aMouse);
}
} catch (InterruptedException e) {
System.out.println("Fel i CatMouse");
}
if (MouseList.isEmpty()) {
System.out.println("Empty list");
break;
}
}
}
}
int slump = MouseList.size()-1;
It seems MouseList is a empty list and size method return 0 and slump become -1 and
MouseList.remove(aMouse); // MouseList.remove(-1)
causing ArrayIndexOutOfBoundsException at -1 index.
you have put condition !CatList.isEmpty(), It might be !CatList.isEmpty() && !MouseList.isEmpty()
The error may be because of this:
int slump = MouseList.size()-1;
int num = CatList.size()-1;
Cat CatRemover = CatList.get(num);
Mouse aMouse = MouseList.get(slump);
Here you are not checking whether MouseList or CatList size is greater than 0.
So if MouseList.size() returns 0,
so int slump = MouseList.size()-1; = int slump = -1;
Now when you do MouseList.get(slump); it means you are calling MouseList.get(-1);
So it throws that exception.
So first check whether the size of the list is greater than 0 (that is not empty).
As others have pointed out, the problem is that slump is -1 when you attempt to get(slump).
The reason it gets into that state is that you are not stopping when the mouse list becomes empty. In particular, the if (...) { break; } at the end only breaks out of the inner loop. So you try the condition for the outer loop, start the inner loop again and ... OOOPs!
The obvious fix would be to test both of the lists sizes in the outer loop's condition.
But a better fix would be to get rid of the inner loop entirely. You can implement this more simply with just one level of looping.
while (!CatList.isEmpty() && !MouseList.isEmpty()) {
try {
TimeUnit.MILLISECONDS.sleep(500);
int slump = MouseList.size() - 1;
int num = CatList.size() - 1;
Cat CatRemover = CatList.get(num);
Mouse aMouse = MouseList.get(slump);
if (aMouse.getStrength().equals(false)) {
System.out.println("En katt fångar en mus.");
CatList.remove(CatRemover);
MouseList.remove(aMouse);
} else if (aMouse.getStrength().equals(true)) {
System.out.println("En mus lyckas fly från en katt.");
CatList.remove(CatRemover);
MouseList.remove(aMouse);
}
} catch (InterruptedException e) {
System.out.println("Fel i CatMouse");
}
}
While I have your attention, you need to fix the names of your local variables. Java variable names should always start with a lowercase letter ... according to the Java style guide. And try to get the indentation right. It makes your code so much easier to read.
Finally, this is really peculiar: aMouse.getStrength().equals(true).
I would infer that getStrength() returns a boolean.
Assuming that, the simple way to test if it is true is simply aMouse.getStrength().
But "strength" is not a yes/no concept in English. It is something that you quantify.
But if "strength" really is a boolean, then the JavaBeans convention says that the method should be called isStrength() not getStrength().
I don't spot any mistake on this code, however eclipse tells me that the variables are not initialized. It is only a warning, but after compiling it doesn't work either. I simply can't find the mistake and thing of this code being 100% correct. Please note that the structure of this code can not easily be changed because the code provided below is simplified so you do not have that much to read ;-)
int min1; float somefloat;
try {
//setting values for min and somefloat
min1 = 1;
somefloat = 0.92f;
} catch (IOException ioe) {
System.err.println("Read Exception");
}
while (true){
//warning: variables min1 and somefloat may not be initialized.
float value1 = (1023 - min1) * somefloat;
System.out.println("Value: " + value1);
}
You have to initialize all your variables before they enter any try block. The Java compiler does not know that in your case, there is no way of an exception to be caused.
So theoretically speaking, there could be an exception somewhere which leaves your variables uninitialized. And that's not acceptable. Thus the warning.
Just initialize your variables to zero.
int min1 = 0;
float somefloat = 0f;
Compiler doesn't analyse if in concrete case the variables would be initialized or no. It assures that if the variables are initialized only in try, and not in catch or finally it would assure they may be not initialized.
Give a similar try with "obvious" condition like if(1>0) {}. The compiler compiles and not makes the analysis of your code. While for human it is obvious that something will happen, the java compiler have no code to detect such cases, neither it is specified by java syntax. So you're expecting from the compiler the AI it doesn't have, to keep the compiling clear, predictable and fast.
Your code has, BTW, error that will be reported instead of this you describe, because there's no place IOException can be thrown.
however eclipse tells me that the variables are not initialized
The warning is shown cause it is a possiblity that exception is thrown before the variable are initialized within try. then within while the variables remain uninitialized.
They should have an initial value just in case if it enters the catch block. Try this:
int min1 = 0; float somefloat = 0f;
try {
//setting values for min and somefloat
min1 = 1;
somefloat = 0.92f;
} catch (IOException ioe) {
System.err.println("Read Exception");
}
while (true){
//warning: variables min1 and somefloat may not be initialized.
float value1 = (1023 - min1) * somefloat;
System.out.println("Value: " + value1);
}
You have to initialize them while declaring them or at least outside the try-catch block. Because compiler cannot be sure the initialization inside the try-catch block is going to complete normally, in which case, you will be having an un-initialized variables outside.
int min1=0; float somefloat=0.0f;
you need to initialize the variables during declaration.variable assignment in try will overwrite that value and if any exception occur(Don't know how in your case..) it will take the default value. during compilation, compiler will not look at your code whether it will throw an exception or not (except throw , it requires a matching catch) so it needs an explicit initialization .
private void tset(){
int min1; float somefloat;
try {
//setting values for min and somefloat
min1 = 1;
somefloat = 0.92f;
while (true){
//warning: variables min1 and somefloat may not be initialized.
float value1 = (1023 - min1) * somefloat;
System.out.println("Value: " + value1);
}
} catch (Exception ioe) {
System.err.println("Read Exception");
}
}
This may be the code you are looking for...