基于多重连接订购arraylist

时间:2016-02-17 09:10:20

标签: java sorting arraylist collections

这是我的VO

public class SomeVO {

    private String name;        
    private String usageCount;
    private String numberofReturns;
    private String trendNumber;
    private String nonTrendNumber;
    private String trendType;
    private String auditType;
    public SomeVO(String name,String usageCount,String numberofReturns,String trendNumber,String nonTrendNumber,String trendType,String auditType){
        this.name = name;
        this.usageCount = usageCount;
        this.numberofReturns = numberofReturns;
        this.trendNumber = trendNumber;
        this.nonTrendNumber = nonTrendNumber;
        this.trendType = trendType;
        this.auditType = auditType;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getUsageCount() {
        return usageCount;
    }
    public void setUsageCount(String usageCount) {
        this.usageCount = usageCount;
    }
    public String getNumberofReturns() {
        return numberofReturns;
    }
    public void setNumberofReturns(String numberofReturns) {
        this.numberofReturns = numberofReturns;
    }
    public String getTrendNumber() {
        return trendNumber;
    }
    public void setTrendNumber(String trendNumber) {
        this.trendNumber = trendNumber;
    }
    public String getNonTrendNumber() {
        return nonTrendNumber;
    }
    public void setNonTrendNumber(String nonTrendNumber) {
        this.nonTrendNumber = nonTrendNumber;
    }
    public String getTrendType() {
        return trendType;
    }
    public void setTrendType(String trendType) {
        this.trendType = trendType;
    }
    public String getAuditType() {
        return auditType;
    }
    public void setAuditType(String auditType) {
        this.auditType = auditType;
    }
}

这是我的价值观

List<SomeVO> myList = new ArrayList<SomeVO>();
        SomeVO some = new SomeVO("A","0","0","123","123","Trend","AuditX");
        myList.add(some);
        some = new SomeVO("B","1","1","234","234","Non trend","AuditX");
        myList.add(some);
        some = new SomeVO("C","0","2","345","345","Trend","AuditX");
        myList.add(some);
        some = new SomeVO("D","2","3","546","546","Trend","AuditX");
        myList.add(some);
        some = new SomeVO("E","2","4","678","678","Non trend","AuditX");
        myList.add(some);
        some = new SomeVO("F","0","0","123","123","Non trend","AuditA");
        myList.add(some);
        some = new SomeVO("G","0","0","123","123","Trend","AuditB");
        myList.add(some);

这是我的比较器

public String currentAudit = "AuditX";
public class AuditComparator implements Comparator<SomeVO> {

        @Override
        public int compare(SomeVO o1, SomeVO o2) {
            if(currentAudit.equalsIgnoreCase(o1.getAuditType()) && currentAudit.equalsIgnoreCase(o2.getAuditType())) {
                int value1 = o2.getUsageCount().compareTo(o1.getUsageCount());
                if (value1 == 0) {
                    int value2 = o1.getNumberofReturns().compareTo(o2.getNumberofReturns());
                    if(o1.getTrendType().equalsIgnoreCase("Trend") && o2.getTrendType().equalsIgnoreCase("Trend")) {
                        if (value2 == 0) {
                            return o1.getTrendNumber().compareTo(o2.getTrendNumber());
                        } else {
                            return value2;
                        }
                    } else {
                        if (value2 == 0) {
                            return o1.getNonTrendNumber().compareTo(o2.getNonTrendNumber());
                        } else {
                            return value2;
                        }
                    }
                }
                return value1;
            } else {
                return 1;
            }

        }
    }

我正在尝试根据以下条件对VO进行排序

  1. 首先应该只考虑currentAudit的一组值 考虑因素,即AuditX

    a)然后它应该与     使用次数按降序排列

    b)如果找到相同的使用次数,那么它     应按升序返回计数

    c)如果相同的话     返回计数然后它应该检查trendType,如果trendType     =&#34;趋势&#34;那么它应该用趋势数排序,否则为非趋势数。

  2. 然后它应该考虑休息所有auditType&并进行排序 a),b),c)条件与currentAudit类似。我尝试实现它和我 结果只有比较器。预期结果:D,A,C,E, F,G。但我得到G,F,D,E,B,A,C。请帮我更新一下 上面的比较器。

3 个答案:

答案 0 :(得分:0)

您的比较器不符合简单条件:它不是无状态的。以下内容应始终为真:A>B => B<A。在您的情况下,在某些情况下A>B and B>A

答案 1 :(得分:0)

我通过将实际列表拆分为基于AuditX的2列表并在另一个列表中休息来解决它。然后逐个使用比较器,然后合并到结果列表中。效果很好。

for(SomeVO some:myList) {
            if(some.getAuditType().equalsIgnoreCase("AuditX")) {
                auditX.add(some);
            } else {
                auditY.add(some);
            }
        }
        Collections.sort(auditX, new AuditComparator());            
        Collections.sort(auditY, new AuditComparator());

    public class AuditComparator implements Comparator<SomeVO> {

            @Override
            public int compare(SomeVO o1, SomeVO o2) {
                int value1 = o2.getUsageCount().compareTo(o1.getUsageCount());
                 if (value1 == 0) {
                        int value2 = o1.getNumberofReturns().compareTo(o2.getNumberofReturns());
                        if (value2 == 0) {
                            return (o1.getTrendType().equalsIgnoreCase("Trend") && o2.getTrendType().equalsIgnoreCase("Trend")) ?
                                    o1.getTrendNumber().compareTo(o2.getTrendNumber()):o1.getNonTrendNumber().compareTo(o2.getNonTrendNumber());
                        } else {
                            return value2;
                        }            
            }
                return value1;
        }

答案 2 :(得分:0)

比较器底部的返回1会产生错误。 如果第二个元素大于第一个元素,比较器只返回1,但如果它们不同,则总是返回1,因此第一个排序标准将是混乱的。

   // a helper for case insensitive comparison
   private int compareIgnoreCase(String o1,String o2) {
       return o1.toLowercase.compareTo(o2.toLowercase());
   }

   @Override
    public int compare(SomeVO o1, SomeVO o2) {
        int result=compareIgnoreCase(o1.getAuditType(),o2.getAuditType());
        if (result==0) {
            // we need to go to the 2nd criteria
            result=o2.getUsageCount().compareTo(o1.getUsageCount());
        }
        if (result==0) {
            // ok, 1st and 2nd criteria was the same, go to the 3rd             
          result=o1.getNumberofReturns().compareTo(o2.getNumberofReturns());
        }
        if (result==0) {
            // check trends
            ...
        }
        return result;
    }

我发现多重比较标准的这种表示使代码更容易理解。我们首先进行比较的最高优先级,如果先前的比较返回两个元素相同(即结果仍然为零),则继续进行进一步的比较。

如果您需要在某个级别进行降序排序,只需输入 - ,例如:

 result=-o1.something.compareTo(o2.something) 

在方法中只有一个退出点是个好主意(这也更容易理解正在发生的事情)。