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

相关文章

Spring Boot读取配置文件的五种方式小结

《SpringBoot读取配置文件的五种方式小结》SpringBoot提供了灵活多样的方式来读取配置文件,这篇文章为大家介绍了5种常见的读取方式,文中的示例代码简洁易懂,大家可以根据自己的需要进... 目录1. 配置文件位置与加载顺序2. 读取配置文件的方式汇总方式一:使用 @Value 注解读取配置方式二

Python中的getopt模块用法小结

《Python中的getopt模块用法小结》getopt.getopt()函数是Python中用于解析命令行参数的标准库函数,该函数可以从命令行中提取选项和参数,并对它们进行处理,本文详细介绍了Pyt... 目录getopt模块介绍getopt.getopt函数的介绍getopt模块的常用用法getopt模

C 语言中enum枚举的定义和使用小结

《C语言中enum枚举的定义和使用小结》在C语言里,enum(枚举)是一种用户自定义的数据类型,它能够让你创建一组具名的整数常量,下面我会从定义、使用、特性等方面详细介绍enum,感兴趣的朋友一起看... 目录1、引言2、基本定义3、定义枚举变量4、自定义枚举常量的值5、枚举与switch语句结合使用6、枚

Java中的Lambda表达式及其应用小结

《Java中的Lambda表达式及其应用小结》Java中的Lambda表达式是一项极具创新性的特性,它使得Java代码更加简洁和高效,尤其是在集合操作和并行处理方面,:本文主要介绍Java中的La... 目录前言1. 什么是Lambda表达式?2. Lambda表达式的基本语法例子1:最简单的Lambda表

Java中Scanner的用法示例小结

《Java中Scanner的用法示例小结》有时候我们在编写代码的时候可能会使用输入和输出,那Java也有自己的输入和输出,今天我们来探究一下,对JavaScanner用法相关知识感兴趣的朋友一起看看吧... 目录前言一 输出二 输入Scanner的使用多组输入三 综合练习:猜数字游戏猜数字前言有时候我们在

SQL BETWEEN 的常见用法小结

《SQLBETWEEN的常见用法小结》BETWEEN操作符是SQL中非常有用的工具,它允许你快速选取某个范围内的值,本文给大家介绍SQLBETWEEN的常见用法,感兴趣的朋友一起看看吧... 在SQL中,BETWEEN是一个操作符,用于选取介于两个值之间的数据。它包含这两个边界值。BETWEEN操作符常用

go 指针接收者和值接收者的区别小结

《go指针接收者和值接收者的区别小结》在Go语言中,值接收者和指针接收者是方法定义中的两种接收者类型,本文主要介绍了go指针接收者和值接收者的区别小结,文中通过示例代码介绍的非常详细,需要的朋友们下... 目录go 指针接收者和值接收者的区别易错点辨析go 指针接收者和值接收者的区别指针接收者和值接收者的

python uv包管理小结

《pythonuv包管理小结》uv是一个高性能的Python包管理工具,它不仅能够高效地处理包管理和依赖解析,还提供了对Python版本管理的支持,本文主要介绍了pythonuv包管理小结,具有一... 目录安装 uv使用 uv 管理 python 版本安装指定版本的 Python查看已安装的 Python

C#中DrawCurve的用法小结

《C#中DrawCurve的用法小结》本文主要介绍了C#中DrawCurve的用法小结,通常用于绘制一条平滑的曲线通过一系列给定的点,具有一定的参考价值,感兴趣的可以了解一下... 目录1. 如何使用 DrawCurve 方法(不带弯曲程度)2. 如何使用 DrawCurve 方法(带弯曲程度)3.使用Dr

MySQL 分区与分库分表策略应用小结

《MySQL分区与分库分表策略应用小结》在大数据量、复杂查询和高并发的应用场景下,单一数据库往往难以满足性能和扩展性的要求,本文将详细介绍这两种策略的基本概念、实现方法及优缺点,并通过实际案例展示如... 目录mysql 分区与分库分表策略1. 数据库水平拆分的背景2. MySQL 分区策略2.1 分区概念