具有多列条件的Java排序
我有一个对象ClientSearch具有多列条件的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
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;
}
}