【问题标题】:writing a triangle equals method编写三角形等于方法
【发布时间】:2016-10-17 23:00:17
【问题描述】:

我不得不编写一个代码,通过一个扩展几何对象的类来创建一个三角形。然后我们必须编写一个 equals 方法来与三角形进行比较。我不确定如何调用另一个三角形来比较它。

    public class Triangle extends GeometricObject {
private double side1 ;
private double side2 ;
private double side3 ;
public final double DEFAULT = 1.0;

public Triangle(){
    super();
    side1= DEFAULT;
    side2= DEFAULT;
    side3= DEFAULT;
}
public Triangle(String color, boolean filled, double side1, double side2, double side3)throws IllegalTriangleException{
    super(color,filled);
    this.side1=side1;
    this.side2=side2;
    this.side3=side3;
    if (side1>=side2+side3||side2>=side1+side3|| side3>=side1+side2){
        throw new IllegalTriangleException(side1,side2,side3);
    }
}
public double getSide1() {
    return side1;
}
public void setSide1(double side1) {
    this.side1 = side1;
}
public double getSide2() {
    return side2;
}
public void setSide2(double side2) {
    this.side2 = side2;
}
public double getSide3() {
    return side3;
}
public void setSide3(double side3) {
    this.side3 = side3;
}
public double getArea(double s1, double s2, double s3){
    side1= s1;
    side2= s2;
    side3= s3;
    double area = .5*(s1*s2*s3);
    return area;
}
public double getPerimeter(double s1, double s2, double s3){
    side1=s1;
    side2=s2;
    side3=s3;
    double perim = s1+s2+s3;
    return perim;
}
public String toString(){

    return super.toString()+ "triangle side 1 +"+ side1+ " side 2= "+side2+" side 3= "+side3;
}
public boolean equals(Object o){

}
  }


public class TestTriangle {
public void main (String[]args){
    try {
        GeometricObject tri1 = new Triangle ("yellow",true,1.0,1.5,1.0);
        GeometricObject tri2 = new Triangle ("red ", true, 2.0,3.7,5.0);
    } catch (IllegalTriangleException e) {
        System.out.print("invalid Side Lengths");
    }


}
}   

【问题讨论】:

  • 您的 IDE 应该能够自动生成 equalshashCode 方法...
  • 另外,添加@Override!只需投射对象并根据任何标准进行比较并相应返回
  • 上次查看时,三角形的面积不是.5*(s1*s2*s3)
  • 自动实施该方法的建议(以及迄今为止提出的答案)似乎非常短视。至少,应该认为边长为 (4,5,6) 的三角形与边长为 (6,4,5) 的三角形“相等”。
  • @Marco13 虽然您对三角形等式算法正确性的观察是准确的,但问题(显然)不是关于这个的。它似乎是关于通用 equals 方法的正确使用和正确实现。这可能是错误的。

标签: java equals


【解决方案1】:

OP 的问题似乎是: “我不确定如何调用另一个三角形来比较它。”

这就是调用 .equals() 方法来比较两个三角形是否相等的方式:

tri1.equals(tri2);

Apache Common 的EqualsBuilder 类本身就很有用。但它对于学习如何编写自己的 equals 方法也很有用。

通常,在您的 equals 方法中,您希望:

检查输入是否为null,如果是则返回false。

o == null

检查输入参数是否与“this”属于同一类,如果不是则返回false。

this.getClass() == o.getClass()

最后,比较每个实例成员变量是否相等。

this.side1 == o.side1 && this.side2 == o.side2 && this.side3 == o.side3

一个完整且更健壮的实现可能如下所示(不考虑边的顺序):

    @Override
    public boolean equals(Object o) {
        if (null == o) return false;
        if (this.getClass() != o.getClass()) return false;

        Triangle t = (Triangle)o;
        List<Double> oSides = new ArrayList<Double>();
        oSides.add(t.side1);
        oSides.add(t.side2);
        oSides.add(t.side3);
        for (Double d : oSides) {
            if (d.equals(this.side1)) {
                oSides.remove(d);
                break;
            }
        }
        for (Double d : oSides) {
            if (d.equals(this.side2)) {
                oSides.remove(d);
                break;
            }
        }
        for (Double d : oSides) {
            if (d.equals(this.side3)) {
                oSides.remove(d);
                break;
            }
        }
        return oSides.isEmpty();
    }

【讨论】:

  • 看方法是空的,可能是“如何实现”和“如何调用”。
【解决方案2】:

两个三角形相等是什么意思?这是否意味着区域相同?好像太松了这是否意味着边的顺序相同?好像太严格了?如果你没有更好的定义,我会比较每一边,不管顺序。

两个双打相等是什么意思?它们只需要在一个小的增量内。

public class Triangle {
    // a small delta for comparing doubles
    private static final double DELTA = 0.00000001;

    // the sides
    private double side1;
    private double side2;
    private double side3;

    /**
     * Constructs a triangle with these sides.
     * @param side1 the first side
     * @param side2 the second side
     * @param side3 the third side
     */
    public Triangle(double side1, double side2, double side3) {
        if (side1 <= 0 || side2 <= 0 || side3 <= 0)
            throw new IllegalArgumentException("Sides must be positive.");

        this.side1 = side1;
        this.side2 = side2;
        this.side3 = side3;
    }

    /**
     * Check if each of the 3 sides are equal - regardless of order.
     */
    @Override
    public boolean equals(Object obj) {
        boolean result = false;
        if (obj instanceof Triangle) {
            Triangle that = (Triangle)obj;

            double[] sides1 = { this.side1, this.side2, this.side3 };
            Arrays.sort(sides1);

            double[] sides2 = { that.side1, that.side2, that.side3 };
            Arrays.sort(sides2);

            result = equalsDelta(sides1[0], sides2[0])
                    && equalsDelta(sides1[1], sides2[1])
                    && equalsDelta(sides1[2], sides2[2]);
        }
        return result;
    }

    /**
     * Check if these numbers are equal within a small delta.  Assumes the
     * numbers are positive - because they represent sides of a triangle.
     *
     * @param d1 the first number
     * @param d2 the second number
     * @return true if within a delta
     */
    private static boolean equalsDelta(double d1, double d2) {
        double diff = (d1 < d2) ? d2 - d1 : d1 - d2;
        return diff < DELTA;
    }

    // hashCode(), toString(), and so on...
}

【讨论】:

  • 虽然关于double 比较的“epsilon”这一点非常重要并且应该指出,但您当前的实现违反了equals 方法的约定:它是不传递。假设 epsilon 为 0.11(用于说明),并假设存在三个三角形,其中第一条边的长度分别为 0.1、0.2 和 0.3(其他边相等)。那么 0.1 和 0.2 是“epsilon-equal”,0.2 和 0.3 是“epsilon-equal”。但是 0.1 和 0.3 “epsilon-equal”。
  • 这是有效的。我想这是一个权衡。有一个容易受到浮点问题影响的实现,或者一个并不总是传递的实现。如果您不习惯使用 delta,那么我建议您使用 java.lang.Double.compare(double d1, double d2) 并检查结果是否为 0。
猜你喜欢
  • 2013-11-30
  • 2023-01-30
  • 1970-01-01
  • 2017-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多