Java: String.equalsIgnoreCase(. . .) not working - java

I am developing a small application in Java. The following if condition never becomes true, does any body be knows the actual reason?
public int foo()
{
String sTitle = "title";
if (sTitle.equalsIgnoreCase(MyCustomObject.sTitle))
return 5;
else
return 6;
}
It always returns 6. I ran it in debug mode and saw that both strings contains same value.
I also tried swapping the positions of both strings like:
MyCustomObject.sTitle.equalsIgnoreCase(sTitle)
but that didn't work either.

The actual reason is that MyCustomObject.sTitle does not have the value "title" or any case variants.
Check where and when that variable is assigned.

I'm assuming that MyCustomObject.sTitle is a string as well.
My first attempt at debugging would be to add the following line before you test the equality:
System.out.println("*"+MyCustomObject.sTitle+"*");
and check for whitespace.

Try adding this code to the foo method:
if (sTitle.length() != MyCustomObject.sTitle.length())
{
System.out.println("I hate the truth");
}
else
{
System.out.println("The mystery remains!");
}

EqualsIgnoreCase method
Compares this String to another String, ignoring case considerations. Two strings are considered equal ignoring case if they are of the same length, and corresponding characters in the two strings are equal ignoring case.
Two characters c1 and c2 are considered the same, ignoring case if at least one of the following is true:
The two characters are the same (as compared by the == operator).
Applying the method Character.toUpperCase(char) to each character produces the same result.
Applying the method Character.toLowerCase(char) to each character produces the same result.
Based on the above the value of MyCustomObject.sTitle is not matching any of the above criteria.

as previous authors have written MyCustomObject.sTitle does not return any variant of "title". You could try running this piece of code and you can prove for yourself that it's not the equalsIgnoreCase method that doesn't work.
public static void main(String[] args) {
System.out.println(foo());
}
public static int foo()
{
String sTitle = "title";
if (sTitle.equalsIgnoreCase(MyCustomObject.sTitle))
return 5;
else
return 6;
}
public static class MyCustomObject {
public static String sTitle = "TITLE";
}

Related

How do I get object and not address without using String/ toString?

I need to create my own String class called MyString without using default String class/vector API. I have to work on some required methods, and their return types are predetermined. I can add other methods as long as String is not used.
Expected use would be:
(at main) System.out.println(str.toLowerCase()) - returns lower case of str
When I want to work with toLowerCase() method with return type MyString, I can't return the object content but only return the address.
Normally, this problem would require modification of toString(), but since this method requires return type of String by default, I can't use modification of toString() for the assignment.
The assignment is supposed to be not so hard and should not require complex extensions. My constructor may be the problem, but I can't specify which part is.
Code
public class MyString {
private char value[];
MyString(char[] arr){
this.value = Arrays.copyOf(arr, arr.length);
}
...
MyString toLowerCase() { // can't change return type
for (int i =0; i<value.length; i++) {
if ((int)value[i] > 64 && (int)value[i] < 91) {
value[i] = (char) (value[i]+32);
}
}
return this; // this returns address, and I can't override toString
}
Problem with System.out.println(str.toLowerCase()) is it ends up calling PrintStream.println(Object o), but that method internally at some point calls o.toString() which uses code inherited from Object#toString() (since you couldn't override toString as it expect as result String which is forbidden in your project) which result in form TypeInfo#hexHashCode.
This means you can't use System.out.println(MyString).
BUT PrintStream (which instance is held by System.out) allows us to provide data to print in different forms. In this case you can use println(char[]). All you need to do is adding to MyString method like toCharArray() which would return (preferably a copy of) array of characters held by MyString class.
This way you can use it like System.out.println(myStringInstance.toCharArray()) so code from your main method would need to look like
System.out.println(str.toLowerCase().toCharArray());
// ^^^^^^^^^^^--this should return char[]
Firstly, the String class is an immutable type, i.e. the methods of String do not change the internal state (i.e. the char array), instead they return a new instance of type String.
To mirror that behavior you could implement something like this:
public MyString toLowerCase() {
char temp = new char[value.length];
// [...] Your code performing the actual logic on temp
return new MyString(temp);
}
The immutability (and its implications) of the String class is very important to understand in practice. For example, the following code procudes the intended result:
String word = "Word";
System.out.println("I can produce upper case (" + word.toUpperCase() + ") " +
"and lower case (" + word.toLowerCase() + ") " +
"without any side-effects on the original (" + word + ").");
However, it's not possible (without "hacky" solutions) to implement a method like this:
void shortenString(String inputAndOutput);
Second, the assignment expects that the class/method must be used as follows:
System.out.println(str.toLowerCase());
The attribute out is effectively a PrintStream, which offers (besides other methods) the following two:
println(Object x) - Prints an Object and then terminate the line.
println(String x) - Prints a String and then terminate the line.
If the method is called with an Object parameter, the internal implementation calls toString() on the given object, thus the only way to satisfy the requirement is to override this method. Unfortunately, this is not allowed by the assignment.
However, if it is not explicitly stated that the solution has to use java.lang.System, you could simply implement your own System class which accepts MyString, e.g.:
public class System {
public static class MyPrintStream /* optional: extends PrintStream */ {
public void println(MyString x) {
java.lang.System.out.println(x.getCharArray());
}
}
public static final out = new MyPrintStream();
}
This would allow you to use it exactly as described in the assignment:
import my.package.System;
public class Main {
public static void main(String[] args) {
// [...] Instantiate str
System.out.println(str.toLowerCase());
}
}

Format string with undefined number of arguments

Is it possible to create in java something like this someFunction("%s, %s, %s", 1, true, "qwe"); where result should be 1 true qwe?
I tried it with different approaches such as using PrintStream and some other classes but I can't figure out how to do it.
So far one things that seem certain is the definition:
public static String prepare(String format, Object... arguments) {
return ???
}
But I cannot figure out how to do it past that. Can you give me some advices?
You can use String.format method:
public static String prepare(String format, Object... arguments) {
// do same sanity checks if needed
return String.format(format, arguments);
}
This is what String.format does, but I assume that you know that already, and would like to build your own function.
The header of the function that you have is correct. Now you need to make a counter count initially set to zero, create a StringBuilder, and run a loop that scans the format string.
When your loop encounters a character other than the '%', append that character to the StringBuilder. Otherwise, check the next character for a format that your program recognizes, and grab the object at the position count from the arguments array. Format the object as required, and append the result to StringBuilder; increment count.
Once the loop is over, StringBuilder contains the result string that you return to the callers.
Of course this is only a skeleton of the algorithm. A real implementation needs to take care of many other important things, such as
Checking that the count in the loop does not advance past the end of the arguments array
Checking that the final count is not less than the number of objects in the arguments
Checking that the format specifier can be applied to the object from the arguments array
and so on.
Yes, this is exactly what String.format() does:
public class Test {
public static void main(String[] args) {
System.out.println(format("%s %s %s", 12, "A", true));
}
public static String format(String format, Object ... args) {
return String.format(format, args);
}
}
That's what String.format() is meant for
String.format("%s, %s, %s", 1, true, "666");
In your case,
return String.format(format, arguments);

Return two Strings from method

I'm a beginner in Java programming, and I'm trying to make a voting machine program, where you can vote for Republicans or Democrats. My question is, how can I edit my method so I would be able to return two strings with two distinct values?
For example, look at my code all the way in the bottom. It's wrong, but I wanted the tester to be able to print out Democrats: (some number) and Republicans: (some number) in one method. How can I do that?
import java.lang.String;
public class VotingMachine1 {
private double Democrats;
private double Republicans;
public VotingMachine1() {
Democrats = 0;
Republicans = 0;
}
public void voteRepublican() {
Republicans = Republicans + 1;
}
public void voteDemocrat() {
Democrats = Democrats + 1;
}
public void clearMachineState() {
Republicans = 0;
Democrats = 0;
}
//this is where I'm having difficulties. I know its wrong
public double getTallies() {
System.out.println("Democrats: ", return Democrats);
System.out.println("Republicans: ", return Republicans);
}
}
No return is necessary there, since you aren't leaving a function. To do what you seem to want to do, just replace that last method with the following:
public void getTallies()
{
System.out.println("Democrats: " + Double.toString(Democrats));
System.out.println("Republicans: " + Double.toString(Republicans));
}
Also, since your votecounts should only ever be integers, there's no reason to declare them as doubles instead of ints.
What you are looking for here is a format string. A format string is used when you know what your output should look like, and only have a few "holes" where unknown data should be filled in. To output your data using format strings, you would use the System.out.format(String, Object...) method:
System.out.format("Democrats: %f\n", Democrats);
System.out.format("Republicans: %f\n", Republicans);
In this case, the %f indicates that a floating-point number (since your variables are declared as double) will be printed instead of the %f. However, you may wish to consider declaring them as int (or long) instead, in which case you would use %d instead of %f in the format strings.
Finally, you ought to change your getTallies() method to return void instead of double, as you are printing the values, not returning them.
Your code and your description are so contradictory, it is not clear that you even know what you are trying to do. I believe that this is the real root of your problems.
Here goes:
public double getTallies()
{
System.out.println("Democrats: ", return Democrats);
System.out.println("Republicans: ", return Republicans);
}
First, your question says that you want to "return two strings with two values" ... but you have declared the method as returning one double.
Next, your code is printing values ... not returning them.
You've also made some major mistakes at the syntactic level, largely (I believe) because you are trying to do contradictory things:
return Republicans is not a valid Java expression, so you can't use it as a argument to the println method.
The println method can't be called with two arguments, as your code is trying to do. There is a zero argument version and a number of one argument overloads ... but no overloads with two or more arguments.
Basically, you need to start by making up your mind about what this method is supposed to do. Is it supposed to:
return the tallies (as two doubles)?
return a string representing the two tallies?
return nothing ... and output the two tallies to standard output?
do something else?
Once you've made up your mind:
code the method to do what you've decided it should do, and
chose a method name that correctly reflects what it is supposed to do. Hint: a method that starts with get is conventionally a "getter" that returns the attribute or attributes themselves ... not a String rendering.
double is a bad choice of type for a vote count too:
You cannot have a fractional vote.
You want to represent vote counts precisely and floating point types (like double) are not precise. (Or at least, not in the sense that you require.)
When you attempt to format or output a double, the resulting character string is likely to include a pesky decimal point ... or worse.
You should use int or long instead of double.
Finally, this is a serious Java style violation, and should get you a significant penalty if your marker is paying attention.
private double Democrats;
private double Republicans;
Variable names in Java should start with a LOWER CASE letter.
A few more random comments:
import java.lang.String; is superfluous as all classes in package java.lang are automatically imported in every Java source file.
Votes can not be fractional. People can't vote 0.75 candidate A, and 0.25 candidate B. If you use integer datatypes (int or long), you will be reflecting this fact better. Also, you will be saving yourself a lot of headache when you start obtaining results like 379857.999999. This is because floating point types have a better range, but worse precision (especially noticeable when working with pure integers).
According to Java usual naming conventions, variable names should start with a lowecase letter.
A better name for function getTallies is printTallies.
For output purposes, it's much better to use string formatting than concatenation. Some advantages are: multiple formats supported, ease of use, and internationalization.
Putting all together:
private int democratVotes;
private int republicanVotes;
public void printTallies() {
System.out.format("Democrats: %,d%n",democratVotes);
System.out.format("Republicans: %,d%n",republicanVotes);
}
In this particular case, votes will be printed with thousand separation (ex: 3,345,623 instead of 3345623). Check Java's Formatting Numeric Print Output tutorial.
Thinking better about it, there are some alternatives where getTallies would effectively be returning some form of value:
1) Make it to return a String with both tallies. It would be hard and inefficient to separate the tallies later, though.
public String getTallies() {
return "Democrats: %,d votes. Republicans: %,d votes.%n".format(democratVotes,republicanVotes);
}
2) Make it to return an array.
public int[] getTallies() {
return new int[2]{ democratVotes, republicanVotes };
}
public int[] getTallies1() { // Same as getTallies, but written step by step.
int[] result= new int[2] ;
result[0]= democratVotes ;
result[1]= republicanVotes ;
return result ;
}
3) Make it to return a class.
public VotingMachineResults getTallies() {
return VotingMachineResults(democratVotes,republicanVotes) ;
}
public static class VotingMachineResults {
private int democratVotes;
private int republicanVotes;
public VotingMachineResults(democratVotes,republicanVotes) {
this.democratVotes= democratVotes ; // `this` required to disambiguate field democratVotes from parameter democratVotes.
this.republicanVotes= republicanVotes ;
}
public int getDemocratVotes() {
return democratVotes ;
}
public int getRepublicanVotes() {
return republicanVotes ;
}
}
As you can see, this class is very similar to VotingMachine1, but it does not accept internal state changes. It is a "value" class.
In Java, you concatenate Strings with the + operator. Proper syntax for what you were trying to do looks like this:
System.out.println("Democrats: " + Democrats);
System.out.println("Republicans: " + Republicans);
A return statement is only used when you want to return some object or value to a method that called your current method. It is not appropriate in this place since you're only passing a value to another method (println()).
ALSO, you need to fix your getTallies() method. Make it return void instead of double since you aren't returning anything.
Here's something completely different: why not override toString()?
Presumably, any instance of VotingMachine1 will apply for all votes that you care about for that instance. That is to say, you don't create a new instance of a VotingMachine1 every time someone casts a vote.
So, what you can do is override the toString() method. We'll also use String.format() to handle the numerical values.
#Override
public String toString() {
// assumes that Democrats and Republicans are declared as int
// since it's pointless to indicate percentages of a vote
return String.format("Democrats: %d\nRepublicans: %d", Democrats, Republicans);
}
Now, whenever you vote, you can use the toString() method to get the information (which is called whenever one does System.out.println(object).
VotingMachine1 voter = new VotingMachine1();
voter.voteDemocrat();
voter.voteRepublican();
System.out.println(voter);
/* This prints:
Democrats: 1
Republicans: 1
*/
A less specific answer to your question would be to return an Object called (say) Votes
public class Vote {
int democratVotes
int republicanVotes
}
and then make your VotingMachine class simply return an instance of this object (suitably changed to make it immutable).
On my project we have created a generic version of this called a Tuple that returns a pair of values in a single object - it has an overloaded toString method for easy printing.
you can return an array with [0] and [1] as key and devide it on the basis of your need..
like
returnArray[0]="first string";
returnArray[1]="second string";
and use it ur way...

Java Input Problems - how to compare strings [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 7 years ago.
This seems to be pretty simple, but I have been stucked here for a couple of hours.
I have a doubt when you have to compare two Strings in Java.
if I just do something like this:
String var1 = "hello";
String var2 = "hello";
and then compare these two words in another function, the result will clearly be true.
But the problem is when I have to compare two words that come from an input. Here is my code:
import java.util.Scanner;
public class Compare{
public static void main(String[] args){
Scanner Scanner = new Scanner (System.in);
System.out.println("Enter first word: ");
String var1 = Scanner.nextLine();
System.out.println("Enter second word: ");
String var2 = Scanner.nextLine();
if (same (var1, var2))
System.out.println("Yes");
else
System.out.println("No");
}
public static boolean same (String var1, String var2){
if (var1 == var2)
return true;
else
return false;
}
}
I have tried several times (clearly entering the same word) and the result is always False.
I don't know why this happens. What am I missing?
This is my first time in Java. I will appreciate any kind of help. Thanks
You should change
if (var1 == var2)
{
return true;
}
else
{
return false;
}
to
if (var1.equals(var2))
{
return true;
}
else
{
return false;
}
See this answer for the difference between the two
To be more accurate, with Strings in Java sometimes you can use == instead of .equals, if your string has been interned. Remember that == always compares the object references, not the contents of the object. Interning a String means that you will get the same object reference back and this is why == works with interned Strings.
Please read the Javadoc here to understand this more clearly:
String.intern()
In Java the == is a reference equality operator.
It works with the following.
String var1 = "hello";
String var2 = "hello";
boolean cmp = var1 == var2;
just because they are string literals and they are allocated in the same place inside the string table, so both variables point to the same string.
If you are fetching data from another source the strings are dynamically allocated, hence you should use the var1.equals(var2) (and you should ALWAYS use that one when comparing two objects).
Instead of if (same (var1, var2)) use if (v1.equals(v2)). No need to create a new method to compare two Strings. That's what equals() does.
== is used to compares references, not the contents of each String object.
The equality operator(==) checks the refernce of string first then checks value of string.
While equals method checks the value first.
So,in this case equals method should be used instead of equality operator.
String s="hello";
String s1="hello";
String s3=new String("hello")
In the above code snippet if you use If(s==s1){System.out.print("Equal");}it would print equal.But if you check If(s==s3){System.out.print("unqual");}it wouldn't print unequal.
so,you can see that even strings s and s3 are equal,output is wrong.Therefore,in this scenario like program in question
Equals method must be used.
var1 == var2
sometimes works because VM allocates the same memory both the variables for memory optimization and thus having same reference. That cannot be always the case so it's better to use
var1.equals(var2)
If you want to compare their values and doesnt care about reference.

Why do != and == not behave like the equals method in Java? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
Java String.equals versus ==
whats the difference between ".equals and =="
public String getName() {
return new String("foobar");
}
if(getName() != "foobar2") {
//Never gets executed, it should, wtf!.
}
if(!getName().equals("foobar2")) {
//This works how it should.
}
So yeah my question is simple.. why doesn't != behave the same as !equals() aka (not Equals).
I don't see any logicial reason why one should fail, both are the same exact code in my mind, WTH.
Looking at java operators
http://download.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
You can clearly see
equality == !=
are the equality operators, sure I usually use != only on numbers.. but my mind started wandering and why doesn't it work for String?
EDIT:
Here's something that looks more like the actual issue..
for (ClassGen cg : client.getClasses().values()) {
final ConstantPoolGen cp = cg.getConstantPool();
if(cp.lookupInteger(0x11223344) != -1) {
for (Method m : cg.getMethods()) {
System.out.println("lots of class spam");
if(m.getName() != "<init>") continue;
System.out.println("NEVER GETS HERE, 100% SURE IT HAS CONSTRUCTOR LOL");
}
}
}
Using != means that you check for the instance reference in the memory, and the same instance will give you true on that comparison.
When you do a new String("foobar"), a new "foobar" is created in the memory, and the comparison using == returns false.
Calling a intern() on that new string may change this behavior, since the String will now be grabbed or added to the String pool.
In any case, it's safer to use the 'equals()'.
public static void main(String[] args) throws Exception {
if (getName() != "foobar2") {
System.out.println("1");
}
if (!getName().equals("foobar2")) {
System.out.println("2");
}
}
public static String getName() {
return new String("foobar");
}
For me this outputs:
1
2
But those two checks are not equivalent. The first check is checking whether the object returned by getName() is the same object that was created for the string literal "foobar2", which it's not. The second check is probably the one you want, and it checks that the VALUE of the String object returned by the getName() method is equal to the VALUE of the String object created for your "foobar2" string literal.
So both checks will return true, the first one because they aren't the same object and the second one because the values aren't the same.
A string is an Object, not a primitive.
== and != compare two primitives to each other.
To compare strings you need to loop trough each character and compare them in order which is what .equals() does.
If you do any OOP in Java you need to override equals when you want to do equality checks on the Objects, and implement Comparable and .compare() if you want to be able to do things like sort them.
Here is a quick example of equals:
public class Person {
public name;
public Person(String name) {
this.name = name;
}
public boolean equals(Object o){
if(o instanceof Person)
if(this.name.equals(o.name))
return true;
return false;
}
}
Now a Person can be compared to another Person like:
person1.equals(person2)
Which will only return true if both people have the same name. You can define what makes two objects equal however you want, but objects are only == if they are really just two pointers to the same object in memory.
Operators only apply to primitives, not Objects, so a String comparison must be done equals, as that operates at the Object level.
--EDIT--
My comment was meant more along the lines of "the value of an Object cannot be compared in the expected way as in other languages". Of course you can use == signs, but not for a textual comparison. This is the classic question that is asked every time someone migrates to Java from a scripting language, or another language that does support operators for text comparison on Strings.

Categories