多个字段的自定义比较器

时间:2016-01-19 12:46:29

标签: java comparator

我有一个定义为:

的类
class Attribute {
    String name;
    Boolean active;
    Boolean obligatory;
    Integer sortIndex;
}

我想以下列方式实现自定义排序顺序:

  1. 名称为“名称”的所有属性应位于顶部
  2. 所有具有义务的属性= true,如果两个字段必须= true,那么它们应该在sortIndex上进一步排序。
  3. 所有属性为active = true但必须为false,如果两个字段为active = true且必须为false,则应在sortIndex上进一步排序。
  4. 所有剩余的属性应按sortIndex排序。
  5. 我试图定义一个比较器

    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;
        }
    

    NameAttributeComparator,ObligatoryAttributeComparator,ActiveAttributeComparator的类定义如下:

    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());
        }
    }
    

    通过这种方法,我得不到预期的结果。 NameAttributeComparator和ObligatoryAttributeComparator已正确应用,但ActiveAttributeComparator未正确应用。我的问题:

    1. 是否可以使用自定义比较器实现所需的顺序?
    2. 如上所述实施方式可能出现的问题是什么?
    3. 有更好的方法吗?
    4. 我已按照this stackoverflow post提出当前解决方案。

      Java Comparator for Objects with multiple fields中的场景在某种程度上与此略有不同,因为在这里,具有相同值的元素应该在sortIndex上进一步排序。

1 个答案:

答案 0 :(得分:0)

您的ObligatoryAttributeComparator会返回一个值!= 0 if !o1.obligatory && !o2.obligatory && o1.sortIndex != o2.sortIndex 因此,根本不会咨询ActiveAttributeComparator