I have an assignment in my APCS class that asks us to make a combination lock and I think I have the basic structure down. However, I keep running into a problem that won't let me compare a raw nextLine() to a String.
I was wondering if nextLine()s are by default ints? Or could anyone just tell me what's wrong with my code?
if((in.nextLine()).compareTo(combo))
{
System.out.println("The lock is now unlocked.");
System.out.println("Please enter the combo to unlock: ");
if((in.nextLine()).compareTo(combo))
{
System.out.println("The lock is now locked.");
}
else
{
System.exit(0);
}
}
P.s. the ide returns the error: "error: incompatible types: int cannot be converted to boolean" and is referring to the if qualifications.
nextLine() will always return a String, so that isn't your problem.
compareTo(str) returns an negative number if str is lexicographically less than the value being compared to, 0 if the Strings are lexicographically equal, or a positive number if the str is lexicographically more than the value being compared to.
You want to use equals(str), which returns a boolean value.
Your problem is that compareTo() returns an integer value, not a Boolean.
See the Java API docs for compareTo (in interface Comparable, at http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html):
Method Detail
compareTo
Returns: a negative integer, zero, or a positive integer
as this object is less than, equal to, or greater than the specified
object.
The simplest way to compare two Strings is to use
if (in.nextLine().equals(combo)) { /* code here */ }
Watch out for another pitfall in this program, too. Your first nextLine() and your second nextLine() are actually two separate input lines. nextLine() returns the next line of input from the reader, so it will return a different line of input each time you call it. A solution is to save the results of nextLine() as a variable:
String enteredCombo = in.nextLine();
if (enteredCombo.equals(combo))
{
System.out.println("The lock is now unlocked.");
System.out.println("Please enter the combo to lock: ");
enteredCombo = in.nextLine();
if(enteredCombo.equals(combo))
{
System.out.println("The lock is now locked.");
}
else
{
System.exit(0);
}
}
Related
I am having trouble understanding how memory buffer works when I am working with Scanner class methods such as hasNextInt() hasNextDouble() etc. Considering the following code,
Scanner in = new Scanner(System.in);
int number;
do {
System.out.print("Enter a positive integer: ");
while (!in.hasNextInt()) {
System.out.println("It's not an integer!");
in.next();
}
number = in.nextInt();
} while (number <= 0);
System.out.println("Your number is " + number);
The output for some random values:
Enter a positive integer: five
It's not an integer!
-1
Enter a positive integer: 45
Your number is 45
What actually happens here? At line 1 when I enter five the nested while loop runs. What is the job of in.next()? After I enter five it says It's not an integer! But why doesn't it ask again: Enter a positive integer: ? Basically, I want the corresponding output to be like this:
Enter a positive integer: five
It's not an integer!
Enter a positive integer: -1
It's not a positive integer!
Enter a positive integer: 45
Your number is 45.
I would appreciate a brief and intuitive explanation how white spaces, line breaks are handled in input validation? And what is memory buffer? And how different methods of Scanner class like next(), nextLine(), nextInt(), nextDouble() etc. operate?
Also, how do I avoid repetition of It's not an integer!
Enter a positive number: five
It's not an integer!
one two three
It's not an integer!
It's not an integer!
It's not an integer!
10
Your number is 10
And finally, why many recommend try catch?
To start with, 0, -1, -66, 2352, +66, are all Integer values so you can't very well decide to designate them as otherwise. Your validation response should really be:
System.out.println("It's not a positive integer value!");
I personally never use those nextInt(), nextDouble(), etc methods unless I want blind validation. I just stick with a single loop, and utilize the nextLine() method along with the String#matches() method (with a small Regular Expression). I also don't really care for using a try/catch to solve a situation where I don't have to.
Scanner in = new Scanner(System.in);
int number = 0;
while (number < 1) {
System.out.print("Enter a positive integer (q to quit): ");
String str = in.nextLine();
if (!str.equals("") && String.valueOf(str.charAt(0)).equalsIgnoreCase("q")) {
System.exit(0);
}
// If a string representation of a positive Integer value
// is supplied (even if it's prefixed with the '+' character)
// then convert it to Integer.
if (str.matches("\\+?\\d+") && !str.equals("0")) {
number = Integer.parseInt(str);
}
// Otherwise...
else {
System.err.println(str + " is not considered a 'positive' integer value!");
}
}
System.out.println("Your number is " + number);
In this particular use-case, I actually find this more versatile but then, perhaps that's just me. It doesn't matter what is entered, you will always get a response of one form or another and, you have a quit option as well. To quit either the word quit or the letter q (in any letter case) can be supplied.
People like to utilize the try/catch in case a NumberFormatException is thrown by nextInt() because a white-space or any character other than a digit is supplied. This then allows the opportunity of displaying a message to console that an invalid input was supplied.
Because the Scanner class is passed System.in within its' constructor (in is an object of InputStream) it is a Stream mechanism and therefore contains a input (holding) buffer. When anything is typed to the Console Window it is place within the input buffer until the buffer is read by any one of the next...() methods.
Not all Scanner class methods like next(), nextInt(), nextDouble(), etc, completely utilize everything contained within the stream input buffer, for example, these methods do not consume whitespaces, tabs, and any newline characters when the ENTER key is hit. The nextLine() method however does consume everything within the input buffer.
This is exactly why when you have a prompt for a User to supply an Integer value (age) and you use the nextInt() method to get that data and then directly afterwords you prompt for a string like the User's name using the nextLine() method, you will notice that the nextLine() prompt is skipped over. This is because there is still a newline character within the input buffer that wasn't consumed by the nextInt() method and now forces the nextLine() method to consume it. That ENTER that was done in the previous nextInt() method is now passed into the nextLine() method thus giving the impression that the prompt was bypassed when in reality, it did receive a newline character (which in most cases is pretty much useless).
To overcome this particular situation the easiest thing to do is to consume the ENTER key newline character by adding scanner.nextLine(); directly after a int myVar = scanner.nextInt(); call. This then empties the input buffer before the String name = scanner.nextLine(); comes into play.
I need to create two different programs. One that does the following:
Enter your first number: 15
Enter your second number: 25
25 is larger than 15
and a second separate one that does the following:
Enter the first string: apple
Enter the second string: bananas
apple comes before bananas lexiographically
This is what I tried for the first one:
import java.util.Scanner;
public class ClosedLab03 {
public static void main(String[] args) {
Scanner keyboard = new Scanner (System.in);
System.out.println("Enter your first number: ");
int firstNumber = keyboard.nextInt();
System.out.println("Enter your second number: ");
int secondNumber = keyboard.nextInt();
int result;
if (firstNumber > secondNumber)
{
result = System.out.println(firstNumber +" is larger than " + secondNumber);
}
else
{
result = System.out.println(secondNumber + " is larger than " firstNumber);
}
Obviously I'm doing something wrong, but I don't really know what. In terms of comparing the strings, I really don't know how to compare them lexicographically. Our textbook shows us how to compare two strings and say whether or not they are the same, but not how to compare them and display which one is lexicographically first.
String.compareTo(String) does this for you. It implements the java.lang.Comparable interface.
Compares two strings lexicographically. The comparison is based on the Unicode value of each character in the strings. The character sequence represented by this String object is compared lexicographically to the character sequence represented by the argument string. The result is a negative integer if this String object lexicographically precedes the argument string. The result is a positive integer if this String object lexicographically follows the argument string. The result is zero if the strings are equal; compareTo returns 0 exactly when the equals(Object) method would return true.
Example
System.out.println("apples".compareTo("bananas")); // returns -1
System.out.println("bananas".compareTo("apples")); // returns 1
System.out.println("apples".compareTo("apples")); // return 0
I have a method I'm using to validate user-inputted values in a program. Whenever the user inputs a string into a JOptionPane, I call this method and pass in the inputted string, plus the maximum and minimum values I need their input to be between. First I check if the input is an integer by trying to parse the input string and catching exceptions, then I check if the integer is between the min and max. My problem is that if the user inputs another incorrect non-integer value after being prompted, I don't know how to check if the new value is correct or not. Here is the method, can anybody help?
int checkInput(String input, int min, int max) {
Boolean isInteger = false;
Boolean inputAccepted = false;
int userInput = 0; //will be set later
while (!isInteger) {
try
{
userInput = Integer.parseInt(input);
}
catch (NumberFormatException e)
{
userInput = Integer.parseInt(JOptionPane.showInputDialog("Please enter only integers between " + min + " and "+ max + "."));
isInteger = true; //the problem here is that it assumes the user inputted a correct value after being prompted... what if they enter another incorrect value?
}
}
while (!inputAccepted) {
if (userInput < min || userInput > max)
{
userInput = Integer.parseInt(JOptionPane.showInputDialog("Please enter only integers between " + min + " and "+ max + "."));
}
else
{
inputAccepted = true;
}
}
return userInput;
}
I believe the main problem is that you have a method whose job isn't simple and well-defined. It looks like you have a statement outside this method that inputs a number; but checkInput has two jobs: making sure the number is valid, and inputting more numbers until it is. This is a problem in two ways: your code that does the input is duplicated in two places, and you have a method whose responsibility isn't clear.
Instead, try writing a method that just checks whether the input is valid, and returns true or false. I'd change the name to isValidInput. The caller would then have a loop that would perform the input, make sure it's valid, and go back if it isn't.
Usually I wouldn't answer a question like this by pointing to flaws in your design. But I think that in this case, if you rethink your design, your question will answer itself. (That's often the case when you design things correctly--things fall into place.)
Your checkInput() function should throw its own exception if the input is not correct. Spliting the code into a validator and a parser would result in parsing the input twice.
So I want to know what indexOf() does. As I want to use it in my program it find out how many vowels are in a word that the user inputs.
public static boolean methodCheck(char a){
return "AEIOUaeiou".indexOf(a) != -1;
}
But that doesnt seem to work at all hahah. as I have no idea what indexOf() actually does. anyway here is my program so far(sorry if its bad I'm really new). I left 5 questions too that would help me a lot! please and thank you for your help :D
import java.util.Scanner;
public class vowelCounter {
private static String input = methodInput(); //1. is there any other way to make a global Scanner?
public static void main(String[] args){
System.out.println("Enter word");
System.out.println(input);
System.out.println("This word has" + methodCheck('a')); //2. what should i put in my parameters?
}
public static boolean methodCheck(char a){
return "AEIOUaeiou".indexOf(a) != -1; //3. what does this line do?
}
public static String methodInput(){
Scanner keyboard = new Scanner(System.in);
String input = keyboard.nextLine();
return input;
//4. the output is 'hastrue' why is that?
//5. how can i make this program better?
}
}
If you don't know what a method does, then the solution is to go look at what it does. For example, the java documentation will tell you that
public int indexOf(int ch)
Returns the index within this string of the first occurrence of the specified character
In either case, if no such character occurs in this string, then -1 is returned.
How you're using it is not necessarily wrong, considering how the method returns -1 if the character wasn't found. But if you want to check how many vowels there are in a word that the user enters, it wouldn't be right to check whether the word they entered is in the string of vowels.
All the standard Java libraries, classes and methods have Javadoc that describes what they do.
All you need to do is look up the Javadoc and they describe it.
In this case the Javadoc is at: http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#indexOf(int)
Your first step with any question like this should always be the documentation, then if that doesn't work try doing a web search looking for examples. For example 5 seconds on google putting in "java indexOf example" found me:
http://www.tutorialspoint.com/java/java_string_indexof.htm
Then if that doesn't work you can try asking the question here.
When you have the word boolean before the name of a method, that means that the method will return either the value true or the value false. And it's this true or false value that your program is printing out, on the same line as "This word has".
This particular method will return true if the character you pass to it is a vowel, or false otherwise. The method indexOf tells you which character of a String is the first one that is equal to the value that you pass in to the method. It returns 0 for the first character, 1 for the second character and so on. It returns -1 if none of the characters match. In this case, you're just checking whether the value returned by indexOf is or isn't -1 - in other words, whether the character is or isn't in the String "AEIOUaeiou".
indexOf(String str) Returns the index within this string of the first occurrence of the specified substring. If no such value of str exists, then -1 is returned.
For examples :
int num1 = "AEIOUaeiou".indexOf("a"); // it gives 5
int num2 = "AEIOUaeiou".indexOf("A"); // It gives 0
int num3 = "AEIOUaeiou".indexOf("z"); // It gives -1
1 Don't do that! Create a scanner in main, read input with it and then call your method(s).
2 How about countVowels(input)? You'd need to write an static int countVowels(String input) method.
3 Returns true since you pass in 'a'.
4 See number 3.
5 See number 2, and add a static boolean isVowel(char a).
Here is what the indexOf method does
string.indexOf(searchvalue,start)
Parameters
searchvalue : Required. The string to search for
start : Optional. Default 0. At which position to start the search
Return Value
Number : The position where the specified searchvalue occurs for the first time, or -1 if it never occurs
In simple terms, the index of method checks the first occurence of the value passed to it from the start position(if specified) and returns the position at which the value was first encountered in the string.
eg.
String s = "AEIOUaeiou";
s.indexOf("a"); //This would get a value of 5.
s.indexOf("v"); //This would get a value of -1, since it doesn't have the character v
To answer your questions,
You can directly declare the scanner as private and use it in the
entire program
`private static Scanner input = new Scanner(System.in);`
you can write a method that receives the String input by the user
and then checks if the String contains any of the vowels. You can
use indexOf or contains methods to check for the each vowel using
the indexOf method.
Already described above.
A better way to do it would be as follows.
public class vowelCounter{
public static void main (String[] args) {
Scanner keyboard = new Scanner (System.in); // No need to declare it as global. You use it only once.
System.out.println ("Enter word : "); //Prompt the user to enter a word
String input = keyboard.nextLine (); //Fetch the word that the user enters into a String
System.out.println ("This word has" + countVowel (input)); // Pass the string to the method to check if it has vowels.
}
private static int countVowel (String a) {
int count = 0;
String s = a.toLowerCase (); // convert the string to lower case so that you only have to check for the lower case characters
// Here you would need to check the number of times each vowel exists in the String and incremenet the count everytime.
return count;
}
}
I am trying to determine whether a string contains a positive int or not. My code is:
public void isInt(String str) throws NotIntException{
String integer=str.replaceAll("\\d","");
System.out.println(integer);
if (!integer.equals("")){
throw new NotIntException("Wrong data type-check fields where an integer"+
" should be.");
}//end if
if (integer.equals("-")){
System.out.println(integer);
throw new NotIntException("Error-Can't have a negative count.");
}//end if
}//end method
I am testing this with a string "-1", which should, after the replaceAll(), become "-". This should enter both if-statements. But it only enters the first. I tried it with the == comparison too, just in case, but it didn't work either. What's odd to me is that whether I look to fulfill the second if-statement's condition or to fulfill its negation [i.e., !integer.equals("-")], the program still doesn't enter the if....
Thanks, usually my comparison issues are just me missing something basic, but I really don't see anything here...
Since you are throwing an Exception in your first if, so, your 2nd if will not even be tested.
if (!integer.equals("")){
throw new NotIntException("Wrong data type-check fields where an integer"+
" should be.");
}
if (integer.equals("-")){
System.out.println(integer);
throw new NotIntException("Error-Can't have a negative count.");
}
If your code enters the first if, it will not execute further.
But, why are you using this approach for your problem.
You can easily use Integer.parseInt to check for valid integer. And then if it is valid, then test whether its less than 0. It would be far easier and readable.
My solution:
public static boolean isPositiveInt(String str) {
try {
int number = Integer.parseInt(str.trim());
return number >= 0;
} catch (NumberFormatException e) {
return false;
}
}
If you want to simply read an int from a String, use Integer.parseInt(), although that would only work if you want to see if a string "is" an int, not contains one.
You could use a combination of Integer.parseInt() and a loop strategy to see if it contains an int fairly easily though, then just check if that is positive or not.
You approach is too complicated. I would keep it simple:
if (integer.startsWith("-")) {
// it's a negative number
}
if (!integer.matches("^\\d+$")) {
// it's not all-numbers
}
and forget the call to replaceAll()