Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / July 2007

Tip: Looking for answers? Try searching our database.

String.equals()

Thread view: 
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 Magazines

Get 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 ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.