A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 奋斗的蜗牛ksd 于 2014-11-19 18:34 编辑
  1. <p> </p><p>import java.util.ArrayList;
  2. import java.util.Iterator;

  3. /*
  4. * 将自定义对象作为元素存到ArrayList集合中,并去除重复元素。
  5. 比如:存人对象。同姓名同年龄,视为同一个人。为重复元素。

  6. */
  7. class Person
  8. {        //建立Person类,封装name和age属性,提供访问方法
  9.         private String name;
  10.         private int age;
  11.         Person(String name,int age)
  12.         {
  13.                 this.name=name;
  14.                 this.age=age;
  15.         }
  16.         public String getName()
  17.         {
  18.                 return name;
  19.         }
  20.         public int getAge()
  21.         {
  22.                 return age;
  23.         }
  24.         public boolean equals(Object obj)
  25.         {
  26.                 if(!(obj instanceof Person))
  27.                         return false;
  28.                 Person p=(Person)obj;
  29.                 return this.name.equals(name)&&this.age==(age);
  30.         }
  31. }

  32. public class DeleteEquals2 {

  33.         public static void main(String[] args) {
  34.                 // TODO Auto-generated method stub
  35.                 @SuppressWarnings("rawtypes")
  36.                
  37.                 ArrayList a1=new ArrayList();
  38.                 a1.add(new Person("lisi",15));//a1存储的是对象的地址
  39.                 a1.add(new Person("zhaosi",19));
  40.                 a1.add(new Person("wangwu",23));
  41.                 a1.add(new Person("wangwu",23));
  42.                 a1.add(new Person("xiaoliu",25));
  43.                 a1.add(new Person("xiaoliu",25));
  44.                 sop("打印a1==="+a1);//打印的是个地址值,a1存储的是4个对象
  45.                
  46. //                sop("观察equals和remove的关系:"+a1.remove(new Person("lisi",15)));
  47.                 //打印结果true---表示:删除了属性为 lissi 15 的这个对象
  48.                
  49.                 a1=singleTest(a1);//去除集合a1中相同元素
  50.                 sop(a1);//测试得  这里a1只接收了一个元素---lis--15这个对象!是为什么呢?
  51.                
  52.                 //建立一个迭代器,获取集合中的元素
  53.                 Iterator it=a1.iterator();//一直就很模糊,不太理解
  54.                 //用hasNext()方法遍历集合中的元素---遍历的结果是输出每个元素
  55.                 while(it.hasNext())
  56.                 {        </p><p style="line-height: 30px; text-indent: 2em;">//向下转型--把地址转型为地址对应的对象属性
  57.                         //Object obj=it.next();  
  58.                         //Person p=(Person)obj;这里是把a1中存放的地址转型成对应的对象属性??
  59.                         Person p=(Person)it.next();//即使知道怎么转型,还是很难理解
  60.                         sop("打印Person对象属性:"+p.getName()+"------"+p.getAge());
  61.                 }
  62.                
  63.                
  64.                
  65.         }
  66.         //建立临时容器,保存不同的元素
  67.         public static ArrayList singleTest(ArrayList a1)
  68.         {
  69.                 //建立临时容器a2
  70.                 ArrayList a2=new ArrayList();
  71.                 //建立迭代器,遍历a1集合的元素!
  72.                 Iterator it=a1.iterator();
  73.                 while(it.hasNext())//遍历a1的元素,为什么我的while循环只遍历了一次?
  74.                 {        
  75.                         Object obj=it.next();
  76.                         if(!a2.contains(obj))//这里调试出现了问题?为什么只比较了一次?
  77.                         {
  78.                                 a2.add(obj);
  79.                         }
  80.                 }
  81.                 return  a2;
  82.         }
  83.     public static void sop(Object obj)
  84.          {
  85.                       System.out.println(obj);
  86.         }


  87. </p>
复制代码

我的问题是:
1.为什么  我明明重写了equals方法,并且 执行remove也成功了【证明remove方法调用底层的equals方法】,
可是执行 singleTest方法【作用是去除集合中相同的元素】,仅仅只遍历的了一次就结束循环了?
2.我对迭代器的理解不透彻
Person p=(Person)it.next();我知道是向下转型,原理如下,
//Object obj=it.next();  
  //Person p=(Person)obj;
可是我感觉理解很困难,难道是我对 迭代器的定义 没有理解吗?那么谁能解释一下对语句Iterator it=a1.iterator();的理解呢?

第一次在帖子里面插入代码-----可能不优美-----没有在 eclipse里面那种排版缩进----我也不会----请各位原谅,尽力理解我写的问题。谢谢

评分

参与人数 1技术分 +1 收起 理由
杨佳名 + 1

查看全部评分

17 个回复

倒序浏览
这个问题困扰了我两个小时------
如果有好心人解答 万分感激,,,饿的不行了,先去吃饭,,,谢谢各位查看!
回复 使用道具 举报
第31行,equals始终返回的是真。
回复 使用道具 举报
哈达洋 发表于 2014-11-19 18:52
第31行,equals始终返回的是真。

谢谢,我刚好自己调试的时候 看到这里错误了,非常感谢
回复 使用道具 举报
刚好吃饭的时候再思考问题---
突然意识到 自己重写equals的方法有点问题,回来试着在euqals方法里面加了一条输出语句观看打印结果
验证equals方法确实有问题,-------这个问题很细小----涉及了this.调用的使用【this代表调用者的对象】
而我把p.name写成了name--------导致this.name.queals(name)恒为真,所以是返回的全是lisi 这一个对象!

虽然我意识到这里的错误,来帖子更正,但是仍然感谢上面朋友的回答,谢谢。
回复 使用道具 举报
哈达洋 发表于 2014-11-19 18:52
第31行,equals始终返回的是真。

可以回答一下第二个问题吗
回复 使用道具 举报
先回答第一个问题:为什么你的while循环只遍历了一次?
回复 使用道具 举报
先回答你第一个问题  首先在你的equals 方法里面  你的this.name  和 name 指向的都是同一个对象的name 所以结果肯定恒为真,所以你的equals 当你传入Person 对象后永远都为真,去重的目的是不会达到的,再说了,看到你的Person p = (Person) obj;这句语句是~~我在想为什么你不用P 呢?那你还转型干嘛?
还有就是你问 while 循环为什么只是循环了一遍?
这和迭代器的遍历有关,在遍历的时候相当于有一个指针,当指针指向数据尾端的时候,整个遍历也就完了,只是一边,如果,你想遍历多遍的话,可以重新先把该迭代器存起来,当到达尾部是在重新赋值即可.还可以使用双向迭代器

评分

参与人数 2技术分 +1 黑马币 +2 收起 理由
奋斗的蜗牛ksd + 2 谢谢你,希望交个朋友!
杨佳名 + 1 赞一个!

查看全部评分

回复 使用道具 举报
DamonZh 中级黑马 2014-11-19 21:07:01
9#
本帖最后由 DamonZh 于 2014-11-19 21:08 编辑
  1. //31行改为: return this.name.equals(p.name)&&this.age==(age);
  2. //Iterator it=a1.iterator();  iterator()方法返回一个Iterator对象的引用,所以用Iterator类型的变量来接受啊,这里有什么理解不了的?
  3. //源码:
  4. public Iterator<E> iterator() {
  5.         return new ArrayListIterator();
  6.     }
  7. //其中,ArrayListIterator实现了Iterator。父类变量接受子类引用嘛
复制代码


回复 使用道具 举报
kerner 中级黑马 2014-11-19 21:25:16
10#
本帖最后由 kerner 于 2014-11-19 21:45 编辑


public static ArrayList singleTest(ArrayList a1)
{

        ArrayList a2=new ArrayList(); //默认初始化,集合没有装没有任何对象

        Iterator it=a1.iterator();
        while(it.hasNext())
        {
                Object obj=it.next();             //    a2.contains(obj) --> a2.indexOf(obj) --> obj.equals(object i)       
                if(!a2.contains(obj))            // 第1次 return :         false       <-- -1                  <-- false
                {                                            // 第n次 return :  ture       <-- 0                <-- ture;
                        a2.add(obj);
                                                        // 第一次person("lisi","15),会被a2集合存贮。       
                }
        }
        return a2;                                         //所以a2集合只存有第一对象Person("lisi","15)
}

public boolean equals(Object obj)
{
        if(!(obj instanceof Person))
                return false;                                                                         //第一次调用时,obj为null,则( obj instanceof Person)为false;则equals返回false;
        Person p=(Person)obj;
                return this.name.equals(name)&&this.age==(age);        //少了p.name,第N (n>1)次调用时,故恒为true;
}

public boolean contains(Object o) {
        return indexOf(o) >= 0;                                                         //index(o)返回-1;则第一返回false;
}                                                                                                 //第N(n>1)时,indexOf()一直返回0;则contain()返回true;

public int indexOf(Object o) {
        if (o == null) {
        for (int i = 0; i < size; i++)
                if (elementData==null)
                        return i;
                } else {
        for (int i = 0; i < size; i++)                                         //因为第一次进来,集合为空,所以elementData = null;
                if (o.equals(elementData))                                //调用equals方法,必须要循环调用o.equals(null),因为要返回false;
                                                                                        //直到循环完毕,因为o.equals(elementData)恒为false;
                return i;                                                                 //以后第n(n>1)调用时,因为该集合已经存在对象elementData[0] = person("lisi","15");所以当执行到i = 0;
                                                                                        // o.equals(elementData[0])返回ture; indexof()方法返回0;
        }
        return -1;                                                                 //循环完毕,返回-1;
}

红色是第一次调用一下代码的解释,蓝色是第N(n>1)次调用的解释.
while(it.hasNext())//遍历a1的元素,为什么我的while循环只遍历了一次?
                {        
                        Object obj=it.next();
                        if(!a2.contains(obj))//这里调试出现了问题?为什么只比较了一次?
                        {
                                a2.add(obj);
                        }
                }

编辑器好蛋疼。

评分

参与人数 2技术分 +2 黑马币 +2 收起 理由
奋斗的蜗牛ksd + 2 真的很认真!向你学习!
杨佳名 + 2 赞一个!

查看全部评分

回复 使用道具 举报
kerner 中级黑马 2014-11-19 21:48:20
11#
代码好难贴,尤其注释加颜色,以后遇到这种问题,最好的解决办法是设置断点debug,一步步的追踪。
回复 使用道具 举报
加油呀  这社会考的是技术 其他都是浮云
回复 使用道具 举报
kerner 发表于 2014-11-19 21:48
代码好难贴,尤其注释加颜色,以后遇到这种问题,最好的解决办法是设置断点debug,一步步的追踪。 ...

初学 还不回设置断电和debug,目前测试通过加输出语句 观看输出结果-----一般都是runtimeException所以还能运行一点点。

十分感谢你的回答!谢谢你了朋友!
回复 使用道具 举报
王小忠 发表于 2014-11-19 20:09
先回答你第一个问题  首先在你的equals 方法里面  你的this.name  和 name 指向的都是同一个对象的name 所 ...

谢谢你的回答朋友。对于 while循环里 那转型,操作,我可以这样理解吗?把 类型为Iterato 的it.next()元素转成 Person类型的p元素,通过P操作 person类的方法,所以转型是必须的。   
我刚开始没理解  it.next()的含义,现在我理解它为一个对象。可以这么说嘛
回复 使用道具 举报
kerner 发表于 2014-11-19 21:25
public static ArrayList singleTest(ArrayList a1)
{

你的注释比我的注释还详细!我看了两遍 。十分感谢你。朋友!
回复 使用道具 举报
kerner 发表于 2014-11-19 21:25
public static ArrayList singleTest(ArrayList a1)
{

你好,打扰一下,再请教一下学习上的问题,我第一次学集合,今天学了视频集合第一天的内容,学完了 代码搞得能写出来,可是具体到 我对每一个语句的理解   跟你比 差太远了。
比如  contains方法 居然 和 equals方法  indexOf方法有关系 我都不知道。
还有对于语句的分析,一看到!这种判断结构我就比较懵,耐不下心分析执行过程,这个我认为我太浮躁了,
那么对于集合的学习,请问我是不是应该把集合第一天的内容多看几遍呢?今天看了两遍感觉收获还不如看你写的代码大------我所有的练习也做了,但都是模仿老师的代码,自己又得语句不理解--都是勉强记住,感觉不靠谱。
2.集合跟前面的String有关系吗,我看很多操作有类似,String我前天刚学,也只是背过了几个常用的方法。
回复 使用道具 举报
也可以这么说~~但是其实你没必要转型,如果可以,你加个泛型,这还有助于你理解
回复 使用道具 举报
王小忠 发表于 2014-11-20 00:35
也可以这么说~~但是其实你没必要转型,如果可以,你加个泛型,这还有助于你理解 ...

昨天刚学习到 集合第一天的内容,泛型计划今天学的,谢谢!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马