我的下一个目标是在罗马数字转换器上实现可比较接口。
也许我需要使用这样的界面:
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();
}
}
最佳答案
给你一些起点。
第一单元测试可能看起来像
@Test
public void testConversionToIntegerD() {
assertThat(new RomanNumber("D").convertToInteger(), is(500));
}
这样,您将编写许多测试。并使其更加复杂,以确保您的转换正确无误。
(理想情况下,您应该先编写这些测试,然后再编写转换代码)。
并且为了与罗马数字进行比较……您知道,您已经实现了对整数的转换……也许,这可能会提示如何与罗马数字进行比较?!一个测试可能看起来像:
@Test
public void testComparingDtoM() {
assertThat(new RomanNumber("D").compareTo(new RomanNumber("M")), is(-1));
}
还有一个警告:您想花很多时间思考“拐角事件”;那些非常复杂的罗马数字。
理想情况下,如果您在教室里做这个事情,应该让其他人来编写测试用例。当您单独执行此类操作时,总是有一定的机会在测试和支持实现中忽略那些“关键情况”。
(最后:我使用assert断言,因为这种断言样式允许编写各种出色的条件;唯一的缺点是您需要像这样与Hamcrest匹配器一起使用它。但是,认真的说:值得您花时间学习一下那东西)