-1

I have a list to be sorted but it cannot be done if values are represented as strings. Example:

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

Therefore I need to use comparator to first sort aircraft numbers such OB123 by their carrier(OB), than by their number (123) and sometimes suffix (""). And after that I would like to compare the whole name with all the rest values as "daily check" etc. So far I can sort only flight Ids:

@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;
}

So since "Daily check" has also carrier+number+suffix representation it is sorted according to it. The question is how to sort them according to their names.

3
  • If you're using Java 8, you can use Comparator chaining (look for "thenComparing"). Commented Aug 23, 2016 at 8:42
  • nope, I don't use it Commented Aug 23, 2016 at 8:45
  • One option is to write a string comparator that takes the flight numbers into account: If two strings both begin with letters followed by digits and the letters are the same, convert the digits into integers and compare them. Commented Aug 23, 2016 at 9:06

2 Answers 2

1

Well, you can make a comparison checking for numbers in the strings:

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+",""));
    }
}

TEST IT

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);
    }
}

OUTPUT

Daily check
Maintenance
OB123
OB123
OB1212

DISCLAIMER

Now, while this data seems correct for what you ask, is not a real answer to your problem. Also if flight letters are different ie, OM1212, OR1212, this will only compare the numbers, so to complete solve your problem now, you can choose between

  • use this Comparator and compare data as shown (not using attributes)
  • adapt this Comparator<String> to Comparator<Flight> (best option)

CREDITS

Sign up to request clarification or add additional context in comments.

3 Comments

Nice. As you said in the disclaimer, making it a Compartor<Flight> is probably even better, but we don’t have enough information for providing that. I suppose you should still sort by carrier before sorting by number. In && containsNumber(arg0) it should probably be arg1. I’m sure the OP can fix such details.
I don’t know whether its nitpicking or helpful (or both): Last time I flew, the carrier code was “4U”. It may be that you should take digits in carrier into account too. It may also be that your code also sorts those correctly, I would at least want to test.
Note that there is an inconsistency: if both getNumber invocations would throw a NumberFormatException, a 1 is returned, regardless of the order, which violates the comparator’s symmetry contract. But since these exceptions shouldn’t happen anyway, the fix is easy: don’t catch the NumberFormatException at all.
0

You can extract the carrier information in another List, there you can parse it by Integer using parseInt() and then sort it.

Later you can merge both lists.

1 Comment

While this might be a valuable hint to solve the problem, an answer really needs to demonstrate the solution. Please edit to provide example code to show what you mean. Alternatively, consider writing this as a comment instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.