Juventus
Juventus

Reputation: 731

What is the Swift equivalent for Java's Comparator Interface

I have the following Java code below that I am trying to convert into Swift accordingly. Can somebody help me on this issue. Thanks

public class CarsSortById implements Comparator<Cars>{

@Override
public int compare(Cars car1, Cars car2) {
    return (car1.getCarId() < car2.getCarId()) ? -1: 
    (car1.getCarId() > car2.getCarId() ) ? 1:0 ;
   }

}

Upvotes: 6

Views: 3586

Answers (3)

Alexander
Alexander

Reputation: 63271

Swift equivalent of Comparable<T>

Is the Comparable protocol. It requires that your type define an < operator. Since it derives from the Equatable protocol, you need to define the == operator, as well:

class Car {
    let id: Int
    // other fields
}

extension Car: Equatable {
    static func == (lhs: Car, rhs: Car) -> Bool {
        return lhs.id == rhs.id
    }
}

extension Car: Comparable {
    static func < (lhs: Car, rhs: Car) -> Bool {
        return lhs.id < rhs.id
    }
}

Swift equivalent of Comparator<T>

In Java, Comparator is an interface that lets you define sorting functions in addition to the one a type defines for itself via the Comparable Interface. Interfaces like this are necessary because Java didn't support lambdas prior to 1.8. And after Java 1.8, interfaces form the basis of lambdas.

Swift doesn't have an equivalent interface (called a protocol, in Swift). There's no need, since Swift can let you just define closures without the @functionalinterface cruft of Java.

Usually, Java Comparators are only used once. In this case, just call sort with a custom sorting closure:

let carsSortedByID = cars.sorted { $0.id < $1.id }

If you need to resume the sorting closure, you could assign it to a variable. Naturally, it would make sense to store these as static variable in an extension on the type that they sort.:

extension Car {
    static let idSorter: (Car, Car) -> Bool = { $0.id < $1.id }
}

let carsSortedByID = cars.sorted(by: Car.idSorter)

Upvotes: 9

Orkhan Alikhanov
Orkhan Alikhanov

Reputation: 10050

As already mentioned in other answers and in the comment, in swift there is nothing for that. It is just closure.

But here is how you define Comparable

class Car {
    var id = -1
}

extension Car: Comparable {
    static func == (lhs: Car, rhs: Car) -> Bool {
        return lhs.id == rhs.id
    }

    static func < (lhs: Car, rhs: Car) -> Bool {
          return lhs.id < rhs.id
    }
}

Upvotes: 3

Cal Stephens
Cal Stephens

Reputation: 793

If you're looking to specifically replicate the Java Comparator behavior where it returns a negative number for "less than", zero for "equal", or a positive number for "greater than", you could write a function that returns a ComparisonResult.

ComparisonResult is an enum with the cases .orderedAscending, .orderedSame, and .orderedDescending.

You could rewrite your function in Swift:

extension Car {
    func compare(with other: Car) -> ComparisonResult {
        return self.carId < other.carId 
            ? .orderedDescending 
            : self.carId > other.carId ? .orderedAscending : .orderedSame
    }
}

Upvotes: 2

Related Questions