【问题标题】:Comparator with ArrayList-objects with multiple subclasses具有多个子类的 ArrayList 对象的比较器
【发布时间】:2015-04-02 09:48:53
【问题描述】:
public class WorthComparator implements Comparator<Värdesak> {
    public int compare(Värdesak v1, Värdesak v2) {
        if (v1 instanceof Apparat && v2 instanceof Apparat) {
            return ((Apparat) v1).worth() > ((Apparat) v2).worth() ? 1
                    : ((Apparat) v1).worth() < ((Apparat) v2).worth() ? -1
                            : 0;
        } else if (v1 instanceof Smycke && v2 instanceof Smycke) {
            return ((Smycke) v1).worth() > ((Smycke) v2).worth() ? 1
                    : ((Smycke) v1).worth() < ((Smycke) v2).worth() ? -1
                            : 0;
        } else if (v1 instanceof Aktie && v2 instanceof Aktie) {
            return ((Aktie) v1).worth() > ((Aktie) v2).worth() ? 1
                    : ((Aktie) v1).worth() < ((Aktie) v2).worth() ? -1 : 0;
        }
    }
}

如您所见,我正在尝试比较 ArrayList 中的不同对象,然后在我的 GUI 中按最高值对它们进行排序。每个不同的对象(“Smycke”、Aktie、Apparat“)都在它们各自的子类中,每个子类都有一个估计它们的值的方法。“Värdesak”是超类。

我的问题是我不知道我会得到谁的退货声明,还是有另一种聪明的方法来做到这一点?

【问题讨论】:

  • 让它们都实现一个带有worth()的接口,或者将worth()作为Värdesak中的抽象方法会更简洁。然后你可以在没有任何强制转换或instanceof 检查的情况下调用worth()
  • 注意:也许将Värdesak 修改为Vardesak 会更好。 using unicode is generally not adviseable.
  • @CommuSoft 这通常是可取的,但是一旦您希望读者能够理解瑞典语中的标识符,拼错单词几乎不会使它们更具可读性。

标签: java swing return-value comparator


【解决方案1】:

在我看来,您的代码设计是错误的,或者您以错误的方式应用它。由于每个“Värdesak”都物有所值,因此您可以/需要在 Värdesak 级别定义此方法:

public abstract class Värdesak {

    public abstract double worth ();

}

然后:

public class Apparat extends Värdesak {

    @Override
    public double worth () {
        return 500.0d;
    }

}

或者如果价格是固定的,你可以使用一个字段:

public abstract class Värdesak {

    private double value;

    public double worth () {
        return worth;
    }

}

现在你可以简单地使用动态绑定原理:

public class WorthComparator implements Comparator<Värdesak> {

    public int compare(Värdesak v1, Värdesak v2) {
        return Double.compare(v1.worth(),v2.worth());
    }

}

instanceof calls are in general considered to be a bad smell: 如果你必须使用它们,通常是你的代码设计有问题。

另一个建议,请不要在标识符中使用 unicode 字符:使用 Vardesak 而不是 Värdesak

【讨论】:

    【解决方案2】:

    感谢您的所有好评。真的很赞!我知道 Unicode,当我清理代码时,它肯定会被修复。您的意思是您覆盖的超类(worth())中的“通用”方法可以解决我的问题吗? 谢谢

    【讨论】:

    • 您应该将此作为评论发布,否则人们会开始投反对票...是的,一般方法可能会解决问题。从您必须使用实例的那一刻起,它就破坏了面向对象的设计。
    • 感谢您通知我。我是 StackOverflow 上的新手。好的,我会努力的,谢谢
    【解决方案3】:

    你也可以让Värdesak实现Comparable接口

    public abstract class Värdesak implements Comparable<Värdesak> {
        //[...] your code
    }
    

    现在您为每个类定义 compareTo 扩展 Värdesak

    public class Smycke extends Värdesak {
    
        //[...] your code
    
        @Override
        public int compareTo(Server o) {
            // TODO: your compare logic
            return 0;
        }
    }
    

    稍后您可以通过这种方式对您的 Värdesak 进行排序:Collections.sort(värdesakList)

    编辑:注意,这个解决方案不像比较器模式那样灵活。

    【讨论】:

    • 如果有多种方法可以对项目列表进行排序,通常会实现Comparator。例如按名称、按值、按 id 编号、...
    猜你喜欢
    • 1970-01-01
    • 2012-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-24
    • 2014-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多