How do you implement compareTo methods cleanly? - java

Currently I am writing a compareTo method for quadratic functions in the form: ax^2 + bx + c.
a, b, c are integer coefficients that are passed to the class through the constructor.
In the compareTo method, I am supposed to first compare the a-coefficients between two functions, but if they are equal, I compare the b-coefficients. If the b's are equal, I compare the c's.
The method that I came up for this ended up being pretty ugly:
public int compareTo(QuadraticFunction other)
{
if (a > other.a)
return 1;
else if (a < other.a)
return -1;
else if (b > other.b)
return 1;
else if (b < other.b)
return -1;
else if (c > other.c)
return 1;
else if (c < other.c)
return -1;
else
return 0;
}
So I was wondering, if you have these "tiered" systems of comparisons (like compare a's before b's before c's), what's the best way to implement them? I can't imagine writing a method like mine if you have to go through 10+ variables.

For an arbitrary number of coefficients (all of the same type), you should store them in a List (or something similar), rather than individually-named member variables. That allows you to convert your example code into an iteration.

The Guava Libraries provide an extremely nice tool to do this called ComparisonChain.
Your code would look something like this:
import com.google.common.base.ComparisonChain;
...
public int compareTo(QuadraticFunction other) {
return ComparisonChain.start()
.compare(a, other.a)
.compare(b, other.b)
.compare(c, other.c)
.result();
}

For readability, and to use the built-in compare methods for a, b, c, I would refactor to this:
public int compareTo(QuadraticFunction other) {
if (a.equals(other.a)) {
if (b.equals(other.b))
return c.compareTo(other.c);
return b.comapreTo(other.b);
}
return a.compareTo(other.a);
}
This code assumes the fields are Number. If they are a primitive, either convert them to wrapped type or change a.equals(b) toa == band changea.compareTo(b)toa - b`.
Also note that when an if returns, there is never a need for an else - it's redundant, so remove it.

You can use an idiom like the below which breaks the comparison into clear sections by field, only requires one test per field, and uses the signum method to produce the return values.
Note, the subtraction below works for int, short, char, or byte fields.
For long, float, and double fields you have to use separate checks for < and == to avoid overflow/underflow, and loss of precision due to rounding. Be careful of NaN too when comparing floating point values.
For Comparable fields, you can just set delta to the result of compareTo after using separate conditions to handle null.
long delta = ((long) a.field1) - b.field1;
if (delta != 0) { return Long.signum(delta); }
delta = ((long) a.field2) - b.field2;
if (delta != 0) { return Long.signum(delta); }
...
return 0;

Related

Using comparable in a method in the main method

I am trying to check the values of a comparable method and assign the 1 and -1 value to true and false. I made a simple if else statement that does just that but I want to make it inside of a method so I can use it multiple times in my main method. When I try to do this I get an error that my compareTo method (in another class) is "undefined for the type Object".
Here is my code for both the compareTo method and my attempt of using this in my test class.
public int compareTo(FPNumber o) {
if ((exp == o.exp) && (fraction - o.fraction < SMALL))
return 1;
else if ((exp == o.exp) || (fraction - o.fraction > SMALL))
return -1;
else
return 0;
}
public String compare(Object FP1, Object FP2) {
if (FP1.compareTo(FP2) == 1)
System.out.println("true");
else if (FP1.compareTo(FP2) == -1)
System.out.println("false");
else
System.out.println("error");
}
Let me start by a simple example using raw values, and then expand it to use objects.
Suppose you have two variables x and y that hold integer values. If I ask you, how do you know if the values for these variables are equal? The question is answered by simple math: if the values of the two variables are equal, the difference between the two must be zero. For example, 5 - 5. In this case, the difference is zero because both variables hold the value of positive 5.
What if they are different? Let x = 5 and y = 13.
x - y = -8 (this means that x < y)
y - x = 8 (same as above)
As you can see, when the values are different, it is not always going to be 1 or -1. This is important when you are comparing more than two values. Let's introduce z = 20. If comparing x to y and x to z and the result was -1 on both comparisons, the implication is that y and z must be equal but they are not.
What about when comparing objects? It is the same principle. Even when an object holds multiple variables, you must decide a hierarchy to determine which variable is more or less important in the comparison. Consider the following example
public class Person implements Comparable<Person> {
private String firstName;
private String lastName;
private int age;
...
public int compareTo(Person other) {...}
}
I can decide that, for my system, when comparing two Person objects, I must check first the last name, then the first name, and lastly the age.
public int compareTo(Person other) {
int i = lastName.compareTo(other.lastName);
if (i != 0) return i;
i = firstName.compareTo(other.firstName);
if (i != 0) return i;
return Integer.compare(age, other.age);
}
Basically, if the last names are the same (i == 0), it will compare the first names. Then if the first names are the same, it will compare the ages. At any point, if the values are different, the difference will be returned. Again, not a 1 or -1. So basically, to convert the results to boolean, the logic is
public boolean compare(Person person, Person other) {
if (person.compareTo(other) == 0) return true;
else return false;
}
By the way, your original code has a compilation error because your compare method should return a String and it returns void. Instead of using System.out.print() inside your method, like you have now, you should print out the output of the method.
public String compare(Object FP1, Object FP2) {
if (FP1.compareTo(FP2) == 1)
return "true";
else if (FP1.compareTo(FP2) == -1)
return "false";
else
return "error";
}
...
System.out.println(compare(FP1, FP2));
UPDATE: I forgot to mention before that, essentially, the compare function I included here is serving basically the same function as the equals() method. Also, because this function is provided by a third party, it is sort of what a Comparator should do. Because of that, it should be done following best practices of what a Comparator should do. For my Person comparator, you may have two Comparators: one that compares age and one that compare names.

Deciding the right HashCode [duplicate]

How do we decide on the best implementation of hashCode() method for a collection (assuming that equals method has been overridden correctly) ?
The best implementation? That is a hard question because it depends on the usage pattern.
A for nearly all cases reasonable good implementation was proposed in Josh Bloch's Effective Java in Item 8 (second edition). The best thing is to look it up there because the author explains there why the approach is good.
A short version
Create a int result and assign a non-zero value.
For every field f tested in the equals() method, calculate a hash code c by:
If the field f is a boolean:
calculate (f ? 0 : 1);
If the field f is a byte, char, short or int: calculate (int)f;
If the field f is a long: calculate (int)(f ^ (f >>> 32));
If the field f is a float: calculate Float.floatToIntBits(f);
If the field f is a double: calculate Double.doubleToLongBits(f) and handle the return value like every long value;
If the field f is an object: Use the result of the hashCode() method or 0 if f == null;
If the field f is an array: see every field as separate element and calculate the hash value in a recursive fashion and combine the values as described next.
Combine the hash value c with result:
result = 37 * result + c
Return result
This should result in a proper distribution of hash values for most use situations.
If you're happy with the Effective Java implementation recommended by dmeister, you can use a library call instead of rolling your own:
#Override
public int hashCode() {
return Objects.hash(this.firstName, this.lastName);
}
This requires either Guava (com.google.common.base.Objects.hashCode) or the standard library in Java 7 (java.util.Objects.hash) but works the same way.
Although this is linked to Android documentation (Wayback Machine) and My own code on Github, it will work for Java in general. My answer is an extension of dmeister's Answer with just code that is much easier to read and understand.
#Override
public int hashCode() {
// Start with a non-zero constant. Prime is preferred
int result = 17;
// Include a hash for each field.
// Primatives
result = 31 * result + (booleanField ? 1 : 0); // 1 bit » 32-bit
result = 31 * result + byteField; // 8 bits » 32-bit
result = 31 * result + charField; // 16 bits » 32-bit
result = 31 * result + shortField; // 16 bits » 32-bit
result = 31 * result + intField; // 32 bits » 32-bit
result = 31 * result + (int)(longField ^ (longField >>> 32)); // 64 bits » 32-bit
result = 31 * result + Float.floatToIntBits(floatField); // 32 bits » 32-bit
long doubleFieldBits = Double.doubleToLongBits(doubleField); // 64 bits (double) » 64-bit (long) » 32-bit (int)
result = 31 * result + (int)(doubleFieldBits ^ (doubleFieldBits >>> 32));
// Objects
result = 31 * result + Arrays.hashCode(arrayField); // var bits » 32-bit
result = 31 * result + referenceField.hashCode(); // var bits » 32-bit (non-nullable)
result = 31 * result + // var bits » 32-bit (nullable)
(nullableReferenceField == null
? 0
: nullableReferenceField.hashCode());
return result;
}
EDIT
Typically, when you override hashcode(...), you also want to override equals(...). So for those that will or has already implemented equals, here is a good reference from my Github...
#Override
public boolean equals(Object o) {
// Optimization (not required).
if (this == o) {
return true;
}
// Return false if the other object has the wrong type, interface, or is null.
if (!(o instanceof MyType)) {
return false;
}
MyType lhs = (MyType) o; // lhs means "left hand side"
// Primitive fields
return booleanField == lhs.booleanField
&& byteField == lhs.byteField
&& charField == lhs.charField
&& shortField == lhs.shortField
&& intField == lhs.intField
&& longField == lhs.longField
&& floatField == lhs.floatField
&& doubleField == lhs.doubleField
// Arrays
&& Arrays.equals(arrayField, lhs.arrayField)
// Objects
&& referenceField.equals(lhs.referenceField)
&& (nullableReferenceField == null
? lhs.nullableReferenceField == null
: nullableReferenceField.equals(lhs.nullableReferenceField));
}
It is better to use the functionality provided by Eclipse which does a pretty good job and you can put your efforts and energy in developing the business logic.
First make sure that equals is implemented correctly. From an IBM DeveloperWorks article:
Symmetry: For two references, a and b, a.equals(b) if and only if b.equals(a)
Reflexivity: For all non-null references, a.equals(a)
Transitivity: If a.equals(b) and b.equals(c), then a.equals(c)
Then make sure that their relation with hashCode respects the contact (from the same article):
Consistency with hashCode(): Two equal objects must have the same hashCode() value
Finally a good hash function should strive to approach the ideal hash function.
about8.blogspot.com, you said
if equals() returns true for two objects, then hashCode() should return the same value. If equals() returns false, then hashCode() should return different values
I cannot agree with you. If two objects have the same hashcode it doesn't have to mean that they are equal.
If A equals B then A.hashcode must be equal to B.hascode
but
if A.hashcode equals B.hascode it does not mean that A must equals B
If you use eclipse, you can generate equals() and hashCode() using:
Source -> Generate hashCode() and equals().
Using this function you can decide which fields you want to use for equality and hash code calculation, and Eclipse generates the corresponding methods.
There's a good implementation of the Effective Java's hashcode() and equals() logic in Apache Commons Lang. Checkout HashCodeBuilder and EqualsBuilder.
Just a quick note for completing other more detailed answer (in term of code):
If I consider the question how-do-i-create-a-hash-table-in-java and especially the jGuru FAQ entry, I believe some other criteria upon which a hash code could be judged are:
synchronization (does the algo support concurrent access or not) ?
fail safe iteration (does the algo detect a collection which changes during iteration)
null value (does the hash code support null value in the collection)
If I understand your question correctly, you have a custom collection class (i.e. a new class that extends from the Collection interface) and you want to implement the hashCode() method.
If your collection class extends AbstractList, then you don't have to worry about it, there is already an implementation of equals() and hashCode() that works by iterating through all the objects and adding their hashCodes() together.
public int hashCode() {
int hashCode = 1;
Iterator i = iterator();
while (i.hasNext()) {
Object obj = i.next();
hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
}
return hashCode;
}
Now if what you want is the best way to calculate the hash code for a specific class, I normally use the ^ (bitwise exclusive or) operator to process all fields that I use in the equals method:
public int hashCode(){
return intMember ^ (stringField != null ? stringField.hashCode() : 0);
}
#about8 : there is a pretty serious bug there.
Zam obj1 = new Zam("foo", "bar", "baz");
Zam obj2 = new Zam("fo", "obar", "baz");
same hashcode
you probably want something like
public int hashCode() {
return (getFoo().hashCode() + getBar().hashCode()).toString().hashCode();
(can you get hashCode directly from int in Java these days? I think it does some autocasting.. if that's the case, skip the toString, it's ugly.)
As you specifically asked for collections, I'd like to add an aspect that the other answers haven't mentioned yet: A HashMap doesn't expect their keys to change their hashcode once they are added to the collection. Would defeat the whole purpose...
Use the reflection methods on Apache Commons EqualsBuilder and HashCodeBuilder.
I use a tiny wrapper around Arrays.deepHashCode(...) because it handles arrays supplied as parameters correctly
public static int hash(final Object... objects) {
return Arrays.deepHashCode(objects);
}
any hashing method that evenly distributes the hash value over the possible range is a good implementation. See effective java ( http://books.google.com.au/books?id=ZZOiqZQIbRMC&dq=effective+java&pg=PP1&ots=UZMZ2siN25&sig=kR0n73DHJOn-D77qGj0wOxAxiZw&hl=en&sa=X&oi=book_result&resnum=1&ct=result ) , there is a good tip in there for hashcode implementation (item 9 i think...).
I prefer using utility methods fromm Google Collections lib from class Objects that helps me to keep my code clean. Very often equals and hashcode methods are made from IDE's template, so their are not clean to read.
Here is another JDK 1.7+ approach demonstration with superclass logics accounted. I see it as pretty convinient with Object class hashCode() accounted, pure JDK dependency and no extra manual work. Please note Objects.hash() is null tolerant.
I have not include any equals() implementation but in reality you will of course need it.
import java.util.Objects;
public class Demo {
public static class A {
private final String param1;
public A(final String param1) {
this.param1 = param1;
}
#Override
public int hashCode() {
return Objects.hash(
super.hashCode(),
this.param1);
}
}
public static class B extends A {
private final String param2;
private final String param3;
public B(
final String param1,
final String param2,
final String param3) {
super(param1);
this.param2 = param2;
this.param3 = param3;
}
#Override
public final int hashCode() {
return Objects.hash(
super.hashCode(),
this.param2,
this.param3);
}
}
public static void main(String [] args) {
A a = new A("A");
B b = new B("A", "B", "C");
System.out.println("A: " + a.hashCode());
System.out.println("B: " + b.hashCode());
}
}
The standard implementation is weak and using it leads to unnecessary collisions. Imagine a
class ListPair {
List<Integer> first;
List<Integer> second;
ListPair(List<Integer> first, List<Integer> second) {
this.first = first;
this.second = second;
}
public int hashCode() {
return Objects.hashCode(first, second);
}
...
}
Now,
new ListPair(List.of(a), List.of(b, c))
and
new ListPair(List.of(b), List.of(a, c))
have the same hashCode, namely 31*(a+b) + c as the multiplier used for List.hashCode gets reused here. Obviously, collisions are unavoidable, but producing needless collisions is just... needless.
There's nothing substantially smart about using 31. The multiplier must be odd in order to avoid losing information (any even multiplier loses at least the most significant bit, multiples of four lose two, etc.). Any odd multiplier is usable. Small multipliers may lead to faster computation (the JIT can use shifts and additions), but given that multiplication has latency of only three cycles on modern Intel/AMD, this hardly matters. Small multipliers also leads to more collision for small inputs, which may be a problem sometimes.
Using a prime is pointless as primes have no meaning in the ring Z/(2**32).
So, I'd recommend using a randomly chosen big odd number (feel free to take a prime). As i86/amd64 CPUs can use a shorter instruction for operands fitting in a single signed byte, there is a tiny speed advantage for multipliers like 109. For minimizing collisions, take something like 0x58a54cf5.
Using different multipliers in different places is helpful, but probably not enough to justify the additional work.
When combining hash values, I usually use the combining method that's used in the boost c++ library, namely:
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
This does a fairly good job of ensuring an even distribution. For some discussion of how this formula works, see the StackOverflow post: Magic number in boost::hash_combine
There's a good discussion of different hash functions at: http://burtleburtle.net/bob/hash/doobs.html
For a simple class it is often easiest to implement hashCode() based on the class fields which are checked by the equals() implementation.
public class Zam {
private String foo;
private String bar;
private String somethingElse;
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Zam otherObj = (Zam)obj;
if ((getFoo() == null && otherObj.getFoo() == null) || (getFoo() != null && getFoo().equals(otherObj.getFoo()))) {
if ((getBar() == null && otherObj. getBar() == null) || (getBar() != null && getBar().equals(otherObj. getBar()))) {
return true;
}
}
return false;
}
public int hashCode() {
return (getFoo() + getBar()).hashCode();
}
public String getFoo() {
return foo;
}
public String getBar() {
return bar;
}
}
The most important thing is to keep hashCode() and equals() consistent: if equals() returns true for two objects, then hashCode() should return the same value. If equals() returns false, then hashCode() should return different values.

Using TreeSet in Java

I have created my own class of which I want to create my TreeSet. My class looks like this :
class mytree implements Comparable
{
int line_no;
line_segment line[];
public int compareTo(Object obj)
{
tree t = (tree)obj;
if(this.line_no == t.line_no)
return 0;
if(this.line[line_no]>t.line[line_no])
return 1;
else
return -1;
}
}
I am defining new objects of the class and then inserting them into the TreeSet.
In cases I am finding out
values like
mytree up = tree.lower(n1);
mytree down = tree.higher(n2);
but if I try to check whether the values of up and down exist in the tree then it sometimes happen that the tree says that the values don't exists in the tree and sometimes it says the values do exist. Though I have handled the case of 0 in compare method what could be the possible error in my creating of the tree.
There are many things wrong in this code. First of all, you're not respecting the Java conventions at all. Second, you're not using generics, as if we were still in 2004, when Java 5 didn't exist yet. Third, your class doesn't represent a tree, so it shouldn't be named mytree. Fourth, your compareTo() method is wrong. It's supposed to be symmetric:
A > B <==> B < A
If A and B's line[line_no] are equal, then if you compare them with A.compareTo(B), the comparison method will return -1. And if you compare them with B.compareTo(A), it will return -1 as well. So you have A < B and B < A at the same time.
if(this.line_no == t.line_no)
return 0;
if(this.line[line_no]>t.line[line_no])
return 1;
You're comparing two different things in these two checks. I'd expect you should be comparing the same thing, e.g.
if(this.line_no == t.line_no)
return 0;
if(this.line_no > t.line_no)
return 1;
or
// also note you probably mean t.line[t.line_no] instead of t.line[line_no]
if(this.line[line_no] == t.line[t.line_no])
return 0;
if(this.line[line_no]>t.line[t.line_no])
return 1;

comparison of String and Integer using compareTo and instanceOf

I have a code snippet which I am not able to understand what exactly it does..
This code is in JavaBean..
private Object myNumb;
//then getter and setter for this
public int compareTo(myRptObj o){
if (myNumb instanceof String && o.myNumb instanceof Integer) {
return_value = 1;
} else if (myNumb instanceof Integer && o.myNumb instanceof String) {
return_value = -1;
} else if (myNumb instanceof String && o.myNumb instanceof String) {
return_value = ((String) myNumb).compareTo((String)o.myNumb);
} else if (myNumb instanceof Integer && o.myNumb instanceof Integer) {
return_value = ((Integer) myNumb).compareTo((Integer)o.myNumb);
}
}
I want to understand compareTo and how the comparison for String and Integer is done?
myNumb can be of type Integer or String.
The snippet makes sure that any Integer compares less than any String.
Integer-Integer and String-String comparisons are done the way you'd expect.
the first two if clauses ensure that Strings are considered greater than integers. The second two if clauses delegate the comparison between Strings and between Integers to the compareTo() implementation of these classes so that they are ordered as usual.
Note that it is very, very bad design to have this kind of code where a variable can be "of type X or Y" - exactly because it forces you to write code like this.
Instead, decide on one type and convert to/from that type where necessary.
... what exactly it does.
Basically: strings are greater than integers, if both are the same type use their natural ordering (either compare 2 strings or 2 integers).
Since myNumb can be either a String or an Integer, compareTo is checking what types they are first. If they are not the same type (one is an Integer and one is a String) they are not equal and therefore returns 1 or -1 as appropriate. If they are of the same type, it is casting them to that type and delegating to that type's compareTo.

Comparing Numbers in Java

In Java, all numeric types extend from java.lang.Number. Would it be a good idea to have a method like the following:
public boolean areEqual(Number first, Number second) {
if (first != null && second != null) {
return first.equals(second);
}
}
I'm concerned about cases where a double 2.00000 does not equal an int 2. Are these handled by the built-in equals? If not, is there any way to write a simple number compare function in java? (external libraries such as apache commons are ok)
A Double is NEVER equals to an Integer. Moreover, a double is not the same as a Double.
Java has primitive types and reference types. The truly numeric types in Java do not extend from Number, because they're primitives.
You may want to consider a system where you're not mixing types, because that usually will cause a lot of trouble with implicit/explicit conversions that may/may not lose information, etc.
Related questions
On int vs Integer:
What is the difference between an int and an Integer in Java/C#?
Is Java fully object-oriented?
On Number comparison:
Why doesn't java.lang.Number implement Comparable?
Comparing the values of two generic Numbers
See also
Java Language Guide/Autoboxing
JLS 4.2 4.2 Primitive Types and Values
The numeric types are the integral types and the floating-point types.
The integral types are byte, short, int, and long and char.
The floating-point types are float and double.
On mixed-type computation
Mixed-type computation is the subject of at least 4 puzzles in Java Puzzlers.
Here are various excerpts:
it is generally best to avoid mixed-type computations [...] because they are inherently confusing [...] Nowhere is this more apparent than in conditional expressions. Mixed-type comparisons are always confusing because the system is forced to promote one operand to match the type of the other. The conversion is invisible and may not yield the results that you expect
Prescription: Avoid computations that mix integral and floating-point types. Prefer integral arithmetic to floating-point.
To compare two Numbers in Java you can use the compareTo from BigDecimal. BigDecimal can hold everything from short until double or BigInteger, so it's the perfect class for this.
So you can try to write something like this:
public int compareTo(Number n1, Number n2) {
// ignoring null handling
BigDecimal b1 = BigDecimal.valueOf(n1.doubleValue());
BigDecimal b2 = BigDecimal.valueOf(n2.doubleValue());
return b1.compareTo(b2);
}
This is surely not the best approach regarding to performance.
The following tests worked so far, at least with JDK7:
assertTrue(compareTo(new Integer(1), new Integer(2)) == -1);
assertTrue(compareTo(new Integer(1), new Double(2.0)) == -1);
assertTrue(compareTo(new Integer(1), new Double(Double.MAX_VALUE)) == -1);
assertTrue(compareTo(new Integer(1), new Double(Double.MIN_VALUE)) == 1);
assertTrue(compareTo(new Integer(1), new Double(1.000001)) == -1);
assertTrue(compareTo(new Integer(1), new Double(1.000)) == 0);
assertTrue(compareTo(new Integer(1), new Double(0.25*4)) == 0);
assertTrue(compareTo(new Integer(1), new AtomicLong(1)) == 0);
The specific method you suggest would fail, because it's using equals() inherited from Object. That is, it would check to see if the Number objects were the same, not whether their values were the same.
If that was just an illustrative example, I will update my answer.
polygene's answer actually pretty much covers the ground I was heading for. You may also be interested in this question: Why doesn't java.lang.Number implement Comparable?.
If you want to know whether the object references are the same, then the existing methods fit the bill. A Double representing 2.0 and an Integer representing 2 are definitely different objects, and certainly not interchangeable in a general sense.
If you just want to know whether the numeric values are the same, you can use the Number.doubleValue() method to convert both numbers to doubles, then compare those numbers together (probably allowing for a small tolerance, as most numbers are represented inexactly, such as 1.99999999996583 for what should be 2, depending on the intermediate calculation steps). Something like the following:
private static final double EPSILON = 0.000000000000001d;
public static boolean areEquivalentNumbers(Number a, Number b)
{
if (a == null)
{
return b == null;
}
else if (b == null)
{
return false;
}
else
{
return Math.abs(a.doubleValue() - b.doubleValue()) < EPSILON;
}
}
On a tangent to a couple of the responses, may I suggest that instead of writing something like:
boolean compare(Object o1, Object o2)
{
if (o1==null)
return o2==null;
if (o2==null)
return false;
return o1.equals(o2);
}
It's much more concise, and I believe slightly more efficient, to write:
boolean compare(Object o1, Object o2)
{
return o1==o2 || o1!=null && o2!=null && o1.equals(o2);
}
If both are null, o1==o2 will return true. If they're not but they're the same object, that's fine too.
Technically the o2!=null is not necessary for most implementations of equals, but if you were really being so generic as to do this on Objects as in the above example, you of course wouldn't know how every override was written.
public static boolean compareTo(Number d1, Number d2) {
Double num1=d1.doubleValue();
Double num2=d2.doubleValue();
if(Double.compare(num1, num2)==0)
return true;
else
return false;
}
OR
public static boolean compareTo(Number d1, Number d2) {
if(d1.doubleValue()==d2.doubleValue())
return true;
else
return false;
}
Comparing numbers between integer and floating point is almost never going to yield what you are after. If however this is a simple exercise, you could implement the comparison by comparing the string representations of the values, as in:
public boolean areEqual(Number first, Number second) {
if (first == null) {
return second == null;
}
if (second == null) {
return false;
}
return first.toString().equals(second.toString());
}
you cannot call
number.equals(number2);
because, if number is a Double and number2 is an Integer, they will not be of the same class and you will get an exception telling you of that fact.
You could write a comparison class yourself that accepts Number objects, but you will have to take into account the different subclasses of Number

Categories

Resources