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

所以目前我正在进行一项任务,我必须有两个类,一个名为Fysiker,另一个名为Human。 Fysiker只是Human类的扩展。 人类有两个属性:姓名和年龄,而Fysiker有三个:名字,年龄和年初。 我创建了一个同时包含Human和Fysiker的数组,我想先按年龄排序,但如果两个fysiker的年龄相同,我希望按照我的第三个属性排序:startyear。

我对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.ageo.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 fysiker=new ArrayList(); 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{ public static final List 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,但我也需要那个,我想要对它们进行排序,但它修复了“在startyear之后没有排序”对于fysiker“-problem。 我从哪里去?

实际上是子类中定义的方法:

 public int compareTo(Fysiker o){ 

不会覆盖基类中的方法:

 public int compareTo(Human o){ 

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

 public int compareTo(Human o){ 

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

Comparable.compareTo()合同声明:

实现者还必须确保关系是传递的:((compare(x,y)> 0)&&(compare(y,z)> 0))表示compare(x,z)> 0。

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

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

你有两种方法。

1)如果列表仅包含Fysiker实例,则声明Fysiker List并创建Comparator

 List fysiker = new ArrayList(); ... Collections.sort(fysiker); 

它限制了List可以接受的元素类型,但在这个特定情况下是希望的。

2)如果列表包含HumanFysiker实例,则声明List of Human并创建Comparator

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

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

 public class ComparatorHumanAndFysiker implements Comparator{ 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)从未使用compareTo(Fysiker o)因为您没有实现Comparable接口。 遗憾的是,对于您的具体类inheritance,您的Fysiker类将无法实现Comparable因为它已经间接实现了Comparable接口,并且在Java中您无法使用不同的generics类型实现相同的接口。

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

 public int compareTo(Human o){ int b; b=(this.age>o.age ? 1:this.age ( (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