2017-08-30 7 views
0

J'ai une classe d'entité avec les champs suivants: id, orderNo. Chaque entité doit être stockée dans une file d'attente de priorité Java. Les éléments dont l'ID est compris entre 1 et 3000 ont une priorité plus élevée et doivent être stockés dans ordre croissant de commandeAucun élément au-dessus des éléments avec id> 3000. Les éléments avec ids> 3000 sont stockés dans l'ordre croissant de commandeNon au-dessous des éléments prioritaires (avec les identifiants 1 - 3000).Tri de la file d'attente prioritaire pour une plage d'éléments de priorité plus élevée et d'autres éléments de priorité inférieure

Par exemple:

(1st insertion to queue: id=4000 orderNo=1) 
(2nd insertion to queue: id=5000 orderNo=2) 
(3rd insertion to queue: id=100 orderNo=3) 
(4th insertion to queue: id=50 orderNo=4) 

séquence de tri Expected:

(id=100 orderNo=3) 
(id=50 orderNo=4) 
(id=4000 orderNo=1) 
(id=5000 orderNo=2) 

classe OrderEntity:

public class OrderEntity implements Comparable<OrderEntity> { 
    private int id; 
    private int getOrderNo; 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public int getOrderNo() { 
     return getOrderNo; 
    } 

    public void setOrderNo(int getOrderNo) { 
     this.getOrderNo = getOrderNo; 
    } 

    @Override 
    public int compareTo(OrderEntity arg0) { 
     if ((this.getId() >= 1 && this.getId() <= 3000) && (arg0.getId() >= 1 && arg0.getId() <= 3000)) { 
      if (this.getOrderNo() > arg0.getOrderNo()) { 
       return 1; 
      } else { 
       return 0; 
      } 
     } else if ((this.getId() <= 3000) && (arg0.getId() > 3000)) { 
      return 1; 
     } else if ((this.getId() > 3000) && (arg0.getId() <= 3000)) { 
      return 1; 
     } else if ((this.getId() > 3000) && (arg0.getId() > 3000)) { 
      if (this.getOrderNo() > arg0.getOrderNo()) { 
       return 1; 
      } else { 
       return 0; 
      } 
     } else { 
      return 0; 
     } 
    } 
} 

classe BonCommande:

public class OrderProcessor { 
    private static int count; 
    static Queue<OrderEntity> pq = new PriorityQueue<>(); 

    public String createOrder(int id) { 
     OrderEntity orderEntity = new OrderEntity(); 
     orderEntity.setId(id); 
     count = count + 1; 
     orderEntity.setOrderNo(count); 
     pq.add(orderEntity); 

     String res = ""; 
     for (OrderEntity rd : pq) { 
      res = res + rd.getId() + " " + rd.getOrderNo() + "\n"; 
     } 
     return res.trim(); 
    } 
} 
+0

Et votre question est ...? –

+0

Ma question est que je ne suis pas en mesure d'obtenir cette séquence avec la mise en œuvre ci-dessus. Je voulais savoir où je me trompe. –

+0

Un problème est votre méthode 'compareTo', qui renvoie 0 (signifiant égal) si le premier élément n'est pas plus grand que le second. 'compareTo' devrait renvoyer -1, 0 ou 1, selon que le premier élément est inférieur, égal ou supérieur au second. Généralement, vous utilisez 'Integer.compare' pour vérifier cela. –

Répondre

2

Dans de tels cas que l'ordre naturel des objets est différent de votre condition spéciale, il vaut mieux ne pas utiliser Comparable car il pourrait avoir d'autres usages dans le futur. Ainsi, la solution restante utilise Comparator ce qui convient très bien à votre problème car votre classe OrderEntity n'aura pas de dépendance sur cette comparaison spéciale. ce qui suit est un exemple de code montrant la solution:

import java.util.Comparator; 
import java.util.PriorityQueue; 

public class OrderProcessor { 
    public static void main(String[] args) { 
     PriorityQueue<OrderEntity> q = new PriorityQueue<>(new OrderEntityComparator()); 
     q.add(new OrderEntity(4000, 1)); 
     q.add(new OrderEntity(5000, 2)); 
     q.add(new OrderEntity(100, 3)); 
     q.add(new OrderEntity(50, 4)); 

     while(!q.isEmpty()) 
      System.out.println(q.poll()); 
    } 

    public static class OrderEntityComparator implements Comparator<OrderEntity> { 

     @Override 
     public int compare(OrderEntity o1, OrderEntity o2) { 
      if(o1.getId() <= 3000 && o2.getId() <= 3000) 
       return Integer.compare(o1.getOrderNo(), o2.getOrderNo()); 
      if(o1.getId() > 3000 && o2.getId() > 3000) 
       return Integer.compare(o1.getOrderNo(), o2.getOrderNo()); 
      if(o1.getId() <= 3000 && o2.getId() > 3000) 
       return -1; 
      return 1; 
     } 
    } 

    public static class OrderEntity { 
     private int id; 
     private int orderNo; 

     public OrderEntity(int id, int orderNo) { 
      this.id = id; 
      this.orderNo = orderNo; 
     } 

     public int getId() { 
      return id; 
     } 

     public void setId(int id) { 
      this.id = id; 
     } 

     public int getOrderNo() { 
      return orderNo; 
     } 

     public void setOrderNo(int orderNo) { 
      this.orderNo = orderNo; 
     } 

     @Override 
     public String toString() { 
      return "OrderEntity{" + 
        "id=" + id + 
        ", orderNo=" + orderNo + 
        '}'; 
     } 
    } 
} 

édité:

Si vous ne voulez pas supprimer des éléments en appelant la méthode poll, vous devez trier vos éléments dans un tableau ou une liste , quelque chose comme ceci:

OrderEntity[] a = new OrderEntity[q.size()]; 
    q.toArray(a); 
    Arrays.sort(a, new OrderEntityComparator()); 

    for(OrderEntity entity : a) 
     System.out.println(entity); 

en fait, dans ce cas, vous n'avez pas besoin d'utiliser un PriorityQueue et une sorte simple sur une liste ou un tableau fera le travail.

+0

Ne fonctionne pas. Essayez avec l'entrée suivante: (100,1) (200,2) (4000,3) (300,4). Sortie attendue: (100,1) (200,2) (300,4) (4000,3). Sortie réelle: (100,1) (200,2) (4000,3) (300,4) –

+0

@AshwinShirva Quelle est votre sortie attendue? Ma sortie est: (100,1) (200,2) (300,4) (4000,3) –

+0

@AshwinShirva J'ai couru le code et la sortie était la même que prévu. Voulez-vous s'il vous plaît vérifier mon code? –

0

Voici une solution utilisant Java 8 qui ne nécessite aucune implémentation de comparateur compliquée. Je l'ai couru contre les deux exemples que vous avez fournis. L'astuce consiste à réaliser qu'il y a 2 groupes d'ID, ceux < = 3000, et ceux ci-dessus. Si vous pouvez normaliser les nombres dans ces deux groupes, vous pouvez simplement utiliser l'ordre naturel des identifiants normalisés suivi de l'ordre naturel par numéro de commande.

public class Main { 
    private static Comparator<OrderEntity> orderEntityComparator = 
     Comparator.<OrderEntity, Integer>comparing(OrderEntity::getId, 
       comparingInt(id -> id/3000) 
     ) 
       .thenComparingInt(OrderEntity::getOrderNo); 

    public static void main(String[] args) { 
     PriorityQueue<OrderEntity> queue = new PriorityQueue<>(orderEntityComparator); 
     queue.add(new OrderEntity(4000, 1)); 
     queue.add(new OrderEntity(5000, 2)); 
     queue.add(new OrderEntity(100, 3)); 
     queue.add(new OrderEntity(50, 4)); 

     // 100, 50, 4000, 5000 

     queue.clear(); 

     queue.add(new OrderEntity(100, 1)); 
     queue.add(new OrderEntity(200, 2)); 
     queue.add(new OrderEntity(4000, 3)); 
     queue.add(new OrderEntity(300, 4)); 

     while (!queue.isEmpty()) { 
      System.out.println(queue.poll()); 
     } 
     // 100, 200, 300, 4000 
    } 

    static class OrderEntity { 
     private int id; 
     private int orderNo; 

     public OrderEntity(int id, int orderNo) { 
      this.id = id; 
      this.orderNo = orderNo; 
     } 

     public int getId() { 
      return id; 
     } 

     public int getOrderNo() { 
      return orderNo; 
     } 

     @Override 
     public String toString() { 
      return String.format("(id=%d, orderNo=%d)", id, orderNo); 
     } 
    } 
}