this accesses an arraylist and there is code that does this same thing already and works fine
is there something wrong with my code here? or a way I can achieve this differently?
System.out.println("Enter cruise ship name: ");
String newCruiseShipName = newCruiseInfo.nextLine();
for(Ship eachShip:shipList) {
if (eachShip.getShipName().equalsIgnoreCase(newCruiseName)){
}
else{
System.out.println("Cruise ship not in service.");
System.out.println("Exiting add cruise");
returnMenu();
}
}
It looks like you are exiting in the first attempt if you cannot find a match based on "Exiting add cruise" line. May be you should also add returnMenu function, so that people can infer what your intention is.
anyways, if this is the case may be you should try something like this:
System.out.println("Enter cruise ship name: ");
String newCruiseShipName = newCruiseInfo.nextLine();
boolean found = false;
for(Ship eachShip:shipList) {
if (eachShip.getShipName().equalsIgnoreCase(newCruiseName)){
found = true;
break;
}
}
if (!found) {
System.out.println("Cruise ship not in service.");
System.out.println("Exiting add cruise");
returnMenu();
}
other possibilities are there can be whitespace in compared strings, or problems with getShipName etc.. may be trim works.
note: could not add comments due to reputation thing
System.out.println("Enter cruise ship name: ");
String newCruiseShipName = newCruiseInfo.nextLine();
if(!newCruiseShipName.contentEquals("")) {
for(Ship eachShip: shipList) {
if(eachShip.getInService()==true||eachShip.getShipName().equalsIgnoreCase(newCruiseShipName)) {
}
for(Cruise eachCruise:cruiseList) {
if(eachCruise.getCruiseShipName().equalsIgnoreCase(newCruiseShipName)) {
System.out.println("Cruise Ship already assigned.");
System.out.println("Exiting add cruise");
returnMenu();
}break;
}
}
}
it was nesting problem I was reducing my array size due to the order the for statements were in previously. I nested them and it solved my problem
Related
I finished a coding assignment for class and was given feedback by a friend that the nested ifs might look a lot better as switch statements
I tried converting it into switches but it seems to be about the same if not more work.
//this is the absolute basic frame of the code created
if(arg){
//code
if(arg){
//code
if(arg){
//code
}
else if(arg){
//code
}
}
else if(arg){
//code
}
else if(arg){
//code
}
Would it be easier and better looking if it was converted to switch statements or would it be the same if not worse mess?
EDIT:
for ghostcat, this is the full section of code that I simplified for the question
while(loop == true){
System.out.print("Do you have more students to enter (Y for yes, N for no): ");
yn = input.nextLine();
if(yn.equals("Y") || yn.equals("y")) {
System.out.print("Undergraduate or Graduate? (U for undergraduate, G for graduate): ");
ug = input.nextLine();
if(ug.equals("U") || ug.equals("u")) {
System.out.print("Student name: ");
NAME = input.nextLine();
System.out.print("Student ID: ");
ID = input.nextInt();
System.out.print("Student GPA: ");
GPA = input.nextFloat();
System.out.print("Is student a transfer student? (Y for yes, N for no): ");
input.nextLine();
transfer = input.nextLine();
if(transfer.equals("Y") || transfer.equals("y")) {
ts = true;
students.add(new UndergradStudent(NAME, ID, GPA, ts));
}
else if(transfer.equals("N") || transfer.equals("n")) {
ts = false;
students.add(new UndergradStudent(NAME, ID, GPA, ts));
}
}
else if(ug.equals("G") || ug.equals("g")) {
System.out.print("Student name: ");
NAME = input.nextLine();
System.out.print("Student ID: ");
ID = input.nextInt();
System.out.print("Student GPA: ");
GPA = input.nextFloat();
System.out.print("What college did the student graduate from: ");
input.nextLine();
college = input.nextLine();
students.add(new GradStudent(NAME, ID, GPA, college));
}
}
else if(yn.equals("N") || yn.equals("n")) {
loop = false;
}
}
From the clean code perspective, both options (if/else or switches) aren't preferable. But solving that without more context isn't possible.
First of all, the real problem is that your method that sits around your example code has to look at so many parameters.
The ideal number of arguments for a function is
zero (niladic). Next comes one (monadic), followed
closely by two (dyadic). Three arguments (triadic)
should be avoided where possible. More than three
(polyadic) requires very special justification—and
then shouldn’t be used anyway.
In other words: you strive to write methods that have as few arguments as possible. Because each argument potentially adds the need for such an
if or switch contrast.
When several switch statement would work for you, one potential path might be turn to polymorphism. The "correct" way of switching in OOP is to have different classes, and use runtime polymorphism to determine which method actually gets invoked at runtime.
Given the added context:
ug = input.nextLine();
if(ug.equals("U") || ug.equals("u")) {
...
The clean code solution could go like this:
ug = input.nextLine();
if (ug.equalsIgnoreCase("u")) {
fetchValuesForUndergraduate();
}
That is it! Your real problem with your current code is that it does so many things in one spot. The "clean code" solution to that is to move code into distinct helper methods, that have nice telling names, and that do much less.
Could be argued either way -- I wouldn't worry about it too much if it works for you like this. Switch statements would make the code look something like
switch(var1)
case 1:
{
//code
switch(var2)
case 1:
{
//code
}
switch(var3)
case 1:
{
//code
}
case 2:
{
//code
}
}
case 2:
{
//code
}
case 2: {
//code
}
You could definitely make it work either way
This is my first post here, so I decided to browse around various posts here in order to try and get a feel for how questions should be posted.
Hence, if I mess up please let me know so I can fix my post accordingly ASAP.
So here is my problem:
I started learning Java today and I'm working on just getting a feel for how everything works. I have the code below set to tell if kids are good or bad and display corresponding replays.
Good kids get candy, bad kids get none. I want to be able to limit the users choices to good or bad and have their answer change the Boolean to true or false to run the right if statement.
I saw a Math.random way of doing it but when I tried it I got more problems.
Thank you for your time.
The following is my code:
import java.util.Scanner;
public class Main {
public static void main (String args[]) {
//take user info
Scanner sc = new Scanner(System.in);
int candy = 12;
int kids = 4;
int bad = 1;
String a = sc.nextLine();
int answer = candy / kids;
String answer2 = "No Candy";
boolean good = false;
System.out.println(a);
//closeing the scanner
sc.close();
if(bad == 1) {
System.out.println(answer2);
} else {
if(bad == 2)
good = true;
System.out.println(answer);
}
if(good == true) {
System.out.println("Good Job");
} else {
System.out.println("Try again tomorrow!");
}
}
}
For one, it is not necessary to end the scanner before your code ends. You can leave it around, closing it is not necessary. (Unless your IDE forces you to , then yes, you should, but close it at the end just in case. I have Eclipse, so my code still runs without a glitch.)
Another comment is, just for the sake of aesthetics you should concatenate some kind of string on to the end of answer, so the reader understands what the variable means.
One more thing. I often find it helpful to name my scanner something a little more intuitive, such as input. Because after all, that's what it is. (I'm only commenting a lot about your code because you are just beginning to learn things, so you should get into good habits early.)
What you can do in this situation is convert your string inputs to booleans, by using boolean userInput = Boolean.parseBoolean(answer). Then, depending on the input the user gives by using an if statement, they can control the flow of the code.
I cleaned up your code a little bit, if you don't mind.
import java.util.Scanner;
public class lol {
public static void main (String args[]){
//take user info
Scanner sc = new Scanner(System.in);
int candy = 12;
int kids = 4;
int answer = candy / kids;
String answer2 = "No Candy";
System.out.println("Are youkids good or bad?");
System.out.println("[1] Good = true");
System.out.println("[2] Bad = false");
String a = sc.nextLine();
boolean userInput = Boolean.parseBoolean(a);
if(userInput== false){
System.out.println(answer2);
System.out.println("Try again tomorrow!");
}
else{
System.out.println("Good Job");
System.out.println("You get" +answer+"pieces.");
}
}
}
Seeing as you're just starting out, I'll try and keep it simple. There are plenty of ways to force your reader to say either "good" or "bad" that are better than below, but they require loops (which I assume you haven't touched yet).
Consider the following:
boolean good = false;
if (a.equals("good")) { // they said good
good = true;
} else if (a.equals("bad")) { // they said bad
good = false;
} else { // they said neither
System.out.println("You didn't say a correct word!");
}
You first specify that you have a boolean good (which you can either give a default value as above, or nothing). Then, depending on the user's input, you can set the boolean to be whatever is appropriate.
The reasoning behind having to declare the boolean good above the if statements has to do with the scope of a variable. If your book/teacher hasn't explained what that is, you should look it up now. The TL;DR is that if you only first declare your variable inside the if statements, then it will disappear as soon as you leave the if statements. You can see how in this case that would basically defeat the purpose of the if statements entirely.
You can limit the input by enclosing it in a loop.
List<String> accepted = new ArrayList<String>();
accepted.add("good");
accepted.add("bad");
System.out.println("Good or bad?");
String input = sc.nextLine();
while(!accepted.contains(input)) {
System.out.println("Invalid query '" + input + "'. Try again.");
input = sc.nextLine();
}
The code you have, well I don't know exactly what it's trying to do. It doesn't look functional at all. So where this fits in I'm not 100% sure.
package test;
import java.util.Scanner;
public class app {
public static void main (String args[]){
//take user info
Scanner sc = new Scanner(System.in);
String a="?";
while(!a.equals("good") && !a.equals("bad")){
System.out.println("Was the kid good or bad ?");
a = sc.nextLine();
}
boolean wasKidGood = a.equals("good");
String result = (wasKidGood ? "Good kid gets candy" : "No candy for bad kid");
System.out.println(result);
sc.close();
}
}
Hello, I wrote something, that will help you grasp a while loop and a ternary operator (alternative version of if loop). You also need to pay attention as to where you are allowed to use == and where you should use the equals() method. Regards
I apologize since I'm always asking n00b questions but I could really use the help. Anyways I'm trying to import words of only a certain length from the dictionary into the variable words which is a hash set. When I run my program and try to print my words aka the hashset of strings. I get nothing in the console and the program does not stop running. How can I fix this? P.S. Also I know part of the JOptionPane code got cut enough, but it's error free and you get the point. Thanks!
Alex
public void inputWords()
{
try
{
frame = new JFrame("Hangman");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300,300);
frame.setVisible(true);
input = new Scanner(new FileInputStream("dictionary.txt"));
wordLength = Integer.parseInt( JOptionPane.showInputDialog(null,
String importedWords = input.nextLine();
while(stillHasWords==true)
{
if(importedWords.length()==wordLength)
{
words.add(importedWords);
}
else
{
}
}
}
catch(FileNotFoundException f)
{
System.out.println("File does not exist.");
System.exit(0);
}
catch(NoSuchElementException q)
{
stillHasWords=false;
}
public static void main(String[] args)
{
EvilHangman j = new EvilHangman();
System.out.println(stillHasWords);
j.inputWords();
System.out.println(words + " ");
}
}
Regarding:
while(stillHasWords==true)
{
if(importedWords.length()==wordLength)
{
words.add(importedWords);
}
else
{
}
}
I'm not sure what words.add(importedWords) does, but most important to the problem you're experiencing,
Question: Where do you change stillHasWords inside of your loop?
Answer: You don't, and so the loop will never end.
I suggest that first you fix this while loop
As an aside, it's better to avoid using == true in a while loop and instead simply test the boolean:
while (stillHasWords) {
// add a word
// change stillHasWords to false if we've run out of words
}
Edit
You state:
Still has words changes in the catch(NoSuchElementException q)
There is no catch block posted inside of the while loop, and so I submit that still the stillHasWords value cannot change inside of the while loop based on code you've posted so far. If you have more pertinent code, then you'll of course want to show it, else we're reduced to guessing what might be wrong with code not shown. Best to post an SSCCE
For some reason this program won't loop correctly, its supposed to wait for user input, then decide on weather or not it should loop.Instead, it skips the user input part, goes straight to deciding it needs to loop, then allows user input to be taken into account.
For example, it asks for a number, i type 5, then it says "would you like to go again?" "Please use either yes or no, case sensitive!" "would you like to go again?".After it has run that it will accept user input,I thought about using a sleep(2000),but I don't want it to just skip over and assume the user didn't put anything in.I am stumped! keep in mind this is my second day working with java. I am a newbie and this is only the 3rd program i am working on. I had this issue on another program but i managed to fix it just fine.However this one seems to not want to work in the same fashion despite the fact that i did framework exactly the same.
do {
System.out.println("would you like to go again?");
if (input.hasNextLine()){
again = input.nextLine();
if (again.equals("yes")){
yon2 = false;
dateconverter.main(args);
}else if (again.equals("no")){
System.out.println("good bye");
Thread.sleep(4000);
System.exit(0);
}else{
yon2 = true;
System.out.println("Please use either yes or no. caps sensative!");
}
}
} while (!(yon2 = false));
Java loops correctly. However, yon2 = false is an assignment and not a comparison.
Thus the loop is equivalent to:
do {
// ..
yon2 = false; // assign! :(
} while (!yon2);
So Java is doing exactly what it was told to do.
Now, with that out of the way, I believe the other issue is being confused about the variables usage. Consider this:
boolean askAgain = true;
do {
System.out.println("would you like to go again?");
if (input.hasNextLine()){
String again = input.nextLine();
if (again.equals("yes")){
// Finally done asking
askAgain = false;
dateconverter.main(args);
} else if (again.equals("no")){
System.out.println("good bye");
Thread.sleep(4000);
System.exit(0);
} else {
// If we're here, we still need to ask again
System.out.println("Please use either yes or no. caps sensative!");
}
} else {
// no more lines! do something sensible
System.exit(0);
}
// Loop while we need to ask again!
// Note that the negative is removed
} while (askAgain);
However, taking a second to refactor this allows for something easier to read later and avoids the dealing with a flag entirely:
boolean promptKeepPlaying (Scanner input) {
while (input.hasNextLine()){
System.out.println("would you like to go again?");
String again = input.nextLine();
if (again.equalsIgnoreCase("yes")){
return true;
} else if (again.equalsIgnoreCase("no")){
return false;
} else {
System.out.println("Please use either yes or no.");
}
}
// no more lines
return false;
}
// somewhere else
if (promptKeepPlaying(input)) {
// restart game
dateconverter.main(args);
} else {
// exit game
System.out.println("good bye");
Thread.sleep(4000);
System.exit(0);
}
You've got a bug in your program. You've accidentally written an assignment instead of an equality test.
However, the real lesson here is that you should not be writing cumbersome == and != tests involving booleans. There are simpler, more elegant and less error prone ways of writing the tests. For example, assuming that condition is a boolean.
condition == true is the same as condition
condition == false is the same as !condition
!(condition == false) is the same as condition
condition == condition2 is the same as !(condition ^ condition2)1.
There is a real benefit in taking the time to write your code simply and elegantly.
1 - This is an example where == is more elegant ... but the ^ exclusive-or operator avoids the accidental assignment trap.
I am working on a loan calculator with data validation. I have written everything and good to go. The only thing I cannot figure out is how to write a while loop in where the user is asked "Continue y/n?: " and then have the program continue ONLY when the user types y/Y and the program ENDS ONLY when the user types n/N, any other input should give an error message like "Invalid, you can only enter Y or N". So if the user enters "x" it should display the error message.
I have tried else if clauses, I have also tried to validate data with the methods I used in the rest of the program but I simply don't know how to validate strings. I can only do it with primitive data types.
This is the only way i know how to write the loop as of now, the problem is it will simply end the program with anything but a Y.
an option for the assignment is to use JOptionPane but I do not know how to incorporate that into the while loop and have it display a yes and a no button.
String choice = "y";
while (choice.equalsIgnoreCase("y")) {
// code here
System.out.print("Continue? (y/n): ");
choice = sc.next();
}
}
while(true) {
//Do something
String choice;
boolean validChoice = false;
boolean breakLoop = false;
while(!validChoice) {
System.out.print("Stay in loop(Y/N)?");
choice = sc.next();
if(choice.equalsIgnoreCase("Y")) {
validChoice = true;
}
if(choice.equalsIgnoreCase("N")) {
validChoice = true;
breakLoop = true;
}
if(!validChoice) {
System.out.print("Error! Pick only Y/N");
}
}
if(breakLoop) {
break;
}
//Do something
}
Essentially, you want two loops: one doing the work and the other one inside prompting for user validation.
boolean isContinuing = true;
while (isContinuing) {
// do work
boolean inputIsInvalid = true;
while (inputIsInvalid) {
System.out.print("Continue? (y/n): ");
String choice = sc.next();
if ("y".equalsIgnoreCase(choice)) {
inputIsInvalid = false;
}
else if ("n".equalsIgnoreCase(choice)) {
inputIsInvalid = false;
isContinuing = false;
}
else {
System.err.print("Error: Only valid answers are Y/N.");
}
}
}
Node: I am using boolean variables instead of break statements, it makes the code more straightfoward and readable.
What about
while(true) {
// do something
// get user input (Y or N)
if(input.equals("Y") {
continue;
} else if(input.equals("N")) {
break;
} else {
System.out.println("entered option not valid, please use Y or N");
}
}
I find the best way is to introduce an explaining method.
while (userWantsToContinue()) {
// do another round
}
And ideally you would even make this a method on an interface that is a UI abstraction :
while (user.wantsToContinue()) {
// do another round
}
decoupling the behavior from the UI implementation.