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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 HM朱蛟 于 2013-4-2 01:47 编辑

问题解决了,谢谢各位!

我明白了
我太局限于代码了。忽略了al.contains(obj)的意思。
caontains是个动作,这个动作遵循 (o==null ? e==null : o.equals(e))
之前看api没看懂,其实o.equals(e)的意思就是说,我contains收到的参数,将与指定容器里的所有element分别作比较,
那么这个指定的容器是哪个呢?newal.contains,这样写是有道理的,这个指定容器就是newal。
所以当写成这样后,思路就清晰了:

Object obj = it.next()
if(!al.contains(obj))
我从函数里接收到的list取第一个元素,那么传入到equals的就是第1个元素01,   01.equals(null)...return false;  -->add(01)
我从函数里接收到的list取第二个元素,那么传入到equals的就是第2个元素02,   02.equals(01)...return false; --->add(02)
我从函数里接收到的list取第三个元素,那么传入到equals的就是第3个元素01,   01.equals(02)...return false;
                                                                                                                          01.equals(01)...return true;--->kill
这样一写,this和p就清晰的分辨出来了。。。

总结:
犯这个问题的主要原因就是没理解到contains的原理,没看懂caontains的api。

-------------------------------------------------------------------------------------------------------------------------------------------------------------
之前的问题:

虽然代码验证了  this代表指向前一个对象  p代表指向后进对象  但是我思路还是不够清晰   
不能很清晰的看出他们之间是如何联系的
我怎么老感觉this和p是同一个对象呢?
该如何想才能清晰的分辨出this指向的对象和p指向的对象不同呢?

感谢各位的指点,可能是我没表述清楚自己的问题,小弟想问的不是this是什么,怎么用,也不是真真的真,真假得假。小弟疑惑的是这段代码里this和p是怎么指向不同的对象的。

我说下我的理解思路吧,我知道自己的思路是错的,运行结果验证了这点,但是我恐怖的发现我自己居然不知道错在哪里!所以我想请大家告诉我该如何去想这个问题.

我的思路:(下面标记  1 2 3 4是针对这个问题的执行顺序)

当执行到killEcho里的这句 if(!al.contains(obj))
取第一个对象,Object obj = it.next();
执行 if(!al.contains(obj)),由于obj不为空,执行o.equlas(e);那么这句自动调用Person里复写的equals,这时候equals里接收的obj为  【 new Person("haha01",1) ,】,所以我认为当前对象就是【 new Person("haha01",1) ,】 ,this指向
【 new Person("haha01",1) ,】继续执行下句,Person p =(Person)obj;  这句只是个向下转型,我觉得操作的还是【 new Person("haha01",1) ,】   所以我在这里也觉得 p也是指向了   【 new Person("haha01",1) ,】 ,
所以我的疑问点就在这里,p和this既然都是指向的【 new Person("haha01",1) ,】 ,2个指向同一个对象的引用味着不管怎么比
this.name.equals(p.name)  都是返回的真
那么这句就是永远返回真  return this.name.equals(p.name) && this.age ==p.age;  ,外面判断结果 !真if(!al.contains(obj))    ,即假,那么应该将元素全部添加到临时容器。

这就是我老是感觉this和p指向的是同一个对象的原因。比较郁闷,问题表述不当,各位见谅啊
---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
代码如下

需求:将自定义对象作为元素存入集合内。并将容器内重复的对象元素剔除,保留不同的元素
比如:存人对象,同姓名同年龄,视为同一个人,为重复元素。

import java.util.*;


class Person
{
        private String name;
        private int age;
        
        Person(String name,int age)
        {
          this.name = name;
          this.age = age;        
        }
        
        public String getName()
        {
                return name;        
        }
        
        public int getAge()
        {
                return age;        
        }
        
        public boolean equals(Object obj) // ----------2
        {
                 if(!(obj instanceof Person))
                         return false;
                 Person p =(Person)obj;   // ----------3
           System.out.println(this.name+"...."+p.name);
                    
           return this.name.equals(p.name) && this.age ==p.age;   // ----------4
        }
}

class Run
{
public static void main(String[] args)
{
          ArrayList al = new ArrayList();
         
          al.add(new Person("haha01",1));
          al.add(new Person("haha02",2));
          al.add(new Person("haha01",1));
          al.add(new Person("haha02",2));
          al.add(new Person("haha01",1));
          al.add(new Person("haha05",5));

          al =  killEcho(al);         

          Iterator it = al.iterator();

          while(it.hasNext())
    {
            Object obj = it.next();
            Person p = (Person)obj;
            sop(p.getName()+"...."+p.getAge());
    }
}

public static ArrayList killEcho(ArrayList list)
{
          ArrayList al = new ArrayList();
         
          Iterator it = list.iterator();
         
          while(it.hasNext())
          {
                   Object obj = it.next();
                  
            if(!al.contains(obj))  // ----------1
              al.add(obj);
          }
          return al;
}

         public static void sop(Object obj)
        {
                System.out.println(obj);
        }
}

da.png (42.41 KB, 下载次数: 28)

da.png

评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1 赞一个!

查看全部评分

14 个回复

倒序浏览
return this.name == p.name && this.age ==p.age

初中数学问题     两个命题    真真为真  假假为假

返回  当前的(this.name)跟p.name 相等,并且 当前的年龄(this.age)跟p.age 相等才会是true  否则为假。
回复 使用道具 举报
本帖最后由 HM朱蛟 于 2013-4-1 11:02 编辑
guobin_lu 发表于 2013-4-1 10:46
return this.name == p.name && this.age ==p.age

初中数学问题     两个命题    真真为真  假假为假

请问this和p为何不是指向同一对象  请看清我问的是什么哦  亲 {:soso_e100:}   谢谢

回复 使用道具 举报
这么跟你说吧
        Person p = new Person("zhangsan",23);
        Person p_2 = new Person("lilsi",22);
        System.out.println(p.equals(p_2));
this.name就相当于是p的name,也就是进行equals比较的name
p.name就相当于是p_2的name,也就是被equals的name
回复 使用道具 举报
Person p1 = new Person();
Person p2 = new Person();
p1.equals(p2);
在equals方法中this代表p1,即调用该方法的对象
equals方法中的p代表p2,即参数,要判断是否相等的对象。
回复 使用道具 举报
这个问题主要是因为你对this关键字理解不到位,毕老师基础视频第五天后面三小节。建议仔细再看看。
回复 使用道具 举报
刘松 发表于 2013-4-1 11:24
这么跟你说吧
        Person p = new Person("zhangsan",23);
        Person p_2 = new Person("lilsi",22);

谢谢指导   但是我还在纠结于他这里:

如果此列表中包含指定的元素,则返回 true。更确切地讲,当且仅当此列表包含至少一个满足 (o==null ? e==null : o.equals(e)) 的元素 e 时,则返回 true。

这里这个e是啥玩意?element么? 集合里的对象?我只看懂了当o不为null时,执行o.equals(e),这e是啥东西哦。

CA.png (9.78 KB, 下载次数: 26)

CA.png
回复 使用道具 举报
this指的是当前调用的对象
例如:Person p1=new Person("aa",23);
          Person p2=new Person("bb",24);
          System.out.println(p1.equals(p2));//这时Person类中的this指的就是当前调用的对象p1,this.name指的就是p1.name;而p指的就是p2了
回复 使用道具 举报
this就代表的事哪一个去引用equalse(Person p)的对象,
而p 代表的就是传进equalse(Perosn p)的那个参数。
回复 使用道具 举报
自己顶一下
回复 使用道具 举报
这里我也只学过去一遍,不知理解的对不对
equals方法里你纠结的那个p是你传进来的对象   this代表集合里的对象
你把p传进去之后contains会根据你的equals方法去al集合里和元素进行比较,如果没有就加上,如果有就不加
也就是说拿你传进来的对象和集合里存在的对象比,现在是al集合在调用你的equals方法,this就代表集合里的对象。
这是我的理解,不对的话请更正
回复 使用道具 举报
本帖最后由 HM朱蛟 于 2013-4-1 15:32 编辑
易贺男 发表于 2013-4-1 14:13
这里我也只学过去一遍,不知理解的对不对
equals方法里你纠结的那个p是你传进来的对象   this代表集合里的 ...

谢谢先,让我想通了一部分。

“al集合在调用你的equals方法,this就代表集合里的对象”

临时容器al.contains(obj)  //我之前也觉得这句的理解模糊
不过按照你的逻辑这样就貌似说得通了,谢了,有点豁然开朗的感觉
可以这样理解不:
al.contains(obj),等于就是 (临时容器al里所有元素)equals(从迭代器取的元素),
意思就是每次从迭代器里取一个元素,然后和临时容器里的所有元素做对比,相同就干掉,不同就加入。
我觉得这样可以想得通呢。
---------------------------------------------------------------------------------------------------
但,这里还是有点悬吊吊的,没有想通的地方(这里可能有点钻牛角尖了)
al.contains(obj) 代表用临时容器里的元素逐个和迭代器取出的元素作对比,但是我查阅API貌似越看越不对的感觉。。。。请看截图


QQ截图20130401145713.png (17.14 KB, 下载次数: 21)

QQ截图20130401145713.png
回复 使用道具 举报
我刚刚把代码运行了一遍,细一推敲之下。发现之前不对  
向下面这样就对了、、希望没把你绕晕了。如果晕了我很抱歉
        public int getAge()
        {
                return age;        
        }
        
        public boolean equals(Object obj) //4、迭代出来的对象传进来
        {
                 if(!(obj instanceof Person))
                         return false;
                 Person p =(Person)obj;   //强转
           System.out.println(this.name+"...."+p.name);
                  
                    
           return this.name.equals(p.name) && this.age ==p.age;   //5、this代表传进来的对象,因为用的是person自定义的比较器。在这里看下边
        }
}
/*运行结果:        this                  p

                        haha02....haha01通过结果看 第一个对象没有比较直接进容器。第二个02传进来时容器里只有一个01,然后02和01比一下。没有,传进来
                        haha01....haha01这是第三个传进来的,01先和01比,有。不传进来
                        haha02....haha01第四个是02,和01比没有,
                        haha02....haha02//02和02比,有。不传。下面的也是这样
                        haha01....haha01
                        haha05....haha01
                        haha05....haha02
                        haha01....1
                        haha02....2
                        haha05....5
就是说开始新定义的集合里没有元素,传进去之后才有的
                  
                   */
class Run
{
public static void main(String[] args)
{
          ArrayList al = new ArrayList();
         
          al.add(new Person("haha01",1));
          al.add(new Person("haha02",2));
          al.add(new Person("haha01",1));
          al.add(new Person("haha02",2));
          al.add(new Person("haha01",1));
          al.add(new Person("haha05",5));

          al =  killEcho(al);  //1、将al传给函数  返回的是下边处理过的新的al。和传进去的不一样     

          Iterator it = al.iterator();

          while(it.hasNext())
    {
            Object obj = it.next();
            Person p = (Person)obj;
            sop(p.getName()+"...."+p.getAge());
    }
}

public static ArrayList killEcho(ArrayList list)
{
          ArrayList al = new ArrayList();//2、定义一个局部的al集合
         
          Iterator it = list.iterator();
         
          while(it.hasNext())
          {
                   Object obj = it.next();
                  
            if(!al.contains(obj))  //3、 迭代出的obj传给空集合,并用person的equals进行比较
              al.add(obj);
          }
          return al;
}

评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1

查看全部评分

回复 使用道具 举报
HM朱蛟 发表于 2013-4-1 15:05
谢谢先,让我想通了一部分。

“al集合在调用你的equals方法,this就代表集合里的对象”

那个 不好意思,这次应该对了
回复 使用道具 举报
易贺男 发表于 2013-4-1 17:24
那个 不好意思,这次应该对了

明白了 谢谢指点
  我把我的理解写到1楼上了。和你的思路一样了,也符合API了。折腾了我好久这小东西。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马