Java while loop works with a netbean error - java

I'm trying to implement a program that needs a loop:
Scanner scan=new Scanner(System.in);
String word= scan.next().toLowerCase();
while !(word.equals("mot1") || word.equals("mot2") || word.equals("motmot") || word.equals("motmotmot") ){
word= word.next().toLowerCase();
}
it works, though, it underlines the while condition with the red error wavelet!!
the error is shown on the left in the margin with an exclamation mark (!) and says
'(' expexted
')' expected
so i've been trying to put bracket in all senses, the only time it would take the wavelet off is the case when it does not work anymore, and there is an infinite loop!
I don't know why?
Cheers
ADDition:
When the wavelet is off but won't do what intended but the logic is here:
String word= scan.next().toLowerCase();
while (!word.equals("onetime") || !word.equals("daily") || !word.equals("weekly") || !word.equals("monthly") ){
}

The logic is wrong and it suffers from the same issue as I answered here.
That is,
!x || !y || !z
is equivalent to (by De Morgan's Law)
!(x && y && z)
Since (in this case), x, y and z can never all be true at the same time the result is:
!(false) -> true
The correct logic for this is then, !(x || y || z) or, applying the rule again, !x && !y && !z.
In any case, I would recommend writing it using a function that utilizes the logic presented above ..
while (!validChoice(word)) {
// ..
}
boolean validChoice (String word) {
return word.equals(..) || word.equals(..) ..;
}
.. as it's how I keep things straight in my head.

Your error is related to the format of your code. The syntax assigned is not correct.
String word;
while (!word.equals("onetime") || !word.equals("daily") || !word.equals("weekly") || !word.equals("monthly") ){
word = input.next();
// do something;
}

Related

Java - I have an issue with Scanner class and reading text file [duplicate]

This question already has answers here:
Semicolon at end of 'if' statement
(18 answers)
Closed 5 years ago.
boolean r = false ; int s = 0 ;
while (r == false) ;
{
s = getInt() ;
if (!(s>=0 && s<=2)) System.out.println ("try again not a valid response") ;
else r = true ;
}
The text never displays itself even when a 3 or a 123 is entered and the loop never terminates. Whats wrong here?
You have a semicolon after the condition. When you use braces to specify a block for your while you don't use a semicolon.
Remove the ';' after while.
Others have pointed out the bug, but your code is scary in other ways that will eventually trip you up:
if (!(s>=0 && s<=2)) System.out.println ("try again not a valid response") ;
else r = true ;
That's bad because you can easily intend more than one statement to run in the case of the if or else clause. Use curly braces and avoid placing conditional statements on a single line:
if (!(s>=0 && s<=2))
{
System.out.println ("try again not a valid response");
}
else
{
r = true;
}
It's easier to read and far less likely to introduce hard-to-see bugs.
while(r == false)
should be
while(!r)
Despite what everyone else said about the semicolon, that is what I think is wrong with it :)
+1 to Daniel DiPaolo. I thought I'd post a separate answer to provide clarification of why this is the case.
While loops in Java can be written in one of two ways. If there is just one line to the body of the loop, you can write them in a short-hand fashion:
while (true)
System.out.println("While loop");
This will print out "While loop" on the console until the program ends. The other option is to specify a loop body between braces, as you have done above:
int i = 0;
while (i < 10) {
System.out.println("i = " + i);
i++;
}
This will print out "i = 0", "i = 1", ..., "i = 9" each on a separate line.
What the code you posted does is confuse the two. In the short-hand while loop, the Java parser expects to find a statement between the while loop condition and the semi-colon. Because it does not find a statement here, the while loop runs, but does nothing; it has no body. Furthermore, because the loop has no body, there is no opportunity for your variable r to assume a new value; the condition always evaluates to true and the loop never exits.
If you were to negate the condition in the while loop in your example, i.e.,
boolean r = false ; int s = 0 ;
while (r != false) ;
{
s = getInt() ;
if (!(s>=0 && s<=2)) System.out.println ("try again not a valid response") ;
else r = true ;
}
(note I left the erroneous semicolon in there), you would find that your intended loop body would execute precisely once, as the loop would never run.
In addition to other comments, you should also change the if to
if (s < 0 || s > 2)
It's much more understandable this way.
Unrelated answer, I really really recommend you to follow Sun's style guidelines.
boolean r = false ;
int s = 0 ;
while (r == false) {
s = getInt() ;
if (!(s>=0 && s<=2)) {
System.out.println ("try again not a valid response") ;
} else {
r = true ;
}
}
You could get rid of the r variable and the if/else condition if you evaluate the result in the loop it self.
int s = 0;
while( ( s = getInt() ) < 0 || s > 2 ) {
System.out.println( "Try again, not a valid response");
}

Fill two-dimensional array with Chars from String Input

I'm making a basic game of Tic Tac Toe, accepting player input in the form of a string (i.e. a2). The first char is made into an int called row depending on the letter, the same being said for the second char into col (for array grid[row][col]). I have a block of code that throws a custom exception in the event that the first char isn't a, b, or c, and if the second char isn't 1, 2, or 3:
if(input == null) {
throw new NullInputException();
}
else if(input.length() != 2) {
throw new InvalidInputException();
}
else if(!(input.substring(0,1).equalsIgnoreCase("a") &&
input.substring(0,1).equalsIgnoreCase("b") &&
input.substring(0,1).equalsIgnoreCase("c") ||
input.substring(1).equals("1") &&
input.substring(1).equals("2") &&
input.substring(1).equals("3"))) {
throw new InvalidInputException();
}
The problem is, this code throws an error even when the input is valid, and I don't know why. I've tried using .charAt() as opposed to .substring(), as well as messed around with my conditional statements. My question is: How do I fix this so that it accepts valid input?
Other questions that just don't help:
fill two dimensional array with parts of a string;
fill a 2d array with chars of 2 string
Sometimes it is better to write a series of simpler tests which are easier to read and verify
row = input.substring(0,1).toUpperCase();
col = input.substring(1);
boolean validRow = (row.equals("A") ||
row.equals("B") ||
row.equals("C"));
boolean validCol =
(col.equals("1") ||
col.equals("2") ||
col.equals("3"));
if(!(validRow && validCol)) {
You AND two conditions:
input.substring(0,1).equalsIgnoreCase("a") &&
input.substring(0,1).equalsIgnoreCase("b")
Both cannot be true in the same time. That is why the result is always false and an exception is thrown.
What you really want is:
String first = input.substring(0,1);
String second = input.substring(1);
if (!((first.equalsIgnoreCase("a") ||
first.equalsIgnoreCase("b") ||
first.equalsIgnoreCase("c")) &&
(second.equals("1") ||
second.equals("2") ||
second.equals("3"))) {
throw new InvalidInputException();
}
Small edit for Neil...

How to use 'or' in Java?

I'm quite new to Java, and can't figure out how to use 'or'. What is the Java equivalent?
I've already tried && and || but eclipse does not recognise it.
This is part of my code:
if (action.equals ("run") || ("sprint")) {
System.out.println("you ran");
}
else {
System.out.println("else");
}
I've already tried && and || but eclipse does not recognise it.
That's very strange, but just to cover the basics: Let's assume you have the variable a and it contains the value 5. Then:
if (a == 5 || a == 7)
...will be true, because the first part of the expression (a == 5) is true. So the statement "a equals 5 or a equals 7" is true.
The || operator can only be used, in Java, where a boolean (true or false) expression is expected, such as in an if statement like the above. So pretty much in an if or a conditional operator (that ?...: thing, sometimes called the ternary operator).
Re your edit, the problem is that both sides of your || operator aren't true or false ("boolean") expressions. Your statement:
if (action.equals ("run") || ("sprint")){
breaks down like this:
if (
action.equals ("run")
|| // ("or")
("sprint")
)
the second part of that isn't a true/false, it's a string. The correct way to express that in Java (or nearly any other programming language) is:
if (action.equals ("run") || action.equals ("sprint")){
Now both sides of the || result in true/false exprssions:
if (
action.equals ("run")
|| // ("or")
action.equals ("sprint")
)
The reason for this is that the second part may have nothing whatsoever to do with action, and so the compiler can't assume you mean to re-use it in the second part of the expression. You might, for instance, want to use || with two completely unrelated things:
if (action.equals("run") || somethingElse.equals("run")) {
Ok. ("sprint") is not a Boolean expression. Since a if condition expects a Boolean expression your code returns an error. You should change the line with:
if (action.equals ("run") || action.equals("sprint")){
The equals method returns a boolean and the || operator wants two booleans on each side.
You're doing an action.equals("run") on one side but then a ("sprint") on the other which isn't a boolean expression.
Change your code like so:
if (action.equals("run") || action.equals("sprint")){

Why won't my code compile which checks if a string begins with vowel?

if (flipped.charAt(0) = "a" || "e" || "i" || "o" || "u"){
paren = "(" + flipped;
String firstpart = paren.substring(0,5);
String rest = paren.substring(5);
System.out.println(rest+firstpart);
}
In this code, I'm looking to check if the first character of String flipped is a vowel. If it is, I'm adding a parenthesis to the beginning and moving the first 5 characters to the end of the string. Eclipse is giving me java.lang.NullPointerException and saying that "The left-hand side of an assignment must be a variable." What can I do to fix this?
Your code has following issues,
Use conditional operator == instead of assignment = at if statement.
Use single quotation ' instead of double " for char
Make a separate method for vowel check.
boolean isVowel(char ch){
ch=Character.toLowerCase(ch);
return ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u';
}
Another very simple solution I often use:
if ("aeiou".indexOf(Character.toLowerCase(text.charAt(0))) >= 0) {
// text starts with vocal.
}
You can also use regular expression matching:
if (text.matches("^[aeiou].*")) {
Use a collection that holds all of these values.
Set<Character> myList = new HashSet<Character>(Arrays.asList('a', 'e', 'i', 'o', 'u'));
if(myList.contains(Character.toLowerCase(flipped.charAt(0)))) {
// Do work
}
This line of code (while wrong: = will assign, == will compare)
if (flipped.charAt(0) == "a" || "e" || "i" || "o" || "u"){
will first compare flipped.charAt(0) == "a" which returns a boolean. Then it will continue with boolean || "e" || "i" || "o" || "u".
boolean || "e" is not valid code.
The accepted answer although explained the problem didn't quite show the solution for how he was checking the problem. So I figured i'd show a corrected solution as well as offer my own solution to such a problem.
Someone who cannot understand Boolean compare syntax isn't going to understand All those special classes. Not to mention some of those needs imports he may not have and will now need to understand why he's getting errors. I assume this person has came to a resolution by now given it's been 5 years.. but in the evnet someone else or even this person still is unsure on something.
Your Original Code Updated ( I removed the contents inside as I don't know what they do or if they were accurate ).
char c = flipped.charAt(0);
if (c == 'a' || c == 'A' || c == 'e' || c == 'E' || c == 'i' ||
c == 'I' || c == 'o' || c == 'O' || c == 'U' || c == 'u')
{
Now this supports checking if "flipped.charAt(0)" equals a vowel weather lower case or uppercase. As you can see we do a Boolean check for each situation by checking if "C" equals something else. You only offered the check one time so the syntax error was because of that you were doing Boolean checks on non Boolean values. When you have values next to "||" it must be "false", "true" or "SomethingA == SomethingB". If that something is an object you typically have to do "SomethingA.equals(SomethingB); E.g. byte,int,short,long,float,double will all work just fine, but String would require the second method.
Below are some tips to reduce this further.
We can force char "c" to lowercase by doing any of the below methods.
char c = Character.toLowerCase(flipped.charAt(0));
Or we can do a more clever way.
char c = flipped.charAt(0) | 32;
As such now we only need to do the following to check if it's a vowel.
char c = flipped.charAt(0) | 32;
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' ||c == 'u')
{
However we can take this a step further.
We can reduce the code even more!
if (((1 << flipping.charAt(0)) & 2130466) != 0)
{
So basically how my final solution works. Unfortunately it's pretty involved to explain it, but i'll try my best.
In any programming language you have values of Byte, Short, Int, and Long these are 8bit, 16bit, 32bit, and 64bit respectively.
When you perform 1 << N you are doing 2^N which is basically the power of two method. The thing is though when you use this on the Byte, Short, Int, or Long the value "N" is reduced.
So.. (keep in mind different languages handle these differently).
Byte can only range from 0-7.
Short can only range from 0-15.
Int can only range from 0-31.
Long can only range from 0-63.
So now we know letters have a value A-Z = 65-90 and a-z = 97-122 when we do 1 << letter it will actually be 1 << (1-26) because the those numbers module or remainder of 32 is 1-26 in both cases.
You can see this by doing the following.
A = 65.
65-32=33.
33-32=1. Stop.
So now we know A will equal 1 in this situation.
So now we do 1 << 1 or 2^1 = 2. So the letter A gives us the value "2".
Repeat this for all the vowels and we can a sum of bit values. Bit values are just powers of two added together. I again really can't go hard explaining this it's pretty involved but hopefully you kind of have an idea.
Now what we are doing is taking the sum of the vowel bits and comparing it to the number 2130466 which contains the bit values of A,E,I,O,U already. If those bit value we check for happens to exist in 2130466 then it must be A,E,I,O,U and as such it's a vowel.
The return result is 0 or the value so we simply check that this value doesn't equal 0.
Please keep in mind if anyone uses this that this assume you know the letter will be A-Za-z situation because if it was for example a "!" this will return a false positive as a "A" vowel. You can solve this by prechecking if the value is below "A" and above "u" and return out early.

Removing Characters within a string-Java

I keep getting an error with removing a character from within a string. I have tried everything that i could find on this site and nothing has worked. This is NOT a help post. Rather maybe an answer that explains why this shows up and how to fix it in case someone else encounters this issue. Without further a due, here is my code:
public JTextField Clean()
{
String Cleaner = TopField.getText();
Cleaner=Cleaner.toLowerCase();
int Length = Cleaner.length();
StringBuilder Combiner = new StringBuilder(Cleaner);
for (int x=0;x+1<Length;x++)
{
char c = Cleaner.charAt(x);
char c1 = Cleaner.charAt(x+1);
if(c==' ' && c1==' ')
{
Combiner.deleteCharAt(x);
Cleaner=Combiner.toString();
}
if(c!='a' && c=='b' && c!='c' && c!='d' && c!='f' && c!='g' && c!='h' && c!='i' && c!='j' && c!='k' && c!='l' && c!='m' && c!='n' && c!='o' && c!='p' && c!='q' && c!='r' && c!='s' && c!='t' && c!='u' && c!='v' && c!='w' && c!='x' && c!='y' && c!='z' && c!=' ')
{Combiner.deleteCharAt(x);
Cleaner=Combiner.toString();}
}
TopField.setText(Cleaner);
return TopField;
}
I receive an error that states that My value is out of bounds by the length of the string that i input. Please note that this is a method inside a class that i created that removes any character that is not an alphabet or space.
Thanks in advance
As you remove characters, Cleaner becomes shorter, so you're likely to reach a point where x is too large.
I would suggest a different approach using regular expressions:
string cleaned = TopField.getText().toLowerCase().replaceAll("[^a-z ]", "");
There are a number of things that pop out at me.
Your basing your loop on a fixed value (Length), but where the actual length of the String can decrease...
You are potentially removing 2 characters per loop (there are two deleteCharAt calls)
The loop doesn't take into account the shrinking size of the String. For example. x == 1, you remove the character at x, you increment x by 1 (x == 2), effectively skipping a character (the character at position 2 is now at position 1
Your if statement is unnecessarily long. In fact, depending on your needs, you could use Character.isDigit or Character.isLetter and Character.isWhiteSpace
String Cleaner = TopField.getText();
Cleaner = Cleaner.toLowerCase();
StringBuilder Combiner = new StringBuilder(Cleaner);
int x =0;
while (x < Combiner.length()) {
char c = Combiner.charAt(x);
if (c >= 'a' && c <= 'z' || c == ' ') {
Combiner.deleteCharAt(x);
} else {
x++;
}
}
From the looks of your code, you appear to wanting to filter a JTextField so it will only allow numeric values. It would be much better to use something like a JSpinner, JFormattedTextField or DocumentFilter and ensure the correctness of the data as it's entered...IMHO
I used a isDigit() function and found the output as incorrect. Look at the code I tested and found problem with the output. Any one explain.
public static void main(String[] args) {
// TODO Auto-generated method stub
String temp="you got 211111 out of 211111?";
StringBuilder cleaner=new StringBuilder(temp);
for(int i=0;i<cleaner.length();i++)
{
char c=cleaner.charAt(i);
if(Character.isDigit(c))
{
cleaner.deleteCharAt(i);
}
}
System.out.println(cleaner);
I am getting output as : you got 111 out of 111?
it is not removing some digits.
Also found that no function called replaceAll() is there in Java.

Categories