2021春软件构造-lab2小结

2024-04-17 13:32
文章标签 软件 构造 小结 2021 lab2

本文主要是介绍2021春软件构造-lab2小结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 前言
  • Equality
    • == 与 equals
    • @Override作用
    • @Override equals的一般模板
    • 可变对象的相等关系
      • 有些时候会有迷惑的现象:
      • 原理
      • 结论
    • AutoBoxing 与 Equality
  • 小结

前言

在lab2对图的vertices方法测试时(代码段如下),涉及到两个集合是否相等的问题,故采用了Set的equals方法,发现集合的相等是分别调用每个元素的equals方法进行逐对比较,现对java中的equals方法进行总结。

    @Testpublic void testvertices(){Graph<String> g = emptyInstance();g.add("a");g.add("b");Set<String> vertices = new HashSet<>();vertices.add("a");vertices.add("b");assertEquals(vertices,g.vertices());Graph<String> g2 = emptyInstance();assertEquals(new HashSet<String>(),g2.vertices());}

Equality

== 与 equals

equals方法比较的是对象的相等性,继承于object类的equals方法,默认就是java中的“==“运算符,该运算符比较的是两个对象的地址相等性,即是否为相同的对象,这是有本质区别的。

@Override作用

在重写equals方法中体现的特别明显,重写要求参数列表的类型必须是一致的,而参数列表不一致则变成了重载,这样子类中存在两个equals方法,不一定能按需调用。

@Override equals的一般模板

以lab3中interval为例
注:这里的getclass会返回子类型,即运行时类型,满足多态性。

public class Interval<L> {private long start;private long end;private final L label;//	AF:时间段开始时刻:start,终止时刻:end,时间段对应标签label。由这三元组映射到一个唯一的时间段。
//	RI:start>=0,end>=0,label非空
//	safety from RE:private访问权限控制,label引用不可变,label自身是不可变类型。@Overridepublic boolean equals(Object obj) {if (this == obj)			//若同一个对象,定相等return true;if (obj == null)return false;if (getClass() != obj.getClass())		//不是同一个类型return false;Interval other = (Interval) obj;			//同类型比较if (end != other.end)					//按需比较return false;if (label == null) {if (other.label != null)return false;} else if (!label.equals(other.label))return false;if (start != other.start)return false;return true;}
}

可变对象的相等关系

往往采用严格的观察等价性。如:List之间的相等关系表现为两个list包含相同顺序的元素,equals才返回true。

有些时候会有迷惑的现象:

	public static void main(String[] args) {// TODO Auto-generated method stubList<String> list = new ArrayList<>();list.add("a");Set<List<String>> s = new HashSet<>();s.add(list);System.out.println(s.contains(list));	//truelist.add("b");System.out.println(s.contains(list));	//false} 

一个已经add的链表却不在集合内部了,看起来内外两个list不相等了。

原理

contains方法机制:这里的Set用HashSet实现,自然采用散列值进行存储。第一次链表只有元素a,与第二次的散列值一定不同,HashSet的内部实现并不会根据可变对象的变化去调整所在bucket的位置。因此,第二次再查找时自然也就找不到了。

结论

可变对象被用作集合中的元素时,集合的行为会表现出不确定性,应谨慎使用

AutoBoxing 与 Equality

java是OOP语言,每个基本数据类型也有相应的封装类,下以Integer为例:

	public static void main(String[] args) {// TODO Auto-generated method stubInteger x = new Integer(3);Integer y = new Integer(3);System.out.println(x==y);		//false 不是同一个对象System.out.println(x.equals(y));	//true	override过System.out.println((int)x == (int) y);	//true	转换基本数据类型后,指向同一个地址Map<String,Integer> a  = new HashMap<>(), b = new HashMap<>();a.put("a", 130);b.put("a", 130);System.out.println(a.get("a") == b.get("a"));	//falsea.put("b", 1);b.put("b", 1);System.out.println(a.get("b") == b.get("b"));	//trueInteger m = 2;Integer n = 2;System.out.println(m == n);			//true} 

在上述代码中,后半段创建了两个字典,put过程中发生了自动打包,所以取出的是Integer对象,进而两个不同对象输出false。为什么当打包1时,又变成相同对象了呢?java实现机制中,-128-127的对象是唯一的,打包时放入的都是对其的引用,因此是相同的对象。这在接下来m与n的自动打包中也得到了证实,2是被打包成Integer-2,m与n都是指向这一对象的引用。

小结

equals是一个非常重要的方法,因此也放在object类中。多数情况下,我们应该override它,来实现满足我们需求的相等性判断。然而相等性也存在着一些较为复杂晦涩的情况,应当具体分析,谨慎使用。

这篇关于2021春软件构造-lab2小结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/911931

相关文章

MySQL中VARCHAR和TEXT的区别小结

《MySQL中VARCHAR和TEXT的区别小结》MySQL中VARCHAR和TEXT用于存储字符串,VARCHAR可变长度存储在行内,适合短文本;TEXT存储在溢出页,适合大文本,下面就来具体的了解... 目录一、VARCHAR 和 TEXT 基本介绍1. VARCHAR2. TEXT二、VARCHAR

全网最全Tomcat完全卸载重装教程小结

《全网最全Tomcat完全卸载重装教程小结》windows系统卸载Tomcat重新通过ZIP方式安装Tomcat,优点是灵活可控,适合开发者自定义配置,手动配置环境变量后,可通过命令行快速启动和管理... 目录一、完全卸载Tomcat1. 停止Tomcat服务2. 通过控制面板卸载3. 手动删除残留文件4.

Python打包成exe常用的四种方法小结

《Python打包成exe常用的四种方法小结》本文主要介绍了Python打包成exe常用的四种方法,包括PyInstaller、cx_Freeze、Py2exe、Nuitka,文中通过示例代码介绍的非... 目录一.PyInstaller11.安装:2. PyInstaller常用参数下面是pyinstal

python中getsizeof和asizeof的区别小结

《python中getsizeof和asizeof的区别小结》本文详细的介绍了getsizeof和asizeof的区别,这两个函数都用于获取对象的内存占用大小,它们来自不同的库,下面就来详细的介绍一下... 目录sys.getsizeof (python 内置)pympler.asizeof.asizeof

springboot中使用okhttp3的小结

《springboot中使用okhttp3的小结》OkHttp3是一个JavaHTTP客户端,可以处理各种请求类型,比如GET、POST、PUT等,并且支持高效的HTTP连接池、请求和响应缓存、以及异... 在 Spring Boot 项目中使用 OkHttp3 进行 HTTP 请求是一个高效且流行的方式。

mybatis映射器配置小结

《mybatis映射器配置小结》本文详解MyBatis映射器配置,重点讲解字段映射的三种解决方案(别名、自动驼峰映射、resultMap),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定... 目录select中字段的映射问题使用SQL语句中的别名功能使用mapUnderscoreToCame

Vue和React受控组件的区别小结

《Vue和React受控组件的区别小结》本文主要介绍了Vue和React受控组件的区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录背景React 的实现vue3 的实现写法一:直接修改事件参数写法二:通过ref引用 DOMVu

Vite 打包目录结构自定义配置小结

《Vite打包目录结构自定义配置小结》在Vite工程开发中,默认打包后的dist目录资源常集中在asset目录下,不利于资源管理,本文基于Rollup配置原理,本文就来介绍一下通过Vite配置自定义... 目录一、实现原理二、具体配置步骤1. 基础配置文件2. 配置说明(1)js 资源分离(2)非 JS 资

Java Stream 并行流简介、使用与注意事项小结

《JavaStream并行流简介、使用与注意事项小结》Java8并行流基于StreamAPI,利用多核CPU提升计算密集型任务效率,但需注意线程安全、顺序不确定及线程池管理,可通过自定义线程池与C... 目录1. 并行流简介​特点:​2. 并行流的简单使用​示例:并行流的基本使用​3. 配合自定义线程池​示

Java实现复杂查询优化的7个技巧小结

《Java实现复杂查询优化的7个技巧小结》在Java项目中,复杂查询是开发者面临的“硬骨头”,本文将通过7个实战技巧,结合代码示例和性能对比,手把手教你如何让复杂查询变得优雅,大家可以根据需求进行选择... 目录一、复杂查询的痛点:为何你的代码“又臭又长”1.1冗余变量与中间状态1.2重复查询与性能陷阱1.