Проверьте значение до «потолка» и верните соответствующую переменную - PullRequest
1 голос
/ 03 ноября 2011

У меня есть некоторые константы f.e.:

BigDecimal ceiling1 = new BigDecimal(5);
BigDecimal ceiling2 = new BigDecimal(10);
BigDecimal ceiling3 = new BigDecimal(20);

BigDecimal rate1 = new BigDecimal(0.01);
BigDecimal rate2 = new BigDecimal(0.02);
BigDecimal rate3 = new BigDecimal(0.04);
BigDecimal rate4 = new BigDecimal(0.09);

Теперь на основе параметра f.e.:

BigDecimal arg = new BigDecimal(6);

Я хочу получить правильную ставку, которая основана на этом, если структура (упрощенная):

if(arg <= ceiling1) {
   rate = rate1;
}else if(arg <= ceiling2) {
   rate = rate2;
} else if (arg <= ceiling3) {
   rate = rate3;
}else rate = rate4;

Так что в моем примере rate должно быть rate2

Но мне интересно, знает ли кто-нибудь лучший способ реализовать это, вместо связки ifs.

Любые указатели приветствуются!

PS: я знаю, что мой код не на 100% прав, просто хотел показать идею

Ответы [ 3 ]

4 голосов
/ 03 ноября 2011

Вы можете хранить свои потолки как ключи в TreeMap, а ваши ставки как значения.Затем используйте floorEntry и посмотрите также здесь .

final TreeMap<BigDecimal, BigDecimal> rates = new TreeMap<BigDecimal, BigDecimal>();
rates.put(new BigDecimal(0), new BigDecimal(0.01));
rates.put(new BigDecimal(5), new BigDecimal(0.02));
rates.put(new BigDecimal(10), new BigDecimal(0.04));
rates.put(new BigDecimal(20), new BigDecimal(0.09));

System.out.println(rates.floorEntry(new BigDecimal(0)).getValue());
System.out.println(rates.floorEntry(new BigDecimal(6)).getValue());
System.out.println(rates.floorEntry(new BigDecimal(10)).getValue());
System.out.println(rates.floorEntry(new BigDecimal(100)).getValue());

Test: http://ideone.com/VrucK. Возможно, вы захотите использовать другое представление, как вы можете видеть в тесте, оно выглядит некрасиво (Вроде целые числа для потолка).Между прочим, уродливый вывод происходит из того факта, что 0,01 - это двойное число , которое делает забавные вещи с десятичными представлениями .

Редактировать: Рекомендуется Очистка .

1 голос
/ 03 ноября 2011
class RateCalculator {
  double ceiling[] = new double[]{5,10,20};
  double rate[] = new double[]{0.01,0.02,0.04}
  // use assertions to ensure that the sizes of these two arrays are equal.
  // ensure that successive values in ceiling are higher than the last.
  public double calculateRate(double value) {
    for (int i=0;i<ceiling.length;++i) {
      if (value < ceiling[i]) {
        return rate[i];
      }
    // the rate for values higher than the highest ceiling
    return 0.09;
  }
}

Вы можете изменить количество тарифов, изменив размер массивов. Некоторые значения должны называться константами, чтобы следовать хорошему стилю программирования - они оставлены здесь как числа, чтобы проиллюстрировать соответствие между значениями OP и значениями здесь.

Преобразование в BigDecimal оставлено читателю в качестве упражнения.

1 голос
/ 03 ноября 2011

Я бы, вероятно, избавился бы от объектов BigDecimal и сохранил бы показатели (и потолки) как CONSTANTS (ФИНАЛЬНЫЕ переменные). Тогда я буду использовать оператор Switch, чтобы найти правильную ставку.

...