Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
My function is to make the code below print out 'Math' at an even number and 'English' at an odd number and repeat the process five times.
public static String[] subject() {
String[] subjects = { 'Math', 'English' };
int i=0;
while (i<5) {
if (i%2==0) {
System.out.println(subjects[0]);
}
else {
System.out.println(subjects[1]);
}
i++;
}
return subjects;
}
public static void main(String[]args) {
for(int n=0; n<5; n++) {
subject();
}
Originally it's double quotes, but I don't know how to do it, so I put single quotes.
It works, but I don't know how to use the return exactly.
I understand placing variable after return makes it the same type, ends the method and calls the result.
so why should I write a variable name, instead of writing the name of the function.
sorry im not good at English so had to refer to a translator to help
For this requirement, you should declare the return type as void as you just want to print the elements from the array and you are not using the returned array.
You need to remove the loop from inside main because it's already there in your method, subject.
0 is neither an odd number nor an even number. So, you should start with i = 1 and the terminating condition of the loop should be i <= 5.
In Java, single quotes are used to enclose char literals. To enclose String literals, you need to use double-quotes. Note that many languages, especially scripting languages and SQL, support enclosing String literals using single quotes.
Demo:
public class Main {
public static void subject() {
String[] subjects = { "Math", "English" };
int i = 1;
while (i <= 5) {
if (i % 2 == 0) {
System.out.println(subjects[0]);
} else {
System.out.println(subjects[1]);
}
i++;
}
}
public static void main(String[] args) {
subject();
}
}
Output:
English
Math
English
Math
English
Java newbie here.
I made a function to simply return an int given by user through Scanner.
The goal is to avoid an error if the user does not type an integer, notify them and let them retry.
It works fine if the value is an integer on the first try, but if I type a char (get an error, function "restart") then the function will return the "default" zero.
Tried different things but I definitly don't get the logic here.
Here is the code :
//Initialize the Scanner earlier
public static Scanner keyBoardRead = new Scanner(System.in);
public static int intEntry()
{
int entry;
keyBoardRead = new Scanner(System.in);
if (keyBoardRead.hasNextInt() == true)
{
entry = keyBoardRead.nextInt();
System.out.println("entry variable = "+entry);
// Here the correct entry prints but doesn't seem to return
return entry;
}
else
{
System.out.println("Invalid entry.\n");
intEntry();
}
return 0;
}
Sample output :
z
Invalid entry.
2
entry variable = 2
// Function exits and output = 0 (?!)
Thanks for your help and please criticize my code :)
I reworked your code a bit as there were a few flaws with it:
public static Scanner keyBoardRead = new Scanner(System.in);
public static int intEntry()
{
int entry;
if (keyBoardRead.hasNextInt())
{
entry = keyBoardRead.nextInt();
System.out.println("entry variable = "+entry);
// Here the correct entry prints but doesn't seem to return
return entry;
}
keyBoardRead.next();
System.out.println("Invalid entry.\n");
return intEntry();
}
Here are the changes explained below:
You do not need to redeclare new Scanner(System.in) with every call
to the method, you state you initially declare it as a class field,
so it should be accessible from inside the method each time.
Your else statement in general is completely unnecessary because you have a return in your if. If your if is executed, it will never enter the code afterward anyway.
You need to return the value from intEntry() with return intEntry() as currently you are just discarding the return value and simply returning 0 unconditionally if else is executed even a single time.
You need to use keyBoardRead.next() if an invalid entry is entered in order to move to the next value and discard the previously entered result. You can also use keyBoardRead.nextLine() instead if you wish to discard the entire line instead.
Using == true on a boolean value is redundant as you can simply check the boolean directly, so if (keyBoardRead.hasNextInt()) instead of if (keyBoardRead.hasNextInt() == true). Credit to #Joop Eggen for catching it.
Example Run:
hi
Invalid entry.
wrong
Invalid entry.
entries
Invalid entry.
55
entry variable = 55
Note: You have a lot of blank space in the output because you are use println and also using \n in the print so it will move to the next line twice.
Also you could easily create a variant to this solution that utilizes a while loop instead of recursion, which is probably a better way to do it so you cannot possibly run into a stack overflow (and is typically easier to read), but I kept the recursion in to keep it similar to your solution.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a break label in my java code but it doesn't jump to the label when I go to the break statement in my code:
OUTERMOST:for(String s :soso){
if(wasBreaked){
//code never enters this loop
Log.e("","WASBREAK = FALSE");
wasBreaked = false;
}
if(true){
Log.e("","WASBREAK = TRUE GOING TO OUTERMOST");
wasBreaked = true;
break OUTERMOST;
}
}
Break statement is not really a goto statement as in other programming languages like C.
What your code does instead is, break from the loop which has label OUTERMOST. I would have thought you need continue OUTERMOST; instead of break. But to me it really doesn't makes sense as you dont have further any statement post continue (now break in your code) and it's going to continue anyways irrespective of whether you say explicitly continue or not.
public class Test {
public static void main(String[] args) {
String soso[]={"1","2"};
boolean wasBreaked=false;
OUTERMOST:for(String s :soso){
if(wasBreaked){
Log.e("","WASBREAK = FALSE");
wasBreaked = false;
}
if(true){
Log.e("","WASBREAK = TRUE GOING TO OUTERMOST");
wasBreaked = true;
System.out.println("before break");
break OUTERMOST;//use continue in place of break here for going to label
}
System.out.println("Inside outermost loop");
}
System.out.println("outside outermost loop");
}
}
I tried this and it works
it gives output
before break
outside outermost loop
For going back to label you should use continue keyword rather than break in code. After using continue the output will be like
before break
before break
outside outermost loop
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
The following loop is not good practice. Is it due to a String being the main condition of the for loop rather than an int variable, meaning the for loop is infinite? Also, is it due to there being no instance to enter 'end' to stop the loop?
Scanner in = new Scanner(System.in);
int i = 0;
for (String s = in.next(); !s.equals("end"); i++)
{
System.out.println("The value of i is: " + i + " and you entered " + s);
}
How can I rewrite it, so that it conforms to accepted style?
(This is a question in a past exam paper.)
Well your string s is never changing, which can lead to an infinite loop. You probably wanted:
for (String s = in.next(); !s.equals("end"); s = in.next(), i++) {
...
}
Some (me included) might say that i++ shouldn't be in the increment section of this loop, since it's not directly relevant to the condition:
for (String s = in.next(); !s.equals("end"); s = in.next()) {
...
i++;
}
Is it due to a string being the main condition of the for loop rather than an int variable, meaning the for loop is infinite?
The original loop was indeed infinite (at least, after an initial input is entered and assuming "end" wasn't the first input). However, it's not for the reason you state. For-loops are most commonly written using integral loop control variables, but it's not always the case. For example, a common idiom for iterating through a linked list is:
for (Node node = list.head; node != null; node = node.next) {
...
}
The problem with your loop is that the string s is never changed, so it will never equal "end" unless that's the first input.
I would suggest separating the looping condition and the call to Scannner.next():
while (in.hasNext()) {
String s = in.next();
if (s.equals("end")) {
break;
}
System.out.println("The value of i is: " + i + " and you entered " + s);
i++;
}
I think this is much easier to understand than trying to squeeze everything into a for expression.
There are multiple problems with this code:
s never changes after the initial assignment, so it's an infinite loop.
Calling .next() could throw NoSuchElementException or IllegalStateException. Rather than catching these exceptions, I consider it more polite to check .hasNext() beforehand, since running out of input is a foreseeable rather than an exceptional situation. However, the alternative ask-for-forgiveness style could also be acceptable.
The for-loop header does not form a coherent story — it initializes s and tests s, but updates i.
In my opinion, System.out.format() would be slightly more preferable to System.out.println() with concatenation.
I would write it as:
Scanner in = new Scanner(System.in);
int i = 0;
String s;
while (in.hasNext() && !"end".equals(s = in.next())) {
System.out.format("The value of i is: %d and you entered %s\n", i++, s);
}
It might also be a nice user interface touch to tell the user that end is a magic word to terminate the loop (assuming it were modified to work as probably intended).
The common practice with for loops is that the counter variable is repeated in each term:
for(int i=...; i<... ; i++)
In the example above, the code mixes variables. Which is confusing to the reader and probably lead to the bug that the loop only terminates if you input end as the first value.
This loop is a bad idea, because you're taking setting s once from the user input and not in every iteration.
Thus, it will cause you to run infinite time in case s was filled with value different from "end".
You probably wanted something more like this:
for (String s; (s = in.nextLine()).equals("end"); i++)
{
System.out.println("The value of i is: " + i + " and you entered " + s);
}
This isn't a good idea because the string s may never equal "end". You'll probably want to check if the scanner has another string. Also, you only initialize the string to in.next() but you need to set s to the next string after each iteration of the loop.
while(in.hasNext()) {
String s = in.next();
if (s.equals("end")) {
break;
}
// ..
}
This approach is too bad.
The Given Code :-
Scanner in = new Scanner(System.in);
int i = 0;
for (String s = in.next(); !s.equals("end"); i++)
{
System.out.println("The value of i is: " + i + " and you entered " + s);
}
The 1st part of for loop only execute once in life.
String s = in.next() //Execute only once in life
The 2nd part of this for loop never be true , because the input console will never allow to enter the 2nd input.
!s.equals("end")//2nd part
This program will never allow to enter 2nd input from console, because the in.next() will execute only once.And the exit token for this loop is "end" which is not possible to enter after first input.
This type of loops should be implemented by while loop .
Scanner in = new Scanner(System.in);
while(in.hasNext()){
String yourdata=in.next();
if(yourdata.equals("end")){
//Stop the loop
}
//Do you code here
}
It bad practice because it's terminated only if next obtained token is "end". It does'n not consider situation like. e.g. end of input stream.
So when then stream ends and nowhere along "end" appeared you'l get s=null and NullPointerException at s.equals("end").
You can correct it e.g. by changing condition to in.hasNext() && !"end".equals(s).
Also s is never changing after it was initialized.
If the question is "why rewrite it" the answer is basically as others have pointed out, that it's currently an infinite loop, and also that it's not very readable as it stands. Personally I'd rewrite it as a while loop, which several others have already pointed out how to do, as it makes your intentions a little more clear than a for loop with a counter that's counting up to infinity. Someone unfamiliar with how the code is supposed to work could easily confuse an infinite increment to be an oversight by the programmer who wrote it.
The string s is never modified. The loop never ends. What about this :
Scanner in = new Scanner(System.in);
String s = "";
for (int i = 0 ; !s.equals("end"); i++) {
s = in.next();
System.out.println("The value of i is: " + i + " and you entered "
+ s);
}
Others have mentioned that the loop does not end because you are not changing the value of s, so the loop never ends. This may be what your professor intended, and it may not be. Bad code is bad practice, as a rule, but there are other reasons why this is bad practice.
What jumped out to me as being bad practice here, and what the professor could have intended, is the use of a for loop here. As my professor told me, "For loops are for when you know when you want the code to end, while loops are for when you don't know when you want the code to end." So if you have an iterable i such as this code:
for(i = 0; i<100; i++)
{
...
}
In this code, you know that you want to iterate i from 0 to 100. A while loop is what you would want to use in the situation your professor is discussing.
int counter;
while(*(str+counter))
counter++;
You have no idea when the loop is going to end, because you don't know how long the str is, but you know that sometime it will get to the null pointer, and the loop will terminate. This generally what is best practice.
So for the code your professor posted, you may want it to look like this:
Scanner in = new Scanner(System.in);
int i = 0;
while(!s.equals("end"))
{
i++;
String s = in.next();
System.out.println("The value of i is: " + i + " and you entered " + s);
}
It is not in good practice because of two things:
for loops are meant to iterate over a collection of data
a for loop consists of iterator initial state, loop condition and an iterating function that are related
The for statement just intermixes two different information (the stream and the counter). Even if it does work, it isn't good practice to do it.
I think this is bad practice, because there isn't any need for a for loop. In this case, I believe it's useless. It could be just this:
Scanner in = new Scanner(System.in);
String s = in.next();
if (!s.equals("end"))
{
System.out.println("You have enetered" + s);
}
See, there isn't any need for a loop. The loop you had was making things more complicated than they had to be. I was always think that things should be kept as simple as they can be unless they require complexity. For loops are only to be used when you have more than one action that you want the code to do. In the case above, only one thing is happening: the println statement, so there's no need for a loop. It's unnecesary...
Also, the loop never ends. So there's that too, but that's just faulty code. That's not why it's bad practice. It's bad practice because of the unnecesary use of a for loop. It's also faulty, because the code is wrong. So there are two different things going on with this code.
I would have just left a comment, but I don't have the rep yet.
What I haven't seen explained is WHY your s value is not changing.
In a typical for loop:
for(a=1; a<=10; a+=1) {body}
the initial phrase, 'a=1', is ONLY performed once as an initialization.
the third phrase, 'a+=1', is performed once at the end of every cycle, until…
the second phrase, 'a>=10', evaluates false.
so a for loop would be represented in 'psuedo-code' something like this:
a=1 // first phrase
:LoopLabel
{body}
a+=1 // third phrase
if (a<=10) // second phrase (boolean evaluation)
then goto LoopLabel
Likewise, your example, in similar pseudo-code might look like this:
Scanner in = new Scanner(System.in);
int i = 0;
String s = in.next()
:LoopLabel
{
System.out.println("The value of i is: " + i + " and you entered " + s);
}
++i
if (!s.equals("end"))
goto LoopLabel
So the reason your program was an infinite loop was the value of 's' was only set on entry to your loop and never changed during each loop execution, as most likely desired.
for (int i = 0; in.hasNext(); i++) {
String s = in.next();
if (s.equals("end")) {
break;
}
...
Endless loop, or no loop (when s is initially "end").
A number of responses above are correct to say that what you've written is an infinite loop. But I wanted to clarify why this is an infinite loop. The for loop you're using differs from the other form you may be thinking of:
String[] stringArray = { "1", "2", "3" };
for (String s : stringArray) {
System.out.println(s);
}
In that case, the variable s is initialized with the next value from your collection or array on each iteration. But that form of for loop works with collections and arrays and can't be used with iterators like the Scanner class.
The form of for loop you're using differs in that the initialization clause (where you have String s = in.next()) is called ONLY the first time through the loop. s is set that first time, then never changed.
You could re-write like this:
int i = 0;
for (String s = in.next(); !s.equals("end"); s = in.next()) {
System.out.println("The value of i is: " + i++ + " and you entered " + s);
}
But another bad thing in here is that there's no null or end check. It's conceivable if not likely that you would run out of strings before you found one that equaled "end". If that happened, then the for test clause (the middle one) would give you a NullPointerException when it tried to the call to the equals() method. THAT is definitely bad practice. I would probably re-write this like this:
int i = 0;
while (in.hasNext()) {
String s = in.next();
if (s.equals("end")) {
break;
}
System.out.println("The value of i is: " + i++ + " and you entered " + s);
}
If you really want a for loop instead of a while, it would be better to do this:
int i = 0;
for (Scanner in = new Scanner(System.in); in.hasNext();) {
String s = in.next();
if (s.equals("end")) {
break;
}
System.out.println("The value of i is: " + i++ + " and you entered " + s);
}
One last variation that preserves the test against the string in the test clause would look like this:
int i = 0;
String s = "";
for (Scanner in = new Scanner(System.in);
in.hasNext() && !s.equals("end");
s = in.next()) {
System.out.println("The value of i is: " + i++ + " and you entered " + s);
}
You could also add a null check in there before the s.equals("end") for total safety.
It is not a good practice maybe because you are comparing the String s with a String but you are not comparing the value, you are comparing the memory position of the s value.
This question already has answers here:
How to evaluate a math expression given in string form?
(26 answers)
Closed 9 years ago.
Good morning everyone, I'm a beginner student in java programming. So, direct to the point, I'm creating a program that can read and compile a .txt file with a click of a button.
I'm already done with the reading of the file. My problem is that my program doesn't compile the text from the first JTextArea and show the results to the second JTextArea.
I've been having this problem for four days now, I've been trying to change the code in any possible ways I can think of. Can someone enlighten me and tell me what's wrong with my code? It will surely help me a lot.
Many thanks to all.
#SuppressWarnings("IncompatibleEquals")
private void executeCodeActionPerformed(java.awt.event.ActionEvent evt) {
String loadi = "Load";
String add = "Add";
String subt = "Subt";
String mult = "Mult";
String div = "Div";
String input = "Input";
String print = "Print";
int number = 0;
String txt = textAreaCode.getText();
String split = " ";
String [] text = txt.split(split);
String word = text[0];
int num = Integer.getInteger(text[1]);
int result = num;
int result1 = 0;
Scanner scan = new Scanner(txt);
scan.nextLine();
for (int count=0;count<txt.length();count++ ) {
if (loadi.equalsIgnoreCase(word)){
result1 = num + number;
}
else if (add.equalsIgnoreCase(word)){
result1 = num + result;
}
else if (subt.equalsIgnoreCase(word)){
result1 = num - result;
}
else if (mult.equalsIgnoreCase(word)){
result1 = num * result;
}
else if (div.equalsIgnoreCase(word)){
result1 = num / result;
}
else if (print.equalsIgnoreCase(word)){
textAreaOutput.setText(String.valueOf(result1));
}
else if (input.equalsIgnoreCase(word)){
String nmbr = inputField.getText();
int nmr = Integer.parseInt(nmbr);
result1 = nmr + number;
}
}
I see a few errors in your code that might add up to not working at all. Here they are:
The variable word is never updated to the following tokens (it is set to text[0] at first then never changed). Same goes for num.
All operations act on variables num and result, then put the result into result1. So intermediate results are not carried from an operation to the next.
The "input" operation load current value from inputField, without waiting for the user to actually type something.
The main loop iterate until count reach the number of characters in the program; it should loop for the number of tokens instead.
Also, here are a few suggestions to make your code more ligible:
If you are beginning in Java, then get rid of the Scanner object, and keep only the "split on spaces" approach. I would not recommend this for real problems, but Scanner is somewhat complex to use correctly.
Wrap the splited words array into a List collection, then obtain an iterator from it. Here it is:
Iterator<String> words = Arrays.asList(txt.split("[ ]+")).iterator();
Then, write your loop as:
while (words.hasNext()) {
String command = words.next();
...
}
Move your operation mnemonics outside of the function, and mark them as final.
Read your operation arguments from inside each operation block; this is required because some operation do not receive arguments.
Well, I won't give you the code, as this is something you really have to do by yourself. Hope that helps. Good luck.