String concatenation in relation to JOptionPane - java

So, I haven't done any programming in a few months because I'm taking general prerequisite courses right now and I have a job, so now I'm a little rusty and I'd like to be up to par for when I take my next programming class in the Fall. Long story short, I'm trying to get back on track, so I'm making a silly practice program.
I made this program with all input and output done through the console using a Scanner, but then decided to go ahead and move over to JOptionPane as an interface. It was a pretty easy transition overall, but I'm just having a problem with the output at the very end. I'm trying to make all of the elements of an array into a nice, grammatically correct String for easy output in JOptionPane, but I can't really get my concatenation to work correctly. I realize that the output is not grammatically accurate when the amount of cats is one or two. I'll work on that after this, it's an easy fix.
Here is the code:
import javax.swing.JOptionPane;
public class JavaTestClass {
public static void main(String[] args)
{
//Get number of cats
int numOfCats = Integer.parseInt(JOptionPane.showInputDialog("How many cats do you have?"));
JOptionPane.showMessageDialog(null, "Oh, so you have " + numOfCats + " cats.\n", "Confirmation", JOptionPane.INFORMATION_MESSAGE);
//Get cat's names
String[] catNames = new String[numOfCats];
for(int i=0;i<numOfCats;i++)
{
catNames[i] = JOptionPane.showInputDialog("Enter the name of cat " + (i+1) + ": ");
}
//Output cat's names
String catNameList = null;
for(int i=0;i<numOfCats;i++)
{
if((i+1) == (numOfCats-1))
{
catNameList.concat(catNames[i] + ", and ");
}
else if ((i+1) == numOfCats)
{
catNameList.concat(catNames[i] + ".");
}
else
{
catNameList.concat(catNames[i] + ", ");
}
}
JOptionPane.showMessageDialog(null, "So your cat's names are: " + catNameList, "Names of cats", JOptionPane.INFORMATION_MESSAGE);
}
}
Sorry about the spacing. It didn't really come out the way I wanted it to on here, but I don't have all day the indent all of the lines just for the sake of the post. Anyway, it should be relatively obvious, even without my long description above what I'm trying to do. Any help would be much appreciated. Thanks in advance.

Strings are immutable. Every operation that modifies a String returns a new one.
So it should be:
catNameList = catNameList.concat(catNames[i] + ", and ");
Also don't initialize it to null.
String catNameList = "";

Reference the String concat javadoc. Concat method is returning the result of concatenation.

Related

How do I initialize a result variable?

I need to make the result variable so that it is concatenated with my other strings to print my result and I tried multiple ways that are not working.
I have included my set of strings and first if statement to give an idea of my project.
My project rubric states "Initialize 'result' as a single string using concatenation. This string will contain the event type, party size, as as meal and preparation suggestions. Prints the result variable to the console." It also says " 'result' is a string that will be printed to the console.
import java.util.Scanner;
public class whatToEat {
public static void main (String[] args) {
int partySize;
String eventType;
System.out.println("Is your event Casual, Semi-Formal, or Formal?");
Scanner sc = new Scanner(System.in);
eventType = sc.next();
System.out.println("How many people will your event have?");
partySize = sc.nextInt();
if (eventType.equals("Casual") && partySize == 1) {
System.out.println("Since you're hosting a casual event for "
+ partySize +
" person, you should serve sandwiches prepared in the mircowave. ");
Because it says that 'result' is a string that you print in console, I suggest you saving your information in a String first:
String result = "";
Then:
result = "Since you're hosting a casual event for "
+ partySize +
" person, you should serve sandwiches prepared in the mircowave."
Finally:
System.out.println(result);

Why are my while loops not working and ignoring code?

So, what I am trying to do is get my while loops to do different things based on different key words. What I want is that when I type yes, I want it to exit the program, when I type no, for it to print a new song, and if there is a spelling error, for a message to pop up and allow the user to re enter yes or no to print the same song. I have 4 or 5 songs that I want to print out based on these three commands. In my last while loop. I want it to repeat the song every time the user types continue, and for it to end when the user types yes. I want the same thing to happen where it prompts the user to type again if there is a spelling error. This worked before, and now it does not. When I make a spelling error, it prompts me to enter again but will not print out the song in that loop. It will send me to the last while loop, ignoring all code in between. That last loop will only recognize spelling errors and yes, not continue, even though it did before.
Here is one song loop and my last loop:
import java.io.*;
import java.util.*;
public class FullNurseryRhymes
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
String aBCs, neverEnds, frogs, frogs2, monkeys, hdd, hdd2;
NurseryRhymes rhymes = new NurseryRhymes();
{
System.out.println("Is the baby asleep? yes\\no");
frogs=input.next();
int byeFrog = 2;
for(int i = 3; i >= 1; i--)
{
if (frogs.equalsIgnoreCase("no"))
{
System.out.print(i + " " + rhymes.getFrogs());
System.out.println(" " + byeFrog + " " + rhymes.getFrogs2());
byeFrog -= 1;
}
else if (frogs.equalsIgnoreCase("yes"))
{
System.out.println("The baby is asleep");
System.exit(0);
}
while(!frogs.equalsIgnoreCase("no"))
{
System.out.println("Non requested input, please retry.");
System.out.println("\nIs the baby asleep? continue\\yes");
frogs = input.next();
if(frogs.equalsIgnoreCase("no"))
{
System.out.print(i + " " + rhymes.getFrogs());
System.out.println(" " + byeFrog + " " + rhymes.getFrogs2());
byeFrog -= 1;
}
else if (frogs.equalsIgnoreCase("yes"))
{
System.out.println("The baby is asleep");
System.exit(0);
}
}
}
}
//last loop
{
System.out.println("Is the baby asleep? continue\\yes");
neverEnds = input.next();
while(neverEnds.equalsIgnoreCase("continue"))
{
System.out.println(rhymes.getNeverEnds());
System.out.println("Is the baby asleep? continue\\yes");
neverEnds = input.next();
}
if(neverEnds.equalsIgnoreCase("yes"))
{
System.out.println("The baby is asleep");
System.exit(0);
}
while(!neverEnds.equalsIgnoreCase("continue")||!neverEnds.equalsIgnoreCase("yes"))
{
System.out.println("Non requested input, please retry");
System.out.println("\nIs the baby asleep? continue\\yes");
neverEnds = input.next();
while (neverEnds.equalsIgnoreCase("continue"))
{
System.out.println(rhymes.getNeverEnds());
System.out.println("Is the baby asleep? continue\\yes");
neverEnds = input.next();
if(neverEnds.equalsIgnoreCase("yes"))
{
System.out.println("The baby is asleep");
System.exit(0);
}
}
if (neverEnds.equalsIgnoreCase("yes"))
{
System.out.println("The baby is asleep");
System.exit(0);
}
}
}
Based on the comments, it sounds like there is too much (potentially) relevant code for us to plough through.
There are three ways you could proceed with this.
You could learn how to use the debugger in your IDE. Use breakpoints and single stepping, and figure out where your mistakes are.
You could comment out parts of the code to track down where the problems are. That may also help you to create an MCVE
You could simplify the code by refactoring common / repetitious code into methods. For instance the "last loop" section is incredibly repetitious.
On the last point, it might actually be less work to throw this code away and start again ... after figuring out what common code can be implemented as methods.
Your question is a bit long. We don't need a story, just an explanation of your problem and a BIT of code, not your whole class. Try putting your while loop on the outside. Have a string outside the while loop called babySleep that starts as "no". Then, while(babySleep.equals("no") execute your code. Then at the end, check if the baby is a sleep, if he is, move on, if not, the while loop will re-execute. Also, instead of .equals try .equalsIgnoreCase so the user can type in "Yes" or "yES" etc.

Int and String array in Java

public class CHECK {
public CHECK(){
String []wrkrs = {"Денис", "Саша", "Наталья", "Анатолий", "Юра", "Коля", "Катя", "Дима", "Антон","Тамара"};
int [] wrkrsPhone = {22626,22627,22628,22629,22630,22631,22632,22633,22634,22635};
String a = JOptionPane.showInputDialog(null, "Hello,friend!Do you wanna know, is that guy at work?Enter name:");
if(Arrays.asList(wrkrs).contains(a)){
JOptionPane.showMessageDialog(null, "That guy is at work!");
JOptionPane.showMessageDialog(null, "calling " + wrkrsPhone[wrkrsPhone.toString().indexOf(a)]);
}else{
JOptionPane.showMessageDialog(null, "Такого сотрудника нет!");
}
}
I have two arrays, which contain ints and strings. As you can see, I want to add the number of elements in the string array (for example, wrkrs number 3) to the int array, called wrkrs phone. How can i do it? I tried IndexOf, but it doesn't work.
The output, i want is something like:
Enter name:
Юра
That guy is at work!
Calling Юра + wrkrsPhone(Юра).
A better solution would be to have a Worker class that would contain the worker's name and their phone number.
Then you can use a HashMap<String,Worker> instead of your arrays to store the data.
This makes the search more efficient :
Map<String,Worker> workersMap = new HashMap<>();
workersMap.put ("Денис", new Worker ("Денис", 22626));
...
Worker worker = workersMap.get(a);
if (worker != null) {
call (worker.getPhone()); // or do whatever you want to do with the phone number
}
This is more efficient than Arrays.asList(wrkrs).contains(a), which performs linear search on the List.
...
List list = Arrays.asList(wrkrs);
if(list.contains(a)){
JOptionPane.showMessageDialog(null, "That guy is at work!");
JOptionPane.showMessageDialog(null, "calling " + wrkrsPhone[list.indexOf(a)]);
}
...
U better use a Map or extract a class Contact which have name and phone property but i think this is what u looking for :)

Array Response Output

So I'm working on a little fun project that'll ask you a series of questions, and depending on what you respond with, give a specific output. Well, I've gotten all the way to the first output answer, but I can't figure out what to do.
Here's the source code. I can't seem to get the code input into the question correctly.
import java.util.Scanner;
public class Questionaire {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String answers[] = new String[1];
String response[] = new String[5];
System.out.println (" Good Evening, Devin. How are you today? ");
answers [0] = in.nextLine();
response [0] = "I'm good";
response [1] = "I'm okay";
response [2] = "I'm alright";
response [3] = "I'm great";
response [4] = "good";
if (answers[0].equals (response.length)) {
System.out.println (" That's awesome! What would you like to talk about?" );
}
else {
System.out.println( " Oh, well then.." );
}
}
}
OUTPUT:
Good Evening, Devin. How are you today?
I'm okay
Oh, well then..
Basically, I'm trying to get the if statement to take the whatever the user inputs into the answer[0] array, and if they respond with any of the responses in the response array, they get the first system.out, but whenever I type in any of them, I keep getting the else output. Can anyone tell me what I'm doing wrong?
You want to find the match of the user input from response array.
if (answers[0].equals (response.length)) will never evaluate to true unless the user input is 5 because you are comparing user input with response.length which value is 5. You need to loop from each element in response
or simply change
if (answers[0].equals (response.length))
to
if(Arrays.asList(response).contains(answer[0]))
you will need to add import java.util.Arrays
answers[0].equals (response.length)
This code will be false as answer[0] is string matching with response.length which is 5. if you want to check the answer with the response exist then code need to be modify as below
Boolean checkresponse=false;
for(int i=0;i<response.length;i++){
if (answers[0].equalsIgnoreCase(response[i])) {
System.out.println (" That's awesome! What would you like to talk about?" );
checkresponse=true;
break;
}
}
if(checkresponse==false)
System.out.println( " Oh, well then.." );

Why is this loop bad practice? [closed]

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.

Categories