zoukankan      html  css  js  c++  java
  • 增强型for循环与集合

    在python中对可迭代对象实现了__iter__方法。只要一个对象实现了__iter__方法,并返回一个迭代器,这个对象就是可迭代对象,就可以用for对其迭代。每次迭代的时候会调用迭代器__next__方法。在python中写如下代码

    class A:
        def __iter__(self):
            print('.....iter........')
            return (i for i in ['1',2,4,'python','java',"c"] if type(i)==str)
    a = A()
    for i in a:
        print(i)

    观察运行结果

    会看到先输出了.....iter........,这是因为遇到for时python解释器会自动调用对象的__iter__方法,因此会看到该行输出

    在java中是否有相同的概念?先看这一段代码

    在代码中for语句加上断点。运行跟踪代码,执行到断点时发现果然跳到了LinkedList父类里面的iterator方法里面,在父类AbstractSequentialList方法里有调用了listIterator方法,接着到了LinkedList的自己中的listIterator方法

    这样看来java中也有相同的概念,遇到for时jvm自动调用对象的iterator方法,该方法返回一个迭代器(实现了java.util.Iterator接口的都是迭代器),每一次迭代都会调用该迭代器的next方法。

    在LinkedList的listIterator方法中返回的是一个ListItr对象,这个对象其父类是一个ListIterator,ListIterator又继承 Iterator接口,因此ListItr是一个迭代器对象会有next方法。

    查看iterator接口时发现这个接口没有iterator方法,那遇到for时jvm自动调用的谁itorator方法?查看LinkedList的一系列父类最终发现其超父类Collection里面有一个itorator方法

    而Collection又继承了Iterable接口。

    因此一个对象要能进行迭代必须实现Iterable接口(告诉jvm该类是能迭代的),重写iterator方法,并且在该方法返回一个Iterator的实现

    package cn.itcast.jdk15;
     
    import java.util.Iterator;
     
    //自定一个类使用增强for循环
    class MyList implements Iterable<String>{
        
        Object[] arr = new Object[10];
        
        int index = 0 ;    //当前的指针
        
        public void add(Object o){
            arr[index++] = o;  // 1
        }
        
        public int size(){
            return index;
        }
     
        @Override
        public Iterator<String> iterator() {
            
            
            return new Iterator<String>() {
     
                int cursor  = 0;
     
                @Override
                public boolean hasNext() {
                    return cursor<index;
                }
     
                @Override
                public String next() {
                    return (String) arr[cursor++];
                }
     
                @Override
                public void remove() {
                    
                }
            };
        }
    }
     
    public class Demo3 {
        
        public static void main(String[] args) {
            MyList list = new MyList();
            list.add("张三");
            list.add("李四");
            list.add("王五");
            
            for(String item :list){
                System.out.println(item);
            }
            
            
            
        }
        
    }

    在遍历HashMap的时候你想过为什么不能直接写这样的代码吗?

    原因就是map和其超父类没有任何一个与Iterable接口有关系,map是不可直接迭代的,因为其本身或其超父类都没有实现或继承Iterable接口

    到这你可以写一个类继承HashMap同时让这个类实现java.util.Iterable接口,改写HashMap,使其能够直接迭代,代码如下

    import java.util.*;
    public class MyHashMap<K,V> extends HashMap<K,V> implements Iterable {
        @Override
        public Iterator iterator() {
            return entrySet().iterator();
    //        return getIterator();
        }
    
    //    private Iterator getIterator(){
    //        return new mapIterator();
    //    }
    
        /**
         * 很多属性由于是默认访问权限,子类获取不到,因此该方式不可行
         *
         */
    //    private  final class mapIterator<E> implements Iterator<E>{
    //        Entry<K,V> next;        // next entry to return
    //        int expectedModCount;   // For fast-fail
    //        int index;              // current slot
    //        Entry<K,V> current;     // current entry
    //
    //        mapIterator() {
    //            expectedModCount = modCount;
    //            if (size > 0) { // advance to first entry
    //                Entry[] t = table;
    //                while (index < t.length && (next = t[index++]) == null)
    //                    ;
    //            }
    //        }
    //
    //        public final boolean hasNext() {
    //            return next != null;
    //        }
    //
    //        final Entry<K,V> nextEntry() {
    //            if (modCount != expectedModCount)
    //                throw new ConcurrentModificationException();
    //            Entry<K,V> e = next;
    //            if (e == null)
    //                throw new NoSuchElementException();
    //
    //            if ((next = e.next) == null) {
    //                Entry[] t = table;
    //                while (index < t.length && (next = t[index++]) == null)
    //                    ;
    //            }
    //            current = e;
    //            return e;
    //        }
    //        public Map.Entry<K,V> next() {
    //            return nextEntry();
    //        }
    //
    //    }
    
        public static void main(String[]args){
            MyHashMap<String,String> map = new MyHashMap<>();
            map.put("aa","a");
            map.put("bb","b");
            System.out.println(map.get("aa"));
            for(Object obj:map){
                Map.Entry<String,String> e= (Map.Entry<String,String>)(obj);
                System.out.println(e.getKey()+":"+e.getValue());
            }
    
        }
    }

     增强型for循环与集合

    集合类主要分为两大类:Collection和Map

    collection继承了Itarable接口,collection的实现类都是可直接迭代的

    Map没有实现Itarable接口,其实现类不可以直接迭代

  • 相关阅读:
    android使用ant编译打包
    Android OpenGL ES 2.0 (二) 画立方体
    Android OpenGL ES 2.0 (三) 灯光pervertex lighting
    OpenGL ES2.0里的3种变量
    JAVA对DOM的一些解析、修改、新增操作
    webservice(二)示例代码
    linux改IP
    android从未安装的apk文件里获取信息(包信息,资源信息)
    Android OpenGL ES 2.0 (一) 画三角形
    一个关于closure的问题.
  • 原文地址:https://www.cnblogs.com/kin1492/p/9356255.html
Copyright © 2011-2022 走看看