2015-08-03 2 views
0

Я хотел бы, чтобы следующее работало: У меня есть общий класс public class TypeType<T1,T2>, который имеет два поля: public T1 t1 и public T2 t2. Я хотел бы написать два метода public static Comparator для этого класса, compareFirst() и compareSecond(). Я хотел бы, чтобы первый метод сравнивался только на основе t1 s, а второй - только на основе t2 s. Первый метод дает допустимый выход , еслиT1 implements Comparable<T1> и второй , еслиT2 implements Comparable<T2>.Компаратор класса generic в Java

Возможно ли это как можно? Есть ли способ проверить, что T1 и T2 реализовать Comparable? Если нет, могу ли я сделать эту работу? (Этот класс предназначен только для внутреннего использования.)

Спасибо!

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); 
      } 
     } 
    } 

} 

В случае интересно другим: я в конечном итоге реализации решения @ 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); 
    }; 
} 
+0

возвращаемый тип будет что-то вроде 'Comparator ,? >>' – njzk2

+0

вы должны быть общие объекты всегда иметь Сопоставимые реализованы или делать это необходимо с обоих случаях делать? Технически вам не нужны дженерики, если вы хотите, чтобы это были объекты «Comparable», просто попросите интерфейс в конструкторе – engineercoding

ответ

1

Есть несколько хороших ответов здесь, но обратите внимание, что с Java 8 вы можете вернуть лямбду.

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); 
} 
+0

Это выглядит очень гладко, мне это очень нравится. Спасибо! – dotwin

+1

Я бы рекомендовал что-то еще более простое - статический импорт 'Comparator.comparing' и написать' сравнение (tt -> tt.t1) 'для первой версии и' сравнение (tt -> tt.t2) 'для второй. –

1

Оператор instanceof может быть использован как видеть, если конкретный класс является производным от класса, или если класс реализует определенный интерфейс.

i.e. t1 instanceof Comparable вернет true, если он реализует Comparable.

Просто имейте в виду, что генераторы не существуют во время выполнения, поэтому вы можете только проверить, реализует ли он Comparable, а не то, что он реализует Comparable<T1>.

+0

Полезно знать, спасибо. – dotwin

0
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); 
     } 
    } 
} 
1

Это должно удовлетворить ваши потребности:

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); 
    } 

    }; 
} 

Пожалуйста, обратите внимание, что вы не сможете создать компаратор с TypeType экземпляров, которые не параметризованных с типами, которые не проходят Comparable.

+0

Это работает, спасибо вам большое. – dotwin

0

Вы можете использовать следующее определение класса для обеспечения, что оба T1 и T2 реализовать Comparable, так что вы не должны проверить его во время выполнения:

public class TypeType<T1 extends Comparable<T1>, T2 extends Comparable<T2>> { 
... 
} 
Смежные вопросы