How to make a string compare non case sensitive? - java

I am trying to write a code for one of those programs that responds according to your answers. I want to make it so that some of the variables are not case sensitive. For example if my variable x is equal to "Me" I want it to also equal "me". Is that possible?
Here is my code so far:
import java.util.Scanner;
class Tutorial {
public static void main (String args[]){
System.out.println("Who goes there?");
Scanner N = new Scanner(System.in);
String name = N.next();
if (name.equals("me") || name.equals("Me")){
System.out.println("Well, good for you smartass.");
System.exit(1);
}else System.out.printf("Nice to meet you, %s.%n", name);
System.out.print("How are you doing?");
Scanner d1 = new Scanner(System.in);
String doing = d1.next();
switch(doing){
case "good": System.out.println("that is nice to hear.");
case "Well": System.out.println("that is nice to hear.");
case "bad" : System.out.println("That's ruff mate.");
case "Awesome" : System.out.println("Nice");
case "Terrible" : System.out.println("Sucks for you");
}
}
}
I don't want to have to make 2 cases for each answer where one is uppercase and the other is lower case.
Slightly off topic question. How do I close the resource leaks for the scanner?

Worth mentioning String#toLowerCase:
name.toLowerCase().equals("me");
Or simply use String#equalsIgnoreCase:
name.equalsIgnoreCase("me");

I think there is no way to do no case sensitive variable. From your code you want to threat answers in strings into a switch and do some action that depends on answer.
I think the best way is to take user input a use on that string upper method from string class.
YourString = YourString.toUpperCase();

Related

Accessing Scanner objects from subclass in a superclass?

I am a very new, relatively inexperienced Java programmer. The project I am working is just a test of my current skills, and my goal is to write as efficient a program as possible.
In essence, I have three classes: A, B, and C. B extends A and C extends B, but I want a Scanner object in C to be used in a switch statement (part of a larger method) in A.
The reason I want this is because I do not want to overload the method in A (copy-pasting the same code with different parameters is not ideal), and I do not want to combine all of my classes into one (the code is simple enough to do this, but I want to test my knowledge of object creation and use).
Here is some of the code:
import java.time.LocalDateTime;
public class WatchFace {
// MASTER TIME
LocalDateTime dateTimeObject = LocalDateTime.now();
int hour = dateTimeObject.getHour();
int minute = dateTimeObject.getMinute();
// WATCH FACE METHOD
public void watchFaceMethod() {
// Code I'd like to utilize; this is my question for StackOverflow
// switch (userInput) {
// case 1:
// // Intentionally do nothing
// break;
//
// case 2:
// // Change minute and hour to some values obtained by timezone stuff
// break;
//
// case 3:
// // Change both minute and hour to -1
// break;
// }
// Basically, the rest of this code just prints something different to the Windows CLI depending on the
// hour and minute variables' current values (i.e. beyond the intended switch statement).
}
}
import java.time.format.DateTimeFormatter;
public class Watch extends WatchFace {
static void watchMethod() {
// Code printing some Strings is here.
WatchFace watchFaceObject = new WatchFace();
watchFaceObject.watchFaceMethod();
// Code printing some more Strings is here.
DateTimeFormatter dateTimeFormat = DateTimeFormatter.ofPattern("hh:mm a 'on' EEEE, MMMM dd, yyyy");
String dateTimeDisplay = watchFaceObject.dateTimeObject.format(dateTimeFormat);
System.out.print("\nIt is currently " + dateTimeDisplay + "\n");
if (watchFaceObject.hour == 11 && watchFaceObject.minute == 11) {
System.out.println("Make a wish!");
}
}
}
import java.util.Scanner;
public class InteractiveWatch extends Watch {
public static void main(String[] args) {
// WATCH OBJECT
Watch watchObject = new Watch();
// STARTUP
System.out.println("Welcome to Interactive Watch!\n");
System.out.println("What would you like to do?");
System.out.println("[1] See local time.");
System.out.println("[2] See local time in a particular place.");
System.out.println("[3] See something special.\n");
Scanner scannerObject = new Scanner(System.in);
// INPUT
boolean loopBreak = true;
while (loopBreak) {
loopBreak = false; // loopBreak set to false
String userInput = scannerObject.nextLine(); // User inputs some string
switch(userInput) {
case "1":
watchObject.watchMethod(); // watchFaceMethod ideally detects userInput == 1
break;
case "2":
watchObject.watchMethod(); // watchFaceMethod ideally detects userInput == 2
break;
case "3":
watchObject.watchMethod(); // watchFaceMethod ideally detects userInput == 3
break;
default:
loopBreak = true; // loopBreak set to true; while loop reinitiates
System.out.println("\nPlease enter a valid key.\n");
break;
}
}
}
}
I learned everything I have from w3schools' Java course, but I still have much more to learn. Let me know if what I want is even possible, or anything else that would make this code more efficient. Thank you!
The short answer is no. You cannot access an object belonging to a subtype.
The long answer: The watchFaceMethod does not know that the call came from an InteractiveWatch. Think about it this way; what if we made a new class OtherWatch, which also extends Watch. Suppose OtherWatch does not have a Scanner object. Now what is watchFaceMethod() going to do when it's told to invoke a method of your Scanner object? It can't do anything, because the Scanner object does not exist. I'm not sure I understand why you're trying to access the Scanner object in watchFaceMethod in the first place, though. You already got the input from the user. You don't want to get more input, so you really want access to the string that the nextLine() method returned. I would approach this by simply passing the string up the hierarchy as a parameter to the watchMethod() and watchFaceMethod() methods. It's not "inefficient" to pass parameters to another method. You would end up with methods something like these:
public void watchMethod(String userInput) {
...
WatchFace watchFaceObject = new WatchFace();
watchFaceObject.watchFaceMethod(userInput);
...
}
and
public void watchFaceMethod(String userInput) {
switch (userInput) {
case "1":
...
break;
case "2":
...
break;
case "3":
...
break;
}
...
}
Another option is to make userInput a public, static variable, and then just reference it from watchFaceMethod(), but I would advise against this as you could quickly lose track of what methods are accessing and mutating that variable.
One more little thing I noticed about your code; you use \n for your line separators, which produces a linefeed character. This is the standard line separator on UNIX systems, but Windows uses a carriage return together with a linefeed, and OSX uses just the carriage return, so if you want your returns to show up on all platforms, you should use %n, which produces the correct platform-specific line separator.
No, it's not possible.
superclass does not have access to members of its subclasses in Java. But the subclass has access to all non-private members of its superclass.

What's a better or more standard way to perform this function?

I am a java beginner, and in this particular problem I practiced making a program that converts any given string to lowercase string. Is there a a better way to achieve this goal in java (in terms of design)?
Also, how does the "else" (after "else if") catches or waits for me to make an input. Somehow that part does not make sense to me, even though I achieved what I wanted. How is the value of "ans" from input transferred to the entire loop and used until the loop is closed?
After many attempts and failures, I used a separate method for the conversion part. My second question is a bit too complicated to be researched.
import static java.lang.System.out;
import java.util.Scanner;
public class MyClass {
public static Scanner s = new Scanner(System.in);
public static String ans;
public static void main(String args[]) {
Conversion();
do {
ans = new String(s.nextLine());
if (ans.equalsIgnoreCase("Y")) {
Conversion();
} else if (ans.equalsIgnoreCase("N")) {
out.println("Thank you for using this program!");
break;
} else {
out.println("Invalid entry!");
out.println("Would you like to convert another string?\n(Please type 'Y' for yes, or 'N' for no.)");
}
} while (ans != "N");
}//END MAIN
public static void Conversion() {
out.println("Please enter string to be converted to lowercase: ");
String str = new String(s.nextLine());
out.println("Your new string is: " + str.toLowerCase());
out.println("Would you like to convert another string? (Y/N)");
}
}
I notice a few issues; Conversion looks like a class-name (Java naming convention would be conversion) and ans != "N" is using == instead of .equals - and wouldn't ignore case (!ans.equalsIgnoreCase("N")). Globals (e.g. static) are bad (pass the Scanner to the methods that need it), and the static import just makes the code more difficult to reason about (in my opinion). Your current loop doesn't really follow a conventional form, I would extract the prompt and loop for "another" conversion to a new method and if you must print a thank you I'd do so after the "main loop". Something like,
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
do {
conversion(sc);
} while (another(sc));
System.out.println("Thank you for using this program!");
}
public static void conversion(Scanner s) {
System.out.println("Please enter string to be converted to lowercase: ");
System.out.printf("Your new string is: %s%n", s.nextLine().toLowerCase());
}
public static boolean another(Scanner s) {
while (true) {
System.out.println("Would you like to convert another string? (Y/N)");
String ans = s.nextLine();
if (ans.equalsIgnoreCase("Y")) {
return true;
} else if (ans.equalsIgnoreCase("N")) {
return false;
}
System.out.println("Invalid entry!");
System.out.println("(Please type 'Y' for yes, or 'N' for no.)");
}
}
Answering your first question:
There are many design patterns and practices so many people can argue what I would recommend you to do. It's basically the same for all programming languages. Let's take your function "Conversion". The name itself says that you use it to convert stuff. Not to display, not to prompt - to convert. In this case, the only actual thing it should do is to convert upperCase to lowercase. In fact, you might want to specify what type of conversion it has in the name of the function (convertToLowerCase?). In fact, in Java, we use lowerCamelCase for all function names and UpperCamelCase for classes.
If you accept my previous suggestion, you could break the Conversion function into multiple ones like promptUserForInput, WrongInputHandler and so forth.
If I understood your second question correctly, you wonder about the way the code executed and how the variable ans is transferred further into the loop. Let's take a look at your code and what variables do:
You initialize your variable in the class MyClass by making it accessible to all methods in the class;
You prompt the user for the input to assign to this variable inside the do..while loop with this line ans = new String(s.nextLine()); which saves the value of the variable and, again, which can be accessed inside the whole class so its value is changed.
It goes into the if..else if...else statement. The way it works, it goes line by line - if the first if-statement fails, it goes on until it finds a truthy statement and it doesn't go any further. In your case, if the ans is not equal to either y/Y/ it will go to else if statement and if it's not n/N, it will go to else (so basically whatever except y/Y/n/N) and will be executed. After that, it jumps into the while (ans!= "N"); line where it compares your class-member variable ans and if it's not equal to "N" it starts over the loop right after the do{ part until you type in the "N".
I hope that makes sense. Whenever the program is asking you for input, it does not execute code further but is stuck until you provide any input. The value from input itself isn't passed throughout the loop and the program. The reason why you can use it because you created a higher-scope variable ans where you saved the result of your input.
IMPORTANT: if you've declared the ans inside the do..while loop, you would've not been able to have accessed it in the while (ans...) because it will 'die' right before the curly brace between do { ...here} while(). If you want to learn more about the scope and variables in general, you can read this article.
Here is my code example:
public static void main(String args[]) {
//declare before entering the loop to have higher scope
String ans = "y";
do {
//we get the given string to convert from the user
String str = promptForString();
//we convert the string
str = converseStringToLowerCase(str);
//display the string (could use another function for that: easier to debug and locate problems and in bigger projects)
out.println("Your new string is: " + str);
//prompt user for respond to continue or not
ans = promptForContinue();
handleResponse(ans);
} while (!ans.equals("n"));
}//END MAIN
//prompts user for an input string
public static String promptForString() {
out.println("Please enter string to be converted to lowercase: ");
String str = new String(s.nextLine());
return str;
}
//converts any given string to lower case
public static String converseStringToLowerCase(String str) {
return str.toLowerCase();
}
//is used to prompt user for reply
public static String promptForContinue() {
out.println("Would you like to convert another string? (Y/N)");
String str = new String(s.nextLine());
//is good to make if...else statements easier - it will always be lower case (or upper if you prefer)
return str.toLowerCase();
}
//easier to locate other response scenarios
public static void handleResponse(String response) {
if (response.equals("n")) {
out.println("Thank you for using this program!");
//it's not a very good practice to innaturally break loops. Use input for that in while(..) statement
// break;
} else if (!response.equals("y")) {
out.println("Invalid entry!");
out.println("Would you like to convert another string?\n(Please type 'Y' for yes, or 'N' for no.)");
}
}

Printing contents of file based on user input

Trying to print a file based off the user's input as mentioned in the title. Basically, my program has been altered from one that I previously created which reads data from a file, so I know that the file has been imported correctly (not the problem).
The problem I have is that I'm trying to make the program print the entirety of the .txt file if the user chooses a specific number, in this case '1'. My current code so far is:
import java.io.FileReader;
import java.util.Scanner;
public class InputOutput {
public static void main(String[] args) throws Exception {
// these will never change (be re-assigned)
final Scanner S = new Scanner(System.in);
final Scanner INPUT = new Scanner(new FileReader("C:\\Users\\JakeWork\\workspace\\Coursework\\input.txt"));
System.out.print("-- MENU -- \n");
System.out.print("1: Blahblahblah \n");
System.out.print("2: Blahblahblah \n");
System.out.print("Q: Blahblahblah \n");
System.out.print("Pick an option: ");
if (S.nextInt() == 1) {
String num = INPUT.nextLine();
System.out.println(num);
}
I feel as if my if statement is totally off and I'm heading in the entire wrong direction, could anyone point me in the right and give me a helping hand?
You're close, but not quite there.
You a reading the user input correctly, but now you need the file contents in a loop.
if(S.nextInt() == 1) {
while (INPUT.hasNextLine()) {
System.out.println(INPUT.nextLine());
}
}
This will keep looking as long as the file contents hasNextLine
You can safely remove the String option = S.next();
Also, just a small bit of naming convention nitpicking, don't use all upper case letters for variable names unless they are meant to be static. Also, the first letter of a variable is generally lower case.
if (S.nextInt() == 1) {
// check if there is input ,if true print it
while((INPUT.hasNextLine())
System.out.println(INPUT.nextLine());
}
Also, for menu scenarios like this, consider using a switch statement, then place a call to the menu-printing (that you move to a separate method) in the default case, so that if you enter something wrong, you can reprint the menu choices. Also, the switch statement is more readable (arguably) than a bunch of if's, like this:
int option = S.nextInt();
switch(option) {
case 1 :
while(INPUT.hasNextLine()) {
System.out.println(INPUT.nextLine());
}
break;
case 2 :
//Do stuff
break;
default :
//Default case, reprint menu?
}
}

User input for an if/else statement

its only my second program with java and im running into some issues.
I'm trying to get input from a user, either yes or no, then based on that go to an if else statemene. Heres what I have so far
String answer= UI.askString("Do you want to continue?");
if(answer=="yes"){
UI.println("Lets go");
}
else if(answer == "no"){
UI.println("Thank you. Goodbye");
}
else{
UI.println("Please enter yes or no");
}
Im thinking perhaps its better to use booleans for this?
Any help is gladly appreciated!
(also if you're wondering, its a custom import hence the weird syntax in some lines)
Cheers.
When you compare two Strings in Java with the == operator, they are compared to see if they are the same object, rather than whether they contain the same text. So, you could type "yes", and when you use if (answer == "yes") the comparison fails, because the object you got back from UI.askString is a different object, stored at a different place in memory, than the String the compiler generated from the literal "yes".
To compare the value of the two Strings you need to write answer.equals("yes"), or "yes".equals(answer). Either one will work, and will call the equals method of the String class, which will compare the actual text.
The latter syntax, "yes".equals(answer), is often recommended because it will not cause a NullPointerException, even if the variable answer is set to null. This is because the equals method handles null and simply returns false. If, on the other hand, you used the answer.equals("yes") form, and answer was null, you would be trying to invoke a method on null and an exception would be thrown.
what you are looking for is a dialog box. Here is oracle examples, with code. It is more than I can write here. There are ton of yes, no boxes and detection's of user input with them.
http://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html
Quick answer:
int dialogResult = JOptionPane.showConfirmDialog (null, "Would You Like to Save your Previous Note First?","Warning",dialogButton);
if(dialogResult == JOptionPane.YES_OPTION){ ... }
Other choices ...
YES_OPTION, NO_OPTION, CANCEL_OPTION, OK_OPTION, and CLOSED_OPTION
For a command line program you need...
import java.util.Scanner;
The code will look like ...
Scanner in = new Scanner(System.in);
String line = in.nextLine();
//ask them to write yes, no, whatever
if(line.equal("yes"){ }
else if (line.eqals("no") {}
else {}
using MikeG010590's answer, you can try:
Scanner in = new Scanner(System.in);
String line;
System.out.println("you want to continue?");
Boolean exit = null;
do {
line = in.nextLine();
switch (line) {
case "yes":
exit = false;
break;
case "no":
exit = true;
break;
default:
System.out.println("Please enter yes or no");
break;
}
}
while (exit == null);
System.out.println(exit ? "Thank you. Goodbye" : "Lets go");

Recognizing spaces in java

I'm a newb and I started out trying out some things, so I made a calculator that only required one line. It works when I do it in this format : Int space String space int. EG : 10 + 50. If I don't do spaces like 50+50 the program fails. Is there someway to recognise spaces in Java? Bare in mind that I'm a noob but I find that I did a great job that keeped me motivated. Here's teh code :
package Tests;
import java.util.Scanner;
public class Calculator {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter your values : ");
int first = input.nextInt();
String character = input.next();
int second = input.nextInt();
int answer = 0;
switch (character) {
case "*":
answer = first * second;
break;
case "/":
answer = first/second;
break;
case "-":
answer = first-second;
break;
case "+":
answer = first+second;
break;
default:
System.out.println("Failed to recognise character");
break;
}
System.out.println("Answer : " + answer);
}
}
Scanner#next reads the next token from the input string based on whatever delimiter you have set for your Scanner object when you create it. The default delimiter is whitespace, so when you space out the operands and operator your program processes them correctly. You could set the delimiters for your Scanner as the operators.
Scanner input = new Scanner(System.in);
input.useDelimiter("\+|\-|\*|\\");
and your program will function properly.
There are some convenience methods in Scanner that you're using now (i.e. nextInt()) but for your purpose you should probably just get the nextLine() and do some more complex parsing of the expression.
This is probably too much and I wouldn't make this my main focus right now if I were you, but eventually you may want to read up about formal languages and use tooling such as http://www.antlr.org/ for purposes like these.
The problem here is not with Java not handling white spaces right, the problem is with Scanner class which uses white space as a separator (way to distinguish different pieces) by default.
You can still use Scanner class but you'll need some basic Regular Expression knowledge to achieve what you're trying to do.
For Java beginner it would be better to do some basic string processing. You just need to do input.nextLine() and parse the string contents.
Keywords you're looking for are indexOf, substring, trim and Integer.parseInt()

Categories

Resources