Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有多列条件的Java排序_Java_Sorting_Comparator - Fatal编程技术网

具有多列条件的Java排序

具有多列条件的Java排序,java,sorting,comparator,Java,Sorting,Comparator,我有一个对象ClientSearch public class ClientSearch{ private Long clientNumber; private String queueNumber; private String clientName; private String customerName; ..... } 我需要按照以下规则对其进行排序: 先显示clientNumber降序,然后按customerName降序,显示所有带有clientNumber的记录后,按queueNu

我有一个对象ClientSearch

public class ClientSearch{
private Long clientNumber;
private String queueNumber;
private String clientName;
private String customerName;
.....
}
我需要按照以下规则对其进行排序:

先显示clientNumber降序,然后按customerName降序,显示所有带有clientNumber的记录后,按queueNumber降序排序,按customerName降序排序

这应该是结果---ClientNumber desc then,CustomerName desc,然后,QueueNumber desc then,CustomerName desc

ClientNumber     ClientName    CustomerName
987654           Client1       Xyz1
987654           Client2       Abc2
555555           Client3       zzzzz1
21212            XYZ1          aaaab
111111           Client10      cZ
111111           Client11      cY
Z1Z1Z1           ClientX       zzzzz
Z1Z1Z1           ClientY       yyyyy
X2X2X2           Clienxyz      aaaaaa
HHHHHH           ClientH       bbbbbb
AAAAAA           ClientA       xxxxxx
基本上,每个ClientSearch对象都有一个clientNumber或queueNumber(如果没有客户机编号,则QueunMember被视为客户机编号,这就是为什么它显示在该列下)

我想做的是,在我从我的查询中收到一个列表(我没有控制权,我只是收到了这个列表)之后,我将使用这个条件遍历这个列表

 if clientNumber is present then add to a List<ClientSearch> withClientNumbers

 else if queueNumber is present then add to a List<ClientSearch> withQueueNumbers

你能推荐其他优雅的方法吗?我觉得我的方法不是最优化的。请注意,我使用的是Java1.6,您的方法是正确的,我只是按如下方式测试了它。注:优化是在排序中完成的,而不是在比较函数中完成的。因为您将使用JavaOwn的排序方法,所以不必担心优化问题。 基本上,你只是打破了客户数量与客户数量相等的联系。这里我将QueueNumber作为ClientNumber只是为了简单起见。由于您已经创建了不同的列表,因此可以对两个列表应用相同的解决方案,然后合并列表。示例代码如下:

public class ClientSearch{
    private String clientNumber;
   // private String queueNumber;
    private String clientName;
    private String customerName;


    public ClientSearch(String clientNumber, String clientName, String customerName) {
        this.clientNumber = clientNumber;
        //this.queueNumber = queueNumber;
        this.clientName = clientName;
        this.customerName = customerName;
    }

    public String toString(){
        return clientNumber+" "+clientName+" "+customerName;
    }

    public static void main(String[] args) {
        try {
            BufferedReader br = new BufferedReader(new FileReader("input.txt"));
            String tmp = null;
            List<ClientSearch> list = new ArrayList<>();
            while((tmp=br.readLine())!=null){
                String split [] = tmp.split(" ");
                list.add(new ClientSearch(split[0],split[1],split[2]));
            }
            System.out.println("Sorting.....");
            list.sort(new Comparator<ClientSearch>() {
                @Override
                public int compare(ClientSearch o1, ClientSearch o2) {
                    int diff = o1.clientNumber.compareTo(o2.clientNumber);
                    return diff ==0 ? o1.customerName.compareTo(o2.customerName) : diff;
                }
            });

            for (ClientSearch c : list){
                System.out.println(c);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
公共类ClientSearch{
私有字符串clientNumber;
//私有字符串队列号;
私有字符串clientName;
私有字符串客户名称;
公共ClientSearch(字符串clientNumber、字符串clientName、字符串customerName){
this.clientNumber=clientNumber;
//this.queueNumber=queueNumber;
this.clientName=clientName;
this.customerName=客户名称;
}
公共字符串toString(){
返回clientNumber+“”+clientName+“”+customerName;
}
公共静态void main(字符串[]args){
试一试{
BufferedReader br=新的BufferedReader(新文件读取器(“input.txt”);
字符串tmp=null;
列表=新的ArrayList();
而((tmp=br.readLine())!=null){
字符串拆分[]=tmp.split(“”);
添加(新客户端搜索(拆分[0]、拆分[1]、拆分[2]);
}
System.out.println(“排序…”);
list.sort(新的比较器(){
@凌驾
公共整数比较(客户端搜索o1,客户端搜索o2){
int diff=o1.clientNumber.compareTo(o2.clientNumber);
return diff==0?o1.customerName.compareTo(o2.customerName):diff;
}
});
用于(客户端搜索c:列表){
系统输出打印ln(c);
}
}捕获(例外e){
e、 printStackTrace();
}
}
}

说到排序,通常只是关于如何实现
比较器。在这种情况下,您只需要一个
比较器
,它按照您描述的方式比较两个
ClientSearch
对象

如果你能简化你的排序要求,它会更干净

  • 客户编号(上次为空)
  • 然后是队列ID
  • 客户名称
  • 使用Java 8,比较器将与此一样简单:

    import static java.util.Comparator.*;
    ....
    Comparator<Customer> comparator = 
        comparing(Customer::getCustNumber, nullsLast(naturalOrder()))
        .thenComparing(Customer::getQueueId)
        .thenComparing(Customer::getCustName);
    
    (我相信我不需要告诉您如何使用
    比较器进行排序,对吗?)


    更新: 正如您提到的,您正在使用Java 6,下面是关于比较器的基本概念(伪代码):

    公共类ClientSearchComparator实现Comparator{
    @凌驾
    公共整数比较(ClientSearch c1、ClientSearch c2){
    如果(c1.custNum!=null&&c2.custNum!=null){
    if(c1.custNum!=c2.custNum){
    返回c1.custNum.compareTo(c2.custNum);
    }
    返回c1.custName.compareTo(c2.custName);
    }else if(c1.custNum==null&&c2.custNum==null){
    if(c1.queueId!=c2.queueId){
    返回c1.queueId.compareTo(c2.queueId);
    }
    返回c1.custName.compareTo(c2.custName);
    }else如果(c1.custNum==null){//c1 null&&c2不为null
    返回1;
    }else{//c1不为空&&c2为空
    返回-1;
    }
    }
    

    (通过一些重组,或者借助Guava或Apache Common Langs等工具,看起来会更好)

    在您的表中,您显示了“clientName”,但在您的文本描述中,您在这两种情况下都使用了“customerName”。您能澄清这一点吗?以及,让比较器比较ClientNumber(最后为空)有什么问题吗然后是队列号,然后是客户名称?请注意,阅读本文的任何人都可以使用Java 8:有一种非常优雅的方法来链接比较条件:
    humans.sort(Comparator.comparing(Human::getName)。然后是comparing(Human::getAge));
    请参阅以获取完整的解释
    import static java.util.Comparator.*;
    ....
    Comparator<Customer> comparator = 
        comparing(Customer::getCustNumber, nullsLast(naturalOrder()))
        .thenComparing(Customer::getQueueId)
        .thenComparing(Customer::getCustName);
    
    public class ClientSearchComparator implements Comparator<ClientSearch> {
        private static Comparator<ClientSearch> custNumberComparator = 
            Comparator.comparing(ClientSearch::getCustNumber)
                    .thenComparing(ClientSearch::getCustName);
        private static Comparator<ClientSearch> queueIdComparator = 
            Comparator.comparing(ClientSearch::getQueueId)
                    .thenComparing(ClientSearch::getCustName);
        @Override
        public int compare(ClientSearch c1, ClientSearch c2) {
            if (c1.getCustNumber() != null && c2.getCustNumber() != null) {
                return custIdComparator.compare(c1, c2);
            } else if (c1.getCustNumber() == null && c2.getCustNumber() == null) {
                return queueIdComparator.compare(c1, c2);
            } else if (c1.getCustNumber() != null && c2.getCustNumber() == null) {
                return -1;
            } else {  // (c1.getCustNumber() == null && c2.getCustNumber() != null) 
                return 1;
            }
        }
    }
    
    public class ClientSearchComparator implements Comparator<ClientSearch> {
        @Override
        public int compare(ClientSearch c1, ClientSearch c2) {
            if (c1.custNum != null && c2.custNum != null) {
                if (c1.custNum != c2.custNum) {
                    return c1.custNum.compareTo(c2.custNum);
                }
                return c1.custName.compareTo(c2.custName);
            } else if (c1.custNum == null && c2.custNum == null) {
                if (c1.queueId != c2.queueId) {
                    return c1.queueId .compareTo(c2.queueId);
                }
                return c1.custName.compareTo(c2.custName);
            } else if (c1.custNum == null) { // c1 null && c2 not null
                return 1;
            } else {  // c1 not null && c2 null
                return -1;
            }
        }