I have a class which is defined as:
class Attribute {
String name;
Boolean active;
Boolean obligatory;
Integer sortIndex;
}
I would like to implement a custom sort order in following way:
- All attributes with name as "Name" should be on the top
- All attributes with obligatory=true, if two fields are obligatory=true then they should be further sorted on sortIndex.
- All attributes with active=true but obligatory=false, if two fields are active=true and obligatory=false then they should be further sorted on sortIndex.
- All remaining attributes should be sorted on sortIndex.
I tried to define a comparator
public class AttributeComparator implements Comparator<Attribute> {
List<Comparator<Attribute>> comparators = Arrays.asList(new NameAttributeComparator(),
new ObligatoryAttributeComparator(), new ActiveAttributeComparator(),
new SortIndexComparator());
@Override
public int compare(Attribute o1, Attribute o2) {
for (Comparator<Attribute> c : comparators) {
int result = c.compare(o1, o2);
if (result != 0) {
return result;
}
}
return 0;
}
Class definitions for NameAttributeComparator, ObligatoryAttributeComparator, ActiveAttributeComparator are as follows:
class NameAttributeComparator implements Comparator<Attribute> {
@Override
public int compare(Attribute o1, Attribute o2) {
int comparisonResult = 0;
if (o1.getName().equals("Name") && !o2.getName().equals("Name")) {
comparisonResult = -1;
} else if (o2.getName().equals("Name") && !o1.getName().equals("Name")) {
comparisonResult = 1;
}
return comparisonResult;
}
}
public class ObligatoryAttributeComparator implements Comparator<Attribute> {
@Override
public int compare(Attribute o1, Attribute o2) {
int comparisonResult = 0;
comparisonResult = o2.isObligatory().compareTo(o1.isObligatory());
if (comparisonResult == 0) {
comparisonResult = o1.getSortIndex().compareTo(o2.getSortIndex());
}
return comparisonResult;
}
}
class ActiveAttributeComparator implements Comparator<Attribute> {
@Override
public int compare(Attribute o1, Attribute o2) {
int comparisonResult = o2.isActive().compareTo(o1.isActive());
if (comparisonResult == 0) {
return o1.getSortIndex().compareTo(o2.getSortIndex());
}
return comparisonResult;
}
}
class SortIndexComparator implements Comparator<Attribute> {
@Override
public int compare(Attribute o1, Attribute o2) {
return o1.getSortIndex().compareTo(o2.getSortIndex());
}
}
With this approach I do not get the expected result. NameAttributeComparator and ObligatoryAttributeComparator are applied correctly but ActiveAttributeComparator is not. My questions:
- is it possible to implement the desired order with custom comparators?
- What can be the likely problem in the way this is implemented as above?
- Is there a better way to do this?
I have followed this stackoverflow post to come up with the current solution.
The scenario in Java Comparator for Objects with multiple fields is somehow slightly different than this since over here the elements with same value should be further sorted on sortIndex.