java immutable类重写equals和hashCode函数

该博客讨论了如何在不可变类Edge中正确重写equals和hashCode方法。Edge类代表图中的边,其等价性基于起点、终点和权重。equals方法比较源点、目标点和权重的相等性,而hashCode则通过源点、目标点和权重的哈希值组合生成。此外,还提供了Edge类的构造方法、获取字段的方法和检查表示不变性的辅助方法。
摘要由CSDN通过智能技术生成

一般immutable类都需要重写equals和hashCode函数。这两个函数继承自Object基类
例如一个代表边的泛型类,认为如果起点终点权重相等的边等价,hashCode采用起点终点权重的hashCode乘质数相加的方法。
如下:
接收任意一个类的对象,首先要判断它是一个Edge对象,然后由于Edge是泛型类,还需要在强制类型转换时加上"<?>"

/**
     * Override equals
     * @param obj an object expected to be Edge<>
     * @return true if source, target, weight are equal
     */
    @Override public boolean equals(Object obj){
        if(obj instanceof Edge){
            if(!this.source.equals(((Edge<?>) obj).source()))
                return false;
            if(!this.target.equals(((Edge<?>) obj).target()))
                return false;
            return this.weight == ((Edge<?>) obj).weight;
        }
        return false;
    }

    /**
     * Override hashCode
     * @return hashCode of this
     */
    @Override public int hashCode(){
        int result = this.source.hashCode();
        result = 17 * result + this.target.hashCode();
        result = 17 * result + this.weight;
        return result;
    }

完整类如下:

/**
 * TODO specification
 * Immutable.
 * This class is internal to the rep of ConcreteEdgesGraph.
 * 
 * <p>PS2 instructions: the specification and implementation of this class is
 * up to you.
 */
class Edge<L> {
    
    // TODO fields
    private final L source;
    private final L target;
    private final int weight;
    
    // Abstraction function:
    //   represents one edge from source to target of weight
    //   field source represents the source of the edge
    //   field target represents the target of the edge
    //   field weight represents the weight of the edge
    //   TODO
    // Representation invariant:
    //   source and target are two different vertex
    //   weight > 0
    //   TODO
    // Safety from rep exposure:
    //   All fields are private
    //   source and target are String and weight is int. So they are immutable
    //   TODO
    
    // TODO constructor
    public Edge(L sourceVertex, L targetVertex, int weightOfEdge){
        source = sourceVertex;
        target = targetVertex;
        weight = weightOfEdge;
        checkRep();
    }
    
    // TODO checkRep
    public void checkRep(){
        assert (weight > 0);
        assert (!source.equals(target));
    }
    
    // TODO methods

    /**
     * get immutable field source
     * @return this.source
     */
    public L source(){
        return source;
    }

    /**
     * get immutable field target
     * @return this.target
     */
    public L target(){
        return target;
    }

    /**
     * get immutable field weight
     * @return this.weight
     */
    public int weight(){
        return weight;
    }

    /**
     * generate a new Edge from this.source to this.target of weight w to replace older Edge
     * @param w weight
     * @return a new Edge from source to target of weight w
     */
    public Edge<L> setWeight(int w){
        return new Edge<>(source, target, w);
    }

    /**
     * Override equals
     * @param obj an object expected to be Edge<>
     * @return true if source, target, weight are equal
     */
    @Override public boolean equals(Object obj){
        if(obj instanceof Edge){
            if(!this.source.equals(((Edge<?>) obj).source()))
                return false;
            if(!this.target.equals(((Edge<?>) obj).target()))
                return false;
            return this.weight == ((Edge<?>) obj).weight;
        }
        return false;
    }

    /**
     * Override hashCode
     * @return hashCode of this
     */
    @Override public int hashCode(){
        int result = this.source.hashCode();
        result = 17 * result + this.target.hashCode();
        result = 17 * result + this.weight;
        return result;
    }

    // TODO toString()
    /**
     * useful human-readable representation of the abstract value.
     * @return representation
     */
    @Override public String toString(){
        return String.format(source.toString() + " -> " + target.toString() + " %d\n", weight);
    }
    
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值