Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing comparator multiple times in a single class file [duplicate]

I have some code to sort paths by date modified. I want to also write some code to sort the paths in reverse order, and might later want to add some other sorting methods. Is there any way to do all the sorting from a single class file? Or do I have to create another class PathSortByDateReverse, PathSortByCreated, PathSortByFoo, etc. Also, how would I use the different sorting methods?

import java.nio.file.Path;
import java.util.Comparator;

public class PathSortByDate implements Comparator<Path> {

@Override
public int compare(Path first, Path second) {
    long seconddate = second.toFile().lastModified(); // get just the filename
    long firstdate = first.toFile().lastModified();

    if (firstdate == seconddate) {
        return 0;
    } else if (firstdate > seconddate) {
        return 1;
    } else {
        return -1;
    }
}
}

I then call it from the other class with:

public static ArrayList<Path> sortArrayListByDate(ArrayList<Path> pathlist) {
    Collections.sort(pathlist,new PathSortByDate());
    return pathlist;
}    
like image 241
localhost Avatar asked Apr 25 '12 05:04

localhost


People also ask

Can Comparator be used to sort in multiple ways?

compareTo(Object o) method implementation can provide default sorting and we can't change it dynamically. Whereas with Comparator, we can define multiple methods with different ways of sorting and then chose the sorting method based on our requirements.

When would you use a Comparator instead of implementing comparable to sort a collection or an array?

To summarize, if sorting of objects needs to be based on natural order then use Comparable whereas if you sorting needs to be done on attributes of different objects, then use Comparator in Java.

What is difference between Comparator and comparable in Java?

Comparator in Java is used to sort attributes of different objects. Comparable interface compares “this” reference with the object specified. Comparator in Java compares two different class objects provided. Comparable is present in java.


2 Answers

Why not go for an anonymous inner classes?

public static final Comparator<Person> ID_DESC
     = new Comparator<Person>() {
      public int compare(Person p1, Person p2) {
         return -1 * p1.getId().comparedTo(p2.getId());
         // reversed order
      }
    };
like image 190
Shashank Kadne Avatar answered Oct 29 '22 05:10

Shashank Kadne


I would usually do it like this. Notice, the constructor is "private" and there is a "public factory method" to get an instance. There will ever exist two PathComparator instances at any given point. This is a big deal if you are into optimizing your code and using best practices.

import java.nio.file.Path;
import java.util.Comparator;

final public class PathComparator implements Comparator<Path> {

// comparator for in order
final private static PathComparator ascendingOrderComparatorDate = new PathComparator(true);
// comparator for reverse order
final private static PathComparator descendingOrderComparatorDate = new PathComparator(false);

final private int isAscendingOrderInt;

final public PathComparator getPathComparator(boolean isAscendingOrder) {
    return isAscendingOrder ? ascendingOrderComparatorDate : descendingOrderComparatorDate;
}

private PathComparator(boolean isAscendingOrder) {
    this.isAscendingOrderInt = isAscendingOrder ? 1 : -1;
}

@Override
public int compare(Path first, Path second) {
    // for optimization (not required but highly recommended)
    if(first == second) return 0;

    long seconddate = second.toFile().lastModified(); // get just the filename
    long firstdate = first.toFile().lastModified();

    if (firstdate == seconddate) {
        return 0;
    } else if (firstdate > seconddate) {
        return isAscendingOrderInt * 1;
    } else {
        return isAscendingOrderInt * -1;
    }
}}
like image 33
ZeX Avatar answered Oct 29 '22 05:10

ZeX