[英]Java PriorityQueue Comparator to insert a 2D array under certain conditions
[英]Sorting an array in java with certain conditions
我有一類叫做“運動員”的類,它是人類的一個副類。 在“人”類中,我實現了可比較的界面,並使用compareTo方法來比較不同運動員的年齡。 在運動員課中,我還有一個名為Year的字段,它對應於運動員開始比賽的年份。 在我程序的主要方法中,我有一個添加運動員和人類的數組列表。 我希望,如果運動員的年齡與開始比賽的年份相同。 我使用instanceof來檢查班級實例中的實例是否是運動員類型的對象,但此后我不知道如何使其工作。
public int compareTo(Human other)
{
if(this instanceof Athlete && other instanceof Athlete && this.age == other.age){
return ;
}
return this.age - other.age;
}
}
使用多態性 ,而不是運算符instanceof
。
即:重載Athlete類中的compareTo方法。
public int compareTo(Athlete other) {
//This method will be invoked if and only if you compare an athlete with another athlete
}
另外,請考慮equals方法的結果應與compareTo方法的結果一致。
一種可能的解決方案是在Athlete
類中也添加一個compareTo
方法,其內容如下(需要重寫,因為很久以前我一直沒有從事Java的工作):
public int compareTo(Athlete other){
int result = super.compareTo((Human)other);
if(result == 0){
return this.year - other.year;
}
return result;
}
作為代碼審查,我想說完整的代碼應類似於以下內容:
人的java
public int compareTo(Human other){
return age - other.age;
}
Athlete.java
@Override
public int compareTo(Human other){
if(other instanceof Athlete){
return compareTo((Athlete)other);
}
return super.compareTo(other);
}
public int compareTo(Athlete other){
int result = super.compareTo((Human)other);
if(result == 0){
return this.year - other.year;
}
return result;
}
使用您的示例,您也可以只比較年份:
public int compareTo(Human other)
{
if(this instanceof Athlete && other instanceof Athlete && this.age == other.age){
String tYear = ((Athlete)this).getYear();
String oYear = ((Athlete)other).getYear();
int tYearInt = 0;
int oYearInt = 0;
try {
tYearInt = Integer.parseInt(tYear);
oYearInt = Integer.parseInt(oYear);
} catch (Exception e){
e.printStackTrace();
}
return tYearInt - oYearInt;
}
return this.age - other.age;
}
但是,話雖如此,請隨時考慮@Andres答案,無論何時使用instanceof,都應質疑您的設計是否錯誤。
就像安德列斯(Andres)所說的,使用多態。 這樣做的方法如下:
首先,在“ Human
類中this instanceof Athlete
不是好的樣式,因為從“ Human
類的角度來看,“ Athlete
是一個子類,而引用子類在某些情況下會導致問題。 而是,將另一個compareTo()
方法放入Athlete
類。 如果Athlete.compareTo()
被調用,你已經知道, this
是類型的Athlete
,如果你要比較的year
場,你只需要檢查other instanceof Athlete
,這是確定的,因為現在我們是在透視Athlete
類,從這里開始, Athlete
不是子類。
就是說,在Athlete
課程中,使用以下命令:
public int compareTo(Human other) {
int humanComp = super.compareTo(other);
if (humanComp != 0){
return humanComp;
}
if (other instanceof Athlete) {
return ((Athlete)other).year - this.year;
}
return 0;
}
該解決方案首先使用Human.compareTo()
(與super.compareTo(other)
一起super.compareTo(other)
)來檢查Human
類是否已經知道如何對this
和other
實例進行排序。 如果不是,即該調用返回0,則必須繼續比較更多詳細信息,在本例中為year
字段。
因為我們使用了Human.compareTo()
,所以我們必須確保它存在於Human
類中並且可以正常工作:
public int compareTo(Human other) {
return this.age - other.age;
}
這只是按age
進行比較,因為這是Human
類中我們知道可用於比較的唯一字段。
compareTo
的文檔說:
最后,實現者必須確保對於所有
z
,x.compareTo(y)==0
意味着sgn(x.compareTo(z)) == sgn(y.compareTo(z))
。
您提出的方法不符合此要求。 例如,假設
x = Athlete, age = 35, start date = 2000
y = Human, age = 35
z = Athlete, age = 35, start date = 2001
在這個例子中
x.compareTo(y) == 0 // y is not an athlete
x.compareTo(z) < 0 // Both athletes, different start dates.
y.compareTo(z) == 0 // y is not an athlete
如果您不遵守Comparable
的合同,則未指定Arrays.sort
或Collections.sort
的行為。 理想情況下,您會得到一個異常,但是麻煩的是,這些排序方法根據數組或列表的大小使用不同的算法,並且如果輸入數組或列表包含以下內容 ,則您更有可能因不正確的compareTo
方法而引發異常大量的要素 。 這意味着您應該使用隨機生成的長數組非常仔細地測試您的compareTo
方法,否則,您的代碼中可能會包含難以發現的細微錯誤。
正確的compareTo
方法如下所示:
public int compareTo(Human other) {
int result = Integer.compare(age, other.age);
if (result != 0)
return result;
if (!(this instanceof Athlete))
return other instanceof Athlete ? -1 : 0;
return other instanceof Athlete
? Long.compare(((Athlete) this).startDate(), ((Athlete) other).startDate())
: 1;
}
該方法首先按年齡排序。 如果兩個人的年齡相同,則按類型將其排在第一位(運動員排在第一位)。 年齡相同的運動員按開始日期排序。 具有相同年齡的非運動員不會以任何特定順序出現。
最后,請注意,通常最好使用多態性而不是instanceof
。 這里的問題是Human implements Comparable<Human>
。 因此compareTo
方法必須接受一個Human
而不是一個Athlete
。 即使您在Athlete
重寫compareTo
,該參數也必須是Human
,並且無論如何您都必須使用instanceof
來檢查參數的類型(如@GentianKasa的回答), 或者編寫一個完全獨立的方法compareToAthlete(Athlete athlete)
滲漏compareToAthlete(Athlete athlete)
和在Athlete
執行以下操作
@Override
public int compareTo(Human human) {
return -human.compareToAthlete(this); // Note the minus sign!
}
compareToAthlete
也將需要兩個版本。 在此有效的同時,這意味着compareTo
方法的邏輯分布在四種方法中,這使得更難於推理其正確性。 在這種情況下,我會nose之以鼻並使用instanceof
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.