out of range error for condition statement - java

I don't understand why when I use the code below it throws the following exception: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at java4.main(java4.java:11)
import java.util.Scanner;
public class java4{
public static void main (String[] args) {
Scanner console = new Scanner(System.in);
System.out.println("Enter start time");
String startTime = console.nextLine();
String [] tokens = startTime.split(":");
double starttimeHours = Double.parseDouble(tokens[0]);
double startMinutes = Double.parseDouble(tokens[1]);
if (starttimeHours >=6 && starttimeHours <=9 );
int wage = 2;
System.out.println("Enter estimated hours work:");
String esthourswork = console.nextLine();
double wagedoubleNumber = Double.parseDouble(esthourswork);
if (starttimeHours >=06.0 && starttimeHours <=09.0 );
double totalPay = 2 * wage;
double totalPay1 = (Math.round(totalPay *100))/100.0;
System.out.println("Total fare:$ " + totalPay1);
}}
Because I think it is for this section of code:
if (starttimeHours >=06 && starttimeHours <=9 );
With this section when I change the <=9 to <=09 it comes up with the red cross and says:
The literal 09 of type int is out of range. But I thought int range was from 2.5 million to either way of 0.. I tried changing <=9 to <=09.0 which does not give me a red cross but still throws the same runtime error when I run it. Does anyone know how to solve this? thanks

You are using String [] tokens = startTime.split(":"); before explicitly using tokens at index 0 and 1. That is, you are assuming that whatever the user entered definitely contains at least one colon.
After you split the entered string, make sure to verify the length of your array and also make sure to verify that each individual token represents the value you want (you are using parseDouble - so make sure that each token contains a double value. The easiest way would be to just surround your conversion with try/catch and catch NumberFormatException.

Problem is probably here
double starttimeHours = Double.parseDouble(tokens[0]);
double startMinutes = Double.parseDouble(tokens[1]);
Make sure that lenght of your tokens is 2.

String [] tokens = startTime.split(":");
if(tokens.length>2) {
double starttimeHours = Double.parseDouble(tokens[0]);
double startMinutes = Double.parseDouble(tokens[1]);
your code would throw indexoutofbound when the length of tokens is less than 2.

You need to escape : in startTime like startTime.split("\\:");
// error may lie here, you will get exception when user enters string which does not contain :
String [] tokens = startTime.split(":");
double starttimeHours = Double.parseDouble(tokens[0]);
// exception is thrwon from following line as tokens[] contain only one element
double startMinutes = Double.parseDouble(tokens[1]);

06 is an octal literal in Java, which is why 09 in an error. 09.0 is a double, but since that's not the reason you get an ArrayIndexOutOfBoundsException, of course you'll still get it. See the other answers for that.

Related

Splitting a string at a certain character in java

In this code, I'm trying to split a string at a definite position, but it doesn't work and i'm not sure what to put, knowing that I'm trying to have it in the format "xy" without spaces, commas, anything.
import java.util.*;
public class xy {
public static void main(String[] args) {
System.out.println("Enter a number with the format 'xy'. x is the row number and y the column number.");
Scanner scanner = new Scanner(System.in);
String[] xy = scanner.nextLine().split(charAt(1)); // not sure what to put here so I tried charAt but it doesn't work
String x = xy [0];
String y = xy [1];
}
}
In this code, I'm trying to split a string at a definite position, but it doesn't work and i'm not sure what to put, knowing that I'm trying to have it in the format "xy" without spaces, commas, anything
You don't have to use split, there is no delimiter in the input received. Since the expected input is of xy. Receive it as a String and use charAt:
String input = scn.nextLine();
char x = input.charAt(0);
char y = input.charAt(1);
Or
String x = input.substring(0, 1);
String y = input.substring(1);
In this case you don't need to split. You basically know that the first string should go from index 0 to n-1, and then you got a second string from n-1 to "length".
Thus: don't split; simply call substring() twice, and give the required numbers.
And as you only deal with two chards in the first place; just go:
char x = str.charAt(0);
char y = str.charAt(1);
Done.

Something wrong in my coding in java with numbers and strings

I tried to develop a java program using netbeans in which a GUI accepts subject marks from five text fields and displays the total marks, percentage and the grade in their respective text fields.
The problem is I am getting errors while executing the GUI. I tried replacing int with double to hold decimal values of percentage but that didn't help. I am unable to find any errors and since I am a beginner i am unable to understand the errors given in the monitor by my netbeans. Please help.
ERRORS: Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: " 34"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:481)
at java.lang.Integer.parseInt(Integer.java:527)
at NewJFrame.submit_buttonActionPerformed(NewJFrame.java:173)
at NewJFrame.access$000(NewJFrame.java:4)
at NewJFrame$1.actionPerformed(NewJFrame.java:60)
Here's the coding I've done.
int sub1_ = Integer.parseInt(sub1.getText());
int sub2_ = Integer.parseInt(sub2.getText());
int sub3_ = Integer.parseInt(sub3.getText());
int sub4_ = Integer.parseInt(sub4.getText());
int sub5_ = Integer.parseInt(sub5.getText());
// Here each subject holds a max. of 100 marks.
int a = sub1_+sub2_+sub3_+sub4_+sub5_;
total_marks.setText(""+a);
// Since each subject holds a max. of 100 marks, the total marks of five subjects sums up to 500.
int b = (a/500)*100;
percentage.setText(b+"%");
if(b<=100&&b>=91)
{grade.setText("A1");}
else if(b<=90&&b>=81)
{grade.setText("A2");}
else if(b<=80&&b>=71)
{grade.setText("B1");}
else if(b<=70&&b>=61)
{grade.setText("B2");}
else if(b<=60&&b>=51)
{grade.setText("C1");}
else if(b<=50&&b>=35)
{grade.setText("C2");}
else if(b<=34&&b>=0)
{grade.setText("D");}
else {grade.setText("");}
java.lang.NumberFormatException: For input string: " 34"
Trim the String of whitespace before using the parse methods.
try {
int sub1_ = Integer.parseInt(sub1.getText().trim());
int sub2_ = Integer.parseInt(sub2.getText().trim());
int sub3_ = Integer.parseInt(sub3.getText().trim());
int sub4_ = Integer.parseInt(sub4.getText().trim());
int sub5_ = Integer.parseInt(sub5.getText().trim());
} catch (NumberFormatException e) {
// invalid input
}
At some point you are trying to parse the integer " 34", the leading space is a problem for the parsing method.
You should either make sure your integer has no whitespace when you create it, or use the trim() function to remove leading and trailing whitespace,
In addition to the issues already reported, the line int b = (a/500)*100; should be int b = (a * 100) / 500; or, simpler, int b = a/5;. The division by 500 rounds down to an integer, so if a is less than 500 the result is zero.
In addition to the question asked, there is a way to reduce the clutter in your code.
For example, you have multiple if-statements that all do the same thing, but with different numbers.
In this case, you can just create a function.
private boolean inRangeOf(int value, int max, int min) {
return value <= max && value >= min;
}
You can then replace your conditions with calls to inRangeOf(x, a, b)
if( inRangeOf(b, 100, 91) ) {
grade.setText("A1");
}
else if( inRangeOf(b, 90, 81) ) {
grade.setText("A2");
}
else if( inRangeOf(b, 80, 71) ) {
grade.setText("B1");
}

Unexpected Type errors

I'm getting two small unexpected type errors which I'm having trouble trying to solve.
The errors occur at:
swapped.charAt(temp1) = str.charAt(temp2);
swapped.charAt(temp2) = temp1;
Any advice?
public class SwapLetters
{
public static void main(String[] args)
{
System.out.println("Enter a string: ");
String str = new String(args[0]);
String swapped = str;
char[] charArray = str.toCharArray();
System.out.println("Enter a position to swap: ");
int Swap1 = Integer.parseInt(args[1]);
System.out.println("Enter a second position to swap: ");
int Swap2 = Integer.parseInt(args[2]);
char temp1 = str.charAt(Swap1);
char temp2 = str.charAt(Swap2);
swapped.charAt(temp1) = str.charAt(temp2);
swapped.charAt(temp2) = temp1;
System.out.println("Original String = " + str);
System.out.println("Swapped String = " + swapped);
}
}
You can assign values to variables, not other values. Statements like 5 = 2 or 'a' = 'z' don't work in Java, and that's why you're getting an error. swapped.charAt(temp1) returns some char value you're trying to overwrite, it's not a reference to a particular position inside the String or a variable you can alter (also, mind that Java Strings are immutable so you can't really change them in any way after creation).
Refer to http://docs.oracle.com/javase/7/docs/api/java/lang/String.html for information on using String, it should have a solution for what you're trying to do.
Your code may even throw IndexOutOfBoundsException - if the index argument is negative or not
less than the length of this string. Check the length of each string.
The left side of your assignment cannot receive that value.
Description of String#charAt(int):
Returns the char value at the specified index
It returns the value of the character; assigning values to that returned value in the following lines is the problem:
swapped.charAt(temp1) = str.charAt(temp2);
swapped.charAt(temp2) = temp1;
Also, String#charAt(int) expects an index of a character within the String, not the character itself (i.e. chatAt(temp1) is incorrect), so your method will not work as expected even if you fix the former problem.
Try the following:
String swapped;
if(swap1 > swap2) {
swap1+=swap2;
swap2=swap1-swap2;
swap1-=swap2;
}
if(swap1!=swap2)
swapped = str.substring(0,swap1) + str.charAt(swap2) + str.substring(swap1, swap2) + str.charAt(swap1) + str.substring(swap2);

Java Array index out og bounds Exception when getting input in java

I got Java ArrayIndexOutOfBoundsException when getting String input in Java. Please help me. This is my code: I edited my code to split using : it says "Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at solution2.Solution.main(Solution.java:27)
"
import java.util.Scanner;
public class Solution {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
String str = scan.next();
String strarr[] = str.split(",");
String temp = strarr[0];
String temparr[] = temp.split(".");
String temp1 = strarr[1];
String temparr1[] = temp.split(".");
int x1 = Integer.parseInt(temparr[0]);
int x2 = Integer.parseInt(temparr[1]);
int y1 = Integer.parseInt(temparr1[0]);
int y2 = Integer.parseInt(temparr1[1]);
System.out.println(distance(x2,x1,y2,y1));
}
public static int distance(int x1,int y1,int x2,int y2){
int xlen=x2-x1;
int ylen=y2-y1;
return (xlen+ylen)*10-(ylen*5);
}
}
You need to escape the dot character in the String.split() regex, otherwise any character will be matched:
String temparr[] = temp.split("\\.");
For temparr1, I think you meant to use temp1:
String temparr1[] = temp1.split("\\.");
If you are expecting double values you could use Scanner.nextDouble() instead.
Did you notice that you are assigning temp.split() to temparr1 instead of temp1.split()?
Also, split takes in a regular expression as an argument, and as it happens, the regexp . matches just about anything. So, you should correct that.
I assume, from lack of anything disproving my guess, that you are parsing an input of format 1.2,3.4, where 1,2,3, and 4 are arbitrary numbers.
Beside that, Scanner.next reads in the next token, meaning that it will read only "1" from "1.2,3.4". You have to use Scanner.nextLine.

ArrayList in Java and inputting

I'm used to python, so this is a bit confusing to me. I'm trying to take in input, line-by-line, until a user inputs a certain number. The numbers will be stored in an array to apply some statistical maths to them. Currently, I have a main class, the stats classes, and an "reading" class.
Two Questions:
I can't seem to get the input loop to work out, what's the best practice for doing so.
What is the object-type going to be for the reading method? A double[], or an ArrayList?
How do I declare method-type to be an arraylist?
How do I prevent the array from having more than 1000 values stored within it?
Let me show what I have so far:
public static java.util.ArrayList readRange(double end_signal){
//read in the range and stop at end_signal
ArrayList input = new ArrayList();
Scanner kbd = new Scanner( System.in );
int count = 0;
do{
input.add(kbd.nextDouble());
System.out.println(input); //debugging
++count;
} while(input(--count) != end_signal);
return input;
}
Any help would be appreciated, pardon my newbieness...
What you need in your loop condition is:
while ( input.get( input.size()-1 ) != end_signal );
What you're doing is decrementing the counter variable.
Also you should declare the ArrayList like so:
ArrayList<Double> list = new ArrayList<Double>();
This makes the list type-specific and allows the condition as given. Otherwise there's extra casting.
Answers:
>1. I can't seem to get the input loop to work out, what's the best practice for doing so.
I would rather have a simple while loop instead of a do{}while... and place the condition in the while... In my example it read:
while the read number is not end signal and count is lower than limit: do.
>2. What is the object-type going to be for the reading method? A double[], or an ArrayList?
An ArrayList, however I would strongly recommend you to use List ( java.util.List ) interface instead. It is a good OO practice to program to the interface rather to the implementation.
>2.1How do I declare method-type to be an arraylist?
See code below.
>2.2. How do I prevent the array from having more than 1000 values stored within it?
By adding this restriction in the while condition.
import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
public class InputTest{
private int INPUT_LIMIT = 10000;
public static void main( String [] args ) {
InputTest test = new InputTest();
System.out.println("Start typing numbers...");
List list = test.readRange( 2.0 );
System.out.println("The input was " + list );
}
/**
* Read from the standar input until endSignal number is typed.
* Also limits the amount of entered numbers to 10000;
* #return a list with the numbers.
*/
public List readRange( double endSignal ) {
List<Double> input = new ArrayList<Double>();
Scanner kdb = new Scanner( System.in );
int count = 0;
double number = 0;
while( ( number = kdb.nextDouble() ) != endSignal && count < INPUT_LIMIT ){
System.out.println( number );
input.add( number );
}
return input;
}
}
Final remarks:
It is preferred to have "instance methods" than class methods. This way if needed the "readRange" could be handled by a subclass without having to change the signature, thus In the sample I've removed the "static" keyword an create an instance of "InputTest" class
In java code style the variable names should go in cammel case like in "endSignal" rather than "end_signal"
I think you started out not bad, but here is my suggestion. I'll highlight the important differences and points below the code:
package console;
import java.util.;
import java.util.regex.;
public class ArrayListInput {
public ArrayListInput() {
// as list
List<Double> readRange = readRange(1.5);
System.out.println(readRange);
// converted to an array
Double[] asArray = readRange.toArray(new Double[] {});
System.out.println(Arrays.toString(asArray));
}
public static List<Double> readRange(double endWith) {
String endSignal = String.valueOf(endWith);
List<Double> result = new ArrayList<Double>();
Scanner input = new Scanner(System.in);
String next;
while (!(next = input.next().trim()).equals(endSignal)) {
if (isDouble(next)) {
Double doubleValue = Double.valueOf(next);
result.add(doubleValue);
System.out.println("> Input valid: " + doubleValue);
} else {
System.err.println("> Input invalid! Try again");
}
}
// result.add(endWith); // uncomment, if last input should be in the result
return result;
}
public static boolean isDouble(String in) {
return Pattern.matches(fpRegex, in);
}
public static void main(String[] args) {
new ArrayListInput();
}
private static final String Digits = "(\\p{Digit}+)";
private static final String HexDigits = "(\\p{XDigit}+)";
// an exponent is 'e' or 'E' followed by an optionally
// signed decimal integer.
private static final String Exp = "[eE][+-]?" + Digits;
private static final String fpRegex = ("[\\x00-\\x20]*" + // Optional leading "whitespace"
"[+-]?(" + // Optional sign character
"NaN|" + // "NaN" string
"Infinity|" + // "Infinity" string
// A decimal floating-point string representing a finite positive
// number without a leading sign has at most five basic pieces:
// Digits . Digits ExponentPart FloatTypeSuffix
//
// Since this method allows integer-only strings as input
// in addition to strings of floating-point literals, the
// two sub-patterns below are simplifications of the grammar
// productions from the Java Language Specification, 2nd
// edition, section 3.10.2.
// Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt
"(((" + Digits + "(\\.)?(" + Digits + "?)(" + Exp + ")?)|" +
// . Digits ExponentPart_opt FloatTypeSuffix_opt
"(\\.(" + Digits + ")(" + Exp + ")?)|" +
// Hexadecimal strings
"((" +
// 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt
"(0[xX]" + HexDigits + "(\\.)?)|" +
// 0[xX] HexDigits_opt . HexDigits BinaryExponent
// FloatTypeSuffix_opt
"(0[xX]" + HexDigits + "?(\\.)" + HexDigits + ")" +
")[pP][+-]?" + Digits + "))" + "[fFdD]?))" + "[\\x00-\\x20]*");// Optional
// trailing
// "whitespace"
}
In Java it's a good thing to use generics. This way you give the compiler and virtual machine a hint about the types you are about to use. In this case its double and by declaring the resulting List to contain double values,
you are able to use the values without casting/type conversion:
if (!readRange.isEmpty()) {
double last = readRange.get(readRange.size() - 1);
}
It's better to return Interfaces when working with Java collections, as there are many implementations of specific lists (LinkedList, SynchronizedLists, ...). So if you need another type of List later on, you can easy change the concrete implementation inside the method and you don't need to change any further code.
You may wonder why the while control statement works, but as you see, there are brackets around next = input.next().trim(). This way the variable assignment takes place right before the conditional testing. Also a trim takes playe to avoid whitespacing issues
I'm not using nextDouble() here because whenever a user would input something that's not a double, well, you will get an exception. By using String I'm able to parse whatever input a user gives but also to test against the end signal.
To be sure, a user really inputed a double, I used a regular expression from the JavaDoc of the Double.valueOf() method. If this expression matches, the value is converted, if not an error message will be printed.
You used a counter for reasons I don't see in your code. If you want to know how many values have been inputed successfully, just call readRange.size().
If you want to work on with an array, the second part of the constructor shows out how to convert it.
I hope you're not confused by me mixin up double and Double, but thanks to Java 1.5 feature Auto-Boxing this is no problem. And as Scanner.next() will never return null (afaik), this should't be a problem at all.
If you want to limit the size of the Array, use
Okay, I hope you're finding my solution and explanations usefull, use result.size() as indicator and the keyword break to leave the while control statement.
Greetz, GHad
**
public static java.util.ArrayList readRange(double end_signal) {
//read in the range and stop at end_signal
ArrayList input = new ArrayList();
Scanner kbd = new Scanner(System. in );
int count = 0;
do {
input.add(Double.valueOf(kbd.next()));
System.out.println(input); //debugging
++count;
} while (input(--count) != end_signal);
return input;
}
**
public static ArrayList<Double> readRange(double end_signal) {
ArrayList<Double> input = new ArrayList<Double>();
Scanner kbd = new Scanner( System.in );
int count = 0;
do{
input.add(kbd.nextDouble());
++count;
} while(input(--count) != end_signal);
return input;
}

Categories