2016-11-02 3 views
1

у меня есть этот объект ClientSearchJava сортировка с несколькими условиями колонок

public class ClientSearch{ 
private Long clientNumber; 
private String queueNumber; 
private String clientName; 
private String customerName; 
..... 
} 

мне нужно разобраться в этом по этому правилу:

показать clientNumber убыванию первую затем CUSTOMERNAME нисходящим и после того, как все записи с clientNumber являются отображать, сортировать по очереди в порядке убывания и имя_пользователя в порядке убывания. не

Это должно быть результатом --- ClientNumber убывание затем, CustomerName по убыванию, а затем, по убыванию QueueNumber затем, CustomerName по убыванию

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 (если нет клиентский номер, то номер квина считается номером клиента, поэтому он отображается под этим столбцом),

Я думал, что после того, List <>), я буду перебирать список с условием.

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

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

После этого, я буду сортировать withClientNumbers с компаратором, который сравнивает clientNumber в ClientSearch в то, если они равны нулю плохо делать другое сравнение с CUSTOMERNAME ClientSearch в. Мне просто нужно умножить их на -1, чтобы убедиться, что это DESC.

Я сделаю то же самое с queueNumbers, но с другим компаратором.

затем Ill создать новый список NewList и затем сделать это

newList.addAll(withClientNumbers); //make sure this is first in the list 
newList.addAll(queueNumbers); // so to satisfy the condition that queueNumbers are shown after a sorted clientNumbers. 

Можете ли вы предложить какой-либо другой элегантный способ сделать это? Я чувствую, что мой метод не самый оптимизированный. Обратите внимание, что я использую Java 1.6

+0

в таблице вы показали «CLIENTNAME», но в описании текстологии, вы использовали «CUSTOMERNAME» в обоих случаях. Можете ли вы это прояснить? И в чем проблема, заключающаяся в сравнении компаратора с номером ClientNumber (null last), а затем с номером очереди, а затем с именем клиента? –

+0

Примечание для тех, кто читает это, что может использовать Java 8: Существует очень элегантный способ привязки условий сравнения: 'people.sort (Comparator.comparing (Human :: getName). ThenComparing (Human :: getAge));' См. Http : //www.baeldung.com/java-8-sort-lambda для полного объяснения – Thirler

ответ

2

Когда дело доходит до сортировки, как правило, только о том, как вы собираетесь реализовать Comparator. В таком случае вам просто нужен Comparator, который сравнивает два объекта ClientSearch с описанным вами способом.

Это будет гораздо чище, если вы можете упростить требования для сортировки

  1. Номер клиента (аннулирует последний)
  2. ID очереди, затем
  3. Имя клиента

Компаратор будет таким же простым, как это, с Java 8:

import static java.util.Comparator.*; 
.... 
Comparator<Customer> comparator = 
    comparing(Customer::getCustNumber, nullsLast(naturalOrder())) 
    .thenComparing(Customer::getQueueId) 
    .thenComparing(Customer::getCustName); 

Это немного отличается от того, что вы изначально просили. То, что вы просили это

  1. Если оба имеют номер клиента, сравнить по
    1. Номер клиента
    2. Имя клиента
  2. Если оба не имеют номер клиента, сравнить по
    1. Очередь ID
    2. Имя клиента
  3. Если у кого-то есть номер клиента, а другой нет, то номер с нулевым номером клиента считается больше.

Если вам действительно нужно то, что вы ищете, это не составит труда. Например, у вас может быть два Comparator каждый для отдельного случая и объединяться тогда как один Comparator, выглядит что-то вроде (с помощью Java 8, нетрудно написать один для предыдущей версии Java, если вы получите идею):

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

(Я считаю, что мне не нужно, чтобы сказать вам, как сделать сортировку с Comparator правой?)


Update: как вы уже упомянули, что вы используете Java 6, здесь основная идея о том, как будет выглядеть этот компаратор (псевдокод):

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

(это будет выглядеть лучше с какой-то реорганизации, или с помощью таких инструментов, как гуавы или Apache Common LANGS)

0

Ваш правильный путь, я просто протестировал его, как показано ниже. Оптимизация заметок выполняется при сортировке, а не в сравнении функций. Поскольку вы будете использовать метод сортировки Java, вам не нужно беспокоиться об оптимизации. В принципе, вы просто разорвали связи равенства clientNumber с customerNames. Здесь я принимаю queuenumbers как clientnumbers только для простоты. Поскольку вы уже создаете разные списки, то одно и то же решение может быть применено к обоим спискам, а затем объединить списки. Пример кода ниже:

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(); 
     } 
    } 
} 
Смежные вопросы