将 collections.sort() 与 compareTo(而不是排序)一起使用



所以目前我正在做一个作业,我必须有两个班级,一个叫Fysiker,另一个叫人类。Fysiker只是人类阶级的延伸。人类有两个属性:名字和年龄,而Fysiker有三个属性:名字,年龄和开始年份。我创建了一个同时接受 Human 和 Fysiker 的数组,我想先按年龄对其进行排序,但如果两个 fysiker 具有相同的年龄,我希望它按我的第三个属性进行排序:开始年份。

我对compareTo的理解(为了练习,我需要使用compareTo)是有限的,但从我读到的内容来看,它是一个与Collections.sort()自动交互的可比物,我的代码目前看起来像这样:

import java.util.List;
import java.util.Arrays;
import java.util.Random;
import java.util.ArrayList;
import java.util.Collections;
public class Fysiker extends Human{
public int startyear;
public Fysiker(int age, String name, int startyear){
this.age=age;
this.name=name;
this.startyear=startyear;
}
public int getYear(){
return startyear;
}
public int compareTo(Fysiker o){
int b;
b=(this.age>o.age ? 1:this.age<o.age ? -1:0);
if (b==0){
b=(this.startyear>o.startyear ? 1:this.startyear<o.startyear ? -1:0);
return b;}
else{
return b;}
}
public String toString(){
return "åldern är:"+this.age+" "+"namnet är:"+this.name+" "+"började fysik:"+String.format("F%02d",this.startyear%100);
}
public Fysiker(){
this.age=15+rand.nextInt(86);
this.name=names.get(rand.nextInt(names.size()));
this.startyear=2015-rand.nextInt(this.age-14);
while (this.startyear<1932){
this.startyear=2015-rand.nextInt(this.age-14);
}
}
public static void main(String[] args){
ArrayList<Human> fysiker=new ArrayList<Human>();
int q;

for (q=0;q<=80;q++){
fysiker.add(new Fysiker());
//fysiker.add(new Human());
//System.out.println(fysiker.get(q).toString());
}
int s;
Collections.sort(fysiker);
for (s=0;s<=fysiker.size()-1;s++){
//fysiker.get(0).compareTo(fysiker.get(s));
System.out.println(fysiker.get(s).toString());
//System.out.println(fysiker.get(0));
}
}
}

人类类反过来:

import java.util.List;
import java.util.Arrays;
import java.util.Random;
import java.util.ArrayList;
public class Human implements Comparable<Human>{
public static final List<String> names = Arrays.asList("Rutger","Oscar","Aram","Noak","Hilda","Dahl");
public Random rand=new Random();
public String name;
public int age;
public Human(int age, String name){
this.age=age;
this.name=name;
}
public Human(){
this.age=rand.nextInt(101);
this.name=names.get(rand.nextInt(names.size()));
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
public String toString(){
return "åldern är:"+this.age+" "+"namnet är:"+this.name;
}
public int compareTo(Human o){
return this.age-o.age;
}
}

我的问题是它在开始年份之后不会排序,但是如果我从我的 Human 类中删除 compareTo,我可以修复它,但我也需要那个,我想将它们全部排序,但它解决了"在开始年份后不排序为 fysiker"问题。我该何去何从?

事实上,子类中定义的方法:

public int compareTo(Fysiker o){

不重写基类中的方法:

public int compareTo(Human o){

您可以定义具有相同签名的子类以有效地覆盖:

public int compareTo(Human o){

并使用instanceof根据实际类型进行比较。
但这也不是一个好主意。 事实上,Fysiker知道如何比较HumanFysiker,但Human只知道如何比较Human

Comparable.compareTo()合同规定:

实现者还必须确保关系是可传递的: ((compare(x

, y)>0) && (compare(y, z)>0)) 表示 compare(x, z)>0。

Comparable不应尝试在类之间互操作,因为它可能违反传递性比较原则。

我认为在您的情况下,作为替代方案,您应该使用Comparator对元素进行排序。

你有两种方法。

1) 如果列表仅包含Fysiker个实例,请声明FysikerList并创建一个Comparator<Fysiker>

List<Fysiker> fysiker = new ArrayList<Fysiker>();
...
Collections.sort(fysiker);

它限制了清单可以接受的要素的类型,但在这种特定情况下是希望的。

2) 如果列表同时包含HumanFysiker实例,请声明HumanList并创建一个Comparator<Human>

List<Human> humans = new ArrayList<Human>();
...
Collections.sort(fysiker);

Comparator实现中,您应该检查实例的类型并根据以下内容进行比较:

public class ComparatorHumanAndFysiker implements Comparator<Human>{
public int compare(Human o1, Human o2){
if (o1 instanceof Fysiker && o2 instanceof Fysiker){
Fysiker f1 = (Fysiker) o1;
Fysiker f2 = (Fysiker) o2;
// specific comparison
return ...;
}
// else mixed type comparison or human comparison              
return o1.age - o2.age;                         
}
} 

在排序过程中,仅使用compareTo(Human o)方法。从不使用compareTo(Fysiker o),因为您没有实现Comparable<Fysiker>接口。不幸的是,使用具体的类继承,您的Fysiker类将无法实现Comparable<Fysiker>因为它已经间接实现了Comparable<Human>接口,并且在 Java 中您无法实现具有不同泛型类型的相同接口。

作为快速解决方法,您可以重写Fysiker类中的compareTo(Human o),而不是定义重载的compareTo(Fysiker o)方法:

public int compareTo(Human o){
int b;
b=(this.age>o.age ? 1:this.age<o.age ? -1:0);
if (b==0 && o instanceof Fysiker){
b= ( this.startyear> ( (Fysiker) o ).startyear ? 1:this.startyear< ( (Fysiker)o ).startyear ? -1:0);
return b;
}else{
return b;
}
}

更新:

我认为这种方法要干净得多:

public int compareTo(Human o){
int age1 = this.age;
int age2 = o.age;
int result = age1 - age2;
if (result != 0) return result;
int startyear1 = this.startyear;
int startyear2 = (o instanceof Fysiker) ? ( (Fysiker)o ).startyear : 0;
return startyear1 - startyear2;
}

输出:

åldern är:0 namnet är:Oscar
åldern är:5 namnet är:Oscar
åldern är:6 namnet är:Aram
åldern är:6 namnet är:Dahl
åldern är:7 namnet är:Aram
åldern är:8 namnet är:Oscar
åldern är:10 namnet är:Oscar
åldern är:12 namnet är:Noak
åldern är:14 namnet är:Aram
åldern är:15 namnet är:Aram
åldern är:15 namnet är:Oscar
åldern är:16 namnet är:Aram
åldern är:17 namnet är:Dahl
åldern är:17 namnet är:Hilda
åldern är:18 namnet är:Noak
åldern är:18 namnet är:Noak började fysik:F2015
åldern är:18 namnet är:Oscar
åldern är:18 namnet är:Oscar började fysik:F2014
åldern är:19 namnet är:Noak
åldern är:19 namnet är:Oscar började fysik:F2013
åldern är:19 namnet är:Hilda började fysik:F2015
åldern är:19 namnet är:Noak
åldern är:20 namnet är:Hilda började fysik:F2011
åldern är:20 namnet är:Dahl
åldern är:21 namnet är:Hilda började fysik:F2015
åldern är:21 namnet är:Rutger
åldern är:21 namnet är:Dahl
åldern är:21 namnet är:Dahl började fysik:F2009
åldern är:21 namnet är:Noak började fysik:F2009
åldern är:21 namnet är:Aram började fysik:F2015
åldern är:22 namnet är:Rutger började fysik:F2011
åldern är:22 namnet är:Hilda
åldern är:22 namnet är:Aram
åldern är:22 namnet är:Oscar
åldern är:24 namnet är:Rutger började fysik:F2006
åldern är:24 namnet är:Hilda
åldern är:24 namnet är:Oscar
åldern är:26 namnet är:Hilda började fysik:F2013
åldern är:27 namnet är:Noak började fysik:F2012
åldern är:27 namnet är:Hilda började fysik:F2013
åldern är:28 namnet är:Rutger
åldern är:28 namnet är:Dahl
åldern är:28 namnet är:Oscar började fysik:F2004
åldern är:29 namnet är:Aram började fysik:F2007
åldern är:29 namnet är:Aram började fysik:F2013
åldern är:29 namnet är:Rutger började fysik:F2013
åldern är:31 namnet är:Oscar började fysik:F2009
åldern är:31 namnet är:Dahl
åldern är:31 namnet är:Oscar
åldern är:33 namnet är:Aram började fysik:F2004
åldern är:33 namnet är:Aram började fysik:F2008
åldern är:34 namnet är:Noak
åldern är:34 namnet är:Noak började fysik:F2007
åldern är:34 namnet är:Hilda
åldern är:34 namnet är:Hilda började fysik:F1999
åldern är:35 namnet är:Aram
åldern är:35 namnet är:Hilda började fysik:F2010
åldern är:36 namnet är:Noak
åldern är:36 namnet är:Oscar
åldern är:38 namnet är:Hilda började fysik:F1999
åldern är:39 namnet är:Rutger började fysik:F2013
åldern är:42 namnet är:Dahl
åldern är:43 namnet är:Oscar
åldern är:43 namnet är:Noak började fysik:F2002
åldern är:43 namnet är:Aram
åldern är:43 namnet är:Oscar
åldern är:44 namnet är:Rutger
åldern är:44 namnet är:Aram
åldern är:44 namnet är:Oscar
åldern är:44 namnet är:Dahl
åldern är:45 namnet är:Oscar
åldern är:47 namnet är:Oscar började fysik:F1986
åldern är:48 namnet är:Hilda
åldern är:50 namnet är:Dahl började fysik:F2004
åldern är:50 namnet är:Dahl började fysik:F2008
åldern är:50 namnet är:Rutger
åldern är:51 namnet är:Hilda började fysik:F2014
åldern är:52 namnet är:Aram
åldern är:54 namnet är:Noak
åldern är:56 namnet är:Noak började fysik:F2011
åldern är:56 namnet är:Aram
åldern är:56 namnet är:Dahl
åldern är:56 namnet är:Rutger började fysik:F2009
åldern är:58 namnet är:Aram
åldern är:59 namnet är:Oscar började fysik:F1982
åldern är:59 namnet är:Oscar
åldern är:60 namnet är:Aram började fysik:F1985
åldern är:60 namnet är:Hilda
åldern är:60 namnet är:Aram
åldern är:61 namnet är:Aram började fysik:F1976
åldern är:61 namnet är:Hilda började fysik:F2003
åldern är:62 namnet är:Hilda
åldern är:63 namnet är:Noak började fysik:F1989
åldern är:63 namnet är:Dahl
åldern är:63 namnet är:Oscar
åldern är:64 namnet är:Hilda började fysik:F2013
åldern är:65 namnet är:Hilda började fysik:F1998
åldern är:65 namnet är:Dahl började fysik:F1998
åldern är:67 namnet är:Rutger började fysik:F1968
åldern är:67 namnet är:Rutger började fysik:F1972
åldern är:68 namnet är:Hilda
åldern är:69 namnet är:Noak började fysik:F2007
åldern är:69 namnet är:Hilda
åldern är:69 namnet är:Noak
åldern är:70 namnet är:Rutger började fysik:F1977
åldern är:70 namnet är:Noak började fysik:F2000
åldern är:71 namnet är:Dahl började fysik:F1961
åldern är:71 namnet är:Aram började fysik:F2009
åldern är:72 namnet är:Oscar
åldern är:73 namnet är:Dahl började fysik:F1998
åldern är:75 namnet är:Noak
åldern är:75 namnet är:Hilda
åldern är:76 namnet är:Hilda
åldern är:76 namnet är:Noak började fysik:F1998
åldern är:76 namnet är:Dahl
åldern är:77 namnet är:Oscar
åldern är:77 namnet är:Aram
åldern är:78 namnet är:Rutger började fysik:F1958
åldern är:78 namnet är:Oscar
åldern är:79 namnet är:Rutger började fysik:F1958
åldern är:79 namnet är:Aram började fysik:F1960
åldern är:79 namnet är:Aram började fysik:F1967
åldern är:79 namnet är:Hilda
åldern är:80 namnet är:Oscar började fysik:F1961
åldern är:80 namnet är:Oscar började fysik:F1969
åldern är:80 namnet är:Oscar började fysik:F2007
åldern är:81 namnet är:Rutger började fysik:F1996
åldern är:81 namnet är:Oscar
åldern är:81 namnet är:Aram började fysik:F2011
åldern är:85 namnet är:Dahl
åldern är:87 namnet är:Hilda
åldern är:88 namnet är:Dahl började fysik:F1976
åldern är:88 namnet är:Rutger
åldern är:88 namnet är:Hilda började fysik:F1968
åldern är:88 namnet är:Hilda började fysik:F2003
åldern är:88 namnet är:Oscar började fysik:F2005
åldern är:88 namnet är:Oscar började fysik:F2005
åldern är:89 namnet är:Noak började fysik:F1970
åldern är:89 namnet är:Noak
åldern är:89 namnet är:Dahl
åldern är:90 namnet är:Noak började fysik:F1975
åldern är:91 namnet är:Oscar började fysik:F1984
åldern är:91 namnet är:Hilda
åldern är:91 namnet är:Dahl
åldern är:91 namnet är:Aram
åldern är:92 namnet är:Rutger
åldern är:92 namnet är:Aram började fysik:F1997
åldern är:94 namnet är:Oscar började fysik:F1936
åldern är:95 namnet är:Dahl
åldern är:95 namnet är:Rutger började fysik:F1940
åldern är:96 namnet är:Hilda började fysik:F1945
åldern är:96 namnet är:Rutger började fysik:F1962
åldern är:96 namnet är:Aram började fysik:F1994
åldern är:96 namnet är:Noak började fysik:F1997
åldern är:97 namnet är:Dahl började fysik:F1941
åldern är:97 namnet är:Oscar började fysik:F1958
åldern är:97 namnet är:Oscar började fysik:F2014
åldern är:98 namnet är:Oscar började fysik:F1973
åldern är:98 namnet är:Hilda började fysik:F2012
åldern är:99 namnet är:Noak började fysik:F1951
åldern är:100 namnet är:Noak
åldern är:100 namnet är:Dahl började fysik:F1995

最新更新