1. 程式人生 > 實用技巧 >2020年9月21日 Collection系列集合的遍歷三種方式

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++];
        }
        
    }
}