Search code examples
javasortingcomparatorcomparable

How to convert Comparator to compare?


Here's the code that I'm trying to get.

public static final Comparator<Youku> AscDurRevCreationDate =
      Comparator.comparing(Youku::getDuration)
          .reversed()
          .thenComparing(Youku::getDateCreation)
          .reversed();

And the code below is the one I'm trying to convert it to. However, I'm getting a little different result from this code below. Btw, I'm using the Duration object in here.

@Override
  public int compare(Youku obj1, Youku obj2) {
    Integer duration = obj1.getDuration().compareTo(obj2.getDuration());
    Integer dateCreation = obj2.getDateCreation().compareTo(obj1.getDateCreation());

    return duration.compareTo(dateCreation );
  }

Solution

  • Explanation

    Looking at your Comparator:

    public static final Comparator<Youku> AscDurRevCreationDate =
          Comparator.comparing(Youku::getDuration)
              .reversed()
              .thenComparing(Youku::getDateCreation)
              .reversed();
    

    You want to compare Youkus by their duration (getDuration), descending and not ascending (reversed()) and if two durations are equal, break the ties by the creation date (getDateCreation), descending.

    The correct Comparable implementation for that looks like:

    @Override
    public int compareTo(Youku other) {
        int durationResult = Integer.compare(getDuration(), other.getDuration());
        durationResult *= -1; // for reversed
    
        if (durationResult != 0) { // different durations
            return durationResult;
        }
    
        // break ties using creation date
        int creationDateResult = Integer.compare(getDateCreation(), other.getDateCreation());
        creationDateResult *= -1;
    
        return creationDateResult;
    }
    

    or in compact:

    int durationResult = -1 * Integer.compare(getDuration(), other.getDuration());
    return durationResult != 0
        ? durationResult
        : -1 * Integer.compare(getDateCreation(), other.getDateCreation());
    

    Based on Comparator

    Alternatively you can also implement the method based on the Comparator you already have:

    public static final Comparator<Youku> comparator =
        Comparator.comparing(Youku::getDuration)
          .reversed()
          .thenComparing(Youku::getDateCreation)
          .reversed();
    
    ...
    
    @Override
    public int compareTo(Youku other) {
       return comparator.compare(this, other);
    }
    

    Notes

    Your code attempt does not show a Comparable implementation but a manual implementation for a Comparator. I suppose you confused something there.