2016-02-17 2 views
1

для расширения моих подразделений private Libary Я попытался реализовать метод isBetween. Этот метод является общим и ожидает Comparable типа T за его минимальное значение, его максимальное значение и значения varargs. Его цель - проверить, находятся ли все значения в указанном диапазоне.укажите общий тип аргументов метода

public static void main(String[] args) { 
    System.out.print(isBetween(1, 100, 200, 100, 1, 2)); 
    } 


    @SafeVarargs 
    public static <T extends Comparable> boolean isBetween(T minimum, T maximum, T... values) { 
    for (T value : values) { 
     if (!(value.compareTo(minimum) >= 0 && value.compareTo(maximum) <= 0)) 
     return false; 
    } 
    return true; 
    } 

Это работает просто отлично. Но тип T может содержать любые сопоставимые объекты. Вызов метода:

System.out.print(isBetween(1, 100, 200, 100, "How awkward", 2)); 

также принимается во время компиляции. Это не типичное и не может быть принято.

Два решения пришли мне на ум:

1. Вызовите метод как следующий

System.out.print(Class.<Integer>isBetween(1, 100, 200, 100, 1, 2));

2. сделать один из моих параметров метода типа U и удлинить тип T к типу U

Оба «решения» не очень элегантны. Для первого требуется написать дополнительный код, прежде чем вы вызовете метод, а второй - как взломать.

Есть ли еще более элегантные способы решения моей проблемы?

+3

'>'? – fge

+0

отлично это не приходило в голову, спасибо :) –

ответ

3

Ну, это может быть легко зафиксировано avoiding raw types.

Давайте посмотрим на код:

public static <T extends Comparable> boolean isBetween(T minimum, T maximum, T... values) { 
    // ... 
} 

T хороший и универсальный, но Comparable является сырьевым типа. Вы хотите Comparable<T>, так что ваш метод должен выглядеть следующим образом:

public static <T extends Comparable<T>> boolean isBetween(T minimum, T maximum, T... values) { 
    // ... 
} 

isBetween(1, 100, 200, 100, "How awkward", 2), а затем не будет возможно больше.


isBetween метод позволяет «равные» типы аргументов, если они имеют равный супер класс, который реализует Comparable.

Например, используя java.util.Date и java.sql.Date (пользователь fge имел эту хорошую идею):

isBetween(new java.util.Date(1L), new java.util.Date(4L), new java.sql.Date(5L)) 

Это приведет к «ложным», так как третий аргумент «больше», чем верхняя граница. И java.sql.Date принимается, потому что он расширяет java.util.Date и будет вызывать T с ним как «общий родительский класс, который реализует Comparable».

+1

Однако это не удастся, если ваши аргументы 'java.sql.Date's :) – fge

+1

@fge Если аргументы являются' java.util.Date' и 'java .sql.Date', то нет, он также работает. Этот метод позволяет использовать аргументы, которые имеют общий суперкласс, который также реализует «сопоставимый». – Tom

+0

@fge Или я не понял ваш комментарий? – Tom

1

Сделать это <T extends Comparable<T>>:

@SafeVarargs 
public static <T extends Comparable<T>> boolean isBetween(T minimum, T maximum, T... values) { 
    for (T value : values) { 
     if (!(value.compareTo(minimum) >= 0 && value.compareTo(maximum) <= 0)) 
      return false; 
    } 
    return true; 
} 

это произойдет сбой во время компиляции.

0

Использование сравнимого < T> вместо необработанного сравнимого. Таким образом, вы убедитесь, что все экземпляры типа T имеют один и тот же тип, и он не скомпилируется.

1

Другим способом вы могли бы сделать это передать в Comparator вместо того, чтобы требовать T быть Comparable:

public static <T> boolean isBetween(Comparator<? super T> comparator, 
     T minimum, T maximum, T... values) { 
    for (T value : values) { 
     if (!(comparator.compare(value, minimum) >= 0 && 
       comparator.compare(value, maximum) <= 0)){ 
      return false; 
     } 
    } 
    return true; 
} 

Это позволяет сравнивать объекты, как вы хотите, и они не должны быть Comparable ,

Вы также могли бы обеспечить такой же метод, чтобы другие ответы, чтобы пропустить записи Comparator когда T является Comparable:

public static <T extends Comparable<? super T>> boolean isBetween(T minimum, 
     T maximum, T... values) { 
    return isBetween(T::compareTo, minimum, maximum, values); 
} 
+0

Мне нравится идея с компаратором. Идея состояла в том, чтобы сделать простой метод для простых целей, но я также могу реализовать ваш расширенный метод:) ... К сожалению, мы работаем с java 7, надеюсь, что скоро получим обновление –

+0

Образец java 8 не работает для меня не может разрешить метод –

+0

@TomWellbrock Я скомпилировал его с eclipse и javac 1.8.0_51, оба эти метода работали каждый раз, но вызов версии компаратора дал мне ошибку с javac. Возможно, вам придется изменить имя одного из методов. Какую версию компилятора вы используете? – Alex

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