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.
精彩评论