简体   繁体   English

Java泛型类的比较器

[英]Comparator of generic class in Java

I would like the following thing to work: I have a generic class public class TypeType<T1,T2> that has two fields public T1 t1 and public T2 t2 . public class TypeType<T1,T2>以下事情:我有一个通用类public class TypeType<T1,T2> ,它具有两个字段public T1 t1public T2 t2 I would like to write two public static Comparator methods for this class, compareFirst() and compareSecond() . 我想为此类编写两个public static Comparator方法, compareFirst()compareSecond() I would like the first method to compare only based on the t1 s, and the second only based on the t2 s. 我希望第一种方法仅基于t1进行比较,第二种仅基于t2 The first method produces valid output if T1 implements Comparable<T1> and the second if T2 implements Comparable<T2> . 第一种方法产生有效的输出,如果 T1 implements Comparable<T1>和第二如果 T2 implements Comparable<T2>

Is something like this possible? 这样的事情可能吗? Is there a way to check that T1 and T2 implement Comparable ? 有没有办法检查T1T2实现Comparable If not, can I still make this work? 如果没有,我仍然可以进行这项工作吗? (This class is only for internal usage.) (此类仅供内部使用。)

Thanks a bunch! 谢谢一群!

public class TypeType<T1,T2> {

    public T1 t1;
    public T2 t2;

    public TypeType() {
        this(null, null);
    }

    public TypeType(T1 t1, T2 t2) {
        this.t1 = t1;
        this.t2 = t2;
    }

    /*
     * I know that the following does not work.
     * This is just pseudo-code for what I would like to achieve.
     */
    public static Comparator<TypeType<?,?>> comparatorFirst() {
        return new Comparator<TypeType<?,?>> {
            public int compare(TypeType<?,?> tt1, TypeType<?,?> tt2) {
                return tt1.t1.compareTo(tt2.t1);
            }
        }
    }

}

In case interesting to others: I ended up implementing @pbabcdefp's Java 8 solution using Lambda Expressions. 以防其他人感兴趣:我最终使用Lambda Expressions实现了@pbabcdefp的Java 8解决方案。

public static <T1 extends Comparable<? super T1>> Comparator<TypeType<T1,?>> compareOne() {
    return (tt1, tt2) -> tt1.t1.compareTo(tt2.t1);
}

public static <T2 extends Comparable<? super T2>> Comparator<TypeType<?,T2>> compareTwo() {
    return (tt1, tt2) -> tt1.t2.compareTo(tt2.t2);
}

public static <T1 extends Comparable<? super T1>,T2 extends Comparable<? super T2>> Comparator<TypeType<T1,T2>> compareOneThenTwo() {
    return (tt1, tt2) -> {
        if ( tt1.t1.equals(tt2.t1) )
            return tt1.t2.compareTo(tt2.t2);
        else
            return tt1.t1.compareTo(tt2.t1);
    };
}

public static <T1 extends Comparable<? super T1>,T2 extends Comparable<? super T2>> Comparator<TypeType<T1,T2>> compareTwoThenOne() {
    return (tt1, tt2) -> {
        if ( tt1.t2.equals(tt2.t2) )
            return tt1.t1.compareTo(tt2.t1);
        else
            return tt1.t2.compareTo(tt2.t2);
    };
}

The instanceof operator can be used both to see if a specific class is derived from a class or if a class implements a specific interface. 可以使用instanceof运算符查看特定类是否派生自某个类,或者该类是否实现特定接口。

ie t1 instanceof Comparable would return true if it implements Comparable . 也就是说,如果t1 instanceof Comparable实现Comparable则将返回true

Just be aware that generics don't exist at runtime, so you can only check if implements Comparable , not that it implements Comparable<T1> . 请注意,泛型在运行时不存在,因此您只能检查是否实现Comparable ,而不是它实现Comparable<T1>

This should suit your needs: 这应该满足您的需求:

public static <U1 extends Comparable<? super U1>, U2 extends Comparable<? super U2>> Comparator<TypeType<U1, U2>> compareFirst() {
  return new Comparator<TypeType<U1, U2>>() {

    @Override
    public int compare(TypeType<U1, U2> o1, TypeType<U1, U2> o2) {
      return o1.t1.compareTo(o2.t1);
    }

  };
}

Please note that you won't be able to create a comparator with TypeType instances that are not parameterized with types that don't extend Comparable . 请注意,您将无法使用未使用不扩展Comparable类型进行参数化的TypeType实例创建比较器。

There are several good answers here, but note that with Java 8 you can return a lambda. 这里有几个很好的答案,但是请注意,使用Java 8可以返回一个lambda。

public static <T1 extends Comparable<? super T1>> Comparator<TypeType<T1,?>> comparatorFirst() {
    return (tt1, tt2) -> tt1.t1.compareTo(tt2.t1);
}

public static <T2 extends Comparable<? super T2>> Comparator<TypeType<?, T2>> comparatorSecond() {
    return (tt1, tt2) -> tt1.t2.compareTo(tt2.t2);
}
public static Comparator<TypeType<T1 extends Comparable<T1>,T1 extends Comparable<T2>>> comparatorFirst() {
    return new Comparator<> {
        public int compare(TypeType<T1,T2> tt1, TypeType<T1,T2> tt2) {
            return tt1.t1.compareTo(tt2.t1);
        }
    }
}

You can use the following class definition to enforce that both T1 and T2 implement Comparable , so you don't have to check it at runtime: 您可以使用以下类定义来强制T1T2实现Comparable ,因此您不必在运行时检查它:

public class TypeType<T1 extends Comparable<T1>, T2 extends Comparable<T2>> {
...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM