将collections.sort()与compareTo一起使用,而不是排序 [英] Using collections.sort() with compareTo, not sorting

查看:162
本文介绍了将collections.sort()与compareTo一起使用,而不是排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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 two attributes: name and age while Fysiker has three: name, age and startyear. I have created an array which takes both Human and Fysiker, and I want to sort it by age first, but if two fysiker have the same age, I want it to sort by my third attribute: the startyear.

我对compareTo的理解(我需要使用compareTo,为了练习)是有限的,但从我所读到的它是一个可比较的自动交互使用Collections.sort(),我的代码目前如下所示:

My understanding of the compareTo (I need to use compareTo, for the sake of the exercise) is limited, but from what I've read it's a comparable which interacts automatically with the Collections.sort(), my code currently looks like this:

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,但我也需要那个,我想对它们进行排序,但它修复了在fyeiker的startyear之后没有排序-problem。我从哪里开始?

My issue is that it does not sort after the startyear, but I can fix it if I remove compareTo from my Human class, but I need that one as well, I want to sort them all, but it fixes the "not sorting after startyear for the fysiker"-problem. Where do I go from here ?

推荐答案

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

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){

并使用 instanceof 根据实际类型进行比较。

但这也不是一个好主意。
的确, Fysiker 会知道如何比较人类 Fysiker 但是人类会知道如何只比较人类 s。

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.

Comparable.compareTo() 合同规定:

The Comparable.compareTo() contract states that :


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

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

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

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.

您有两种方式。

1)如果list仅包含 Fysiker 实例,声明列出 Fysiker 并创建一个比较器< Fysiker>

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

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

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

2)如果列表中包含 Human Fysiker 实例,声明一个 List Human 并创建一个 Comparator< Human>

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

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

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

这篇关于将collections.sort()与compareTo一起使用,而不是排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆