增强for循环和泛型的使用

 


要开始写高新课程的学习笔记了,写点不同的,这一篇就写一些简单,但挺多人不在意的小知识,有关基本类型以及基本语法的理解,以后的学习笔记我会尽量以代码加上自己理解的方式写下来,以便让老师知道我不是把知识点copy来copy去,而是经过自己理解的。

基本类型:int,long,float,double,short,char,byte,boolean八大类型,应该没写错吧。

这八大类型都有他们的包装类,比如int的包装类是Integer,为什么需要包装类呢??我想是因为java是纯面向对象的原因吧,比如一个实现了collection接口的子类,都可以称之为一个容器,由于纯面向对象的原因,它只能装对象,不能装基本类型。你要让容器装基本类型数据,只有把基本类型数据变成对象才可以装进去,于是包装类应运而生。

       在1.5之前,装数据必须先把数据打包成该类型的包装类,比如一个容器需要装int类型的数据,就要这样做:

   

 Collection c = new ArrayList();

       int a = 3;

       Integer integer = new Integer(a);

       c.add(integer);


当然如果你知道你的数据是准备装在容器上的,你也可以直接这样做

       Integer integer = new Integer(3);

这样做挺麻烦的,因为你拿出来用的时候还得进行强制转换,比如:

      

 Iterator iterator = c.iterator();

       while(iterator.hasNext()) {

           int a1 = ((Integer)iterator.next()).intValue();

       }


麻烦吧?所以在1.5之后,加了很多新特性,让麻烦的东西简便一些,比如自动装箱和自动装箱,你在1.5以及之后的版本中可以直接使用c.add(3);编译器并不会报错,但也不是把基本类型装进去了,只是它会在编译的时候自动帮你把a打包成Integer对象而已。就算如此,代码还是挺多的,于是又增加了泛型,你可以这样写:

   

 Collection<Integer> c = new ArrayList<Integer>();

       c.add(3);

       Iterator<Integer> iterator = c.iterator();

       while(iterator.hasNext()) {

           int a1 = iterator.next().intValue();

       }


在你的容器上打上标记,告诉编译器,这个容器是装Integer类型的,所以你取出来的时候也省却了强制类型装换的麻烦,还有一个更大的好处是,假若你让容器装了一个其他对象,比如String,但你却强制转换成Integer类型,编译器并不会报错,但运行期间一定报错。但有了泛型,指定了容器只能装某个类型,你在写代码的时候,编译器就不给你通过!写代码最重要的一点是,能在编译期间就能发现的错误,绝对不要留到运行才发现。

    另外需要迭代容器的话,往往需要一个迭代器,这样也挺麻烦的,所以1,5又增加了一个语法,for增强循环。当你需要遍历一个容器的时候并想打印出来,你可以这样写的:

Collection<Integer> c = new ArrayList<Integer>();

       c.add(3);

       c.add(4);

       for(Integer a: c) {

           System.out.println(a);

       }


 

另外需要注意的是,for增强循环只能用那些实现了iterable接口的对象或者数组上,因为前者的实现就是用iterator遍历的,只不过内部实现不让你知道而已,当用iterator遍历一个实现了iterable接口的对象时,该对象已被锁定,你不能在遍历的时候进行修改,例如删除一个对象的时候,你不能这么写:

Collection<Integer> c = new ArrayList<Integer>();

       c.add(3);

       c.add(4);

       Iterator<Integer> iterator = c.iterator();

       while(iterator.hasNext()) {

           c.remove(3);

       }

       System.out.println("阿门");


 

这样做的话你会发现“阿门“这个单词并没有打印出来,并且你会发现机器跑起来了,散热的风扇声越来越大,至于是什么原因,我不太了解,是堵塞么?查了下文档,给的内容是:iterator里面的remove方法给出的解释是:从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。每次调用next 只能调用一次此方法。如果进行迭代时用调用此方法之外的其他方式修改了该迭代器所指向的 collection,则迭代器的行为是不确定的

所以啊,在使用for循环遍历一个容器的时候,千万注意别使用collections的remove方法,就算使用iterator的remove,也要注意一点,每次调用next只能调用此方法一次,下面举个例子吧:

while(iterator.hasNext()) {

           iterator.remove();

           iterator.next();

       }


 

若使用这种代码,必定报错(实际上是我在编译器上试下了),因为迭代器并没有使用next方法就想删除了,迭代器没指向那个对象,你是删除不了的,只要把那两个方法的调用顺序改变一下就可以了,代码我就不写了,上面对调下顺序就可以了。

另外需要补充一点的是,泛型作用只是在编译期间有用,运行的时候虚拟机会把泛型的标签除掉,就是所Arraylist<String>和Arraylist<Integer>在虚拟机上的类字节码完全是一样的。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值