如何比较 Java 中一个类的两个不同的泛型实例化?

How to compare two different generic instantiations of a class in Java?

提问人:kesarling He-Him 提问时间:10/9/2023 更新时间:10/9/2023 访问量:84

问:

MRE,因为好吧,任务......叹息

这就是我遇到的问题:考虑以下类:

class MyClass<T extends Comparable<T>> implements Comparable<MyClass<T>> {

... override the compareTo
}

这使我可以与另一个甚至另一个进行比较. 但是,作业要求我能够进行比较,因为比较仅使用计数器并返回具有较大计数器的类作为两者中较大的一个。
我该如何实现这一目标?我的猜测是比较器开始发挥作用,这在这里很明显。但是,我无法完全理解它。是像使用比较器中的比较(Object,Object)一样简单,还是其他东西
MyClass<Integer>MyClass<Integer>MyClass<MyClass<Integer>>MyClass<MyClass<Integer>>MyClass<MyClass<Integer>>MyClass<MyClass<String>>

Java Comparator 可比

评论

0赞 Progman 10/9/2023
编辑您的问题以包含完整的完整作业。
0赞 kesarling He-Him 10/9/2023
嗯,好吧......抄袭检查器检查得如此积极...... @Progman
0赞 kesarling He-Him 10/9/2023
我不需要代码,甚至一个提示都可能起作用。
1赞 Progman 10/9/2023
原始作业中可能有一些信息可以更清楚地说明您正在尝试做什么或应该做什么。这就是为什么原始作业应该在问题中的原因。

答:

3赞 babanin 10/9/2023 #1

可以使用已知作为通配符,而不是显式指定类型:?

class MyClass<T extends Comparable<T>> implements Comparable<MyClass<?>> {
    private int counter; // or any other variable
    
    @Override
    public int compareTo(MyClass<?> o) {
        return counter - o.counter;
    }
}

然后像这样使用它:

MyClass<String> string = new MyClass<>();
MyClass<Integer> integer = new MyClass<>();

int result = string.compareTo(integer);

评论

0赞 kesarling He-Him 10/9/2023
这也适用于原始实例化,对吧?
0赞 babanin 10/9/2023
@kesarlingHe-他 - 对
0赞 Slaw 10/9/2023
@kesarlingHe-Him Raw 类型会擦除范围内的所有泛型。因此,即使您拥有它,它也会“适用于”原始类型。但这并不重要,因为你永远不应该使用原始类型,除非你真的无法避免它(例如,与非常古老的遗留代码交互)。implements Comparable<MyClass<T>>MyClass
0赞 Slaw 10/9/2023
请注意,绑定 没有多大意义,除非由于其他原因,它具有可比性很重要。因为现在,实现没有使用,也不可能使用,因为无法与 进行比较。Textends Comparable<T>TcompareToT?
2赞 WJS 10/9/2023 #2

根据巴巴宁的回答,我有几点建议。

  • 摆脱它,因为它没有发挥作用。T extends Comparable<T>
  • 虽然在这种情况下可能无关紧要,但不要养成减去整数进行比较的习惯。使用将确保您在遇到 int 溢出时不会得到错误的结果。Integer.compare(int a, int b)
class MyClass<T> implements Comparable<MyClass<?>> {
    T value;
    int counter;
    public MyClass(T val, int v) {
        this.counter = v;
        this.value = val;
    }
    
    @Override
    public int compareTo(MyClass<?> ob) {
        return Integer.compare(this.counter, ob.counter);
    }
}

另一种方法是声明一个具有支持计数器方法和值的 THAT。然后只是扩展它的问题。当然,根据您的用例,此替代方案可能没有用处(并且它确实会耗尽您的单个允许类扩展)。abstract class

abstract class MyCounter implements Comparable<MyCounter> {
    protected int counter;
    public int getCounter() {
        return counter;
    }
    public int compareTo(MyCounter obj) {
        return Integer.compare(this.counter, obj.counter);
    }
    // other methods that may be useful to a counter.
}     

class MyClass<T> extends MyCounter {
    T value;
    public MyClass(T val, int v) {
        this.counter = v;
        this.value = val;
    }
    // other required code here.
} 

并考虑它不能支持类型唯一的操作。例如,您不能同时拥有方法和方法,即使可以是 或 。1 但是你可以有一个方法和一个方法,因为列表可能包含不同的类型。MyClass<T>TdividereverseStringTDoubleStringList<T> getList()void addToList(T val)


1 对于有限的类型,您可以执行此操作,但您必须检查类型,确保操作适合该类型,然后强制转换为该类型。但这将是一个设计不佳的类,根本无法扩展。