`
pandonix
  • 浏览: 401363 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

一个粗心的问题引发的思考

JDK 
阅读更多

问题的起因是编写的以下代码今天出现了问题:

 

private List<Integer> ids = new ArrayList<Integer>();	//new a list to store user id
......
ids.add(user.getID());   	//add user id to ids
......
ids.remove(user.getID());	//remove user id from ids

 细心的朋友很容易就找到问题所在。因为List提供两个remove方法:

 

remove(int index) 

remove(Object o) 

 

 而我使用Integer作为泛型,这样调用remove方法时,编译器自动将Integer转化为了Int,所以实际调用的是remove(int index)这个方法。显然,我的本意是调用remove(Object o)。这样的问题,如果不是程序抛出IndexOutBoudsException,对于一向粗心的我还一直蒙在鼓里。

 

本文的重点在于解决此问题的过程中引发的一系列思考,并结合最近再次拜读《Effective Java》这本经典著作的结果给出了一些对java语言的心得体会。

 

回到问题本身来,最直接的解决方案如下:

 

ids.remove(Integer.valueOf(user.getID()));

 

经过测试,该方案是可行的。

心血来潮,我提出了以下新的方案,它是否可行呢:

 

ids.remove(new Integer(user.getID()));

 

初步分析,应该是不行的,因为传入的参数是一个新的Integer对象,而与原来的Integer是不相等的,所以remove操作将失败。

遗憾的是,以上分析是错误的,事实证明第二种方案也是可行的。为什么呢?

回想起《Effective Java》一书中,介绍"equals"方法的一段,有了启发。以上分析的结论是基于remove方法是以对象引用是否相等来判断,即通过“==”操作符来判断是否存在指定移除的对象。然而,它有没有可能是通过Integer对象的"equals"方法来判断的呢?如果是,两个不同的Integer对象,他们的值相同时,"equals"方法是否返回true呢?

验证第二个疑问很简单,写段程序验证一下就可。事实上,两个不同的Integer对象,他们的值相同时,"equals"方法是返回true的。因为Integer类override了Object.equals方法

验证第一个疑问也很简单,查看JDK源码:)

这时候,我突然想起了大学英语课文中关于爱因斯坦研究玩具鸟原理的文章(MS内容是这样的吧,大意是爱因斯坦想知道一只玩具鸟是怎么发出叫声的,而他一直不愿意拆开玩具来知道答案,直到最后他经过冥思苦想来得到答案时也没有拆开玩具鸟)当然,老爱是伟大的理论物理学家,咱只是个小Coder,没法比,只是好奇罢了。

扯远了,回到正题。可以通过以下测试来验证remove是否通过equals方法来判断的

 

	private List<INT> INTs = new ArrayList<INT>();

	public void testListINT()
	{
		System.out.println("-----testListINT-----");
		INTs.add(new INT(1));
		INTs.add(new INT(2));
		INTs.remove(new INT(1));
		INTs.remove(new INT(2));
		System.out.println("size="+INTs.size());
		System.out.println("=====END=====");
	}

	class INT
	{
		public int i;

		public INT(int i) {
			this.i = i;
		}
                }

 

输出结果为:

-----testListINT-----
size=2
=====END=====

 

Object的equals方法,对于不同的对象返回的是false。在INT中override equals方法:

 

	private List<INT> INTs = new ArrayList<INT>();

	public void testListINT()
	{
		System.out.println("-----testListINT-----");
		INTs.add(new INT(1));
		INTs.add(new INT(2));
		INTs.remove(new INT(1));
		INTs.remove(new INT(2));
		System.out.println("size="+INTs.size());
		System.out.println("=====END=====");
	}

	class INT
	{
		public int i;

		public INT(int i) {
			this.i = i;
		}

		public boolean equals(Object arg0) {
			if(arg0 instanceof INT){
				if(((INT)arg0).i == i)
					return true;
			}
			return false;
		}

                }

 

输出结果为:

-----testListINT-----
size=0
=====END=====

 

所以说,remove方法还是通过equals方法来判断指定的对象是否与列表中的对象相同。

《Effective Java》一书中还提到:

“在每个改写了equals方法的类中,你必须也要改写hashCode方法。如果不这样的话,就会违反Object.hashCode的通用约定,从而导致该类无法与所有基于hash的集合类结合在一起正常运作”

“相等的对象必须具有相等的hash code”

为了验证,再添加以下代码:

 

	public void testMapINT()
	{
		System.out.println("-----testMapINT-----");
		INTmap.put(new INT(1), "1");
		INTmap.put(new INT(2), "2");
		INTmap.remove(new INT(1));
		INTmap.remove(new INT(2));
		System.out.println("size="+INTmap.size());
		System.out.println("=====END=====");
	}

 

输出为:

-----testMapINT-----
size=2
=====END=====

 

而在INT中override hashCode方法之后:

 

	class INT
	{
		public int i;

		public INT(int i) {
			this.i = i;
		}

		public boolean equals(Object arg0) {
			if(arg0 instanceof INT){
				if(((INT)arg0).i == i)
					return true;
			}
			return false;
		}

		public int hashCode() {
			return i;
		}

                }

 

输出为:

-----testMapINT-----
size=0
=====END=====

 

总结本文,List中,通过equals方法来判断元素是否相同;Hash类型的Collection子类,如:HashMap等是通过hashCode的返回值来标示Key值。

分享到:
评论
2 楼 ocaicai 2011-09-11  
真是一个勤于思考的孩子!
1 楼 beneo 2010-06-20  
看了好几遍,对API不熟悉的飘过。。

相关推荐

    乔晓阳 - 一个直方图问题引发的思考

    标题中提及的“一个直方图问题引发的思考”指向的是在Oracle数据库环境下,对直方图和SQL执行计划的深入分析和优化过程。直方图是Oracle数据库中用于记录列内值分布的统计工具,它在优化器选择执行计划时起到关键...

    问号思考解决问题PPT模板.rar

    - 表格:提供了一个结构化的方式来整理数据、比较不同解决方案,使问题分析更加清晰和有条理。 3. **适用场景**: - 项目讨论:在项目团队中,可以用来探讨遇到的问题,提出和评估各种解决方案。 - 教学培训:...

    从食品安全问题引发的思考.doc

    从食品安全问题引发的思考.doc

    关于北京市停车问题的思考

    停车问题不仅仅是城市交通问题的一个方面,更是城市规划和管理的重要组成部分。因此,需要我们从多方面进行考虑,包括交通需求管理、城市规划、政策调节等。 在解决北京市停车问题时,需要从以下几个方面进行考虑:...

    近年食品安全问题引起的思考.doc

    近年食品安全问题引起的思考.doc

    促进学生深度学习的“问题链”设计与思考——以“1.6尺规作图”一课为例.pdf

    衔接性原则要求问题之间具有内在的关联性,前一个问题应能为后一个问题做铺垫,通过解决前一个问题的知识积累,指引学生解决后面的问题。 在《尺规作图》课程中,问题链的设计围绕尺规作图的概念和操作展开,包括...

    食品安全问题引起的思考和建议.doc

    食品安全问题引起的思考和建议.doc

    京东物流仓储管理的问题与对策思考.zip

    《京东物流仓储管理的问题与对策思考》 ...综上所述,京东物流仓储管理的问题与对策是一个持续改进的过程。通过深入分析问题,采取有效的解决方案,京东物流有望进一步提升服务质量,巩固其在电商领域的竞争优势。

    幼儿园食品安全问题引起的思考.docx

    这起事件不仅牵动了无数家长的心,也引发了社会对于幼儿园食品安全管理的广泛关注和深入思考。在中国的法律体系中,《侵权责任法》对幼儿园这类教育机构的人身安全保障责任有着明确规定。依据该法律,幼儿园对在其...

    由ChatGPT引发中医智能诊断研究中数据问题的思考.pdf

    因此,建立一个全面、多样化的中医数据集是必要的,这包括病史记录、脉象分析、舌象图片等。 同时,数据的质量直接影响到诊断的准确性。中医的诊断过程涉及复杂的辨证论治,需要高质量、结构化的数据来支持推理。...

    思考疑问3D小人ppt模板.rar

    "思考疑问3D小人ppt模板"是一个专为呈现思考、疑问或问题解决场景设计的独特模板。这个模板的特点在于其立体的问号和3D小人的元素,这些元素可以增强观众对内容的理解和兴趣。 首先,我们来看3D小人。在PPT设计中,...

    对非典所引发法律问题的思考.docx

    【标题】:对非典所引发法律问题的思考 【描述】:文章探讨了非典时期法律面临的挑战,包括紧急强制行为的法律属性、政府的法律责任以及公民的权利和义务。 【标签】:解决方案 【正文】: 在2003年的非典(SARS)...

    食品安全问题引发对幼儿道德教育的思考.pdf

    食品安全问题不仅仅是技术层面的问题,更是一个涉及道德素质的社会问题。这让我们不禁思考:如何在幼儿时期就开始培养他们正确的道德观念,从而构建一个更加安全、健康的社会环境? 幼儿道德教育的重要性不言而喻,...

    现代物理学基础的思考之七:光学问题思考.doc

    多普勒效应是光速不变性原理的一个直接结果,它解释了光源与观察者相对运动时频率的变化。此外,群速度和相速度的概念则帮助我们理解光信号在不同条件下的传播特性。 然而,关于超光速的讨论一直是物理学界的热点。...

    像程序员一样思考

    本书分析了程序员解决问题的方法,并且教授你其他图书所忽略的一种能力,即如何像程序员一样思考。 全书分为8章。第1章通对几个经典的算法问题切入,概括了问题解决的基本技巧和步骤。第2章通过实际编写c++代码来...

    儿童“好问题”驱动深度学习的实践与思考.pdf

    在教育领域,一个“好问题”是指源自儿童内心深处的需求,而非教师刻意设计的问题。这样的问题能够引起儿童的强烈好奇心和求知欲,从而推动他们进行深入的探索和思考。这种教学方法强调从儿童的立场出发,充分利用...

    强化问题探究促进“深度学习”发展核心素养——由一道“解三角形”试题的探究教学引发的思考.pdf

    标题和描述中提到的“深度学习”是教育领域中一个重要的概念。深度学习不仅仅指人工智能领域的深度神经网络,也涉及学习者对知识的深入理解和掌握,需要通过批判性思维和问题探究来实现。文件中通过一道“解三角形”...

    哲学、哲学精神与未来教育——人工智能发展所引发的思考.pdf

    哲学的核心是哲学精神,它不同于教条式的教育模式,后者往往给予人们一个肯定的答案,而哲学精神则鼓励人们自主思考一系列问题,如“为什么它是这个?”、“它怎样成为了这个?”、“如何能够让它不是这个?”教条式...

    基于元问题引发学生深度学习的化学教学设计.pdf

    【教学实践与研究】该文提到了两个相关研究项目,表明了元问题教学法在初中化学教育中的实践价值。通过这种方法,不仅能够提高学生的学习成效,还能发展他们的核心素养,符合我国教育改革的目标。 综上所述,元问题...

    《直击本质》洞察事物底层逻辑的思考方法-人生破局的终极逻辑.pdf

    1. **定义**:指一个事物之所以成为该事物的根本原因。 2. **识别方法**: - **清晰定义**:通过属加种差的方式对事物进行定义,即明确事物所属的大类及其区别于同类其他成员的独特特征。 - **类比**:运用简单的...

Global site tag (gtag.js) - Google Analytics