繁体   English   中英

具有2个优先级参数的Java优先级队列

[英]Java Priority Queue with 2 Priority parameters

我有一个Person类,它实现Comparable,如下所示,因为我想将Person对象放置在优先级队列中。

public class Student implements Comparable{
    private String fullName;
    private Date registrationDate;

public Person(String fullName){
    this.fullName = fullName;
}

public String getFullName() {
    return fullName;
}

public void setFullName(String fullName) {
    this.fullName = fullName;
}

public Date getRegistrationDate() {
        return registrationDate;
    }
    public void setRegistrationDate(Date registrationDate) {
        this.registrationDate = registrationDate;
    }

@Override
    public int compareTo(Object obj) {
        Person person = (Person) obj;

        if(person instanceof Staff){
            return 1; 
        }else if(person instanceof Student){
            return -1;
        }
        else if(getRegistrationDate().before(person.getRegistrationDate())){
            return 1;
        }else if(getRegistrationDate().after(person.getRegistrationDate())){
            return -1;
        }
        return 0;
    }
}

我有两个扩展Person的类,如下所示

public class Staff extends Person{
    public Staff(String fullName){
        this.fullName = fullName;
     }
}

public class Student extends Member{
    public Student(String fullName){
        this.fullName = fullName;
     }
}

在主要方法中,我将创建“职员”对象和“学生”对象,设置对象的注册日期并将其置于优先级队列中

public class School {

    public static void main(String args[]) {

        //list of students
        Student student1 = new Student("John Kent");
        Date dateStudent1Joined = new GregorianCalendar(2014, Calendar.JULY, 1).getTime();
        student1.setRegistrationDate(dateStudent1Joined);

        Student student2 = new Student("Peter Tush");
        Date dateStudent2Joined = new GregorianCalendar(2014, Calendar.JULY, 2).getTime();
        student2.setRegistrationDate(dateStudent2Joined);

        Student student3 = new Student("Mike Monroe");
        Date dateStudent3Joined = new GregorianCalendar(2014, Calendar.JULY, 3).getTime();
        student3.setRegistrationDate(dateStudent3Joined);

        Student student4 = new Student("Tom Johnson");
        Date dateStudent4Joined = new GregorianCalendar(2014, Calendar.JULY, 4).getTime();
        student4.setRegistrationDate(dateStudent4Joined);

        Student student5 = new Student("Tony Spencer");
        Date dateStudent5Joined = new GregorianCalendar(2014, Calendar.JULY, 5).getTime();
        student5.setRegistrationDate(dateStudent5Joined);

        //list of staff
        Staff staff1 = new Staff("Luke Clint");
        Date dateStaff1Joined = new GregorianCalendar(2014, Calendar.JULY, 6).getTime();
        staff1.setRegistrationDate(dateStaff1Joined);

        Staff staff2 = new Staff("Ron West");
        Date dateStaff2Joined = new GregorianCalendar(2014, Calendar.JULY, 7).getTime();
        staff2.setRegistrationDate(dateStaff2Joined);

        Staff staff3 = new Staff("Jim Gary");
        Date dateStaff3Joined = new GregorianCalendar(2014, Calendar.JULY, 8).getTime();
        staff3.setRegistrationDate(dateStaff3Joined);


        //create a queue data structure to hold Persons in school
        PriorityQueue<Person> schoolQueue = new PriorityQueue<Person>();
        //add students to queue
        schoolQueue.offer(student1);
        schoolQueue.offer(student2);
        schoolQueue.offer(student3);
        schoolQueue.offer(student4);
        schoolQueue.offer(student5);
        //add staff to queue
        schoolQueue.offer(staff1);
        schoolQueue.offer(staff2);
        schoolQueue.offer(staff3);

        //print names of people in queue
        for(Member member : clubQueue){
            String memberName = member.getFullName();
            System.out.println(memberName);
        }

    }
}

我的优先级队列应遵循3条规则1.员工对象应比学生对象具有更高的优先级2.注册日期较早的员工应比注册日期较晚的员工具有更高的优先级3.注册日期较早的学生应具有更高的优先级优先级高于注册日期较晚的学生。

我得到的输出目前无法产生预期的结果。 人员对象的优先级高于学生对象的优先级,但根据日期的优先级无效。 我了解compareTo方法中的规则是问题所在,我该如何改善呢? 再次为方便起见

@Override
        public int compareTo(Object obj) {
            Person person = (Person) obj;

            if(person instanceof Staff){
                return 1; 
            }else if(person instanceof Student){
                return -1;
            }
            else if(getRegistrationDate().before(person.getRegistrationDate())){
                return 1;
            }else if(getRegistrationDate().after(person.getRegistrationDate())){
                return -1;
            }
            return 0;
        }

让我们开始让您的Person类使用通用类型而不是原始类型:

public class Person extends Comparable<Person>

然后,为类分配优先级。 您没有告诉我们既不是员工也不是学生的“裸”人应该与其他人相比。 因此,我假设“裸”人员不应该存在,因此您的Person类应该是抽象的:

public abstract class Person extends Comparable<Person>

然后,您希望每个班级都有一个优先级。 因此,让我们实现它,而不是依赖于丑陋的instanceof

protected abstract int getPriority();

教职员工应先于学生,因此在教职员工中:

@Override
protected int getPriority() {
    return 0;
}

在学生中:

@Override
protected int getPriority() {
    return 1000;
}

现在让我们实现compareTo方法:

public int compareTo(Person other) {
    int result = Integer.compare(this.getPriority(), other.getPriority());
    if (result == 0) {
        result = this.getRegistrationDate().compareTo(other.getRegistrationDate())
    }
    return result;
}

请注意,添加另一种Person是微不足道的。 您只需要在getPriority中返回适当的值,就不必更改比较代码。

还要注意,compareTo现在将Person作为参数,并且由于正确的泛型类型,编译器现在将阻止您执行诸如person.compareTo("foo")类的愚蠢的事情。

如果使用Java 8,则您的compareTo方法甚至可能更简单:

private static final Comparator<Person> COMPARATOR = 
    Comparator.comparingInt(Person::getPriority) 
              .thenComparing(Person::getRegistrationDate);

@Override
public int compareTo(Person other) {
    return COMPARATOR.compare(this, other);
}

注意: Comparable是通用接口。 将泛型用于您的使用。

让我们看看您的compareTo method compareTo方法首先检查天气objStaff还是Student instanceof

schoolQueue包含StaffStudent对象。 或者:

if(person instanceof Staff){
  return 1; 

要么:

}else if(person instanceof Student){
  return -1;
}

被执行。 所以最后两个else if块永远不会执行。

解:

// If the object on which compareTo() is applied is of type Student and person
// is of type Staff, return -2
// -2 indicates that Staff has priority over student
if(this instanceof Student && person instanceof Staff){
  return -2; 
}
// If the object on which compareTo() is applied is of type Staff and person
// is of type Student, return 2
else if(this instanceof Staff && person instanceof Student){
  return 2;
}
// If both are of same type, prioritize the one who registered early
else {
  return (this.getRegistrationDate()).compareTo(person.getRegistrationDate());
}

一个问题是,您始终假定一个人是工作人员,一个人是学生。 两者可能是同一类。

 if(this instance Student && person instanceof Staff) {
        return 1; // Student has priority
 } else if (this instance Staff && person instanceof Student){
        return -1; // Student has priority
 }
 return getRegistrationDate().compareTo(person.getRegistrationDate());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM