2014-02-11 3 views
0

У меня есть кусок кода, который должен определить, существует ли заданное целое число между множеством других целых чисел. Я также хотел бы иметь это в случае с заявлением, чтобы не иметь избытка if..else утверждений везде. Вот немного кода:Как определяются диапазоны в Java?

switch (copies) { 
     case copies >= 0 && copies <= 99: copyPrice = 0.30; break; 
     case copies >= 100 && copies <= 499: copyPrice = 0.28; break; 
     case copies >= 500 && copies <= 749: copyPrice = 0.27; break; 
     case copies >= 750 && copies <= 1000: copyPrice = 0.26; break; 
     case copies > 1000: copies = 0.25; break; 
    } 

где copies целое и copyPrice является двойной. Я получаю несколько ошибок, говорящих, что он ожидает получить целое число, но вместо этого получает логическое значение. Каков наилучший (или оптимальный) способ настройки этого? Любая помощь очень ценится!

+3

Какой смысл в случае, если против-то еще? У вас так же много случаев, как и в случае других утверждений. – turbo

+1

«ожидает получить логическое значение, но получает двойной». - Я думаю, что ошибка говорила обратное. – Maroun

+1

Отметьте это сообщение http://stackoverflow.com/questions/7721332/ranges-in-java-whats-the-best-approach – mikemil

ответ

7

Эта линия (и аналогичные):

case copies >= 0 && copies <= 99: 

Возвращает ошибку компилятора, поскольку он дает boolean но компилятор ожидает int так copy объявлен как int.

Одним из способов решения этой проблемы является использование массива с заданными рангами, и есть переключатель заявление для индекса найден:

public double calculateCopyPrice(int copies) { 
    int[] range = { 99, 499, 749, 1000 }; 
    double copyPrice = 0; 
    int index = -1; 
    for (int i = 0; i < range.length; i++) { 
     if (range[i] >= copies) { 
      index = i; 
      break; 
     } 
    } 
    switch (index) { 
     case 0: copyPrice = 0.30; break; 
     case 1: copyPrice = 0.28; break; 
     case 2: copyPrice = 0.27; break; 
     case 3: copyPrice = 0.26; break; 
     default: copyPrice = 0.25; break; 
    } 
    //probably more logic here... 
    return copyPrice; 
} 

После некоторых тестов, я нашел более гибкое решение используя TreeMap<Integer, Double>, который позволяет вам иметь звонкий диапазон (то, что вы ищете) и облегчить поиск с помощью TreeMap#ceilingEntry:

//TreeMap to store the "ranges" 
TreeMap<Integer, Double> theMap = new TreeMap<Integer, Double>(); 
//add the data 
theMap.put(99, 0.3); 
theMap.put(499, 0.28); 
theMap.put(749, 0.27); 
theMap.put(1000, 0.26); 
//the "default" value for max entries 
theMap.put(Integer.MAX_VALUE, 0.25); 
//testing the solution 
Double ex1 = theMap.ceilingEntry(50).getValue(); 
Double ex2 = theMap.ceilingEntry(500).getValue(); 
Double ex3 = theMap.ceilingEntry(5000).getValue(); 
Double ex4 = theMap.ceilingEntry(100).getValue(); 
System.out.println(ex1); 
System.out.println(ex2); 
System.out.println(ex3); 
System.out.println(ex4); 
+1

+1 Хороший подход. Спасибо, что показал мне 'ceilingEntry()'. –

+0

@ XaviLópez добро пожаловать. –

+0

+1 для treemap – radai

2

java не имеет собственной концепции «диапазонов», не говоря уже о поддержке для них в случае утверждений.

обычно, когда сталкиваются с такой логикой я лично бы сделать одну из 2-х вещей:

  1. просто цепь, если это-то еще заявления. оленья кожа даже Habe быть цепь:

    public static double calculateCopyPrice(int copies) { 
        if (copies > 1000) return 0.25; 
        if (copies >= 750) return 0.26; 
        //etc 
    } 
    

    этот код не имеет «Else» ветви и так же, набрав в качестве синтаксиса переключателя вы хотите. возможно, даже меньше (я только проверить один связанный каждый раз)

  2. вы могли использовать перечисление, сказать:

    public enum Division {UNDER_100, 100_to_500, ... } 
    

    , а затем:

    Division division = categorize(copies); 
    switch (division) { 
        case UNDER_100: 
        //etc 
    } 
    

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

1

функция переключения случая должна иметь точную число в случае. Например:

case 0: 
case 1: 

Вы пытаетесь использовать случай с некоторого значения до некоторого значения, и это не реализовано, что путь в Java. Для вашей проблемы вы должны использовать инструкцию if-else, так как это невозможно сделать с помощью корпуса коммутатора. Надеюсь, это помогло.

1

Посмотрите, что проблема очень простая ..

В распределительном заявлении он позволяет только следующие типы данных и классы-оболочки байт, короткие, CHAR, INT, Byte, Short, символов, Integer, перечисление, Струнные ..

Если вы передаете ничего, кроме это даст вам ошибку. В вашем случае условие, которое вы оцениваете, даст вам результат, который является логическим значением.

0

NavigableMap.seilingEntry() может быть хорошим решением во многих случаях
, но в других случаях могут быть следующие понятнее:

double getPrice(int copies){ 
    return copies>1000 ? 0.25 
      : copies>750 ? 0.26 
      : copies>500 ? 0.27 
      : copies>100 ? 0.28 
      : copies>0 ? 0.30 
      : 0; // or check this condition first, throwing an exception 
} 
Смежные вопросы