问题引入(使用普通的foreach语句进行循环可能会少删除一些内容)
package com.example20.collection;
public class User {
public static final String HAERBIN = "哈尔滨";
public static final String BEIJING = "北京";
private int id;
private String name;
private String city;
public User() {
}
public User(String name) {
this.name = name;
}
public User(int id, String name, String city) {
this.id = id;
this.name = name;
this.city = city;
}
public int getId() {
return id;
}
public String getCity() {
return city;
}
public void setId(int id) {
this.id = id;
}
public void setCity(String city) {
this.city = city;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
创建的USERS常量
private static final List<User> USERS = create();
private static List<User> creat(){
User user1 = new User("BO");
User user2 = new User("SUN");
User user3 = new User("SUN");
List<user> users = new ArrayList<>();
users.add(user1);
users.add(user2);
users.add(user3);
return users;
}
//USERS内存在两个SUN那么下面的程序运行结束之后只会删除最后一个
for(int i = 0;i < USERS.size();i++){
if("SUN".equals(USERS.get(i).getName())){
USERS.remove(i)
}
}
//因为在查到第一个SUN的时候进行一次remove后整体的长度都变了,第二个SUN没有被遍历到就结束了
Iterator接口
1,的位置:java.util.Iterator
2,功能:迭代器,允许遍历集合,并根据需求选择性的从集合中移除元素
3,具体实现
(1)对于不同的集合类型的不同数据结构的实现类,存在不同的迭代器实现
(2)对于程序员而言,只需面向Iterator接口完成遍历与移除即可
(3)Iterator iterator()方法,Collection接口方法,获取集合对象的迭代器
4,实现方法
(1)Iterator通过移动游标遍历集合,初始时,游标位于第一个元素前
(2)boolean hasnext(), //Iterator中是否有下一个元素
(3)E next() 向后移动游标,同时返回游标指向的元素
Iterator<User> iUsers = USERS.iterator();
while(iUsers.hasNext()){
User u = iUsers.next();
System.out.println(u.getName());
}
Iterator<User> iUsers = USERS.iterator();
//获取iterator迭代器对象
while(iUsers.hasNext()){ //进行循环判断
User u = iUsers.next(); //获取元素对象
//进行字符串判断
if("SUN".equals(u.getName())){
//使用remove方法删除迭代器当前游标指向的元素
iUsers.remove();
}
}
在后续的学习中上面所写的这个循环遍历检索删除的操作可以优化为
USERS.removeIf(u -> "SUN".equals(u.getName()));
对于ArrayList源码的解析
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;
// prevent creating a synthetic constructor
Itr() {}
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
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();
checkForComodification();
try {
//移除ArrayList当前的对象的最后一个元素
ArrayList.this.remove(lastRet);
//上面next()方法中我们已经将游标进行了加一操作
//因为我们删除了一个元素,所以我们应该将这个已经加上去的右边变成当前游标
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}