This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 7 years ago.
I'm making a game where the user enters his/her first name and last name. The program extracts the first letters from the names, then outputs names from a string array.
I'm thinking the issue is in the last part of the code, where I'm comparing the Strings firstletter and lastLetter to the array. But I'm not sure. I have spent some time researching, and I'm stuck.
Any comments welcome. You won't hurt my feelings.
import java.util.Arrays;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Scanner;
public abstract class ChristmasName extends JFrame implements ActionListener {
public static void main(String[] args) {
JFrame frame = new JFrame("What is your Christmas Name?");
frame.setVisible(true);
frame.setSize(400,300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.add(panel);
JLabel firstName = new JLabel("First name:");
JTextField first = new JTextField(15);
JLabel lastName = new JLabel("Last name:");
JTextField last = new JTextField(15);
panel.add(firstName);
panel.add(first);
panel.add(lastName);
panel.add(last);
JButton submit = new JButton("Submit");
panel.add(submit);
submit.addActionListener(new ActionListener() {
#Override
public actionPerformed(ActionEvent e) {
String[] first_name = {"Apple","Eggnogg","Candy","Jingle","Holly","Goldie","Ho Ho","Frosty","Joyous","Mittens","Tinsel","Turkey","Tiny","Cranberry","Bloated","Angel","Bauble","Bulb","Ginger","Blitzen","Eve","Faith","Fruitcake","Goose","Glitter","Grinch"};
String[] last_name = {"Tidings","Swan","Jolly","Claus","Mistletoe","Punch","Chimney","Coal","Igloo","Jumper","Myrhh","Pudding","Reindeer","Rejoice","Icicle","Midnight","Shepherd","Surprise","Gift","Magi","Train","Tree","White","Donkey","Wreath","Stuffing"};
String firstLetter = first.getText();
firstLetter = firstLetter.substring(0,1);
String lastLetter = last.getText();
lastLetter = lastLetter.substring(0,1);
if (firstLetter == "A") {
firstLetter = first_name[0];
}
JOptionPane.showMessageDialog(null, firstLetter + " " + lastLetter);
System.exit(0);
}
});
}
}
Because you only need one character, you should use charAt() instead of substring. Although substring is possible, I always forget which parameter is inclusive or exclusive. I think you will too.
You should declare 2 chars:
char firstChar = first.getText().charAt(0);
char lastChar = last.getText ().charAt (0);
And then you can check them:
if (firstChar == 'A') { //Remember to use single quotes!
Not sure what you're asking but the first problem I see in your code is:
if (firstLetter == "A") {
firstLetter = first_name[0];
}
See the following on how to check if two strings have the same value:
How do I compare strings in Java?
Here's my solution for your problem:
String[] first_names = {"Apple","Eggnogg","Candy","Jingle","Holly","Goldie","Ho Ho","Frosty","Joyous","Mittens","Tinsel","Turkey","Tiny","Cranberry","Bloated","Angel","Bauble","Bulb","Ginger","Blitzen","Eve","Faith","Fruitcake","Goose","Glitter","Grinch"};
String[] last_names = {"Tidings","Swan","Jolly","Claus","Mistletoe","Punch","Chimney","Coal","Igloo","Jumper","Myrhh","Pudding","Reindeer","Rejoice","Icicle","Midnight","Shepherd","Surprise","Gift","Magi","Train","Tree","White","Donkey","Wreath","Stuffing"};
// User Input:
// Note: converted to lower case so the chars can be compared easily.
String firstName = first.getText().toLowerCase();
String lastName = last.getText().toLowerCase();
// Vars for output:
String sChristmasFirstName = null;
String sChristmasLastName = null;
// Do first name (if entered)
if(firstName.length() > 0){
// Loop all names to find the match:
for(String name : first_names){
if(name.toLower().charAt(0) == firstName.charAt(0)){
// We found a Christmas first name for the user
sChristmasFirstName = name;
// we can now exit the loop
break;
}
}
} // else, the user left this field blank
// Do same thing for last name
if(firstName.length() > 0){
// Loop all names to find the match:
for(String name : last_names){
if(name.toLower().charAt(0) == lastName.charAt(0)){
// We found a Christmas last name for the user
sChristmasLastName = name;
// we can now exit the loop
break;
}
}
} // else, the user left this field blank
// Prepare output string:
String output = "";
String outputErrorPortion = "";
if(sChristmasFirstName != null){
output += sChristmasFirstName;
}else{
if(firstName.length() == 0){
outputErrorPortion += "It looks like you didn't enter a first name.";
}else{
// Could not find an applicable first name
output += firstName;
ouputErrorPortion += "It looks like we couldn't find a Christmas first name for you :-(";
}
}
if(sChristmasLastName != null){
output += " " + sChristmasLastName;
}else{
if(lastName.length() == 0){
outputErrorPortion += " It looks like you didn't enter a last name.";
}else{
// Could not find an applicable last name
output += " " + lastName;
ouputErrorPortion += " It looks like we couldn't find a Christmas last name for you :-(";
}
}
// trim leading and trailing spaces if there are any:
output = output.trim();
outputErrorPortion = outputErrorPortion.trim();
// Variable 'output' now contains the Christmas first name, last name, both, or neither.
// Error message now contains a descriptive error about what happened (if anything)
The string comparisons to choose the Christmas names occurs in a for each loop which loops over the first_names and last_names String arrays to find the first match that starts with the same letter as the user's inputted first and last names. The Christmas names are then concatenated at the end to the output variable with the user's inputted first and/or last names being used in place of the Christmas equivalent if a relevant entry could not be found in the arrays of Christmas names. An error message is also constructed in the outputErrorPortion variable if any errors occurred while processing to names.
Here is the code you need read it carefully:
String[] firstNames = { "Apple", "Eggnogg", "Candy", "Jingle", "Holly", "Goldie", "Ho Ho", "Frosty","Joyous", "Mittens", "Tinsel", "Turkey", "Tiny", "Cranberry", "Bloated", "Angel", "Bauble","Bulb", "Ginger", "Blitzen", "Eve", "Faith", "Fruitcake", "Goose", "Glitter", "Grinch" };
String[] lastNames = { "Tidings", "Swan", "Jolly", "Claus", "Mistletoe", "Punch", "Chimney", "Coal","Igloo", "Jumper", "Myrhh", "Pudding", "Reindeer", "Rejoice", "Icicle", "Midnight", "Shepherd","Surprise", "Gift", "Magi", "Train", "Tree", "White", "Donkey", "Wreath", "Stuffing" };
// ArrayLists will contain the matching items
ArrayList<String> firstNamesMatching = new ArrayList<String>();
ArrayList<String> lastNamesMatching = new ArrayList<String>();
// Check which names from firstNames matching the firstLetter
String firstLetter = first.getText().substring(0, 1).toUpperCase();
for (String s : firstNames) {
if (s.startsWith(firstLetter))
firstNamesMatching.add(s);
}
// Check which names from lastNames matching the lastLetter
String lastLetter = last.getText().substring(0, 1).toUpperCase();
for (String s : lastNames) {
if (s.startsWith(lastLetter))
lastNamesMatching.add(s);
}
JOptionPane.showMessageDialog(null, firstNamesMatching.toArray() + " " + lastNamesMatching);
Also:
Although the arrays firstNames and lastNames and etc have to be outside the actionListener.You should have in mind the memory that your program use and not initialize the same things again and again.
Related
Say for instance I have this string:
"His name is Justin Hoffman"
and need to check if it is a valid name:
In order for this to return true I need to make sure I have "His name" before "is" and I need "Justin Hoffman" after the "is" how can I check to see if I have the correct substring before "is" and the correct one after "is"
String sentence = "His name is Justin Hoffman";
String[] splitSentence = sentence.split(" is ");
String first = splitSentence[0]; // His name
String second = splitSentence[1]; // Justin Hoffman
boolean isTrue = (first.equals("His name") && second.equals("Justin Hoffman"));
String input = "His name is Justin Hoffman";
String requiredFirstName = "His name";
String requiredLastName = "Justin Hoffman";
String delimiter = " is ";
// Example 1
if (input.equals(requiredFirstName + delimiter + requiredLastName))
{
System.out.println("The input is OK");
}
// Example 2
int posi = input.indexOf(delimiter);
if (posi > 0) // found
{
String leftPart = input.substring(0, posi);
String rightpart = input.substring(posi + delimiter.length());
if (requiredFirstName.equals(leftPart) && requiredLastName.equals(rightpart))
{
System.out.println("The input is OK");
}
}
// Example 3
String[] parts = input.split(delimiter);
if (requiredFirstName.equals(parts[0]) && requiredLastName.equals(parts[1]))
{
System.out.println("The input is OK");
}
The second example is possibly the fastest one because it does not produce temporary strings. The third example is the slowest one. Be careful with special character in the delimiter because the split() function interprets the argument as a regular expression.
I have a text file called UserDetails.txt that I am trying to read from.
Each line of the text file is as follows:
John : Doe : Seattle : jd3 : 1234
Jane : Doe : Olympia : jd4 : 5678
Jerry : Doe : Redmond : jd5 : 9101
And so on...
Each line has the first name, last name, username, and password of the registered user by which I am trying to search for only the last two variables (username and password).
public class LoginFrame extends javax.swing.JFrame
{
private static Scanner keyboard = new
Scanner(System.in);
String username;
String password;
String filePath = "UserDetails.txt";
public LoginFrame() {
initComponents();
}
private void jButtonLoginActionPerformed(java.awt.event.ActionEvent evt) {
username = jTextFieldUsername.getText();
password = jTextFieldPassword.getText();
verifyLogin(username,password,filePath);
}
public static void verifyLogin(String username,
String password, String filepath)
{
boolean match = false;
String tempUserName = "";
String tempPassword = "";
try
{
keyboard = new Scanner(new
File(filepath));
keyboard.useDelimiter("[:\n]");
while(keyboard.hasNext() && !match)
{
tempUserName = keyboard.next();
tempPassword = keyboard.next();
if(tempUserName.trim().equals(username.trim()) &&
tempPassword.trim().equals(password.trim()))
{
match = true;
}
}
keyboard.close();
System.out.print(match);
}
catch (Exception e)
{
System.out.print("Error");
}
}
This above code snippet is my original code by which I tried to use a delimiter to find the two specific values but it only seems to work if the username and password are the only two variables in the text file (with first and last names removed).
I've been reading up on the String.split() method so that I can replace my original use of the delimiter. However, I'm still struggling with how I can apply it to my text file. Many of the examples online explain how one can convert an individual line into a String array (which in my example, would have the username at index 3 and password at index 4). This is where I'm confused though. How can I implement the String.split() method without having to manually input it for every specific line? (since there are 50 users in the text file). Would it be possible to implement it with the Scanner.nextLine() method?
Here:
while(keyboard.hasNext() && !match)
{
tempUserName = keyboard.next();
tempPassword = keyboard.next();
You are reading each of the lines in pairs. You should instead call keyboard.next four times in each iteration. I am guessing that you intend to ignore the first name and last name, so you don't need to assign them to any variable:
while(keyboard.hasNext() && !match)
{
// These two lines read the first name and last name and do nothing with them
keyboard.next();
keyboard.next();
// these will read the username and password
tempUserName = keyboard.next();
tempPassword = keyboard.next();
If you want to use split, you need to call nextLine and hasNextLine instead:
while (keyboard.hasNextLine() && !match) {
String[] parts = keyboard.nextLine().split(" : ");
tempUserName = parts[2];
tempPassword = parts[3];
...
}
The program that I am writing is in Java.
I am attempting to make my program read the file "name.txt" and store the values of the text file in an array.
So far I am using a text file that will be read in my main program, a service class called People.java which will be used as a template for my program, and my main program called Names.java which will read the text file and store its values into an array.
name.txt:
John!Doe
Jane!Doe
Mike!Smith
John!Smith
George!Smith
People.java:
public class People
{
String firstname = " ";
String lastname = " ";
public People()
{
firstname = "First Name";
lastname = "Last Name";
}
public People(String firnam, String lasnam)
{
firstname = firnam;
lastname = lasnam;
}
}
Names.java:
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import java.util.StringTokenizer;
public class Names
{
public static void main(String[]args)
{
String a = " ";
String b = "empty";
String c = "empty";
int counter = 0;
People[]peoplearray=new People[5];
try
{
File names = new File("name.txt");
Scanner read = new Scanner(names);
while(read.hasNext())
{
a = read.next();
StringTokenizer token = new StringTokenizer("!", a);
while(token.hasMoreTokens())
{
b = token.nextToken();
c = token.nextToken();
}
People p = new People(b,c);
peoplearray[counter]=p;
++counter;
}
}
catch(IOException ioe1)
{
System.out.println("There was a problem reading the file.");
}
System.out.println(peoplearray[0]);
}
}
As I show in my program, I tried to print the value of peoplearray[0], but when I do this, my output reads: "empty empty" which are the values I gave String b and String c when I instantiated them.
If the program were working corrrectly, the value of peoplearray[0] should be, "John Doe" as those are the appropriate values in "names.txt"
What can I do to fix this problem?
Thanks!
StringTokenizer(String str, String delim)
is the constructor of StringTokenizer.
You have written it wrong .
Just change your line
StringTokenizer token = new StringTokenizer("!", a); to
StringTokenizer token = new StringTokenizer(a, "!");
Just change it a little bit
StringTokenizer token = new StringTokenizer(a, "!");
while(token.hasMoreTokens())
{
b = token.nextToken();
c = token.nextToken();
}
//do something with them
I want to filter a string.
Basically when someone types a message, I want certain words to be filtered out, like this:
User types: hey guys lol omg -omg mkdj*Omg*ndid
I want the filter to run and:
Output: hey guys lol - mkdjndid
And I need the filtered words to be loaded from an ArrayList that contains several words to filter out. Now at the moment I am doing if(message.contains(omg)) but that doesn't work if someone types zomg or -omg or similar.
Use replaceAll with a regex built from the bad word:
message = message.replaceAll("(?i)\\b[^\\w -]*" + badWord + "[^\\w -]*\\b", "");
This passes your test case:
public static void main( String[] args ) {
List<String> badWords = Arrays.asList( "omg", "black", "white" );
String message = "hey guys lol omg -omg mkdj*Omg*ndid";
for ( String badWord : badWords ) {
message = message.replaceAll("(?i)\\b[^\\w -]*" + badWord + "[^\\w -]*\\b", "");
}
System.out.println( message );
}
try:
input.replaceAll("(\\*?)[oO][mM][gG](\\*?)", "").split(" ")
Dave gave you the answer already, but I will emphasize the statement here. You will face a problem if you implement your algorithm with a simple for-loop that just replaces the occurrence of the filtered word. As an example, if you filter the word ass in the word 'classic' and replace it with 'butt', the resultant word will be 'clbuttic' which doesn't make any sense. Thus, I would suggest using a word list,like the ones stored in Linux under /usr/share/dict/ directory, to check if the word is valid or it needs filtering.
I don't quite get what you are trying to do.
I ran into this same problem and solved it in the following way:
1) Have a google spreadsheet with all words that I want to filter out
2) Directly download the google spreadsheet into my code with the loadConfigs method (see below)
3) Replace all l33tsp33k characters with their respective alphabet letter
4) Replace all special characters but letters from the sentence
5) Run an algorithm that checks all the possible combinations of words within a string against the list efficiently, note that this part is key - you don't want to loop over your ENTIRE list every time to see if your word is in the list. In my case, I found every combination within the string input and checked it against a hashmap (O(1) runtime). This way the runtime grows relatively to the string input, not the list input.
6) Check if the word is not used in combination with a good word (e.g. bass contains *ss). This is also loaded through the spreadsheet
6) In our case we are also posting the filtered words to Slack, but you can remove that line obviously.
We are using this in our own games and it's working like a charm. Hope you guys enjoy.
https://pimdewitte.me/2016/05/28/filtering-combinations-of-bad-words-out-of-string-inputs/
public static HashMap<String, String[]> words = new HashMap<String, String[]>();
public static void loadConfigs() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(new URL("https://docs.google.com/spreadsheets/d/1hIEi2YG3ydav1E06Bzf2mQbGZ12kh2fe4ISgLg_UBuM/export?format=csv").openConnection().getInputStream()));
String line = "";
int counter = 0;
while((line = reader.readLine()) != null) {
counter++;
String[] content = null;
try {
content = line.split(",");
if(content.length == 0) {
continue;
}
String word = content[0];
String[] ignore_in_combination_with_words = new String[]{};
if(content.length > 1) {
ignore_in_combination_with_words = content[1].split("_");
}
words.put(word.replaceAll(" ", ""), ignore_in_combination_with_words);
} catch(Exception e) {
e.printStackTrace();
}
}
System.out.println("Loaded " + counter + " words to filter out");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Iterates over a String input and checks whether a cuss word was found in a list, then checks if the word should be ignored (e.g. bass contains the word *ss).
* #param input
* #return
*/
public static ArrayList<String> badWordsFound(String input) {
if(input == null) {
return new ArrayList<>();
}
// remove leetspeak
input = input.replaceAll("1","i");
input = input.replaceAll("!","i");
input = input.replaceAll("3","e");
input = input.replaceAll("4","a");
input = input.replaceAll("#","a");
input = input.replaceAll("5","s");
input = input.replaceAll("7","t");
input = input.replaceAll("0","o");
ArrayList<String> badWords = new ArrayList<>();
input = input.toLowerCase().replaceAll("[^a-zA-Z]", "");
for(int i = 0; i < input.length(); i++) {
for(int fromIOffset = 1; fromIOffset < (input.length()+1 - i); fromIOffset++) {
String wordToCheck = input.substring(i, i + fromIOffset);
if(words.containsKey(wordToCheck)) {
// for example, if you want to say the word bass, that should be possible.
String[] ignoreCheck = words.get(wordToCheck);
boolean ignore = false;
for(int s = 0; s < ignoreCheck.length; s++ ) {
if(input.contains(ignoreCheck[s])) {
ignore = true;
break;
}
}
if(!ignore) {
badWords.add(wordToCheck);
}
}
}
}
for(String s: badWords) {
Server.getSlackManager().queue(s + " qualified as a bad word in a username");
}
return badWords;
}
I am working on a homework assignment, and I am going a little "above and beyond" what is called for by the assignment. I am getting a run-time error in my code, and can not for the life of me figure out what it is that I have done wrong.
Here is the assignment:
Write a program that displays a simulated paycheck. The program should ask the user to enter the date, the payee’s name, and the amount of the check. It should then display a simulated check with the dollar amount spelled out.
Here is my code:
CheckWriter:
/* CheckWriter.java */
// Imported Dependencies
import java.util.InputMismatchException;
import java.util.Scanner;
public class CheckWriter {
public static void main(String args[]) {
Scanner keyboard = new Scanner(System.in);
// Try to get the name
String name = "";
NameValidator validateName = new NameValidator();
while (validateName.validate(name) == false) {
System.out.println("Enter the name: ");
name = keyboard.nextLine();
if (validateName.validate(name) == false) {
System.out.println("Not a valid name.");
}
}
// Get the date
String date = "";
DateValidator validateDate = new DateValidator();
while (!validateDate.validate(date)) {
System.out.println("Enter the date (dd/mm/yyyy): ");
date = keyboard.nextLine();
if (!validateDate.validate(date)) {
System.out.println("Not a valid date.");
}
}
// Try to get the amount of the check
String checkAmount = "";
CurrencyValidator validateCurrency = new CurrencyValidator();
while (!validateCurrency.validate(checkAmount)) {
System.out.print("Enter the Check Amount (XX.XX): $");
checkAmount = keyboard.nextLine();
if (!validateCurrency.validate(checkAmount)) {
System.out.println("Not a valid check amount.");
}
}
String checkWords = checkToWords(checkAmount); // ERROR! (48)
System.out
.println("------------------------------------------------------\n"
+ "Date: "
+ date
+ "\n"
+ "Pay to the Order of: "
+ name
+ " $"
+ checkAmount
+ "\n"
+ checkWords
+ "\n"
+ "------------------------------------------------------\n");
}
private static String checkToWords(String checkAmount) {
/**
* Here I will use the string.split() method to separate out
* the integer and decimal portions of the checkAmount.
*/
String delimiter = "\\.\\$";
/* Remove any commas from checkAmount */
checkAmount.replace(",", "");
/* Split the checkAmount string into an array */
String[] splitAmount = checkAmount.split(delimiter);
/* Convert the integer portion of checkAmount to words */
NumberToWords intToWord = new NumberToWords();
long intPortion = Long.parseLong(splitAmount[0]); // ERROR! (84)
intToWord.convert(intPortion);
String intAmount = intToWord.getString() + " dollars";
/* Convert the decimal portion of checkAmount to words */
String decAmount = "";
long decPortion = Long.parseLong(splitAmount[1]);
if (decPortion != 0) {
NumberToWords decToWord = new NumberToWords();
decToWord.convert(Long.parseLong(splitAmount[1]));
decAmount = " and " + decToWord.getString() + " cents.";
}
return (intAmount + decAmount);
}
}
Note that I am using external class files to handle validation of the name, date, currency, and conversion from numbers to words. These class files all work as intended.
The error I am getting is:
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Long.parseLong(Unknown Source)
at java.lang.Long.parseLong(Unknown Source)
at CheckWriter.checkToWords(CheckWriter.java:82)
at CheckWriter.main(CheckWriter.java:46)
I have commented the lines in my code that are causing the errors that I am experiencing.
Could someone please assist me in figuring where my code is going wrong? I can include the other class files if you feel that it would be needed.
EDIT: When I run the code, it asks for the name and date. Before asking for the check amount is when it throws the error.
EDIT 2: A huge thank you to cotton.m! Thanks to his advice, I have changed the while statements to look like this:
while(!validateDate.validate(date) && date == "")
This has now fixed my issue. It would appear that when validating data with a regex expression, an empty string will return true.
The String you are trying to parse in an empty length string.
My suggestion would be to
1) Check the value of checkAmount at the start of checkToWords - if it is blank there's your problem
2) Don't do that split. Just replace the $ like you did the , (I think this is your real problem)
Also you are going to have another issue in that 10000.00 is not a long. I see you are splitting out the . but is that really what you want?
It is NumberFormatException, the value in checkAmount (method parameter) is not a valid Number.
You need to set checkAmount=checkAmount.replace(",", "");
Otherwise checkAmount will still have , inside and causes NumberFormatExcpetion.
Your issue is with your delimiter regex, currently you are using \.\$ which will split on a literal . followed by a literal $. I'm assuming that what you are actually intending to do is to split on either a . or a $, so change your delimiter to one of the following:
String delimiter = "\\.|\\$"
or
String delimiter = "[\\.\\$]"
As your code is now, checkAmount.split(delimiter) is not actually successfully splitting the string anywhere, so Long.parseLong(splitAmount[0]) is equivalent to Long.parseLong(checkAmount).
It should be:
String delimiter = "[\\.\\$]";
and then you have to check that splitWord[i] is not empty.