0

To preface this, I've looked for numerous examples prior to asking and can't find any solution in regards to my problem.

I'm trying to implement a generic queue in a program I'm making, but stuck at a certain point. The program I've made is supposed to simulate a printer, queued with print jobs. There is a Queue class, PrintQueue class, and job class. (It is important to note the Job class consists of a job ID and String of who ordered it). I've included a function (in the printQueue class) where if the first job matches the job ID you put in, it will be deleted.

Unfortunately however, the queue is generic. This means I can't traverse the array with just an integer to check equality because it is a queue of job objects. To fix this I create a job with a blank name, and regular ID. The Job class has an equals method, which determines if either ID or Owner match, then it is true. But when I execute the code, this class is not called. The generic equals class is called instead, which will of course be false. After looking at many examples on this site, I tried all the recommended solutions, which did not work for me as my case (and problem) are different. What can I do to override the generic equals method? My code below is as simple as I could make it to reproduce this problem while keep context.

JOB CLASS

public class Job{
    private String owner;
    private int jobId;

    public Job(String o, int j){
        owner = o;
        jobId = j;
    }
    public String getOwner(){
        return owner;
    }
    public int getJobId(){
        return jobId;
    }
    public String toString() {
        return owner + "    " + jobId + ".  ";
    }

    public boolean equals(Job a) {
        if(this.jobId == a.getJobId() || this.owner.equals(a.getOwner())) {
            return true;
        }
        else
            System.out.println("nomatch");
            return false;
    }
}

GENERIC QUEUE CLASS

   import java.util.ArrayList;
   public class Queue<T>{
    private ArrayList<T> queue;
    public Queue() {
        queue = new ArrayList<T>();
    }
    public void enQueue(T obj1) {
        queue.add(obj1);
    }
    public T deQueue() {
        if(queue.size() != 0) {
            T temp = queue.get(queue.size() - 1);
            queue.remove(queue.size() -1);
            return temp;
        }
        else
            return null;
    }
    public int size() {
        return queue.size();
    }
    public boolean isEmpty() {
        if (size() == 0) {
            return true;
        }
        else
            return false;
    }
    public int positionOf(T a) {
        for(int x = 0; x < queue.size(); x++) {
            if(a.equals(queue.get(x))) {
                System.out.println("Positionmatch");
                return x;
            }
        }
        return -1;
    }
}

PRINTQUEUE CLASS

public class PrintQueue {
    Queue<Job> prqueue = new Queue<Job>();
    public PrintQueue() {}

    public void lprm(int jobID) { //Removes the active job at the front of the queue if jobId matches, error message otherwise
        //I can't JUST use jobID to check the position because the queue is a collection of JOBS not JobId's
        if (prqueue.positionOf(new Job("",jobID))==0) {
            prqueue.deQueue();
        }
        else if (prqueue.positionOf(new Job("",jobID))== -1) {
            System.out.println("Job does not occupy first row.");
        }
    }
}

I know this is an extensive question, so if you do take the time to read it thank you very much. I wouldn't ask this if I could find the answer anywhere else.

  • when you override equals you have to override also the hashCode() method – François LEPORCQ Sep 29 '17 at 14:10
  • 1
    You are **not** overriding the equals methods in your Job class. The correct method signature is `public boolean equals(Object obj)`. It must take an Object as parameter. If you would have used the @Override annotation you would have probably spotted that error by yourself. – OH GOD SPIDERS Sep 29 '17 at 14:13
  • I had used @Override but I guess I didn't make sense of the error message. Thanks –  Sep 29 '17 at 14:14

2 Answers2

1

Solution is simple: you are not overriding equals in your class, common mistake. Always annotate your methods with @Override so you can avoid this mistake.

Real equals method is taking an Object parameter, and yours has a Job as parameter, change that to Object and then cast it accordingly.

If you are using IDE I suggest right click -> source -> generate equals and you will see a good example how to do it.

Shadov
  • 5,421
  • 2
  • 19
  • 38
  • Awesome answer and even better way to give me understanding, thanks so much! –  Sep 29 '17 at 16:01
  • I can't upvote answers as I'm not high enough rank yet. Sorry! –  Sep 29 '17 at 16:03
0

You have to override your methods like this

@Override
public boolean equals(Object a) {
    if(!(a instanceof Job))
        throw new IllegalArgumentException();
    Job job =(Job)a;
    if(this.jobId == job.getJobId() || this.owner.equals(job.getOwner())) {
        return true;
    }
    else
        System.out.println("nomatch");
    return false;
}

See also Why do I need to override the equals and hashCode methods in Java?