2016-08-16 1 views
-1

Моя следующая цель - реализовать Comparable Interface на конвертере римских номеров.Как реализовать интерфейс java.lang.Comparable по классу римского номера?

Может быть, мне нужно использовать интерфейс, как это:

public interface Comparable { 
    public int compareTo(Object x); 
    } 

и после реализации RomanNumber с этой инструкцией:

public class RomanNumber implements Comparable<RomanNumber> 

, но я не знаю, как продолжить. И еще мне нужно проверить в JUnit этот новый метод. Я думаю, что это:

@Override 
public int compareTo(Object o) { 
    if(this.number>((RomanNumber)o).convertToInteger()){ 
    return 1; 
    } else if(this.number<((RomanNumber)o).convertToInteger()){ 
    return -1; 
    } else{ 
    return 0; 
    } 
    } 
} 

Вот код тестируемой:

public class RomanNumber{ 
    private String number; 
    public RomanNumber (String number){ 
     validateState(number); 
     this.number = number; 
    } 
    public int convertToInteger() { 
     int decimal = 0; 
     int lastNumber = 0; 

     number = number.toUpperCase(); 
     for (int x = number.length() - 1; x >= 0; x--) { 
      char convertNumber = number.charAt(x); 
      switch (convertNumber) { 
      case 'M': 
       decimal = processDecimal(1000, lastNumber, decimal); 
       lastNumber = 1000; 
       break; 
      case 'D': 
       decimal = processDecimal(500, lastNumber, decimal); 
       lastNumber = 500; 
       break; 
      case 'C': 
       decimal = processDecimal(100, lastNumber, decimal); 
       lastNumber = 100; 
       break; 
      case 'L': 
       decimal = processDecimal(50, lastNumber, decimal); 
       lastNumber = 50; 
       break; 
      case 'X': 
       decimal = processDecimal(10, lastNumber, decimal); 
       lastNumber = 10; 
       break; 
      case 'V': 
       decimal = processDecimal(5, lastNumber, decimal); 
       lastNumber = 5; 
       break; 
      case 'I': 
       decimal = processDecimal(1, lastNumber, decimal); 
       lastNumber = 1; 
       break; 
      } 
     } 
     return decimal; 
    } 

static int processDecimal(int decimal, int lastNumber, int lastDecimal) { 
    if (lastNumber > decimal) { 
     return lastDecimal - decimal; 
    } else { 
     return lastDecimal + decimal; 
    } 
} 

private void validateState(String number){ 
    if (number == null) 
    throw new IllegalArgumentException("Null argument"); 
    if (number.isEmpty()) 
    throw new IllegalArgumentException("Empty string"); 
    if (!number.matches("^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$")) 
    throw new IllegalArgumentException("Invalid Roman number");  
} 

@Override 
public boolean equals(Object obj){ 
    if ((obj instanceof RomanNumber)) { 
    RomanNumber decimal = (RomanNumber)obj; 
    if (number.equals(decimal.number)) { 
     return true; 
    } else { 
     return false; 
    } 
    } else { 
    return false; 
    } 
} 

public int hashCode(){ 
    return number.hashCode(); 
} 
} 
+2

Ну, вам нужно добавить метод compareTo, и вам нужно написать логику, которая сравнивает два римских номера. Как вы узнаете, если один римский номер больше другого? Примените ту же логику к двум объектам, которые вы сравниваете. И в тесте Unit вам нужно проверить, что он работает, сравнивая несколько пар римских чисел. – RealSkeptic

+0

@RealSkeptic: спасибо Я понимаю логику. – InExperience

+0

Пожалуйста, отформатируйте свой код, чтобы он не прокручивался: удалите ненужные комментарии, пробелы и, самое главное, упростите код, чтобы показать точную проблему. – zhon

ответ

1

Давать вам некоторые отправные точки.

Первые тесты блок может выглядеть

@Test 
public void testConversionToIntegerD() { 
    assertThat(new RomanNumber("D").convertToInteger(), is(500)); 
} 

И можно было бы написать много много испытаний, как это; и сделать их более сложными, чтобы убедиться, что ваше преобразование верное. (в идеале вы бы написали те тесты , предшествующие, записывающие код конвертации).

И для того, чтобы сравнить с римскими номерами ... вы знаете, вы уже внесли конверсию в Integer ... может быть, может быть, это может дать подсказку, как сравнить с римскими цифрами ?! Тест на который может выглядеть следующим образом:

@Test 
public void testComparingDtoM() { 
    assertThat(new RomanNumber("D").compareTo(new RomanNumber("M")), is(-1)); 
} 

И слово предупреждения: Вы хотите, чтобы провести некоторое время, думая о «угловых случаях»; эти приятные римские цифры, которые действительно сложны. В идеале, если вы делаете эту вещь в классной комнате, у вас должно быть других людей, которые записывают контрольные образцы. Когда вы делаете такие вещи в одиночку, всегда есть определенный шанс, что вы упускаете эти «угловые случаи» как в тестах, так и в поддержке.

(наконец: я использовал assertThat, так как этот стиль утверждений позволяет писать все виды больших условий, единственным недостатком является то, что вам нужно использовать его с Hamcrest matchers как является А если серьезно: это будет. стоит ваше время узнать о том, что вещи)

+2

Если бы был только удобный способ сравнения целых чисел, хотя ... –

+0

@GhostCat: Большое вам спасибо за предложение предложить тестовые примеры. Но в мастер-классе мне нужно поставить: public class RomanNumber реализует Comparable и после переопределения CompareTo? – InExperience

+0

А, да. Видите ли, вы уже использовали '@ Override' с equals(), поэтому я предположил, что вы были знакомы с этим. Но правильно, чтобы сделать ваш римский номер сопоставимым, вы должны реализовать этот интерфейс. – GhostCat

0

это моя логическая идея:

public int compareTo(RomanNumber other){     
       // Compare RomanNumber 
      if (this.convertToInteger()<other.convertToInteger()) 
       return -1; 
      if(this.convertToInteger()>other.convertToInteger()) 
       return 1; 
      return 0; 

и для теста JUnit:

// TODO test instance comparison 
@Test 
public void shouldCompareInstances() { 

    RomanNumber rn1 = new RomanNumber("M"); 
    RomanNumber rn2 = new RomanNumber("MM"); 
    Assert.assertTrue(rn1.compareTo(rn2) == -1); 
} 
Смежные вопросы