The returned comparator is serializable and throws NullPointerException when comparing null. The returned comparator is serializable if the specified function and comparator are both serializable. Module java. Package java. A comparison function, which imposes a total ordering on some collection of objects.
Comparators can be passed to a sort method such as Collections. Comparators can also be used to control the order of certain data structures such as sorted sets or sorted maps , or to provide an ordering for collections of objects that don't have a natural ordering.
Modifier and Type. Compares its two arguments for order. Indicates whether some other object is "equal to" this comparator. Returns a comparator that compares Comparable objects in natural order. Returns a null-friendly comparator that considers null to be less than non-null.
Since the sort results are displayed to users I indeed want nulls to be sorted consistently. String 's methods, including compareTo throw a NullPointerException if a null is handed in to them, so you should too. Similarly, Comparator throws a ClassCastException if the arguments' types prevent them from being compared.
I would recommend you implement these inherited behaviors. You can almost regain the original elegance by extracting a method to do the type checking and conversion. If you are not particular about the Exception messages, you can lose the "name" parameter. I'm sure you can lose an extra line here or word there by applying little tricks. You say you need to repeat this pattern with three other classes which compare different types of strings and could raise three other exceptions.
It's difficult to offer specifics there without seeing the situation, but you may be able to use "Pull Up Method" on a version of my parseStringAsDouble into a common ancestor of NumericComparator that itself implements java's Comparator. First, the trouble you're describing is the canonical symptom of a language that lacks first-class functions, which would enable you to succinctly describe these patterns.
Second, in my opinion, it should be an error to compare two Strings as Doubles if one of them cannot be considered a representation of a double. The same is true for nulls, etc. Therefore, you should permit the exceptions to propagate! This will be a contentious opinion, I expect.
First, exctract a method for converting the value. It's being repeated, multiple try Finally do horrible obfuscation to the actual comparator to raise a few WTF:s in code review or like others like to say it, "Implement the Comparator" :.
If anyone complains about it, say what others here have been saying: Handling nulls isn't Comparator's job. You could create a utility method that handles parsing and returns a certain value in the case of nulls or parse exceptions. Take a step back. Where does those Strings come from? For what is this Comparator to be used? Do you have a Collection of Strings which you would like to sort or so?
The only problem, if it you consider it that, is that null Strings and other non-parseable Strings will all be intermingled. That's probably not a big deal, considering the benefits -- this gives you a comparator that is guaranteed to be correct, whereas with a hand-coded comparator, even relatively simple ones, it's amazing how easy it is to commit a subtle error that breaks transitivity or, umm, antisymmetricity.
It seems that there are two concerns being mixed here and maybe should be broken up into separate components. Consider the following:. The Parser interface would have implementations for numbers, dates, etc. You could potentially use the java. Format class for your Parser interface. If you don't want to use commons-lang, you could replace the use of CompareToBuilder with some logic to handle nulls and use Comparable instead of Object for c1 and c2.
The Double comparator is not defined for either non-numbers or nulls. Make people give you useful data Doubles, Dates, Dinosaurs, whatever and write your comparators for that. As near as I can tell, this is a case of user input validation. For example, if you are taking input from a dialog box, the correct place to ensure that you have a parseable String that is a Double, Date or whatever is in the input handler.
Make sure it's good before the user can tab away, hit "Okay" or equivalent. Second, that whole thing become your comparator, so you don't need the LoanAccountAmountComparator class at all. It differs in the following points: It create the aggregated comparator only once, then store it in a static field. Because functions such as Comparator.
Null checks on the LoadAccount objects themselves have also been delegated to Comparator. That means that absolutely no if statement is required! I moved that comparator to a public, static field of a utility class. I have learned from personal experience that comparators on domain model objects very often come in "families".
In different places, you want different sorting strategies, for the same objects. Here, for demonstration, I also included one comparator for loadAmount that is, without fallback on tie , and another one for creationDate. But you can see how this idea can be generalized.
In this sample, I have adopted an uncommon indentation strategy. I think this is justified in this case because it helps make it easier to see which fields are sorted by each comparator, and in which order. This is of great importance when you have comparators that involve a significant number of fields. Sign up or log in Sign up using Google.
We have made the birthdate of Charlie as null. Trying to sort it using birthday results in a NullPointerException. Unlike the earlier case where one of the students was null, here the mapped value by the key extractor results in a null. This fails with a NullPointerException either when it calls the compareTo on a null or in the comparator function of LocalDate since it does not handle nulls depending on whether the first or the second value is null.
To your surprise, this too fails with a NullPointerException. This is because the null-friendly comparator works only when one or both of the parameters it receives is null. Note that we pass Comparator. Charlie is the Student with a null birthdate and hence it gets to the first or the last depending on if we use nullsFirst or nullsLast.
If we wanted to sort by reverse order of date, pass Comparator. We learnt about the Comparator nullsFirst and nullsLast method in this post.
First, we looked at the problem of using a Comparator when a collection has null elements in it. Second, we learnt about the Comparator nullsFirst and nullsLast methods and saw how to use them. Third, we saw how nullsFirst and nullsLast are implemented. Finally, we used them on a collection of Student objects for various scenarios. When both the arguments are null, they are considered as equal. If both are non-null, it uses the specified comparator to determine the order.
If the specified comparator is null, then it considers all non-null values to be equal. This outputs, [null, apple, grapes, orange, pear] It orders null before any non-null string and the rest of the non-null values are ordered by their natural ordering. Like the nullsFirst method, when both the arguments are null, they are considered as equal.
We can say that it uses the Decorator Design Pattern since it adds additional responsibility to handle nulls when one or more of the arguments passed to the compare method is null. We can see the implementation as: Case 1: When both a and b are null — it returns 0. Case 2: If a is null and b is non-null When nullFirst is true, it returns -1 a before b. Else it returns 1 b before a. Case 3: If b is null now a is non-null When nullFirst is true, it returns 1 b before a Else it returns -1 a before b Case 4: When both a and b are non-null: If the underlying comparator is present, it uses it to compare the ordering between the two arguments.
0コメント