企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
## Java专题五:遍历与迭代 [TOC] ### 5.1.for loop 最常使用的遍历元素方法,同时可以访问任意位置的元素,如数组中的a[5] ```java for (int i=0; i<10; i++){ // do something } ``` ### 5.2.break、continue跳出循环 相当于c语言中goto语句,通常用在循环前面,如下面的`retry:` **break retry**: 跳出外层循环,直接结束 **continue retry** : 跳出内层循环,进行下一轮循环 ```java // #ThreadPoolExecutor#addWorker(Runnable firstTask, boolean core) retry: for (;;) { int c = ctl.get(); int rs = runStateOf(c); // Check if queue empty only if necessary. if (rs >= SHUTDOWN && ! (rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty())) return false; for (;;) { int wc = workerCountOf(c); if (wc >= CAPACITY || wc >= (core ? corePoolSize : maximumPoolSize)) return false; if (compareAndIncrementWorkerCount(c)) break retry; c = ctl.get(); // Re-read ctl if (runStateOf(c) != rs) continue retry; // else CAS failed due to workerCount change; retry inner loop } } ``` ### 5.3.for-each loop 在Java中能使用for-each语法包括三种情况: - 数组 - Collection子类 - 自定义类 后2种情况,类必须**实现Iterable接口**。 之所以集合框架中Collection的子类能使用for-each语法对集合元素进行遍历,是因为Collection接口继承了Iterable接口`public interface Collection<E> extends Iterable<E>`,并在其子类如ArrayList,Vector等集合类中实现了`iterator()`方法。 **在ArrayList**中就实现了`iterator()`方法: ```java public Iterator<E> iterator() { return new Itr(); } private class Itr implements Iterator<E> { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount; Itr() {} public boolean hasNext() { return cursor != size; } public E next() { // ... } public void remove() { // ... } } ``` **在HashMap**中,因为HashMap既不是Collection的子类,也没有实现Iterable接口,选择了一种迂回方法,先通过`Set<Map.Entry<K,V>> entrySet()`方法将HashMap转换成可迭代的接口集合,在转换后的EntrySet中实现实现了`iterator()`方法,同时其元素类型变为为`HashMap.Entry`。 ```java public Set<Map.Entry<K,V>> entrySet() { Set<Map.Entry<K,V>> es; return (es = entrySet) == null ? (entrySet = new EntrySet()) : es; } final class EntrySet extends AbstractSet<Map.Entry<K,V>> { public final Iterator<Map.Entry<K,V>> iterator() { return new EntryIterator(); } // ... } final class EntryIterator extends HashIterator implements Iterator<Map.Entry<K,V>> { public final Map.Entry<K,V> next() { return nextNode(); } } ``` for-each loop语法如下: ```java for (E e: iterable){ // do something with element of subclass of iterable interface. } ``` ### 5.4.Iterable接口 ```java public interface Iterable<T> { Iterator<T> iterator(); } ``` ### 5.5.Iterator迭代器 类在实现Iterable接口时,必须定义一个实现Iterator接口的内部类。比如前面提到的ArrayList中`Itr`就是`Iterable`接口实现类,然后根据类中的数据结构(在ArrayList中的就是数组)重写`hasNext()`和`next()`方法。 ```java public interface Iterator<E> { boolean hasNext(); E next(); default void remove() { throw new UnsupportedOperationException("remove"); } } ``` 常见的Iterator迭代用法: - list和set集合(ArrayList、HashSet等): ```java for (Iterator it = list.iterator(); it.hasNext();) { System.out.println(it.next()); } Iterator it = list.iterator(); while(it.hasNext()){ System.out.println(it.next()); } ``` - map集合(HashMap、HashSet等): ```java for (Iterator it = map.iterator(); it.hasNext();) { System.out.println(it.next().getKey()); System.out.println(it.next().getValue()); } Iterator it = map.iterator(); while(it.hasNext()){ System.out.println(it.next().getKey()); System.out.println(it.next().getValue()); } ``` ### 5.6.Enumeration接口 与Iterator接口功能重复,在设计类时应该优先考虑Iterator接口,因为Iterator接口有更短命名的方法,还增加了remove方法。 ```java public interface Enumeration<E> { boolean hasMoreElements(); E nextElement(); } ``` **在Hashtable**中使用,也是定义一个实现Enumeration接口的内部类,实现`hasMoreElements()`和`nextElement()`方法。 ```java public synchronized Enumeration<V> elements() { return this.<V>getEnumeration(VALUES); } private <T> Enumeration<T> getEnumeration(int type) { if (count == 0) { return Collections.emptyEnumeration(); } else { return new Enumerator<>(type, false); } } private class Enumerator<T> implements Enumeration<T>, Iterator<T> { Entry<?,?>[] table = Hashtable.this.table; int index = table.length; Entry<?,?> entry; Entry<?,?> lastReturned; int type; boolean iterator; protected int expectedModCount = modCount; Enumerator(int type, boolean iterator) { this.type = type; this.iterator = iterator; } public boolean hasMoreElements() { // ... } public T nextElement() { // ... } // Iterator methods public boolean hasNext() { return hasMoreElements(); } public T next() { return nextElement(); } public void remove() { // ... } } ```