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