首页 > 解决方案 > 如何在 Java 中通过参数接收到的对象中检索数据?

问题描述

我正在尝试通过修改我之前实现的接受泛型的队列来构建优先级队列。我创建了一个名为 Priority Queue 的类(它接受泛型),它扩展了我的 Queue 类(它接受泛型)。最后一个类是主要焦点,Queue<T>。我在测试中推送了一个客户,当我在我的 Queue 推送方法中收到该客户时,我想用它来比较它的优先级和我的队列中另一个客户的优先级。有关解决此问题的任何建议都会有所帮助,但我的问题是,如何从 Queue 内部访问我的对象客户(或推送中的 val)的 3 个字段?

我有一个测试类来测试我的比较器是否工作。我还设置了一个测试用例,以便我可以确保我的优先级队列在我实现它时工作。

我的类用于测试我的比较器是否工作以及我的优先级队列在实施时是否工作:

public class TestCustomer {

   public static void main(String args[]) {

   Customer customer1 = new Customer(3000, 20, 5);
   Customer customer2 = new Customer(5000, 15, 7);
   Customer customer3 = new Customer(5000, 20, 5);
   Customer customer4 = new Customer(3000, 3, 5);
   Customer customer5 = new Customer(3000, 3, 8);


   // comparator test

   Customer.WorthComparator worth = new Customer.WorthComparator();
   Customer.LoyaltyComparator loyal = new Customer.LoyaltyComparator();
   Customer.WorthPoliteComparator polite = new Customer.WorthPoliteComparator();

   assert worth.compare(customer1, customer2) == -1;  
   assert worth.compare(customer2, customer3) == 0;  
   assert worth.compare(customer2, customer1) == 1; 

   assert loyal.compare(customer1, customer2) == 1; 
   assert loyal.compare(customer2, customer1) == -1; 
   assert loyal.compare(customer1, customer3) == 0; 

   assert polite.compare(customer3, customer2) == -1; 
   assert polite.compare(customer2, customer3) == 1; 
   assert polite.compare(customer1, customer2) == -1; 
   assert polite.compare(customer2, customer3) == 1; 
   assert polite.compare(customer1, customer4) == 0;

   // priority queue test

   PriorityQueue<Customer> pQueueW = new PriorityQueue<Customer>(worth); 
   PriorityQueue<Customer> pQueueL = new PriorityQueue<Customer>(loyal);
   PriorityQueue<Customer> pQueueP = new PriorityQueue<Customer>(polite); 



   // push -- type T, pass in a val // judgement upon worth

   //PUSH customers for Worth
   pQueueW.push(customer1);
   pQueueW.push(customer2);
   pQueueW.push(customer4);
   assert pQueueW.pop() == customer2;



   //PUSH customers for Loyalty
   pQueueL.push(customer1);
   pQueueL.push(customer2);
   pQueueL.push(customer3);
   assert pQueueL.pop() == customer1;


   //PUSH customers for Polite
   pQueueP.push(customer2);
   pQueueP.push(customer4);
   pQueueP.push(customer5);
   assert pQueueP.pop() == customer2;
   assert pQueueP.pop() == customer5;


   //























   }

   }

我的 Priority Queue 类只是扩展了 Queue 并使用它的推送功能。我需要创建一个方法来调用队列中的弹出窗口:

import java.util.Comparator;

public class PriorityQueue<T> extends Queue<T>
{

   Comparator<T> compare;

   public PriorityQueue(Comparator<T> comp)
   {
      compare = comp;
   }


    //@Override
   public void push(T val)
   {
       super.push(val); //right now this is just a normal Queue as it will do what its parent did.
   }

我的客户类有一个构造函数来创建客户。这也是我实现不同比较器以创建客户排序的地方:

import java.util.Comparator;

public class Customer
{

   int netWorth;
   int yearsWithCompany;
   int politeness;


   public Customer(int netWorth,int yearsWithCompany,int politeness)
   {
      this.netWorth = netWorth;
      this.yearsWithCompany = yearsWithCompany;
      this.politeness = politeness;
   }


/**
   compares clients based on thier net worth
*/
   public static class WorthComparator implements Comparator<Customer>
   {




   */
      public int compare(Customer c1, Customer c2)
      {
         int net1 = c1.netWorth;
         int net2 = c2.netWorth;
         if (net1 == net2) {
            return 0;
            }
         else if (net1 < net2) {
            return -1;
            }
         else {
            return 1;
            }
      }

   }


/**
   compares clients based on thier loyalty 
*/
   public static class LoyaltyComparator implements Comparator<Customer>
   {

   /**



   */
      public int compare(Customer c1, Customer c2)
      {

         int years1 = c1.yearsWithCompany;
         int years2 = c2.yearsWithCompany;

         if (years1 == years2) {
            return 0;
            }
         else if (years1 < years2) {
            return -1;
            }
         else {
            return 1;
            }

      }

   }



/**
   compares clients based on thier net worth.
   If there is a tie, politeness is used.
*/
   public static class WorthPoliteComparator implements Comparator<Customer>
   {

   /**

   */
      public int compare(Customer c1, Customer c2)
      {
         if (c1.netWorth == c2.netWorth)
        {
         if (c1.politeness < c2.politeness) {
            return -1;
         }        
         else if (c1.politeness > c2.politeness) {
            return 1;
         }
         else {
            return 0;
            }
         }
        else if (c1.netWorth > c2.netWorth){
         //int politeness = WorthComparator.compare(c1, c2);
         //return politeness;
         return 1;
          }

        else {
         return -1 ;
         }


         }

   }

}

我的 Queue 类被实现为一个常规队列。我现在正在修改它,以便我可以将它变成优先队列。Queue 类如下: public class Queue {

   public class QNode<T> {

      private QNode<T> node;
      private T val;  

      public QNode(QNode<T> node, T val) {
         this.node = node;
         this.val = val;

      }
   }

   protected QNode<T> head;
   protected QNode<T> rear;
   protected QNode<T> temp;




   public Queue()
   {
      head = null;
      rear = null;

         }

   public void push(T val) // T = Customer type -- val is a customer
   {
      // if I wanted to get the contents out of val, which is a customer
      // who has a net worth, years loyal, and politeness
      // how would I access let's say, the netWorth from val?

      // first node created
      if (head == null && rear == null){
         head = new QNode<T>(rear, val);
         rear = head;

      }


   }

   public T pop()
   {
      if (head == null){
         throw new QueueUnderFlowException();
      }

      else if(head == rear) {
        T temp_hold = head.val;
        head = null;
        rear = null;
        return temp_hold;

      }

      else {

         T oldN = head.val;

         this.head = this.head.node;
         return oldN;      
         }
      }

    /**
      returns true if the queue is empty
     */

   public boolean isEmpty()
   {
      if (head == null) {
       return true;
   }
      else {
       return false;
      }
   }

}

标签: javaobjectinstance-variables

解决方案


如果您Queue是通用的,则不能Customer直接引用的属性。您必须通过某些Queue已知的接口/基类使它们可以访问。由于Queue并不真正关心客户的净资产,而是关心不同客户之间的分类,因此有两种经典的方法。

首先,您可以制作Queue句柄Comparable对象:

public class Queue<T extends Comparable<T>> {
    // code...

Customer通过其净值进行比较:

public class Customer implements Comparable<Customer> {
    @Override
    public int compareTo(Customer other) {
        return Integer.compare(netWorth, other.netWorth);
    }

    // rest of the code...
}

或者,如果您不想将这种自然顺序强加于Customer类,则Queue该类可以采用 a Comparator,例如Comparator.comparingInt(Customer::getNetWorth())在其构造时。


推荐阅读