如何创建混合比较器?
How to create a Mixed Comparator?
我有一个 table 全值,其中前 2 位数字是年份,接下来的 3 位数字是 0 到 999 之间的值,最后 2 个字符是 2 个 alphaOnly 字符。一些示例值:0、0、99001AG、99002FG、54001AG、54050AB,还有一些值只是 6 位字符串 SGP4DC 的实例。将有多个值是 SGP4DC。 0 是错误数据,但出于测试目的我必须考虑它们。
特殊情况:由于是两位数年份,因此在降序排序时,1999 年的发射(例如 99001A)总是比 2000 年的发射(例如 06001A)排序为 "greater"。特殊处理程序应确保 00 到 56 之间的任何项目的排序大于 57 到 99 之间的任何项目。
现在我的排序目标是先按前 2 位数字排序,以解决上述特殊情况。然后用以下 3 位数字跟进。最后只是对最后 2 个字符进行字符串排序。最后,对不以 2 个数字开头的值进行字符串比较。
预期按升序排序的示例是
0
0
60001AG
60002FB
42001AG
42002GD
APG4GP
APG4GP
再次注意,如果前 2 位数字大于或等于 57,则表示 1957-1999。如果前 2 位数字小于 57,则表示 2000-2056。
最后是我的代码。请注意,我目前在 table 中有一些值为 0 的虚假数据。因此我试图让它们小于其他所有数据。我无权删除 0,所以我试图围绕它们进行编码。 IE 0 将始终出现在上述排序列表之后。
@Override
public int compare(String o1, String o2) {
if(o1.equals("0") && o2.equals("0")){
return 0;
}
System.out.println("Comparing " + o1 + " and " + o2);
if (o1.length() == 1) {
return -1;
}
if (o2.length() == 1) {
return 1;
}
String o1year = null;
String o2year = null;
Integer obj1year;
Integer obj2year;
if (o1.length() >= 2) {
o1year = o1.substring(0, 2);
}
if (o2.length() >= 2) {
o2year = o2.substring(0, 2);
}
if (isInteger(o1year)) {
if (isInteger(o2year)) {
obj1year = Integer.parseInt(o1year);
obj2year = Integer.parseInt(o2year);
// handles years 2000 - 2056 being greater than anything from
// ##57-##99
if (obj1year < 57 && obj2year > 56) {
return 1;
}
if (obj1year == obj2year) {
int returnValue = compareIncriment(o1, o2);
if(returnValue == 0){
return o1.compareToIgnoreCase(o2);
}
return returnValue;
}
if (obj1year > obj2year) {
return 1;
} else {
return -1;
}
}
return 1;
}
// object 2 starts with a 2 digit year and object 1 didnt
if (isInteger(o2year)) {
return -1;
}
// final return
return o1.compareToIgnoreCase(o2);
}
private int compareIncriment(String o1, String o2) {
// TODO Auto-generated method stub
int inc1;
int inc2;
if(isInteger(o1.substring(2, 4))){
inc1 = Integer.parseInt(o1.substring(2, 4));
}else if(isInteger(o1.substring(2, 3))){
inc1 = Integer.parseInt(o1.substring(2, 3));
}else{
inc1 = Integer.parseInt(o1.substring(2, 2));
}
if(isInteger(o2.substring(2, 4))){
inc2 = Integer.parseInt(o2.substring(2, 4));
}else if(isInteger(o2.substring(2, 3))){
inc2 = Integer.parseInt(o2.substring(2, 3));
}else{
inc2 = Integer.parseInt(o2.substring(2, 2));
}
return inc1 - inc2;
}
更新代码***
我目前在我的 table 中看不到任何内容,并且我收到一个比较方法违反其一般合同错误。
您应该为比较器编写单元测试以发现错误。您还应该更好地分解代码,因为您的函数很难理解。首先,class将商品编码分为“0”、有年份、无年份。如果两个代码不相同class,return相应的结果。
如果它们在同一个 class 中,则将特定比较分解为单独的函数,甚至单独的比较器。有单独的比较器使它们更容易测试;单独的函数更难证明 public.
的合理性
我通过查看代码发现了一个错误:对于 c.compare("0", "0")
它 return 应该 return 0
却 -1
。除此之外,就真的不好说了。
我有一个 table 全值,其中前 2 位数字是年份,接下来的 3 位数字是 0 到 999 之间的值,最后 2 个字符是 2 个 alphaOnly 字符。一些示例值:0、0、99001AG、99002FG、54001AG、54050AB,还有一些值只是 6 位字符串 SGP4DC 的实例。将有多个值是 SGP4DC。 0 是错误数据,但出于测试目的我必须考虑它们。
特殊情况:由于是两位数年份,因此在降序排序时,1999 年的发射(例如 99001A)总是比 2000 年的发射(例如 06001A)排序为 "greater"。特殊处理程序应确保 00 到 56 之间的任何项目的排序大于 57 到 99 之间的任何项目。
现在我的排序目标是先按前 2 位数字排序,以解决上述特殊情况。然后用以下 3 位数字跟进。最后只是对最后 2 个字符进行字符串排序。最后,对不以 2 个数字开头的值进行字符串比较。
预期按升序排序的示例是 0 0 60001AG 60002FB 42001AG 42002GD APG4GP APG4GP
再次注意,如果前 2 位数字大于或等于 57,则表示 1957-1999。如果前 2 位数字小于 57,则表示 2000-2056。
最后是我的代码。请注意,我目前在 table 中有一些值为 0 的虚假数据。因此我试图让它们小于其他所有数据。我无权删除 0,所以我试图围绕它们进行编码。 IE 0 将始终出现在上述排序列表之后。
@Override
public int compare(String o1, String o2) {
if(o1.equals("0") && o2.equals("0")){
return 0;
}
System.out.println("Comparing " + o1 + " and " + o2);
if (o1.length() == 1) {
return -1;
}
if (o2.length() == 1) {
return 1;
}
String o1year = null;
String o2year = null;
Integer obj1year;
Integer obj2year;
if (o1.length() >= 2) {
o1year = o1.substring(0, 2);
}
if (o2.length() >= 2) {
o2year = o2.substring(0, 2);
}
if (isInteger(o1year)) {
if (isInteger(o2year)) {
obj1year = Integer.parseInt(o1year);
obj2year = Integer.parseInt(o2year);
// handles years 2000 - 2056 being greater than anything from
// ##57-##99
if (obj1year < 57 && obj2year > 56) {
return 1;
}
if (obj1year == obj2year) {
int returnValue = compareIncriment(o1, o2);
if(returnValue == 0){
return o1.compareToIgnoreCase(o2);
}
return returnValue;
}
if (obj1year > obj2year) {
return 1;
} else {
return -1;
}
}
return 1;
}
// object 2 starts with a 2 digit year and object 1 didnt
if (isInteger(o2year)) {
return -1;
}
// final return
return o1.compareToIgnoreCase(o2);
}
private int compareIncriment(String o1, String o2) {
// TODO Auto-generated method stub
int inc1;
int inc2;
if(isInteger(o1.substring(2, 4))){
inc1 = Integer.parseInt(o1.substring(2, 4));
}else if(isInteger(o1.substring(2, 3))){
inc1 = Integer.parseInt(o1.substring(2, 3));
}else{
inc1 = Integer.parseInt(o1.substring(2, 2));
}
if(isInteger(o2.substring(2, 4))){
inc2 = Integer.parseInt(o2.substring(2, 4));
}else if(isInteger(o2.substring(2, 3))){
inc2 = Integer.parseInt(o2.substring(2, 3));
}else{
inc2 = Integer.parseInt(o2.substring(2, 2));
}
return inc1 - inc2;
}
更新代码***
我目前在我的 table 中看不到任何内容,并且我收到一个比较方法违反其一般合同错误。
您应该为比较器编写单元测试以发现错误。您还应该更好地分解代码,因为您的函数很难理解。首先,class将商品编码分为“0”、有年份、无年份。如果两个代码不相同class,return相应的结果。
如果它们在同一个 class 中,则将特定比较分解为单独的函数,甚至单独的比较器。有单独的比较器使它们更容易测试;单独的函数更难证明 public.
的合理性我通过查看代码发现了一个错误:对于 c.compare("0", "0")
它 return 应该 return 0
却 -1
。除此之外,就真的不好说了。