1

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:

  1. All attributes with name as "Name" should be on the top
  2. All attributes with obligatory=true, if two fields are obligatory=true then they should be further sorted on sortIndex.
  3. 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.
  4. 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:

  1. is it possible to implement the desired order with custom comparators?
  2. What can be the likely problem in the way this is implemented as above?
  3. 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.

Community
  • 1
  • 1
akki
  • 423
  • 2
  • 12
  • What exactly is wrong with Active comparator? Can you provide an example? – AdamSkywalker Jan 19 '16 at 12:54
  • @AdamSkywalker: With application of ActiveAttributeComparator, the fields with active=false and obligatory=false come before fields with active=true. The expected result is fields with active=false and obligatory=false should appear below all fields with active=true – akki Jan 19 '16 at 13:32
  • Have you tried Java 8 and `Comparator.comparing` and `Comparator.thenComparing`? – tobias_k Jan 19 '16 at 13:37
  • @tobias_k: the application I am using has not yet ported to java 8. But java 8 would be a great option here. Thanks – akki Jan 19 '16 at 13:43

1 Answers1

0

Your ObligatoryAttributeComparator returns a value != 0 if !o1.obligatory && !o2.obligatory && o1.sortIndex != o2.sortIndex Therefore ActiveAttributeComparator is not consulted at all.

Frank Neblung
  • 3,047
  • 17
  • 34