1

I know there many similar questions and I have received big help by reading answers to those questions, however I am not able to see how is my client facing this problem. And there is only one client who is facing this problem.

I have a List, and I am sorting that list using Comparator interface. Does any of you see problem with the following code?

    private static class BiologySamplesComparator implements Comparator<BiologySample>, Serializable {
        @Override
        public int compare(BiologySample left, BiologySample right) {
            if (left == right || (left != null && right != null && left.getSampleDateTime() == right.getSampleDateTime())) {
                return 0;
            }

            if (left == null || left.getSampleDateTime() == null) {
                return 1;
            }

            if (right == null || right.getSampleDateTime() == null) {
                return -1;
            }

            return right.getSampleDateTime().compareTo(left.getSampleDateTime());
        }
    }

And this how I am calling this function

Collections.sort(biologySamples, new BiologySamplesComparator());

I know that the main problem in this kind of scenario is Transitivity. However I couldn't figure what is violating that rule.

This how getSampleDateTime() is returning date Fri Apr 09 17:00:00 PDT 2021


Update This is how I was able to fix my problem. I hope this helps, I was stuck for so long on this problem.

    private static class BiologySamplesComparator implements Comparator<BiologySample>, Serializable {
        @Override
        public int compare(BiologySample left, BiologySample right) {
            if (left == null) {
                if (right == null) {
                    return 0;
                } else {
                    return 1;
                }
            } else if (right == null) {
                return -1;
            } else if (left == right) {
                return 0;
            }
            if (left.getSampleDateTime() == null) {
                if (right.getSampleDateTime() == null) {
                    return 0;
                } else {
                    return 1;
                }
            } else if (right.getSampleDateTime() == null) {
                return -1;
            } else if (left.getSampleDateTime() == right.getSampleDateTime()) {
                return 0;
            }

            return right.getSampleDateTime().compareTo(left.getSampleDateTime());
        }
    }

2 Answers 2

1

You have a possible inconsistency when comparing a null "sample" to a non-null sample with a null timestamp.

Sample a = null;
Sample b = new Sample(null);

bsc.compare(a, b); // -> 1, a > b
bsc.compare(b, a); // -> 1, b > a

First, you should replace the Date in your sample class with Instant if at all possible, and then make your life simpler by saying this:

public static final Comparator<Sample> ORDER_BY_TIMESTAMP =
  Comparator.nullsLast(Comparator.comparing(
      Sample::getDateTime,
      Comparator.nullsLast(Comparator.naturalOrder())
  );

If you can rule out null values, even simpler:

Comparator.comparing(Sample::getDateTime);
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for your suggestion. I was able to fix the problem by changing my code in different way than yours. Check the description of my question. Thanks anyways.
@ParteekSinghBedi Rather than editing your question with a solution, post the solution as an answer to your own question. If it's the one that helped, you can even accept it (mark it with a check). If other answers also helped, you can upvote them.
Added solution as answer.
1

I was missing some conditional for some cases and this is how I was able to solve my problem.

    private static class BiologySamplesComparator implements Comparator<BiologySample>, Serializable {
        @Override
        public int compare(BiologySample left, BiologySample right) {
            if (left == null) {
                if (right == null) {
                    return 0;
                } else {
                    return 1;
                }
            } else if (right == null) {
                return -1;
            } else if (left == right) {
                return 0;
            }
            if (left.getSampleDateTime() == null) {
                if (right.getSampleDateTime() == null) {
                    return 0;
                } else {
                    return 1;
                }
            } else if (right.getSampleDateTime() == null) {
                return -1;
            } else if (left.getSampleDateTime() == right.getSampleDateTime()) {
                return 0;
            }

            return right.getSampleDateTime().compareTo(left.getSampleDateTime());
        }
    }

courtesy of Why does my compare methd throw IllegalArgumentException sometimes?

Comments

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.