泛型对类的compareTo()方法

  • 本文关键字:方法 compareTo 泛型 java
  • 更新时间 :
  • 英文 :


下午好!我用Java编写了下面的通用Pair类,想知道是否有人能帮我为这个类编写compareTo((方法?我希望这个方法首先比较两个对象的第一个元素,只有当它们相等时,它才会比较第二个元素。

public class Pair<T extends Comparable> {
protected T first;
protected T second;
public Pair() {
first = second = null;
}
public Pair(T val1, T val2) {
first = val1;
second = val2;
}
public T getFirst() {
return first;
}
public T getSecnd() {
return second;
}
public void setFirst(T val) {
first = val;
}
public void setSecond(T val) {
second = val;
}
public String toString() {
return "[" + first + "," + second + "]";
}
public boolean equals(Object other) {
if(other == null)
return false;
else if (getClass() != other.getClass())
return false;
else {
Pair<T> otherPair = (Pair<T>) other;
return (first.equals(otherPair.first) && second.equals(otherPair.second));
}
}
public static void main(String[] args) {
Pair<Integer> location = new Pair<>(4, 6);
Pair<String> team = new Pair<>("Steven", "Rebecca");
System.out.println(location);
System.out.println(team);
}

}

它变得有点复杂。事实上,编写的API不能这样做。在java中,所有对象都必须与equals进行比较/可以放在哈希集中(从某种意义上说,所有对象都有hashCode()equals()方法(。。但它们并非都有compareTo方法。

排序(排序、树集等(的实现方式根本不同。与平等不同,几乎每个地方都有可比性,如果您愿意,可以提供自己的Comparator。例如,您可以有一个TreeSet(这是一个保持自身排序的集合(,其中组件类型是Comparable(意思是:定义自然顺序的类。并非所有类都这样做,只有那些实现Comparable<Self>的类(,在创建Comparator<T>对象时必须传递它。

例如,HashSet没有构造函数,您可以在其中传递自定义的"Equalator"或whatnot,因此:它们的工作方式不同。

你必须匹配该功能。因此,您的Pair类必须用Comparator初始化,泛型需要有界,以便Pair的类型至少是Comparable,或者最好是两者都是。

选项1:

class Pair<E> implements Comparable<Pair<E>> {
final E first, second;
final Comparator<? super E> comparator;
public Pair(E first, E second, Comparator<? super E> comparator) {
this.first = first;
this.second = second;
this.comparator = comparator;
}
@Override public int compareTo(Pair<E> other) {
int c = comparator.compare(this.first, other.first);
if (c != 0) return c;
return comparator.compare(this.second, other.second);
}
}

第二种选择:

class Pair<E extends Comparable<E>> implements Comparable<Pair<E>> {
@Override public int compareTo(Pair<E> other) {
int c = this.first.compareTo(other.first);
if (c != 0) return c;
return this.second.compare(other.second);
}
}

第一个有效的原因是——你不需要如何根据第二对中的"第一个"来排序第一对中的第一个。。但那个比较器确实有,所以你只需要让它做比较。

第二个工作的原因是-E的下界是Comparable<E>,也就是说,它有compareTo(E other)方法,所以我们只调用它来完成这项工作。

你可以检查例如java.util.TreeSet的源代码,了解如何同时做到这两件事——它需要在构造函数上使用泛型来自动设置比较器(它可能需要一些"泛型技巧",告诉javac关闭不匹配的泛型,因为你知道即使分析太复杂,编译器也不会失败,它也会抱怨(。

注意:一般来说,这对课是个坏主意。Java是非常标称的-事物应该被适当地命名。Pair是反命名的——Pair作为一个词几乎什么都不说。它很好用,只是。。不太喜欢java。此外,您的Pair要求"left"one_answers"right"都是相同的类型,这似乎是不必要的限制(您可以有多个类型参数!(,并且是可变的,这与大多数关于如何编写此类库的现代想法背道而驰。这两个字段应该是私有的。您的代码也是"null混乱"的。它允许您将firstsecond设置为null(如果您尝试,则不会在setFirst中引发异常,并且没有args构造函数(,但是如果您尝试将一个Pair对象(其中一个或两个组件都是null(包含到使用其可比性的任何对象中,则比较器将崩溃。这看起来很奇怪。

最新更新