关于Java中的List容器的remove注意细节
2012-09-15 00:52
405 查看
第一次发布地址:http://258516630.ddjava.com/blog/blog.html?blogId=437
这个问题,自己在平时中并未遇见,但是有人问了这个问题后,自己加以思考,整理出来自己的思路来解答,并看了底层的代码加以证明。现在和大家分享下,本人只是抛砖引玉,希望能和更多热爱技术的猿猿一起思考探索下技术。欢迎拍砖,发表不同的想法,也欢迎有猿猿对底层这些实现思维交流交流。如果是我们自己设计这些东西,我们会不会有更好的逻辑去实现,如果没有,它这种底层实现为什么好?
下面进入主餐:
我整理下这位提问人的问题:
就是List容器中添加一个new出来的对象,然后为什么在remove点一个新构造出来的一摸一样的对象,总是不能成功remove掉它。
具体问题代码如下:
我看到这个问题后的理解是:
1.list容器中add方法中的对象的内存地址是为aaaa(假定,可以是任意的内存地址值),但是remove方法中的对象,虽然是和add方法中的对象值是一样的,看起来是一个同一个对象,但其实它们是不同的对象。
举个通俗易懂的现实例子来说明吧。
一、在一个小区里,2号楼202室的房间布局、家具以及住的人是和3号楼202室一模一样的,但是这两个房屋的地址是不一样,所以它们是不同的房子。
二、当你聘请拆迁队要拆迁掉你在2号楼202室的房子,你带他去3号楼202室的房屋,它肯定不会拆的,它会给你报提示,这不是你要求我们要拆的房子。
三、因为名单上的地址和带到拆除房屋的地址不相同。
类比:
①拆迁队==List容器
②2号楼202室 == add方法里new出来的对对象
③add(new Objeact()) == 给它2号楼202室的地址的房子
④3号楼202室 == remove方法里new出来的对象
⑤remove(new Object()) == 带它去的3号楼202室的地址的房子
这是我能最快想到一个能用类似的实际例子说明的。可能,现实中拆迁队不会这么迂腐,但是机器就是这么忠贞不二的去执行既定的规则。如果非要和我争论拆迁队肯定二话不说拆除3号楼202室的房子的同学轻绕道,谢谢。
以下是我看java提供的底层代码,来佐证我的理解:
1. java.util.HashSet
HashSet.remove(Object o)
2. java.util.HashMap
3.java.util.HashMap
这个问题,自己在平时中并未遇见,但是有人问了这个问题后,自己加以思考,整理出来自己的思路来解答,并看了底层的代码加以证明。现在和大家分享下,本人只是抛砖引玉,希望能和更多热爱技术的猿猿一起思考探索下技术。欢迎拍砖,发表不同的想法,也欢迎有猿猿对底层这些实现思维交流交流。如果是我们自己设计这些东西,我们会不会有更好的逻辑去实现,如果没有,它这种底层实现为什么好?
下面进入主餐:
我整理下这位提问人的问题:
就是List容器中添加一个new出来的对象,然后为什么在remove点一个新构造出来的一摸一样的对象,总是不能成功remove掉它。
具体问题代码如下:
package javaFile; public class Name { private String fistName ,lastName;//fiseName姓 lastName名 Name(String fistName ,String lastName){ this.fistName =fistName; this.lastName=lastName; } public String getfistName(){ return fistName; } public String getlastName(){ return lastName; } public String getToString(){ return fistName + lastName; } //重写equals的方法 public boolean equalse(Object obj){ if(obj instanceof Name){//如果这个boj输入这个Name对象 Name name =(Name)obj ; return (fistName.equals(name.fistName)) && (lastName.equals(name.lastName)); } return super.equals(obj); } public int hashCoed(){ return fistName.hashCode(); } package javaFile; import java.rmi.Naming; import java.util.*; public class Testconllenction { public static void main(String[] args) { Collection c = new HashSet();//new 一个ArrayListd对象其实是父类指向子类对象 //想list里面放东西 //Name a = new Name("f","ff"); c.add("Hello"); c.add(new String("fafas")); c.add(new Name("f1" ,"f2")); c.add(new Integer(100)); c.remove(new String("fafas"));//除非是内部类才可以删除否则要进行equals对比 c.remove(new Name("f1" ,"f2"));//问题在这里啊看清粗啊运行的时候????????????????????????? c.remove(new Integer(100) ); c.remove("Hello");//remove 是删除的意思 System.out.println(c.remove(new Name("f1","f2")));//false 去不掉 //原因 :没有重写equals 方法 比较两个对像是否相等是要重写equals的方法 // 在用到Map 里面进行对比会用hashCored进行对比原因是效率更高 System.out.println(c.size()); System.out.println(c); //System.out.println(a.toString()); } }
我看到这个问题后的理解是:
1.list容器中add方法中的对象的内存地址是为aaaa(假定,可以是任意的内存地址值),但是remove方法中的对象,虽然是和add方法中的对象值是一样的,看起来是一个同一个对象,但其实它们是不同的对象。
举个通俗易懂的现实例子来说明吧。
一、在一个小区里,2号楼202室的房间布局、家具以及住的人是和3号楼202室一模一样的,但是这两个房屋的地址是不一样,所以它们是不同的房子。
二、当你聘请拆迁队要拆迁掉你在2号楼202室的房子,你带他去3号楼202室的房屋,它肯定不会拆的,它会给你报提示,这不是你要求我们要拆的房子。
三、因为名单上的地址和带到拆除房屋的地址不相同。
类比:
①拆迁队==List容器
②2号楼202室 == add方法里new出来的对对象
③add(new Objeact()) == 给它2号楼202室的地址的房子
④3号楼202室 == remove方法里new出来的对象
⑤remove(new Object()) == 带它去的3号楼202室的地址的房子
这是我能最快想到一个能用类似的实际例子说明的。可能,现实中拆迁队不会这么迂腐,但是机器就是这么忠贞不二的去执行既定的规则。如果非要和我争论拆迁队肯定二话不说拆除3号楼202室的房子的同学轻绕道,谢谢。
以下是我看java提供的底层代码,来佐证我的理解:
1. java.util.HashSet
HashSet.remove(Object o)
public boolean remove(Object obj) { return map.remove(obj) == PRESENT;//这里的map.remove指向2的remove }
2. java.util.HashMap
public Object remove(Object obj) { Entry entry = removeEntryForKey(obj);//这里的removeEntryForKey方法来源于3 return entry != null ? entry.value : null; }
3.java.util.HashMap
final Entry removeEntryForKey(Object obj) { int i = obj != null ? hash(obj.hashCode()) : 0;//关键地方 int j = indexFor(i, table.length); Entry entry = table[j]; Entry entry1; Entry entry2; for(entry1 = entry; entry1 != null; entry1 = entry2) { entry2 = entry1.next; Object obj1; if(entry1.hash == i && ((obj1 = entry1.key) == obj || obj != null && obj.equals(obj1))) { modCount++; size--; if(entry == entry1) table[j] = entry2; else entry.next = entry2; entry1.recordRemoval(this); return entry1; } entry = entry1; } return entry1; }
相关文章推荐
- Java 中注意的细节之List.remove(int location)方法的使用
- Java:List remove时候注意事项
- Java系列: 关于LinkedList的 ListIterator的add和remove
- 关于java字节的问题,所以说明全在注释里面了,百分之百手敲,注意细节
- 关于java对象流使用的细节注意
- Java list.remove( )方法需要注意的两个地方
- java中使用list.remove需要注意的问题
- 关于Java中使用容器的几个注意点
- Java list.remove( )方法需要注意的两个地方
- Java list.remove( )方法注意事项
- 关于java List的remove方法
- 把Java数组转换为List时的注意事项
- Java List的remove()方法陷阱
- 关于初学Java的一些注意要点(一)
- Remove Duplicates from Sorted List ---Leetcode 我的java题解
- 把Java数组转换为List时的注意事项
- java中关于try、catch、finally中的细节分析
- 关于list的remove
- Java for LeetCode 083 Remove Duplicates from Sorted List
- 关于在java中拼接SQL文会出现的错误(不光要注意全角空格,还要注意全角字符,如逗号)。