Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在java中使用comparator实现几个特性_Java_Sorting_Comparator - Fatal编程技术网

在java中使用comparator实现几个特性

在java中使用comparator实现几个特性,java,sorting,comparator,Java,Sorting,Comparator,我有一个要排序的列表,但如果值表示为字符串,则无法排序。例如: to sort: OB123, OB1212, Maintenance, Daily check, OB123 desired result: Daily check, Maintenance, OB123, OB123, OB1212 if values are strings result is: Daily check, Maintenance, OB1212, OB123,OB123 因此,我需要使用比较器,首先按照航空公

我有一个要排序的列表,但如果值表示为字符串,则无法排序。例如:

to sort: OB123, OB1212, Maintenance, Daily check, OB123
desired result: Daily check, Maintenance, OB123, OB123, OB1212
if values are strings result is: Daily check, Maintenance, OB1212, OB123,OB123
因此,我需要使用比较器,首先按照航空公司(OB)对飞机编号进行排序,比如OB123,而不是按照其编号(123),有时是后缀(“”)。之后,我想将整个名称与所有其他值进行比较,如“每日检查”等。 到目前为止,我只能对航班ID进行排序:

@Override
public int compareTo(FlightNumberDisplay toCompare) {

int result = _carrier.compareTo(toCompare.getCarrier());
if (result == 0) {
  result = _number.compareTo(toCompare.getNumber());
  if (result == 0) {
    result = _suffix.compareTo(toCompare.getSuffix());
  }
}

return result;
}

因此,由于“每日检查”也有载体+数字+后缀表示,因此它是根据载体+数字+后缀进行排序的。问题是如何根据名称对其进行排序。

您可以在另一个列表中提取承运商信息,在那里您可以使用
parseInt()
按整数对其进行解析,然后对其进行排序


稍后您可以合并这两个列表。

您可以对字符串中的数字进行比较检查:

FlightComparator.java

public class FlightComparator implements Comparator<String> {
    public int compare(String arg0, String arg1) {
        // both have numbers, compare them
        if (containsNumber(arg0) && containsNumber(arg0)) {
            Integer i1, i2; 
            try {
                i1 = getNumber(arg0);
            } catch (NumberFormatException ex) {
                return 1;
            }
            
            try {
                i2 = getNumber(arg1);
            } catch (NumberFormatException ex) {
                return -1;
            }
            
            return i1.compareTo(i2); 
        } else {
            // no numbers
            return arg0.compareTo(arg1);
        }
    }
    
    private boolean containsNumber(String string) {
        return string.matches(".*\\d+.*");
    }  
    
    private Integer getNumber(String string) throws NumberFormatException {
        return Integer.parseInt(string.replaceAll("\\D+",""));
    }
}
输出

public static void main(String[] args) {
    String[] ss = {"OB123", "OB1212", "Maintenance", "Daily check", "OB123"};
    Collections.sort(Arrays.asList(ss), new FlightComparator());
    list(ss);
}

private static void list(String[] ss) {
    for (String s : ss) {
        System.out.println(s);
    }
}
Daily check
Maintenance
OB123
OB123
OB1212

免责声明 现在,虽然这些数据似乎符合你的要求,但并不是你问题的真正答案。此外,如果航班号不同,即OM1212或1212,这将仅比较数字,因此要立即完成解决问题,您可以在两者之间进行选择

  • 使用此
    比较器
    并按所示比较数据(不使用属性)
  • 将此
    比较器
    调整为
    比较器
    (最佳选项)

学分

  • 方法
    getNumber
    创建自
  • 方法
    containsNumber
    from

如果您使用的是Java 8,您可以使用(查找“thenComparing”)。不,我不使用一个选项是编写一个考虑航班号的字符串比较器:如果两个字符串都以字母开头,后跟数字,并且字母相同,则将数字转换为整数并进行比较。很好。正如您在免责声明中所说,使其成为
比较器可能更好,但我们没有足够的信息来提供这一点。我想你还是应该先按承运人分类,然后再按号码分类。在
和&containsNumber(arg0)
中,它可能应该是
arg1
。我相信OP可以修复这些细节。我不知道它是吹毛求疵还是有用(或者两者兼而有之):我上次飞行时,航母代码是“4U”。也许你们也应该考虑承运人的数字。也可能是您的代码也正确地对它们进行了排序,我至少想测试一下。请注意,存在一个不一致性:如果两个
getNumber
调用都会抛出
NumberFormatException
,那么无论顺序如何,都会返回
1
,这违反了比较器的对称约定。但由于这些异常无论如何都不应该发生,因此解决方法很简单:根本不要捕获
NumberFormatException
。虽然这可能是解决问题的一个有价值的提示,但确实需要一个答案来演示解决方案。请提供示例代码来说明您的意思。或者,考虑将此写入评论。