Java Forum / General / July 2007
String.equals()
Chameleon - 23 Jul 2007 21:34 GMT I want to write this simple code in java: -------------------------------- String oldText, newText; // BLABLA........ if (oldText == newText) actionA(); else ActionB(); --------------------------------
But only this code works fine with same results: -------------------------- String oldText, newText; // BLABLA........ if (oldText == null) if (newText == null) actionA(); else ActionB(); else if (oldText.equals(newText)) actionA(); else ActionB(); --------------------------
How can I avoid this crap?
When this is true? aStringA == aStringB
(aStringA & aStringB have the same value)
thanks
Chameleon - 23 Jul 2007 21:42 GMT O/H Chameleon έγραψε:
> I want to write this simple code in java: > -------------------------------- [quoted text clipped - 21 lines] > > (aStringA & aStringB have the same value) Ok, after googling I saw these:
String a = "f", b = "f"; // a == b;
String a = new String("f"), b = new String("f"); // a != b;
But problem remains: I don't want to write the crapiest code before, to check if 2 strings are equal. Is there a solution?
Daniel Pitts - 23 Jul 2007 22:09 GMT Sorry if this is a double post, google groups wasn't responding.
> O/H Chameleon ??????: > [quoted text clipped - 34 lines] > But problem remains: I don't want to write the crapiest code before, to > check if 2 strings are equal. Is there a solution? If you know that a != null, you can just do a.equal(b). alternatively you can do:
if (a == b || (a != null && a.equal(b))) { // stuff. }
That works for any combination of a=null and b=null.
Patricia Shanahan - 23 Jul 2007 22:20 GMT > I want to write this simple code in java: > -------------------------------- [quoted text clipped - 16 lines] > > How can I avoid this crap? By using more general expressions in the if tests. The literal equivalent of the quoted code is:
if(oldText == newText || (oldText != null && oldText.equals(newText))){ ActionA(); }else{ ActionB(); }
This does ActionA if the two references are identical, either both null or both referencing the same object, or if they are non-null and the objects they reference are equal.
Usually, I deal with null references separately, often as illegal arguments, so the comparison simplifies to:
if(oldText.equals(newText))
Even if I am dealing with null references, I find that I usually do NOT want to take the equal String action for two null references, in which case the code would be:
if(oldText != null && oldText.equals(newText))
If you know one of the references is not null, e.g. because it is a literal, you can use:
if("xyzzy".equals(possiblyNullReference))
> When this is true? > aStringA == aStringB > > (aStringA & aStringB have the same value) If aStringA and aStringB are references to strings, they are equal either if they are both null, or if they both reference the same String object.
Patricia
Mike Schilling - 23 Jul 2007 23:07 GMT > By using more general expressions in the if tests. The literal > equivalent of the quoted code is: [quoted text clipped - 4 lines] > ActionB(); > } Not with strings particularly, but in many other circumstances I find logic like the above handy. .NET defines a static method on Object that amounts to
public static boolean equals(Object o1, Object o2) { return (o1 == o2) || (o1 != null && o1.equals(o2)) }
It would be nice (and backward-compatible) if Java did the same.
CatBurglerV8 - 23 Jul 2007 23:28 GMT On Jul 23, 12:07 pm, "Mike Schilling" <mscottschill...@hotmail.com> wrote:
> > By using more general expressions in the if tests. The literal > > equivalent of the quoted code is: [quoted text clipped - 15 lines] > > It would be nice (and backward-compatible) if Java did the same. go here http://java.sun.com/javase/6/docs/api/ and look up String.compareToIgnoreCase and other such commands and that should illuminate any problems or confusions there are numerous commands to set up any which way you like. Later CatBurglerV8
Mike Schilling - 24 Jul 2007 02:47 GMT > On Jul 23, 12:07 pm, "Mike Schilling" <mscottschill...@hotmail.com> > wrote: [quoted text clipped - 25 lines] > and that should illuminate any problems or confusions > there are numerous commands to set up any which way you like. Other than being an instance method (not, by the way, a "command") and specific to strings, it is perhaps not wholly unlike what I was discussing.
Lew - 24 Jul 2007 02:58 GMT Mike Schilling wrote:
>>> Not with strings particularly, but in many other circumstances I find >>> logic [quoted text clipped - 6 lines] >>> return (o1 == o2) || (o1 != null && o1.equals(o2)) >>> } It's more than just equals(), but there's always Comparator<T>.
<http://java.sun.com/javase/6/docs/api/java/util/Comparator.html>
 Signature Lew
Oliver Wong - 24 Jul 2007 22:24 GMT > Mike Schilling wrote: >>>> Not with strings particularly, but in many other circumstances I find [quoted text clipped - 11 lines] > > <http://java.sun.com/javase/6/docs/api/java/util/Comparator.html> In order to actually obey the contract of Comparator, you're forced to come up with a total-ordering of all your elements of a given type. Sometimes this is difficult or impossible. I've created an interface which is like Comparator, but only checks two items for equality, instead of an ordering. I couldn't come up with a good name though: it's called Equalitor<T>.
- Oliver
Steve Wampler - 24 Jul 2007 22:37 GMT > ...I've created an interface which > is like Comparator, but only checks two items for equality, instead of an > ordering. I couldn't come up with a good name though: it's called > Equalitor<T>. Isomorphicator? Equalizor? Equivacator? Unequivacator?
The possibilities are endless... :)
 Signature Steve Wampler -- swampler@noao.edu The gods that smiled on your birth are now laughing out loud.
Lew - 24 Jul 2007 23:37 GMT >> ...I've created an interface which is like Comparator, but only >> checks two items for equality, instead of an ordering. I couldn't come [quoted text clipped - 3 lines] > > The possibilities are endless... :) Actually, I really like "Equalitor", in contradiction of Oliver's self-effacement. YMMV.
 Signature Lew
Mike Schilling - 24 Jul 2007 23:44 GMT >> Mike Schilling wrote: >>>>> Not with strings particularly, but in many other circumstances I find [quoted text clipped - 18 lines] > ordering. I couldn't come up with a good name though: it's called > Equalitor<T>. Why an interface rather than a class? I can't picture any implementations I'd want other than the one above.
Twisted - 25 Jul 2007 05:12 GMT On Jul 24, 6:44 pm, "Mike Schilling" <mscottschill...@hotmail.com> wrote:
> Why an interface rather than a class? I can't picture any implementations > I'd want other than the one above. A String one using equalsIgnoreCase or a localized comparison might come in handy as well as a straightforward (case-sensitive) String equality test. There are probably additional, less obvious examples like this where one wants comparisons insensitive to some details of an object.
Lew - 25 Jul 2007 15:06 GMT > A String one using equalsIgnoreCase or a localized comparison might > come in handy as well as a straightforward (case-sensitive) String > equality test. But those things already exist in Java!
<http://java.sun.com/javase/6/docs/api/java/lang/String.html#equalsIgnoreCase(jav a.lang.String)> although there are flaws with the implementation, better to use someString.toUpperCase(),equals( otherString.toUpperCase() ) (thus providing a "localized" comparison that ignores case) Regular equals() is the same whether "localized" or not.
<http://java.sun.com/javase/6/docs/api/java/text/Collator.html> if you want ordering as well as equality, and a whole lot more flexibility in localized String comparison (e.g., different "strengths" of equality).
 Signature Lew
nebulous99@gmail.com - 26 Jul 2007 01:10 GMT > > A String one using equalsIgnoreCase or a localized comparison might > > come in handy as well as a straightforward (case-sensitive) String > > equality test. > > But those things already exist in Java! As special functions of String and as the idiosyncratic Collator class, but not via general interfaces such as Comparator or the proposed Equator. (Unless there's a provided Comparator implementation based on String.equalsIgnoreCase(String) or Collator methods...)
In any event, I was just pointing out that one might have multiple "equality" operations for some types, in response to someone else's absurd suggestion that you only ever need whatever equals() is implemented to do in the way of equality tests. The existence of String.equalsIgnoreCase(String) in particular indicates that the experts at Sun don't agree with that idea.
I notice you didn't object to the sister post made later also suggesting that multiple equality operations often makes sense and is desirable, and furnishing additional examples.
Oliver Wong - 25 Jul 2007 15:31 GMT >>> Mike Schilling wrote: >>>>>> Not with strings particularly, but in many other circumstances I [quoted text clipped - 21 lines] > Why an interface rather than a class? I can't picture any > implementations I'd want other than the one above. In the same way that there are multiple ways to impose a total-ordering on objects of a particular type, there are multiple ways to impose an equivalence-relation on objects of a particular type.
For triangles, the equivalence relation which interests you might be "is similar to" (where "similar" has a precise mathematical definition), or "is congruent to", or "has corresponding sides of the same length", or "is positioned identically in the cartesian plane" or maybe something else, depending on the problem you're trying to solve.
For total-orderings, if there's only 1 ordering for the items, you'd implement Comparable on the type. If there are multiple ways, you need a couple of instances of Comparator.
For equivalence, if there's only 1 equivalence relation, you'd implement equals(). If there are multiple possible relations, you need a couple of instances of Equalitor (or Equalizor or whatever you want to call it).
- Oliver
Jeff Higgins - 25 Jul 2007 16:21 GMT > In the same way that there are multiple ways to impose a total-ordering > on objects of a particular type, there are multiple ways to impose an [quoted text clipped - 14 lines] > couple of instances of Equalitor (or Equalizor or whatever you want to > call it). Hi, I kinda like Equatable and Equator. JH
Patricia Shanahan - 25 Jul 2007 16:50 GMT >>>> Mike Schilling wrote: >>>>>>> Not with strings particularly, but in many other circumstances I [quoted text clipped - 37 lines] > couple of instances of Equalitor (or Equalizor or whatever you want to > call it). If you intend it to represent equivalence relations, why not call it "EquivalenceRelation" with method isEquivalent()?
Patricia
Steven Simpson - 25 Jul 2007 19:24 GMT > In order to actually obey the contract of Comparator, Why try, if you know that what you'll submit it to will only care whether it gives zero or non-zero?
> you're forced to > come up with a total-ordering of all your elements of a given type. > Sometimes this is difficult or impossible. So just make a Comparator that returns 0 or 1, and put a note in the docs saying it doesn't obey the contract. Anything wrong with that?
> I've created an interface which > is like Comparator, but only checks two items for equality, instead of an > ordering. I couldn't come up with a good name though: it's called > Equalitor<T>. > (I'd vote for the already mentioned "Equator".)
 Signature ss at comp dot lancs dot ac dot uk |
Oliver Wong - 27 Jul 2007 16:21 GMT >> In order to actually obey the contract of Comparator, > [quoted text clipped - 7 lines] > So just make a Comparator that returns 0 or 1, and put a note in the > docs saying it doesn't obey the contract. Anything wrong with that? Pragmatically, maybe not (depending on who else you expect to use this code). In principle, yes.
- Oliver
Twisted - 23 Jul 2007 23:26 GMT > If aStringA and aStringB are references to strings, they are equal > either if they are both null, or if they both reference the same String > object. One thing nobody mentioned: string interning. If you don't mind the likelihood that it will never be garbage collected, you can do
stringRef = stringRef.intern();
and all occasions of the same String (same sequence of characters) being interned will return references to a single String object with that content. Which means references that are all return values of intern can be tested for equality using ==. You can also test them against literals with ==, because string literals are automatically interned, and the literal becomes a reference to the interned value at run time.
(This still doesn't help you when you want case-insensitive equality, though.)
Another thing you could do is put a static method in a utility class like:
boolean equal (Object x, Object y) { if (x == y) return true; if (x == null) return y == null; if (y == null) return false; return x.equals(y); }
This should work for any pair of references period, extra-efficiently for interned strings and when one or both references is null, and even if someone's equals method is poorly implemented and throws NPE when the argument is null. (If you're confident this won't happen you can dump the if (y == null) line. You might also dump it and wrap the return in try { ... } catch (NPE e) { return false; }.)
You can then just write the likes of:
if (equal(x, y)) { actionA(); } else { actionB(); }
Immutable value objects are natural candidates for providing interning ability for. This can be done with a static WeakHashMap whose keys are the interned values and whose values are explicit WeakReferences to same. The intern() method would look up "this" in the map, and:
private static WeakHashMap<MyClass, WeakReference<MyClass>> theStaticWeakHashMap = new WeakHashMap<MyClass, WeakReference<MyClass>>();
public MyClass intern () { synchronized (theStaticWeakHashMap) { WeakReference<MyClass> result1 = theStaticWeakHashMap.get(this); if (result1 != null) { MyClass result2 = result1.get(); if (result2 != null) return result2; } theStaticWeakHashMap.put(this, new WeakReference<MyClass>(this)); return this; } }
* Interned objects are eligible for garbage collection with this scheme. * It is thread-safe. * It works properly even if the object is garbage collected AFTER the map get() and BEFORE the WeakReference get(). * It does of course require that MyClass properly implement equals() and hashCode().
Adding this to a third-party class isn't difficult since you can create a new class with a static WeakHashMap and an intern(Foo) method. You can even make a generic interner whose instances have a (non-static!) WeakHashMap<T, WeakReference<T>> and an intern(T) method. Trickier is a generic, static interner; it will need a Class<T> parameter to a parametrized static method, and some unchecked casts due do using a non-generic WeakHashMap or a WeakHashMap<Object, WeakReference<Object>>.
Thomas Fritsch - 23 Jul 2007 22:34 GMT Chameleon schrieb:
> I want to write this simple code in java: > -------------------------------- [quoted text clipped - 3 lines] > else ActionB(); > -------------------------------- It seems you don't yet understand the difference between == and equals(), especially when applied to Strings. == detects if 2 object references refer to the same object. equals() detects if 2 object references refer to equal looking objects. You should re-read the chapter of your Java text-book concerning this topic. See also the API docs of String#equals.
> But only this code works fine with same results: > -------------------------- [quoted text clipped - 6 lines] > else ActionB(); > -------------------------- You can condense the lines above a bit without changing the result: if (oldText != null && oldText.equals(newText)) actionA(); else ActionB();
 Signature Thomas
Roedy Green - 24 Jul 2007 02:55 GMT >if (oldText == newText) actionA(); >else ActionB(); that will only work if both strings are interned. Normally you use equals.
See http://mindprod.com/jgloss/gotchas.html#COMPARISON
When one string is a literal, and the other might be null, you can write
if ( "something".equals( other ) )
I have suggested syntax to deal with nulls in Bali, an extended Java. see http://mindprod.com/jgloss/bali.html and http://mindprod.com/jgloss/void.html
 Signature Roedy Green Canadian Mind Products The Java Glossary http://mindprod.com
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|