开发者

Java: Order a collection according to subtype

Not quite sure how I should attack this. I need to create a Comparator for a class called Record. These records have a time I will use, but if the time is the same, I need to order them depending on their type. Say for example we have the following Record subtypes:

  • AaRecord
  • BbRecord
  • CcRecord
  • DdRecord

Now, given a collection with a number of these, I need to order them so that for example all CcRecord come before BbRecord followed by AaRecord and finally DdRecord. What is a good and 开发者_如何学编程clean way of doing this?

Just to be clear, I can't use the names of the types to do this, as they could be anything. It's going to be used to process a list of records in the correct order.

public class RecordComparator implements Comparator<Record>
{
   @Override
   public int compare(Record x, Record y)
   {
      // First compare times
      int result = x.getTime().compareTo(y.getTime());
      if(result != 0)
         return result;

      // Then somehow compare types...

   }
}


You could define a Map<Class, Integer> containing the sort orders for all the types, and then do this:

@Override
public int compare(Record x, Record y)
{
   // First compare times
   int result = x.getTime().compareTo(y.getTime());
   if(result != 0)
      return result;

   // sortOrders is your map
   return sortOrders.get(x.getClass()).compareTo(sortOrders.get(y.getClass()));
}

Or something like that.

Keep in mind that it doesn't have to be integers.


How about having a method that establishes order of the type, for example:

public abstract class Record
{
    public abstract int getRecordOrdinal();
}

public abstract class AaRecord extends Record
{
    @Override
    public int getRecordOrdinal() {
        return 1;
    }
}

public abstract class BbRecord extends Record
{
    @Override
    public int getRecordOrdinal() {
        return 2;
    }
}

//etc

public class RecordComparator implements Comparator<Record>
{
   @Override
   public int compare(Record x, Record y)
   {
      // First compare times
      int result = x.getTime().compareTo(y.getTime());
      if(result != 0)
         return result;

      return y.getRecordOrdinal() - x.getRecordOrdinal();
   }
}


Although this sounds like you let us do your work, here is the outline of how to solve the problem:

(1) Extend your Record class for one abstract method getSortOrder()

public abstract class Record {
    public abstract int getSortOrder();
}

(2) Implement this method in your your subtypes AaRecord, BbRecord, CcRecord, ... as how you want them to be ordered, e.g.

public class AaRecord {
    @Override
    public int getSortOrder() {return 0; }
}

public class BbRecord {
    @Override
    public int getSortOrder() {return 1; }
}

And so on.

(3) RecordComparator implementation

public class RecordComparator implements Comparator<Record>
    {
       @Override
       public int compare(Record x, Record y)
       {
          // First compare times
          int result = x.getTime().compareTo(y.getTime());
          if(result != 0)
             return result;

          // Compare types
          return x.getSortOrder() - y.getSortOrder();
       }
    }

Alternatively, you can define an extra interface Sortable { int getSortOrder(); } and have Record implement it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜