Reputation: 113
I am given an instance of the object class (String, int, double, or boolean) from a database. I need to write a method that can compare this object to something else (String, int, double, or boolean) using binary operators (e.g. <=, !=, >, etc.). I will only run this method if the two objects are of the same type. My method looks like
public boolean comparison(Object a, Object b, String operator) {
int result = a.compareTo(b);
String a2 = a.getClass().getName();
//followed by if/else if blocks to return true or false
//depending on operator and result
}
I have designed the if/else if blocks to ensure that no binary operator will be used for incompatible types (e.g. >= for a String object). The problem is that I get a "can't find symbol error" when I try to compile because the object class doesn't have a compareTo() method. If this was python, there wouldn't actually be any issue because I would never be putting anything into the comparison function that didn't have a compareTo() method. However, because of java's formatting I'm forced to declare the input as 'Object' because I can't say specifically what type of object I have to compare at a given moment.
Is there some way I could override Java's restrictions and force it to trust me that Object a will always have a compareTo() method? Because right now, it seems like I'm going to have to downcast the objects into Strings, ints, doubles, or booleans, and then write 4 different new comparison functions for each data type.
Upvotes: 0
Views: 145
Reputation: 140427
The Java way is to first use the instanceof
operator to then cast to an appropriate class:
if (a instanceof String && b instanceof String) {
String aAsString = (String) a;
int comparisonResult = a.compareTo(b);
compareTo()
gives you a negative result if a < b
, 0
when a == b
and a positive result if a > b
. So alone that int result tells you enough to decide what your potential comparison operations should result in. The numeric types int
/Integer
, ... have similar methods.
Of course this only works if your assumptions are really correct and the object is really a String
or Boolean
. And please note that boolean
and Boolean
are two somehow different types!
Upvotes: 1
Reputation: 4868
Since the compareTo
method is declared in the java.lang.Comparable<T>
interface, the usage of Bounded Type Parameters can constrain your a
and b
arguments in order to accept only objects which implement the interface itself.
You can check the operator
parameter in order to affect the boolean result.
If you wish, the usage of an enum
value helps to avoid string mismatching.
For brevity, the code below doesn't take in account null
values.
enum Operator {
GREATER_OR_EQUALS,
LESS_OR_EQUALS
}
public <T extends Comparable<T>> boolean comparison(T a, T b, Operator operator) {
int test = a.compareTo(b);
switch(operator) {
case GREATER_OR_EQUALS:
return test >= 0;
default:
return test <= 0;
}
}
Upvotes: 1
Reputation: 113
The top answer summarizes what I wanted to do. The code successfully compiled when I said
int result;
if (a instanceof Comparable && b instanceof Comparable) {
result = ((Comparable) a).compareTo((Comparable) b);
}
I haven't tested it, but fantaghirocco's solution also seems like it could work.
Upvotes: -1