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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 王璐 于 2012-6-18 19:17 编辑
  1. import java.util.*;

  2. class Person
  3. {
  4. private String name;
  5. private int age;
  6. Person(String name ,int age)
  7. {
  8. this.name=name;
  9. this.age=age;
  10. }
  11. public String getName()
  12. {
  13. return name;
  14. }
  15. public int getAge()
  16. {
  17. return age;
  18. }
  19. }
  20. class ArrayListTest2
  21. {
  22. public static void main(String[] args)
  23. {
  24. ArrayList al=new ArrayList();
  25. al.add(new Person("lisi01",30));
  26. al.add(new Person("lisi02",32));
  27. al.add(new Person("lisi03",33));
  28. al.add(new Person("lisi04",34));
  29. al.add(new Person("lisi05",35));
  30. Iterator it=al.iterator();
  31. while(it.hasNext())
  32. {
  33. //Person p=(Person)it.next();
  34. //sop(p.getName()+"::"+p.getAge());
  35. sop(((Person)it.next()).getName()+"::"+((Person)it.next()).getAge());
  36. }
  37. }
  38. public static void sop(Object obj)
  39. {
  40. System.out.println(obj);
  41. }
  42. }

  43. (代码已整理完整)
  44. 问题1.   sop(p.getName()+"::"+p.getAge());  //这里用了两次it.next(),next()为什么没有两次指向下一个元素,却打印了对象中成员?

  45. 问题2.   sop(it.next().getName()+"::"+it.next().getAge());   //假如it.next()的返回类型是Person ,这条语句会打印一个元素中的两个成员吗?next()指向几次集合中元素?
  46.    
  47. 问题3.   sop(((Person)it.next()).getName()+"::"+((Person)it.next()).getAge());  //it.next()的返回类型是Object,强制转换下,出现没有“没有这个元素异常”,
  48. it.next()指向了两次,为什么不能在问题1中的语句中直接转换类型?

复制代码

7 个回复

倒序浏览
本帖最后由 唐辉辉 于 2012-6-18 15:45 编辑

请楼主把代码整理好再贴上来, 发现乱七八糟,sop方法写在类外面,it.hasNext这里也缺少括号

问题1:
Person p=(Person)it.next();
sop(p.getName()+"::"+p.getAge());
这里把it.next()的对象引用给了p, p.getName()和p.getAge()调用的是同一个对象的成员。

问题2:
sop(it.next().getName()+"::"+it.next().getAge());
这条语句错误,it.next();目前是未知的对象无法调用Person的特有成员。你必须在定义集合和Iterator时指定其接收的类型,后就可以调用了。再要么像问题1一样将对象转成Person再调用。

问题3:
sop(((Person) it.next()).getName() + "::"+ ((Person) it.next()).getAge());
是可以转换的。楼主报的异常应该是由于it.next()越界所致:
这里第一次循环时应该是:lisi01:32      至于为什么?因为每调用it.next()指针就往下一个。所以这里不是同一个对象。
((Person) it.next()).getName()  调用的是new Person("lisi01", 30),所以得出来的是lisi01
((Person) it.next()).getAge()  调用的是new Person("lisi02", 32),所以得出来的是32


评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 韦念欣 于 2012-6-18 14:53 编辑

楼主的代码确实传给了自定义对象,但是迭代器是有泛型的,楼主写的迭代器并没有指定类型,所以它并不知道你传的具体是什么自定义对象,所以用Object代替了,因为Object类是所有类的父类。
回复 使用道具 举报
在解决楼主的问题之前先提点建议;
1 代码要写的规范,最基本的格式总要吧;你这写的是个什么啊。方法定义在了类的外面;
2 问题要问的具体一点;让别人知道你到底是什么地方不明白;最好是在代码上通过注释的形式表达出来;
免得给你解决问题之前还要修改半天格式上的错误和猜测你到底什么地方不明白 ;
我想你是想问 为什么往ArrayList里面明明传的是Person类的对象;为什么通过跌代器出来后还是Object的类型是吧;
要弄清楚这个问题在毕老师后面的泛型会有详细的讲解;
我在这儿给你大概解释一下 说的不全面希望可以帮到你;当成是后面视频的预习吧;
首先你可以查阅API可以发现ArrayList的后面是带着泛型的;
什么是泛型;通俗的讲就是在往ArrayList集合里存元素之前就确定元素的类型,不是指定的元素不能存;把运行时的错误提前到编译时期;让程序更安全。
以你的这个代码为例:因为你的ArrayList集合没有加泛型;所以往你里存的所以元素都是以Object的形式存入的 而所有的对象都是Object的子类;所以编译可以 通过 ;而在
迭代过程中也是以Object的形式往外返;而你getName()方法是Person类的特有方法;Object并不具备;所以会报错;提示你找不符号;在学习泛型之前的解决方案是把Object对象向下转换即 Person p=it.next(); sop(p.getName()); 这样才可以调用子类的特有方法也就Person类的特有方法;
在学习了泛型之后就应该这样写了:
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 String getAge()

        {

                return name;

        }

}

class  ArrayListTest2

{

        public static void main(String[] args)
        {

                ArrayList<Person> al=new ArrayList<Person>();//在往集合里存入元素之前就明确元素的类型为Person类型;

                al.add(new Person("lisi01",30));

                al.add(new Person("lisi02",32));

                al.add(new Person("lisi03",33));

                al.add(new Person("lisi04",35));

                Iterator<Person> it=al.iterator();//明确返回的元素类型也为Person类型

                while(it.hasNext())

                {
      //Person p=(Person)it.next();//在未定义泛型时必须有一下向下转换的动作;否则编译失败;
                        sop(it.next().getName());//在明确了泛型之后就可以通过编译了;而且你会发现在明确泛型之后JVM的未经检查的不安全
            //操作提示也没有了;

                }

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

}

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

回复 使用道具 举报
其中:sop(it.next().getName());it.next()为什么返回的是Object类型,不是已经传给它自定义的对象了吗?
it.next()返回的并不是Object 类型,而是集合里面存放的元素类型,只是sop(Object obj)函数的参数接收的是Object 当把it.next().getName()传给它时,
就相当于Object obj = it.next().getName();这就叫做多态,父类引用指向子类对象。

还有楼主应该用泛型。
回复 使用道具 举报
刚刚回答了另一个朋友的问题和你这个差不多给你粘过来了:

我想你是想问 为什么往ArrayList里面明明传的是String类的对象;为什么通过跌代器出来后还是Object的类型是吧;
要弄清楚这个问题在毕老师后面的泛型会有详细的讲解;
我在这儿给你大概解释一下 说的不全面希望可以帮到你;当成是后面视频的预习吧;
首先你可以查阅API可以发现ArrayList的后面是带着泛型的;
什么是泛型;通俗的讲就是在往ArrayList集合里存元素之前就确定元素的类型,不是指定的元素不能存;把运行时的错误提前到编译时期;让程序更安全。
以你的这个代码为例:因为你的ArrayList集合没有加泛型;所以往你里存的所以元素都是以Object的形式存入的 而所有的对象都是Object的子类;所以编译可以 通过 ;而在
迭代过程中也是以Object的形式往外返;而你.length方法是String类的特有方法;Object并不具备;所以会报错;提示你找不符号;在学习泛型之前的解决方案是把Object对象向下转换,这样才可以调用子类的特有方法也就String类的特有方法;
在学习了泛型之后就应该这样写了:
import java.util.*;
class ABC
{
public static void main(String[] args)
{
   ArrayList<String> al = new ArrayList<String>();
   al.add("dfafd");
   al.add("jdsasf");
   al.add("sadfd");
   al.add("jaads");

for (Iterator<String> it = al.iterator(); it.hasNext() ; )
   {
    //String s = (String)it.next();//因为父类引用不具备子类特有功能;所以没有加泛型且没有向下转换时就会报错;
   sop(it.next().length());//加了泛型就可以了;
   }
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
回复 使用道具 举报
邓杰 中级黑马 2012-6-18 15:45:24
7#
不好意思 本来是给另一个朋友好的。发错了;
回复 使用道具 举报
邓杰 中级黑马 2012-6-18 15:53:55
8#
第一个问题 it.next();返回的是一个Object对象在被 向下转成Person类型后;p代表的是一个Person对象 ;他调用自己的两个方法;这有什么问题;
第二个问题:不会。 因为第调用一次it.next()就会返回下一个对象;你的那条语句的结果实际上是两个不同对象分别调用了自己的方法;A person 的name和B person的age;
第三个问题 我想你没有认真看我的上一条回复;这就是为什么要加泛型的原因;
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马