可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a Generic Class with two type variables, which implements java.lang.Comparable.
public class DoubleKey<K,J> implements Comparable<DoubleKey<K,J>>{
private K key1;
private J key2;
public DoubleKey(K key1, J key2){
this.key1 = key1;
this.key2 = key2;
}
public K getFirstKey(){
return this.key1;
}
public J getSecondKey(){
return this.key2;
}
// need for Comparable interface
public int compareTo(DoubleKey<K,J> aThat){
...
}
}
Becuase i implemeted it with Comparable, I need to write the compareTo() method. Because K, J can be of ANY type, I'm having problems on how to compare them completely. Is there a way to be able to catch all possible types (Primitive, Wrapper, Object) in the comparison? Thanks for the help!
回答1:
so to summarize the said above and to puzzle it together into a working code this is:
public class DoubleKey<K extends Comparable<K>, J extends Comparable<J>>
implements Comparable<DoubleKey<K, J>> {
private K key1;
private J key2;
public DoubleKey(K key1, J key2) {
this.key1 = key1;
this.key2 = key2;
}
public K getFirstKey() {
return this.key1;
}
public J getSecondKey() {
return this.key2;
}
public int compareTo(DoubleKey<K, J> that) {
int cmp = this.getFirstKey().compareTo(that.getFirstKey());
if (cmp == 0)
cmp = this.getSecondKey().compareTo(that.getSecondKey());
return cmp;
}
}
回答2:
Would you like to introduce a requirement that K
and J
have a natural ordering that you can use? In this case you can declare your class DoubleKey
like this:
class DoubleKey<K extends Comparable<K>, J extends Comparable<J>>
You can then define your DoubleKey's compareTo
as you like. You can do things like:
getFirstKey().compareTo(aThat.getFirstKey())
You can't compare any instance of K
to an instance of J
, though. There is no ordering defined over those types.
If these types don't necessarily have a natural ordering (many don't), you can take a Comparator<K>
and Comparator<J>
as parameters to the constructor of your DoubleKey
. A class that does this already that you can use as an example is Google Guava's excellent Maps class (see specifically the newTreeMap
methods and the bounds of the types they accept).
回答3:
public class DoubleKey<
K implements Comparable<K>,
J implements Comparable<J>>
implements Comparable<DoubleKey<K,J>> {
public int compareTo(DoubleKey<K,J> that){
int cmp = this.key1.compareTo(that.key1);
if(cmp==0) cmp = this.key2.compareTo(that.key2);
return cmp;
}
}
回答4:
You'll have to define a rule when a DoubleKey<K,J>
is smaller, bigger or equal to this one. That's what compare does. Maybe, that's my actual guess, it doesn't make much sense to compare to instances of DoubleKey<K,J>
.
If you don't actual care how they're ordered and only need to implement any ordering, try this:
public int compareTo(DoubleKey<K,J> that){
// real codes needs checks for null values!
return (this.key1.toString() + this.key2.toString()).compareTo(that.key1.toString() + that.key2.toString());
}
回答5:
First way: use hashCodes, like
public int compareTo(DoubleKey<K,J> aThat){
getFirstKey().hashCode() + getSecondKey().hashCode() - aThat.getFirstKey().hashCode() + aThat.getSecondKey().hashCode();
}
(you should think more about formula)
Second way:
add comparator to constructor
public DoubleKey(K key1, J key2, Comparator cmp){
回答6:
As is often the case, there exists a library that can solve your problem: Apache Commons lang3. I often use Pair<L,R> instances as keys. They implement Comparable.