Java 具有 2 个优先级参数的优先级队列
Java Priority Queue with 2 Priority parameters
我有一个 class 实现 Comparable 的 Person,如下所示,因为我想将 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;
}
}
我有两个 class 扩展 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;
}
}
在 main 方法中,我正在创建 Staff 对象和 Students 对象,设置对象的注册日期并将它们放入优先队列
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.Staff 对象的优先级应该高于学生对象
2.Staff 注册日期较早的员工应优先于注册日期较晚的员工
3.Students 注册日期较早的学生应该比注册日期较晚的学生有更高的优先级。
目前我得到的输出没有产生预期的结果。职员对象的优先级高于学生对象,但根据日期的优先级不起作用。我知道我的 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;
}
一个问题是你总是假设一个人是工作人员,一个人是学生。可能两者相同 class.
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());
让我们开始让你的 Person class 使用通用类型而不是原始类型:
public class Person extends Comparable<Person>
那我们给classes分配一个优先级。您没有说明 "bare" 既不是教职员工也不是学生的人应该如何与其他人进行比较。因此,我假设 "bare" 人不应该存在,因此你的 Person
class 应该是抽象的:
public abstract class Person extends Comparable<Person>
那么您希望每个 class 都有一个优先级。所以让我们实现它,而不是依赖丑陋的 instanceof
:
protected abstract int getPriority();
Staff 应该在 Student 之前,因此在 Staff 中:
@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 是微不足道的。你只需要return在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
方法首先检查天气 obj
是 instanceof
Staff
还是 Student
.
schoolQueue
包含 Staff
和 Student
对象。或者:
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());
}
我有一个 class 实现 Comparable 的 Person,如下所示,因为我想将 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;
}
}
我有两个 class 扩展 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;
}
}
在 main 方法中,我正在创建 Staff 对象和 Students 对象,设置对象的注册日期并将它们放入优先队列
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.Staff 对象的优先级应该高于学生对象 2.Staff 注册日期较早的员工应优先于注册日期较晚的员工 3.Students 注册日期较早的学生应该比注册日期较晚的学生有更高的优先级。
目前我得到的输出没有产生预期的结果。职员对象的优先级高于学生对象,但根据日期的优先级不起作用。我知道我的 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;
}
一个问题是你总是假设一个人是工作人员,一个人是学生。可能两者相同 class.
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());
让我们开始让你的 Person class 使用通用类型而不是原始类型:
public class Person extends Comparable<Person>
那我们给classes分配一个优先级。您没有说明 "bare" 既不是教职员工也不是学生的人应该如何与其他人进行比较。因此,我假设 "bare" 人不应该存在,因此你的 Person
class 应该是抽象的:
public abstract class Person extends Comparable<Person>
那么您希望每个 class 都有一个优先级。所以让我们实现它,而不是依赖丑陋的 instanceof
:
protected abstract int getPriority();
Staff 应该在 Student 之前,因此在 Staff 中:
@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 是微不足道的。你只需要return在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
方法首先检查天气 obj
是 instanceof
Staff
还是 Student
.
schoolQueue
包含 Staff
和 Student
对象。或者:
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());
}