2011-04-01 2 views
1

У меня есть класс, который содержит различные типы и реализует интерфейс Iterable<Object>. Но для меня очень важно, что я могу сравнивать элементы. Я знаю, что я не могу написать что-то вроде: Iterable<Object & Comparable<?>>, так что мне делать?Как сделать объекты сопоставимыми

я обеспечил, что каждый отдельный элемент, содержащийся в классе:

  • не может быть null.
  • Является сопоставимым с элементами того же типа.
  • Неизменяется. Ну, по крайней мере, часть, которую я проверяю.

Это не то, что я просто хочу, чтобы сравнить элементы, потому что я могу сделать это с помощью:

private static int hackCMP(Object val, Object val2) 
     throws SecurityException, NoSuchMethodException, 
     IllegalArgumentException, IllegalAccessException, 
     InvocationTargetException { 
    Method m = val.getClass().getMethod("compareTo", val.getClass()); 
    return (Integer) m.invoke(val, val2); 
} 

Я хочу передать элементы в качестве входных данных в другой класс непрямого конструктор, который также обеспечивает элементы должны быть сопоставимым. Этот метод:

public static <T extends Comparable<?>> Os of(final Iterator<T> values) { 
+1

'Iterable >' на самом деле вы можете. ;) –

+3

Почему бы просто не изменить свою подпись на 'Iterable >'? Вы ничего не получаете, явно заявляя, что ваши объекты должны расширять 'Object', поскольку все объекты выполняются. –

+0

@Dave Costa: Тай, это исправило мою проблему. – Margus

ответ

2

Dave Costa делает пункт выше, что вы должны действительно быть просто с помощью Iterator<Comparable<?>>, а не иметь Object там. Ваш тип должен быть как можно более конкретным. Если у вас есть методы, которые ожидают Comparable<?>, используйте его. Методы, принимающие объекты, могут принимать что угодно, в том числе Comparable s.

1

Вы можете написать

public static <T extends Object & Comparable<?>> Os of(final Iterator<T> values) { 

Это ваш вопрос?

EDIT: Если вы хотите предположить, что объект сопоставим, вы можете это сделать.

public static int compare(Object o1, Object o2) { 
    return ((Comparable) o1).compareTo((Compareable) o2); 
} 
+1

Нет, это не мой вопрос. '>' такой же, как '>' (Класс Object является корнем иерархии классов. Каждый класс имеет объект как суперкласс). – Margus

+0

Я верю, что есть разногласия в отношении дженериков, но это ускользает от меня. В любом случае, каков ваш вопрос? –

+0

Ну, если я знаю, что все элементы сопоставимы, но они хранятся как объекты. Затем, как передать их методу, который также предполагает, что вы сопоставимы. – Margus

0

Лучше всего использовать это <T extends Comparable<? super T>>

Вы должны иметь в там второй T, потому что когда у вас есть T extends Comparable<?>, что на самом деле не обеспечивают, что тип сравнима с самим собой. Вы можете подумать, что это глупо, но для меня вполне возможно сделать класс Foo implements Comparable<String>, и поэтому Foo объекты не могут сравниться с самим собой. Без второго T там вы не сможете гарантировать, что объект сравнивается с самим собой, и ему придется либо использовать или использовать необработанные типы, либо что-то небезопасное, чтобы иметь возможность передать его.

? super является немного более тонким. Это необходимо, если вы рассматриваете подклассы классов Comparable. Например, если A implements Comparable<A> и B extends A, то автоматически B implements Comparable<A> (B не может implement Comparable<B>, поскольку он может реализовывать интерфейс только один раз). Чтобы позволить B работать с вашим дизайном, параметр Comparable должен быть ? super T вместо T, чтобы он стал суперклассом T.

Смежные вопросы