Is it possible to implement reverseOrder () method with Comparator <T>?
I have analyzed the Comparator interface in Java SE 8. Now I am interested in how to use a method reverseOrder()
using a class that implements the interface Comparator<T>
. I wrote a sample program to test this.
class NaturalOrderString implements Comparator<String>{
@Override
public int compare(String o1, String o2) {
// TODO Auto-generated method stub
return o1.compareTo(o2);
}
}
public class App {
public static void main(String[] args) {
Comparator<String> mycom= new NaturalOrderString();
mycom.reverseOrder(); // can't use this
}
}
So now I have to use all methods related to the interface Comparator
. But surprisingly the serum I am typing mycom.
, then there is no suggestion for the reverseOrder () method. What for? The class NaturalOrderString
implements Comparator<T>
.
So, I have to accept an object mycom
to access the method reverseOrder()
. Is not it?
Also, I found out that sorting in lists happens with natural ordering . Therefore, using the Collection class , I could access the method reverseOrder()
. So, before my example, I could happily write
Collections.reverseOrder(mycom); // that fine.
But my question is, why can't I use reverseOrder()
using an object of the class that implements Comparator<T>
? And since we can't access it, why does Java include the method reverseOrder()
in the interface Comparator<T>
?
Or, if it is indeed possible to access reverseOrder()
through the mycom object regarding my code, please provide an example.
Basically, the reverseOrder () method returns a comparator that imposes the reverse on the natural ordering.
First, following your question, since reverseOrder () is , you cannot use it like mycom.reverseOrder (). You must use both Comparot.reverseOrder (). Following your code. I created an ArrayList to demonstrate and use Comparator.reverseOrder () static method
public class App {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<String> people= new ArrayList<String>();
people.add("Sam");
people.add("Bob");
people.add("Andrew");
people.add("Michel");
people.add("Abe");
people.add("John");
Comparator<String> mycom= new NaturalOrderString();
Collections.sort(people); // this will sort the people array list in natural order
Collections.sort(people,Comparator.reverseOrder()); // Here your desired method it will reverse the natural order as documentation.
}
}
Hope you now understand this concept.
source to share
In principle, a lot of magic is possible here.
To undo the sort, you just need to "undo" the comparison result.
You can examine these foils . They are written in German, but there is not much text there and the code is all java. The presentation introduces some of the basics of lambda; then explain how you can use lambdas and method references to design an entire system where you sort / reverse sort streams; using "accessor" objects to retrieve any properties from things you are about to sort.
For example, leading to:
interface Comparator<T> {
public int compare(T a, T b);
public default Comparator<T> reversed() {
return (a, b) –> compare(b, a) ;
}
Now you can implement this interface, and reverse sorting comes free.
source to share
The method Comparator.reverseOrder()
just delegates Collections.reverseOrder()
and Collections.reverseOrder()
just returns a comparator that implements the reverse natural ordering.
What you are trying to do is as simple as:
@Override
public int compare(String o1, String o2)
{
int d = o1.compareTo(o2);
return -d;
which can also be achieved with myComparator.reversed()
.
source to share
Because it Comparator.reverseOrder
is a static method.
From the JLS :
[8.4.8] The class does not inherit static methods from its superinterfaces.
If you want to use this method, you can simply call it Comparator.reverseOrder()
. However, this doesn't seem to be what you actually want - use non-static instead reversed()
.
source to share
Can Comparator.reverseOrder () be used
Yes, of course you can. It's just not immediately obvious how you can use it, because the compiler conveys a lot of information.
Signature:
static <T extends Comparable<? super T>> Comparator<T> reverseOrder()
So, as you can see, a generic type is required that must implement Comparable
. It is somewhat stricter than that: it requires the type to be comparable to itself or to one of its supertypes. We were unable to obtain an inverse comparator for Apple using the following definitions:
public class Orange { }
public class Apple implements Comparable<Orange> { /* methods */ }
reverseOrder
takes no arguments, but returns us the Comparator
type we are passing. You can use it like this:
Comparator<Foo> reverseCompatator = Comparator.<Foo>reverseOrder();
Here's a complete, compiled example:
// Simply wraps an integer value
class Foo implements Comparable<Foo>
{
private final Integer value;
Foo(final Integer value) {
this.value = value;
}
public int compareTo(Foo that) {
// use standard integer comparison (i.e. 1,2,3,4,5,...)
return this.value.compareTo(that.value);
}
@Override
public String toString() {
return "Foo " + value;
}
}
public class Main
{
public static void main (String[] args)
{
// create a list
List<Foo> foos = Arrays.asList(new Foo(1), new Foo(3), new Foo(5));
// sort the list in reverse
foos.sort(
Comparator.<Foo>reverseOrder()
);
System.out.println(foos);
}
}
Output example:
[Foo 5, Foo 3, Foo 1]
In practice, you can remove <Foo>
from Comparator.<Foo>
, because the compiler might decide what you need.
source to share