java-增强for循环(foreach)
增强for循环(foreach)
首先定义一个Stu类:
class Stu{
String name;
public Stu(String name) {
this.name = name;
}
@Override
public String toString() {
return "Stu{" +
"name='" + name + '\'' +
'}';
}
}
写些代码测试下:
public class foreachDemo {
public static void main(String[] args) {
//1.遍历数组
int[] arr = {2,3,4,5,6};
for (int i : arr) {
System.out.println(i);
}
//2.遍历对象
ArrayList<Stu> stus = new ArrayList<>();
stus.add(new Stu("a"));
stus.add(new Stu("b"));
for (Stu stu : stus) {
System.out.println(stu.toString());
}
}
}
编译出来对应的字节码文件:
public static void main(String args[])
{
int arr[] = {
2, 3, 4, 5, 6
};
int ai[] = arr;
int j = ai.length;
for (int k = 0; k < j; k++)
{
int i = ai[k];
System.out.println(i);
}
ArrayList stus = new ArrayList();
stus.add(new Stu("a"));
stus.add(new Stu("b"));
Stu stu;
for (Iterator iterator = stus.iterator(); iterator.hasNext(); System.out.println(stu.toString()))
stu = (Stu)iterator.next();
}
有关结论
可以看到,当遍历基本数据类型时底层实现是数组,而遍历引用类型时(包括包装类)底层实现是Iterator迭代器。虽然基本数据类型底层实现是数组,但是同样在使用的时候不能使用下标去访问元素。
最好不要在遍历的时候去删除元素,从遍历对象的字节码文件中可以看到,它是先实例化了一个新的对象,再把对象赋值给这个对象,
要是用集合的方式去删除这个元素,无法删除原集合元素。强行用集合删除可能出现并发修改异常,但是可以用Iterator提供的remove()
方法去删除
(见源码分析)。在你写上去的时候IDEA也会提示不要有删除操作。
Iterator迭代器源码分析
送上源码:
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
public boolean hasNext() {
return cursor != size;
}
public E next() {
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
//删除了不影响理解的多余源码
}