【无标题】软构Lab2遇到的问题及解决

项目场景:实现抽象类接口图graph

(1)在实验中,在使用string类型作为参数实现concreteverticesgraph后,为了提高该adt的可复用性,需要将其中的string类转换为泛型参数L
(2)在实现graph的具体实现类时,需要重写equals和hashcode
(3)书写checkrep检查不变量保持为TRUE


问题描述

(1)在将其中的string类全部转换为泛型参数L之后,出现了报错情况,抛出了异常“java.lang.ClassCastException”
(2)equals()和hashCode()这两个方法属于Object类,而Object类是所有类的父类,因此所有的类都继承了这两个方法,所以需要在实现类中override这两个方法
(3)在书写每个类时需要书写checkup方法来保证RI的不变性,这里主要是针对immutable的类,减少因疏忽导致的表示泄露对程序带来的影响

原因分析:

(1)在遍历List<Vertex> vertices时,错误使用L key:的方式
(2)在object类中的equals方法:

public boolean equals(Object obj) {  
    return (this == obj);  
    } 

它在其中比较的是两个对象指向的地址,而这种方法的适用率较低,“==”在比较基本数据类型例如int是适用的,因为对其赋值相同,它们即指向同一个内存地址,而对对象一般并不适用,因为由new出来的对象之间的内存地址是各不相同的,而我们想要到达这样一个目的:对象中内容(或者说rep)是相同时能够判断两个对象是满足equals返回TRUE的,所以有必要重写equals;
倘若该类中未涉及hash结构,则可不用重写hashcode部分(不予讨论)
(3)尽管在书写类的属性时习惯声明为private,防止在该类外对此属性的引用,导致其发生改变,但可能存在的表示泄露仍然会导致相同的结果,例如在构造函数时直接对外部传入参数的引用,又或者方法返回值的传递失误;

解决方案:

	(1)采用两层循环嵌套:
	for (Vertex<L> vertex : vertices) {
		assert (vertex != null);
		Map<L, Integer> sources = vertex.sources();
		for (Map.Entry<L, Integer> entry : sources.entrySet()) {

(2)一般的重写模式例如:

	@Override
	public boolean equals(Object obj) {
		Map<String, Integer> option = new HashMap<>();
		option.putAll((Map<? extends String, ? extends Integer>) obj);
		if(option.values().equals(this.options.values())) {
			assertTrue(checkRep());
			return true;
		}
		assertTrue(checkRep());
		return false;
	}

(3)利用assert标志符来检查不变量是否保持为TRUE(其中可以在checkrep内部采用assert xxx 检查一些属性的不变,也可以利用checkrep返回值为TRUE,在每个方法返回的最后以assert checkrep()的方式来检查)
第一种:

    private void checkRep() {
        for (L vertex : vertices)
            assert (vertex != null);
        for (Edge<L> edge : edges)
            assert (edge != null);
    }

第二种:

	private boolean checkRep() {
		Collection<Integer> v=new ArrayList<Integer>();
		v=this.options.values();
		if(v.size()!=options.size())
		return false;
		return true;
	}
	......
	{assertTrue(checkrep());
	return ...
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值