I'm learning Java for a class and one of the assignments I need to do is implementing String methods into my code. After prompting the user to set text, I used a toLowerCase() method and printed it. On another line, I used a toUpperCase() method and printed it. Both printed correctly but whenever I used the toString() method, it only my text in lowercase.
Here is my main class:
import java.util.Scanner;
public class TalkerTester
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
System.out.println("Enter some text: ");
String words = input.nextLine();
Talker talky = new Talker(words);
String yelling = talky.yell();
String whispers = talky.whisper();
System.out.println(talky);
System.out.println("Yelling: " + yelling);
System.out.println("Whispering: " + whispers);
}
}
Here is my class with all my methods
public class Talker
{
private String text;
// Constructor
public Talker(String startingText)
{
text = startingText;
}
// Returns the text in all uppercase letters
// Find a method in the JavaDocs that
// will allow you to do this with just
// one method call
public String yell()
{
text = text.toUpperCase();
return text;
}
// Returns the text in all lowercase letters
// Find a method in the JavaDocs that
// will allow you to do this with just
// one method call
public String whisper()
{
text = text.toLowerCase();
return text;
}
// Reset the instance variable to the new text
public void setText(String newText)
{
text = newText;
}
// Returns a String representatin of this object
// The returned String should look like
//
// I say, "text"
//
// The quotes should appear in the String
// text should be the value of the instance variable
public String toString()
{
text = text;
return "I say, " + "\"" + text + "\"";
}
}
I apologize for the long paste and my bad English.
It is because you modify the value of text. It will persist even after you return. You should not. Instead, directly return like this:
String yell() {
return text.toUpperCase();
}
Using your methods yell() and whisper, you also edit your variable text. In fact, before the line
System.out.println(talky);
you have used the method whisper which make the variable text into lowercase.
You have to edit your code like this:
public String whisper()
{
return text.toLowerCase();
}
public String yell()
{
return text.toUpperCase();
}
public String toString()
{
return "I say, " + "\"" + text + "\"";
}
Moreover, to be more precise, use the Java keyword this when you use the variable text! For example,
public Talker(String startingText)
{
this.text = startingText;
}
Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 1 year ago.
I have been given an assignment to create the following method "public String getTextDefinition(String text), which have to be implemented as follows (from the assignment):
Use the text parameter to instantiate a Word object.
Get the text value of the instantiated Word object with its getText() method.
Check if the text value of the instantiated Word object is contained in the keyset of the MasterDictorinary.
If this text value is present in the keySet of the MasterDictionary, get its corresponding value of the type Word in the MasterDictorinary and assign the value of its toString() method to the definition variable.
If this text value is not present in the keySet of the MasterDictionary, assign the toString() method of instantiated Word object of the original text parameter to the definition variabel.
I don't know if I have implemented the method in the correct way, but this is how I have implemented the getTextDefinition(String text) method:
public String getTextDefinition(String text){
String definition = "";
Word word = new Word(text);
word.getText();
if(this.containsValue(text) == true){
this.get(word);
definition = word.toString();
}
if(this.containsValue(text) == false){
definition = get(text).toString();
}
return definition;
}
But I can't get it to print the right output which is to look like this:
half:
Word Definition:
In an equal part or degree;
half nelson:
Word Definition:
A hold in which one arm is thrust under the corresponding armof the opponent.
half seas over:
Word Definition:
Half drunk. [Slang: used only predicatively.] Spectator.
half taste:
Word Definition:
No definition found.
The output that i get looks like this:
half:
Word Definition:
In an equal part or degree;
half nelson:
Word Definition:
A hold in which one arm is thrust under the corresponding armof the opponent.
half seas over:
Word Definition:
Half drunk. [Slang: used only predicatively.] Spectator.
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "dictionaryModels.Word.toString()" because the return value of "dictionaryModels.MasterDictionary.get(Object)" is null
at dictionaryModels.MasterDictionary.getTextDefinition(MasterDictionary.java:27)
at dictionaryModels.MasterDictionary.main(MasterDictionary.java:47)
This is how the MasterDictionary class looks like:
public class MasterDictionary extends TreeMap<String, Word>{
public MasterDictionary(){
super();
}
public void put(Word word){
super.put(word.getText(),word);
}
public String getTextDefinition(String text){
String definition = "";
Word word = new Word(text);
word.getText();
if(this.containsValue(text) == true){
this.get(word);
definition = word.toString();
}
if(this.containsValue(text) == false){
definition = get(text).toString();
}
return definition;
}
public static void main(String[] args) {
MasterDictionary dictionary = new MasterDictionary();
Word word = new Word("HALF", "In an equal part or degree;");
dictionary.put(word);
word = new Word("HALF NELSON", "A hold in which one arm is thrust under the corresponding armof the opponent.");
dictionary.put(word);
word = new Word("HALF SEAS OVER", "Half drunk. [Slang: used only predicatively.] Spectator.");
dictionary.put(word);
word = new Word("HALF-AND-HALF", "A mixture of two malt liquors, esp. porter and ale, in aboutequal parts.");
dictionary.put(word);
System.out.println(dictionary.getTextDefinition("half"));
System.out.println(dictionary.getTextDefinition("half nelson"));
System.out.println(dictionary.getTextDefinition("half seas over"));
System.out.println(dictionary.getTextDefinition("half taste"));
}
And this is how the Word class looks like:
public class Word implements Comparable{
private String text;
private String definition;
public Word(String text){
this.text = text.toLowerCase();
this.definition = "No definition found";
}
public Word(String text, String definition){
this.text = text.toLowerCase();
this.definition = definition;
}
public String getText() {
return text;
}
public String getDefinition() {
return definition;
}
public void setDefinition(String definition) {
this.definition = definition;
}
#Override
public String toString() {
String definition = "";
definition = this.getText() + ":\n \t";
definition += "Word Definition: \n \t \t"+ this.getDefinition()+"\n";
return definition;
}
#Override
public int compareTo(Object o) {
int r;
r = getText().compareTo(getText());
return r;
}
public static void main(String[] args) {
Word word = new Word("HETEROGENEAL");
System.out.println(word);
word = new Word("HEINOUS", "Hateful; hatefully bad; flagrant; odious; atrocious; givinggreat great offense;");
System.out.println(word);
}}
So what am I doing wrong and why do I keep getting a NullPointerException?
If get(text) returns null you will get a NullPointerException because you try to call toString() on the returned object.
public String getTextDefinition(String text){
String definition = "";
Word word = new Word(text);
word.getText(); // unused return
if(this.containsValue(text) == true){
this.get(word);
definition = word.toString();
}
if(this.containsValue(text) == false){
definition = get(text).toString(); // NullPointerException here
}
return definition;
}
If this text value is not present in the keySet of the MasterDictionary, assign the toString() method of instantiated Word object of the original text parameter to the definition variabel.
null being returned from a Map is its way of telling you the key is unknown. See https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#get-java.lang.Object- (adjust for the version of Java you are using)
You are supposed to return word.toString() in that case, so:
public String getTextDefinition(String text){
String definition = "";
Word word = new Word(text);
text = word.getText(); // update text to use the lower-case standardization of Word
if(this.containsValue(text) == true){
this.get(word);
definition = word.toString();
}
if(this.containsValue(text) == false){
Word mappedWord = get(text);
if (mappedWord != null) {
definition = mappedWord.toString();
} else {
definition = word.toString();
}
}
return definition;
}
In addition to the comments I made about overriding methods, this is what you want:
public String getTextDefinition(String text) {
String definition = null;
Word w = get(text);
if (w != null) {
definition = w.getDefinition();
}
return definition;
}
Making your run output:
In an equal part or degree;
A hold in which one arm is thrust under the corresponding armof the opponent.
Half drunk. [Slang: used only predicatively.] Spectator.
null
The above is based on an equals method that compares Word.text
import java.util.*;
public class Help {
public static String fromSender(ArrayList<Message> messageList, String pname){
for(int i=0; i<messageList.size(); i++){
if(messageList.get(i).getSender().equals(pname)){
pname = messageList.get(i).getContent() + " ";
}
}
return pname;
}
public static void main(String[] args){
ArrayList<Message> messageList= new ArrayList<Message>();
messageList.add(new Message("UKMark","UKJohn","message1 "));
messageList.add(new Message("John","Don","ah"));
messageList.add(new Message("UKMark","UKJohn","message2 "));
System.out.print(fromSender(messageList, "UKMark") );
}
}
I tried to test this code which is meant to print message1 message2 however it only prints message1, why does it do this when it goes through the whole array and storing it in pname
You overwrite the value in variable pname in your fromSender function by assigning it the first matched message's content in this line of code pname = messageList.get(i).getContent() + " ";. So in the rest of the loops, the pname is actually the first matched message content and no longer 'UKMark' so the second message's sender won't match.
Just use another variable to return from your fromSender function.
public static String fromSender(ArrayList<Message> messageList, String pname){
String result = "";
for(int i=0; i<messageList.size(); i++){
if(messageList.get(i).getSender().equals(pname)){
result += messageList.get(i).getContent() + " ";
}
}
return result;
}
Instead of =, use += inside your if statement. Issue will be resolved.
But ideally you should be using a separate String variable to maintain what you return, instead of using of the passed parameter, especially when it was supposed to meant something else than you are using it as.
When I run the tester class it can't get past the first letter. It outputs an "!" mark instead of continuing to print the rest of the word reversed. Can't figure why it keeps getting hungup. The recursive method seems to be stuck and unable to continue past the first character. Instead of printing "!olleH" I only get "!". Thanks!
/**
Class reverses text of word
*/
public class Sentence
{
private String text="";
/**
Constructs a sentence
#param word
*/
public Sentence(String textIN)
{
text=textIN;
}
/**
gets text
#return text
*/
public String getText()
{
return text;
}
/**
Reverse word
*/
public String reverse()
{
if (text.length() <= 1)
{
return text;
}
else
{
char val = text.charAt(0);
text=text.substring(1);
return reverse() + val;
}
}
}
/**
A tester class for reversing a sentence.
*/
public class SentenceTester
{
public static void main(String[] args)
{
Sentence greeting = new Sentence("Hello!");
greeting.reverse();
System.out.println(greeting.getText());
System.out.println("Expected: !olleH");
}
}
From a read-through of your code, your reverse method seems to work - it returns a reverse of the original text. However, it does this by altering the value of text, and it never puts the final value into text.
What actually happens is that text gets shorter by one character (removed from the front) until there is only one character left - the !.
So, you could solve the problem in your main method:
public static void main(String[] args)
{
Sentence greeting = new Sentence("Hello!");
String result = greeting.reverse();
System.out.println(result);
System.out.println("Expected: !olleH");
}
I hope you like it that way. Just for information, you could use below -
String reversedString = new StringBuilder("Original String").reverse().toString();
One more thing, your code will not work if you pass null :)
The problem with your code is, you are modifying text in else block.
text = text.substring(1);
So at the end it holds only !
Here is the final program (just changed the return statement):
/**
Class reverses text of word
*/
public class Sentence
{
private String text="";
/**
Constructs a sentence
#param word
*/
public Sentence(String textIN)
{
text=textIN;
}
/**
gets text
#return text
*/
public String getText()
{
return text;
}
/**
Reverse word
*/
public String reverse()
{
if (text.length() <= 1)
{
return text;
}
else
{
char val = text.charAt(0);
text=text.substring(1);
return (text=reverse() + val);
}
}
}
the reason is simple - String is immutable. Every time you want it to change assign it back again.
I want to list all names that end with "Reda" and ignore case sensitivity, I have tried the condition in the toString method at the bottom, but it would not print any thing.
public class Customer {
public static void main(String[] args) throws IOException {
File a = new File("customer.txt");
FileWriter v = new FileWriter(a);
BufferedWriter b = new BufferedWriter(v);
PrintWriter p = new PrintWriter(b);
human Iman = new human("Iman", 5000);
human Nour = new human("Nour", 3500);
human Redah = new human("Redah", 0);
human iman = new human("iman", 200);
human MohamedREDA = new human("MohamedREDA", 3000);
human Mohamed_Redah = new human("Mohamed Redah", 2000);
human[] h = new human[6];
h[0] = Iman;
h[1] = Nour;
h[2] = Redah;
h[3] = iman;
h[4] = MohamedREDA;
h[5] = Mohamed_Redah;
p.println(Iman);
p.println(Nour);
p.println(Redah);
p.println(iman);
p.println(MohamedREDA);
p.println(Mohamed_Redah);
p.flush();
}
}
class human {
public String name;
public double balance;
public human(String n, double b) {
this.balance = b;
this.name = n;
}
#Override
public String toString() {
if (name.equalsIgnoreCase("Reda") && (name.equalsIgnoreCase("Reda"))) {
return name + " " + balance;
} else
return " ";
}
}
Please avoid putting condition in toString method. Remove the condition there
public String toString() {
return name + " " + balance;
}
and change your logic in Customer class
human[] h = new human[6];
h[0] = Iman;
h[1] = Nour;
h[2] = Redah;
h[3] = iman;
h[4] = MohamedREDA;
h[5] = Mohamed_Redah;
for (int i = 0; i < h.length; i++) {
if (h[i].name.toLowerCase().endsWith("reda")) { // condition here
p.println(h[i]);
}
}
And make use of loops do not duplicate the lines of code.Every where you are manually writing the lines.
Check Java String class and use required methods to add condition.
String redahname = ("Redah").toLowerCase(); //put your h[0] instead of ("Redah")
if(name.endsWith("redah")){ //IMPORTANT TO BE IN LOWER CASE, (it is case insenitive this way)
//your code here if it ends with redag
System.out.println(redahname);
} //if it does not end with "redah" it wont out print it!
You can use this, but can you please explain your question more? What exactly do you need?
try this
#Override
public String toString() {
if (name.toLowerCase().endsWith("reda"))) {
return name + " " + balance;
} else
return " ";
}
String.equals() is not what you want as you're looking for strings which ends with "Reda" instead of those equal to "Reda". Using String.match or String.endsWith together with String.toLowerCase will do this for you. The following is the example of String.match:
public class Reda {
public static void main(String[] args) {
String[] names = {"Iman", "MohamedREDA", "Mohamed Redah", "reda"};
for (String name : names) {
// the input to matches is a regular expression.
// . stands for any character, * stands for may repeating any times
// [Rr] stands for either R or r.
if (name.matches(".*[Rr][Ee][Dd][Aa]")) {
System.out.println(name);
}
}
}
}
and its output:
MohamedREDA
reda
and here is the solution using endsWith and toLowerCase:
public class Reda {
public static void main(String[] args) {
String[] names = {"Iman", "MohamedREDA", "Mohamed Redah", "reda"};
for (String name : names) {
if (name.toLowerCase().endsWith("reda")) {
System.out.println(name);
}
}
}
}
and its output:
MohamedREDA
reda
You shouldn't put such condition in toString() method cause, it's not properly put business application logic in this method.
toString() is the string representation of an object.
What you can do, is putting the condition before calling the toString() , or making a helper method for this.
private boolean endsWithIgnoringCase(String other){
return this.name.toLowerCase().endsWith(other.toLowerCase());
}
None of your humans are called, ignoring case, Reda, so your observation of no names printed is the manifestation of properly working logic.
Your condition is redundant: you perform the same test twice:
name.equalsIgnoreCase("Reda") && (name.equalsIgnoreCase("Reda"))
If you need to match only the string ending, you should employ a regular expression:
name.matches("(?i).*reda")
toString is a general-purpose method defined for all objects. Using it the way you do, baking in the business logic for just one special use case, cannot be correct. You must rewrite the code so that toString uniformly returns a string representation of the object.
I need to return finalString value for input operator name.
where,internalPrestring is fixed for specific operator,internalDigit would be retrieved from getting operator name.then all of'em would be added to finalString.
but it is giving null, i can't understand the problem
import java.io.*;
import java.lang.*;
class CallManager
{
public static final String postString = "#";
StringBuilder stringBuilder;
String internalPreString;
String preString;
String middleString;
String finalString;
String operatorName;
int internalDigit;
//needs to set oprator name
public void setOperatorName( String getMeFromPreferences)
{
operatorName = getMeFromPreferences;
System.out.println("I got it " + operatorName);
}
//afeter having operator name need to set inrernal digit for each operator
public void setOperatorBasedInternalDigit(int getIntegerForOperator)
{
internalDigit = getIntegerForOperator;
System.out.println("I got it too " + internalDigit);
}
//it needs to get string from ocr
public void setString( String getMeFromOCR )
{
middleString = getMeFromOCR;
}
//preString creator for differnet operator
public String getOperatorBasedPreString(String operatorName)
{
if(operatorName.equals("Airtel"))
internalPreString = "787";
else if(operatorName.equals("Banglalink"))
internalPreString = "123";
else if(operatorName.equals("Grameen"))
internalPreString = "555";
else if(operatorName.equals("Robi"))
internalPreString = "111";
else if(operatorName.equals("TeleTalk"))
internalPreString = "151";
stringBuilder.append("*").append(internalPreString).append("*");
preString = stringBuilder.toString();
return preString;
}
//get operator name and retrive midlle string's digit size from it
public int getOperatorBasedInternalDigit( String operatorName)
{
if(operatorName.matches("^Airtel | Grameen | Robi$"))
internalDigit = 16;
else if(operatorName.matches("^Banglalink$"))
internalDigit = 14;
else if(operatorName.matches("^TeleTalk$"))
internalDigit = 13;
return internalDigit;
}
//check operator-based digit number with input middle string as a number then retrive final string
public String getString( String toBeInserted, int inetrnalDigit)
{
if(toBeInserted.length() == internalDigit)
{
int counter = 0;
char [] insertHere = new char[internalDigit];
for(int verifier = 0; verifier < internalDigit; verifier ++)
{
insertHere[verifier] = toBeInserted.charAt(verifier);
if(!Character.isDigit(insertHere[verifier]))
break;
counter ++;
}
if(counter == internalDigit)
{
stringBuilder.append(preString).append(toBeInserted).append(postString);
finalString = stringBuilder.toString();
//to see what i've got finally as input for using this call manager method.it would be removed too
System.out.println(finalString);
return finalString;
}
else
{
//this printing could be used in main program
System.out.println("number is less or more than desired ..... INVALID SCAN");
System.out.println(middleString);
//here i will call the method for scan the card again
//
//
return middleString;
}
}
else
{
//this printing could be used in main program
System.out.println("number is less or more than desired ..... INVALID SCAN");
System.out.println(middleString);
//here i will call the method for scan the card again
//
//
return middleString;
}
}
}
//tester class that CallManager works rightly or not
class CallManagerDemo
{
public static void main(String args[]) throws IOException
{
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter name of Operator");
CallManager clm = new CallManager();
clm.setOperatorName("Banglalink");
System.out.println(clm.internalPreString);
System.out.println(clm.preString);
}
}
You are having only four lines that deals with your CallManager class:
CallManager clm = new CallManager();
clm.setOperatorName("Banglalink");
System.out.println(clm.internalPreString);
System.out.println(clm.preString);
The reason why you are getting null :
You are using a default constructor right and there processing is
done in it. So this is not a problem
Now on next line you call setOperator method which has this code:
public void setOperatorName( String getMeFromPreferences)
{
operatorName = getMeFromPreferences;
System.out.println("I got it " + operatorName);
}
Now here you are only setting thw variable operatorName and nothing else. So all other variables are null as you not doing any processing or something that will initialize them to something.
So when you print clm.internalPreString and clm.preString you get null as they are not initialized. But try printing clm.operatorName and it will print the operator name that you passed and was initialzed inside your method setOperatorName.
So as you have defined so many method inside your class, use them so that all the variables are set as per your logic
UPDATE
public void setOperatorName( String getMeFromPreferences)
{
operatorName = getMeFromPreferences;
//call any methods for example and use the values returned from the method by storing it inside a variable
String mystring = getOperatorBasedPreString(String operatorName)
}
You have never set the values for the variables for those you are getting the NULL value.The terms get/set must be used where an attribute is accessed directly.Read Java Programming Style GuideLines For more clarity.Use appropriate getters and setter for getting and setting the value like you have done for operatorName.
Don't you think that you should call any of the function instead of the string variables using object.
You are just calling one function that is
public void setOperatorName(String getMeFromPreferences) {
operatorName = getMeFromPreferences;
System.out.println("I got it " + operatorName);
}
You are calling default constructor with out any variable setting there,
You had not initialized any String you are calling form object.
I think you should call any of the function e-g
public int getOperatorBasedInternalDigit(String operatorName)
OR
public String getString(String toBeInserted, int inetrnalDigit)
Then you will get some string as you are expecting ...
Hope this will help you.