zoukankan      html  css  js  c++  java
  • 2020年9月21日 Collection系列集合的遍历三种方式

    package com.atguigu.test05;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Iterator;
    
    import org.junit.Test;
    
    /*
     * Collection系列的集合的遍历:挨个访问集合的元素
     * (1)Object[] toArray():先返回数组,然后遍历数组
     * (2)迭代器设计模式
     * 每一个Collection系列的集合,内部都自带一个迭代器,类似于,每一趟公交车上都有自己的售票员
     * 
     * java.util.Iterator:接口
     *      它是所有售票员的标准接口。
     *  (1)判断是否还有下一个元素:hasNext()
     *  (2)访问它的下一个元素:next()
     *  (3)请下一个元素下车:remove()
     *  
     *  java.util.Iterator:迭代器接口,这个接口的实现类在每一种集合类中,例如:ArrayList内部有一个内部类实现了Iterator接口
     *  这里声明为内部类有两个原因:
     *  (1)每一种集合的内部实现(物理结构不同),意味着对迭代器(售票员)的实现是不同的,每一种集合都要单独定制迭代器
     *  (2)内部类可以直接访问外部类的私有的属性,成员,迭代器就可以直接访问集合的私有的元素。
     *  
     *  (3)foreach:增强for循环
     *  foreach循环可以用于遍历数组、Collection系列的集合等容器。
     *  语法结构:
     *  for(元素的类型  元素临时名称  :  数组和集合名){
     *  
     *  }
     *  
     *  不同于普通for循环。
     *  for(int i=0; i<5; i++){
     *  }
     *  什么样集合或容器类型可以使用foreach循环?
     *  凡是实现了java.lang.Iterable接口(可迭代)的集合或容器都支持foreach循环
     *  
     *  foreach底层还是调用Iterator迭代器来遍历集合。
     */
    public class TestIterator {
        @SuppressWarnings("all")
        @Test
        public void test5(){
            //自己写的动态数组
            MyArrayList list = new MyArrayList();
            list.add("张三");
            list.add("李四");
            list.add("王五");
            
            for (Object obj : list) {
                System.out.println(obj);
            }
        }
        
        @SuppressWarnings("all")
        @Test
        public void test4(){
            String[] arr = {"hello","world","java"};
            for (String string : arr) {
                System.out.println(string);
            }
        }
        
        @SuppressWarnings("all")
        @Test
        public void test3(){
            Collection c = new ArrayList();//ArrayList是Collection下面的一个实现类而已
            c.add("张三");
            c.add("李四");
            c.add("王五");
            
            //Object:元素的数据类型
            //obj:临时的元素名称
            //c:要遍历的集合的名称
            for (Object obj : c) {
                System.out.println(obj);
            }
        }
        
        @SuppressWarnings("all")
        @Test
        public void test2(){
            Collection c = new ArrayList();//ArrayList是Collection下面的一个实现类而已
            c.add("张三");
            c.add("李四");
            c.add("王五");
            
            //返回这个集合自带的迭代器对象,相当于你找到了售票员
            //让售票员去挨个的访问元素
            Iterator iterator = c.iterator();
            while(iterator.hasNext()){
                String obj = (String) iterator.next();
                //要姓“王”下车
                if(obj.startsWith("王")){
                    iterator.remove();
                }
            }
            
            System.out.println(c);
        }
        
        
        @SuppressWarnings("all")
        @Test
        public void test1(){
            Collection c = new ArrayList();//ArrayList是Collection下面的一个实现类而已
            c.add("张三");
            c.add("李四");
            c.add("王五");
            
            //返回这个集合自带的迭代器对象,相当于你找到了售票员
            //让售票员去挨个的访问元素
            Iterator iterator = c.iterator();
            while(iterator.hasNext()){
                Object obj = iterator.next();
                System.out.println(obj);
            }
        }
    }
    package com.atguigu.test05;
    
    import java.util.Arrays;
    import java.util.Iterator;
    
    /*
     * MyArrayList我们自己设计的一种数据结构,一种逻辑结构,当别人用我这个MyArrayList的对象时,就是一个容器对象,
     * 可以用来装对象。
     */
    public class MyArrayList implements Iterable{
        //为什么使用Object,因为只是说这个容器是用来装对象的,但是不知道用来装什么对象。
        private Object[] data;
        private int total;
        
        public MyArrayList(){
            data = new Object[5];
        }
        
        //添加一个元素
        public void add(Object obj){
            //检查是否需要扩容
            checkCapacity();
            data[total++] = obj;
        }
    
        private void checkCapacity() {
            //如果data满了,就扩容为原来的2倍
            if(total >= data.length){
                data = Arrays.copyOf(data, data.length*2);
            }
        }
        
        //返回实际元素的个数
        public int size(){
            return total;
        }
        
        //返回数组的实际容量
        public int capacity(){
            return data.length;
        }
        
        //获取[index]位置的元素
        public Object get(int index){
            //校验index的合理性范围
            checkIndex(index);
            return data[index];
        }
    
        private void checkIndex(int index) {
            if(index<0 || index>=total){
                throw new RuntimeException(index+"对应位置的元素不存在");
    //            throw new IndexOutOfBoundsException(index+"越界");
            }
        }
        
        //替换[index]位置的元素
        public void set(int index, Object value){
            //校验index的合理性范围
            checkIndex(index);
            
            data[index] = value;
        }
        
        //在[index]位置插入一个元素value
        public void insert(int index, Object value){
            /*
             * (1)考虑下标的合理性
             * (2)总长度是否够
             * (3)[index]以及后面的元素往后移动,把[index]位置腾出来
             * (4)data[index]=value  放入新元素
             * (5)total++  有效元素的个数增加
             */
            
            //(1)考虑下标的合理性:校验index的合理性范围
            checkIndex(index);
            
            //(2)总长度是否够:检查是否需要扩容
            checkCapacity();
            
            //(3)[index]以及后面的元素往后移动,把[index]位置腾出来
            /*
             * 假设total = 5, data.length= 10, index= 1
             * 有效元素的下标[0,4]
             * 移动:[1]->[2],[2]->[3],[3]->[4],[4]->[5]
             * 移动元素的个数:total-index
             */
            System.arraycopy(data, index, data, index+1, total-index);
            
            //(4)data[index]=value  放入新元素
            data[index] = value;
            
            //(5)total++  有效元素的个数增加
            total++;
        }
        
        //返回所有实际存储的元素
        public Object[] getAll(){
            //返回total个
            return Arrays.copyOf(data, total);
        }
        
        //删除[index]位置的元素
        public void remove(int index){
            /*
             * (1)校验index的合理性范围
             * (2)移动元素,把[index+1]以及后面的元素往前移动
             * (3)把data[total-1]=null  让垃圾回收器尽快回收
             * (4)总元素个数减少 total--
             */
            
            //(1)考虑下标的合理性:校验index的合理性范围
            checkIndex(index);
            
            //(2)移动元素,把[index+1]以及后面的元素往前移动
            /*
             * 假设total=8, data.length=10, index = 3
             * 有效元素的范围[0,7]
             * 移动:[4]->[3],[5]->[4],[6]->[5],[7]->[6]
             * 移动了4个:total-index-1
             */
            System.arraycopy(data, index+1, data, index, total-index-1);
            
            //(3)把data[total-1]=null  让垃圾回收器尽快回收
            data[total-1] = null;
            
    //        (4)总元素个数减少 total--
            total--;
        }
        
        //查询某个元素的下标
    /*    public int indexOf(Object obj){
            for (int i = 0; i < total; i++) {
            //这两种写法都有风险
                if(obj.equals(data[i])){
                    //if(data[i].equals(obj)){
                    return i;//找到,返回第一个找到的
                }
            }
            return -1;//没找到返回-1
        }*/
        
        //查询某个元素的下标
        public int indexOf(Object obj){
            if(obj == null){
                for (int i = 0; i < total; i++) {
                    if(data[i] == null){//等价于 if(data[i] == obj)
                        return i;
                    }
                }
            }else{
                for (int i = 0; i < data.length; i++) {
                    if(obj.equals(data[i])){
                        return i;
                    }
                }
            }
            return -1;
        }
        
        //删除数组中的某个元素
        //如果有重复的,只删除第一个
        public void remove(Object obj){
            /*
             * (1)先查询obj的[index]
             * (2)如果存在,就调用remove(index)删除就可以
             */
            
            //(1)先查询obj的[index]
            int index = indexOf(obj);
            
            if(index != -1){
                remove(index);
            }
            //不存在,可以什么也不做
            //不存在,也可以抛异常
            //throw new RuntimeException(obj + "不存在");
        }
        
        public void set(Object old, Object value){
            /*
             * (1)查询old的[index]
             * (2)如果存在,就调用set(index, value)
             */
            
    //        (1)查询old的[index]
            int index = indexOf(old);
            if(index!=-1){
                set(index, value);
            }
            
            //不存在,可以什么也不做
            //不存在,也可以抛异常
            //throw new RuntimeException(old + "不存在");
        }
    
        @Override
        public Iterator iterator() {
            return new MyItr();
        }
        
        private class MyItr implements Iterator{
            private int cursor;//游标
    
            @Override
            public boolean hasNext() {
                System.out.println("还有下一个");
                return cursor!=total;
            }
    
            @Override
            public Object next() {
                System.out.println("拿到下一个");
                return data[cursor++];
            }
            
        }
    }
  • 相关阅读:
    jdk1.5线程知识列表
    linux 常用命令记录
    spring batch 编码问题
    maven
    统计文本中每个单词出现的次数
    生成优惠券,并将优惠券存入Mysql
    python 2.7版本解决TypeError: 'encoding' is an invalid keyword argument for this function
    CSRF verification failed. Request aborted. 表单提交方法为POST时的报错
    InsecureRequestWarning: Unverified HTTPS request is being made.解决方法
    SQL Server 打印九九乘法表
  • 原文地址:https://www.cnblogs.com/douyunpeng/p/13708051.html
Copyright © 2011-2022 走看看