【问题标题】:ArrayList<superclass> but use ArrayList<subclass>.methodofsubclassArrayList<superclass> 但使用 ArrayList<subclass>.methodofsubclass
【发布时间】:2014-10-09 18:14:22
【问题描述】:

我有一个类Woning(房子)和一个子类KoopWoning(可购买的房子)和一个子类HuurWoning(可出租的房子)。 KoopWoning 和 Huurwoning 扩展了 Woning。 HuurWoning 只是一个 Woning,而 KoopWoning 有一个额外的可变能级。 KoopWoning 还有一个函数 getEnergylevel,它返回 KoopWoning 的能级。我还有一个 Portefeuille 类,它有一个 Woningen 的数组列表。

我正在从文本文件中读取 Portefeuille 中的所有 Woningen。在第 5 节课中,我希望能够对 Portefeuille 的 Woningen 的 ArrayList 进行排序(来自文本文件)。我有一个函数 woningenTot(int maxprijs) 返回一个 ArrayList,其中包含满足要求的所有 Woningen(价格低于 maxprijs)。我想在屏幕上打印这些沃宁根。

问题如下: 文件中可能还有一个 KoopWoning。在那种情况下,我还希望能够按能级排序。但是,我无法按能级排序。我不能调用函数getEnergylevel,因为它是一个ArrayList,而Woning不包含函数getEnergylevel。

那么我该如何解决呢?如果太模糊,我可以包含代码,但是它很大:O

感谢任何帮助;我在这个程序上花了几个小时,其中至少有 1.5 小时在这个问题上:(

编辑:这是 KoopWoning 类的代码

public class KoopWoning extends Woning implements EnergiepeilWoning {
private char energiepeil;

public KoopWoning (Adres adres, int kamers, int vraagPrijs, char energiepeil) {
    super(adres, kamers, vraagPrijs);
    this.energiepeil = energiepeil; 
}

public char getEnergiepeil () {
    return energiepeil;
}

public boolean compareEnergiepeil (Object other) {
    boolean res = false;
    if (other instanceof KoopWoning) {
        KoopWoning that = (KoopWoning) other;
        res = (this.getEnergiepeil() == that.getEnergiepeil());
    }
    return res; 
}

public String toString () {
    String res = adres + ", " + kamers + " kamers, prijs " + prijs + ", energiepeil " + energiepeil;
    return res;
}

这是Woning类的代码

public class Woning {
protected int kamers;
protected int prijs;
protected Adres adres;
protected String tag;

public Woning (Adres adres, int kamers, int prijs) {
    this.adres = adres;
    this.kamers = kamers;
    this.prijs = prijs;     
}

public String toString () {
    String res = adres + ", " + kamers + " kamers, prijs " + prijs;
    return res;
}

public void setTag (String tag) {
    this.tag = tag;
}

public String getTag () {
    return tag;
}

public boolean kostHooguit (int maxprijs) {
    return (prijs <= maxprijs);
}

public boolean equals (Object other) {
    boolean res = false;
    if (other instanceof Woning) {
        Woning that = (Woning) other;
        if (this.adres.equals(that.adres))
            res = true;
    }
    return res;
}

public static Woning read (Scanner sc) {
    try {
        Adres adress = Adres.read(sc);
        int kamer = sc.nextInt();
        sc.next();
        sc.next();
        int prijs = sc.nextInt();
        String check = sc.next();
        if (check.equals("energiepeil")) {
            char peil = sc.next().charAt(0);
            KoopWoning kwoning = new KoopWoning (adress, kamer, prijs, peil);
            return kwoning;
        }
        else {
            Woning woning = new Woning (adress, kamer, prijs);
            return woning;
        }
    }
    catch (Exception e) {
        System.out.println("Woning: Exception is caught");
        System.out.println(e.getMessage());
        Adres adress = new Adres ("", "", "", "");
        Woning woning = new Woning (adress, 0, 0);
        return woning;
    }
}
}

最后,Portefeuille 类的代码

public class Portefeuille {

private ArrayList<Woning> woninglijst;

public Portefeuille () {
    woninglijst = new ArrayList<Woning>();
}

public void voegToe (Woning woning) {
    if (!woninglijst.contains(woning))
        woninglijst.add(woning);
}

public ArrayList<Woning> woningenTot (int maxprijs) {
    ArrayList<Woning> woninglijst2 = new ArrayList<Woning>();
    for (int i = 0; i < woninglijst.size(); i++) {
        if(woninglijst.get(i).kostHooguit(maxprijs))
            woninglijst2.add(woninglijst.get(i));
    }
    return woninglijst2;
}

public String toStringExt () {
    String res = "[";
    for (int i = 0; i < woninglijst.size(); i++)
        res = res + woninglijst.get(i).toString() + "; ";
    if (woninglijst.size() != 0)
        res = res.substring (0, res.length() - 2);
    res = res + "]";
    return res;
}

public String toString () {
    String res = "";
    for (int i = 0; i < woninglijst.size(); i++)
        res = woninglijst.get(i).toString2();
    return res;
}

public boolean equals (Object other) {
    boolean res = false;
    if (other instanceof Portefeuille) {
        Portefeuille that = (Portefeuille) other;
        if (this.woninglijst.size() == that.woninglijst.size()) {
            int i = 0;
            while (i < this.woninglijst.size() && this.woninglijst.get(i).equals(that.woninglijst.get(i)))
                i = i + 1;
            res = (i == this.woninglijst.size());
        }
    }
    return res;
}

public static Portefeuille read (String infile) {
    try {
        Scanner sc = new Scanner (new File(infile));
        ArrayList<Woning> wlijst = new ArrayList<Woning>();
        Portefeuille p = new Portefeuille();
        int woningen = sc.nextInt();
        int i = 0;
        while (i < woningen) {
            sc.nextLine();
            String tag = sc.nextLine();
            wlijst.add(Woning.read(sc));
            p.voegToe(wlijst.get(i));
            i++;
        }
        sc.close();
        return p;
    }

    catch (Exception e) {
        System.out.println("Portefeuille: Exception is caught");
        Portefeuille p = new Portefeuille();
        return p;
    }   
}
}

编辑

我自己修好了。谢谢大家的回答:)

【问题讨论】:

  • 你想如何对没有能量水平的东西进行排序?如果你想对整个批次进行排序,那么你需要决定没有能量级别的项目去哪里。
  • 你需要包含代码的relevant部分,听起来它不应该那么大。既然您已经描述了层次结构,那么仅尝试排序和列表的定义就足够了。

标签: java inheritance arraylist


【解决方案1】:

您可以在顶级类上定义一个类似getSortableValue() 的方法,并实现它以返回一个默认字段(您没有提到您需要为Woningen 排序的字段)。在KoopWoning 中,您重写此方法以返回energyLevel。然后你总是按getSortableValue()返回的值排序。

【讨论】:

    【解决方案2】:

    你可以让他们实现Comparable,比如Woning implements Comparable&lt;Woning&gt;。这将让您实现(必需的)方法:

    @override
    public int compareTo(Woning other) {
        int result = Integer.compareto(maxPrijs, other.maxPrijs);
        if (result != 0) return result;
        result = Integer.compareto(someField, other.someField);
        if (result != 0) return result;
        // etc...
        return 0;
    }
    

    子类KoopWoning extends Woning implements Comparable&lt;KoopWoning&gt;可以有这样的方法:

    @override
    public int compareTo(KoopWoning other) {
        int result = Integer.compareto(energylevel, other.energylevel);
        if (result != 0) return result;
        return super.compareTo(other);
    }
    

    那么你需要做的就是将所有Woning实例加载到一个列表中并执行

    Collections.sort(list);
    

    让子类继承Comparable 是可选的,所以HuurWoning 将与Woning 一样排序。

    【讨论】:

    • 请注意,Integer.compareTo() 是 Java 1.6 中的新内容,比仅减去值(可能溢出)更安全。所有原始值类型和基本值类型都存在类似的情况。
    【解决方案3】:

    您可以在Woning 上定义一个Comparator,以确定两个Woning 的相对顺序。您可以通过使用查看两个参数的实际类型然后采取适当行动的方法来做到这一点,或者更好的是,通过使用 Woning 的可覆盖方法返回一些可用于排序目的的值。

    例如,如果您决定任何具有能量水平的事物都应该在没有能量水平的事物之后,那么您可以让 KoopWoning 返回具有 long 高位能量水平的事物,这样它总是比没有它的任何东西都高(基本上你会将默认能量水平设置为零)。

    然后,你可以使用

    Collections.sort(arrayList, myComparator);
    

    根据您创建的Comparator 对列表进行排序。

    Guava 库中有一些不错的类可以帮助 Comparator 在多个键上构建,但如果您的情况相当简单,您可能不需要它们。

    【讨论】:

    • @MarkJeronimus 抱歉,我拒绝了您的编辑,因为我把这与我正在编辑的另一个答案混淆了。我已手动应用您建议的编辑(使用“可以”而不是“可以”)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-18
    • 2013-01-03
    • 2012-11-16
    • 2017-02-06
    • 1970-01-01
    • 2014-05-24
    相关资源
    最近更新 更多