Using collections.sort() with compareTo, not sorting

后端 未结 2 706
悲哀的现实
悲哀的现实 2021-01-22 18:22

So currently I\'m working on an assignment where I have to two classes, one is named Fysiker and the other Human. Fysiker is simply an extension of the Human class. Human has tw

相关标签:
2条回答
  • 2021-01-22 19:00

    In fact the method defined in the subclass :

    public int compareTo(Fysiker o){
    

    doesn't override the method in the base class :

    public int compareTo(Human o){
    

    You could define the subclass with the same signature to override effectively :

    public int compareTo(Human o){
    

    and using instanceof to make the comparison according to the real type.
    But it would be not a good idea either. Indeed, Fysiker would know how to compare Human and Fysiker but Human would know how to compare only Humans.

    The Comparable.compareTo() contract states that :

    The implementor must also ensure that the relation is transitive: ((compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0.

    Comparable should not try to be interoperable between classes as it may violate the transitivity comparison principle.

    I think that in your case, as alternative, you should use a Comparator to sort elements.

    You have two ways.

    1) If the list contains only Fysiker instances, declare a List of Fysiker and create a Comparator<Fysiker> :

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

    It limits the type of the elements that the List may accept but it is wished in this specific case.

    2) If the list contains both Human and Fysiker instances, declare a List of Human and create a Comparator<Human> :

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

    In the Comparator implementation, you should check the type of the instances and compare them according to :

    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;                         
            }
     } 
    
    0 讨论(0)
  • 2021-01-22 19:14

    During the sort, only the compareTo(Human o) method is used. The compareTo(Fysiker o) is never used since you are not implementing Comparable<Fysiker> interface. Unfortunately with your concrete class inheritance your Fysiker class wont be able to implement Comparable<Fysiker> because it already indirectly implements Comparable<Human> interface and in Java you cant implement same interface with different generic types.

    As a quick workaround you can override compareTo(Human o) in your Fysiker class instead of defining an overloaded compareTo(Fysiker o) method:

    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;
        }
    
    }
    

    Update:

    I think this approach is much cleaner:

    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;
        }
    

    Output:

    å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
    
    0 讨论(0)
提交回复
热议问题