11-java-comparisons

Download Report

Transcript 11-java-comparisons

Comparing Objects in Java
The == operator
• When you define an object, for instance
Person p = new Person("John", 23);
we talk about p as if its value were a Person, but it is not-the value of p is a reference to a Person
– The actual data for this Person is stored elsewhere
– The value actually in p is a 4-byte pointer to this data
• When we do assignment, p2 = p, or comparison,
p2 == p, we are working with the pointer values
• When we use dot notation, p.name, we dereference the
pointer to get to the actual data values
• The comparison p == p2 does not test if the data are equal;
it tests if the pointers are equal
Searching an array of Objects
• What does it mean to search for an object?
– Are you looking for that identical object?
• If so, == is what you need
– Or are you looking for any object that is “equal” according to
some other criterion?
• There are many possible criteria—same name field or id field, all
data equal, all elements the same but possibly in a different order, etc.
• You can use the equals method to search an array of
Objects, provided
– The operation equals has been defined appropriately
• equals has been defined for Strings to have the expected meaning
– There is also an equalsIgnoreCase method for Strings
• For almost all other objects, the default meaning of equals is ==
Templates
• In Java you cannot write a search method that works for any
type of array
• To do this, you would need a template facility—a way to write
methods that can take parameters of any type
– C++ has templates
– Templates are likely to be added to a future version of Java
• Note, however:
– We can write a method that works for Objects (because Object has
equals defined, even if it just means ==)
– Such a method would also work fine for Strings (because the String
class overrides equals)
• We can wrap primitives and put them in an array of Objects
Type wrappers
• For every primitive type, there
is a corresponding wrapper
class, in java.lang, to easily
make an Object from the
primitive:
–
–
–
–
–
–
–
–
boolean
byte
char
double
float
int
long
short
Boolean
Byte
Character
Double
Float
Integer
Long
Short
• Here is an example:
class Integer {
private int value;
// Constructor
Integer(int v) {
value = v;
}
public int intValue() {
return value;
}
}
• There’s more to the Integer
class than this, but this is the
most important part
Java review: equals
• The Object class defines
public boolean equals(Object obj)
• For most objects, this just tests identity: whether the two
objects are really one and the same
• This is not generally what you want
• The String class overrides this method with a method that
is more appropriate for Strings
• The wrapper classes for primitive types also override
equals appropriately
• You can override equals for your own classes
– Just write your own equals, defined exactly as above
– But there are some rules you should follow if you do
Overriding equals
• If you override equals, your method should have the
following properties (for your objects x, y, z)
– Reflexive: for any x, x.equals(x) should return true
– Symmetric: for any non-null objects x and y, x.equals(y)
should return the same result as y.equals(x)
– Transitive: if x.equals(y) and y.equals(z) are true, then
x.equals(z) should also be true
– Consistent: x.equals(y) should always return the same
answer (unless you modify x or y, of course)
– For any non-null x, x.equals(null) should return false
• Java cannot check to make sure you follow these rules
About sorted arrays
• When we just say an array is “sorted,” by default
we mean that it is sorted in ascending order:
smaller elements come first
• There is no notion of “smaller” for elements of the
Object class, hence:
– An array of Object cannot be in sorted order !
– But we can define an ordering for objects that belong to a
class we define
• If we ensure that our array of Objects holds only objects for
which we have defined an ordering, then we can sort that array
– In addition to equals, we need some notion of “larger”
and “smaller”
The Comparable interface
• java.lang provides a Comparable interface with
the following method:
– public int compareTo(Object that)
– This method should return:
• A negative integer if this is less than that
• Zero if this equals that
• A positive integer if this is greater than that
• You implement an interface like this:
class MyObject implements Comparable {
public int compareTo(Object that) {...}
...other stuff...
}
Rules for implementing Comparable
• You must ensure:
– x.compareTo(y) and y.compareTo(x) either are both zero,
or else one is positive and the other is negative
– x.compareTo(y) throws an exception if and only if
y.compareTo(x) throws an exception
– The relation is transitive: (x.compareTo(y)>0 &&
y.compareTo(z)>0) implies x.compareTo(z)>0
– if x.compareTo(y)==0, then x.compareTo(z) has the same
sign as y.compareTo(z)
• You should ensure:
– compareTo is consistent with equals
Consistency with equals
• compareTo is consistent with equals if:
x.compareTo(y)==0
gives the same boolean result as
x.equals(y)
• Therefore: if you implement Comparable, you
really should override equals as well
• Java doesn’t actually require consistency with
equals, but sooner or later you’ll get into trouble if
you don’t meet this condition
The End