Java面试ArrayList的两大陷阱
- ArrayList面试两大陷阱:
- 一边遍历一边删除
用for循环 一边遍历一边删除 会导致删除不干净 或者索引越界异常 - 数组转换成集合
默认是Arrays里面的内部类 不支持增加或者删除元素 需要转换
- 一边遍历一边删除
public static void main(String[] args) {
//数组转化为集合 (一般都是其他类型数组,不是基本数据类型数组)
String[] strings = {"hehe0","hehe1","hehe2","hehe3"};
//数组转换为集合
//转换过来的是一个高仿的ArrayList不支持增加或删除元素
List<String> list = Arrays.asList(strings);
//System.out.println(list);
//list.add("hehe");//UnsupportedOperationException不支持操作
//list.remove(0);//UnsupportedOperationException
//数组转换成集合 转换过来的集合对象默认不支持任何增加或者移除操作
//转换成为正版的ArrayList
ArrayList<String> arrayList = new ArrayList<>(list);
System.out.println(arrayList);
arrayList.add("made");
System.out.println(arrayList);
System.out.println("-------------------->");
System.out.println(arrayList);
arrayList.remove("made");
System.out.println(arrayList);
}
public static void main3(String[] args) {
//集合转换成数组
List<String> list = new ArrayList<>();
for(int i = 0;i<10;i++){
list.add("hehe"+i);
}
Object[] array = list.toArray();//集合转换为数组(Object)
for(Object object :array){
System.out.println(object);
}
}
public static void main2(String[] args) {
List list = new ArrayList<>();
/*
list.add(new Dog());
//这样并不能移除该Dog对象,因为new Dog()对象时匿名对象。所以两次操作的对象并不是同一个对象
System.out.println(list);
list.remove(new Dog());
System.out.println(list);
//虽然显示的地址是一样的,但这是对象的回收
*/
//包装一下就可以成功移除
Dog d = new Dog();
list.add(d);
System.out.println(list);
list.remove(d);
System.out.println(list);
}
public static void main1(String[] args) {
//一边遍历一边移除
List<String> list = new ArrayList<String>();//<>里面要写大写的数据类型 String Boolean Char等
list.add("呵呵1");
list.add("呵呵2");
list.add("呵呵3");
list.add("呵呵4");
list.add("呵呵5");
// System.out.println("清空之前list元素"+list);
// for(int i = 0;i<list.size();i++){
// System.out.println("-----------------------------");
// System.out.println("移除之前集合的大小:"+list.size());
// System.out.println("本次没移除前集合的所有元素:"+list);
// System.out.println("本次要移除角标为"+i+"的元素!");
// System.out.println("本次要移除的元素是:"+list.remove(i));
// System.out.println("本次移除后所有集合的元素"+list);
// System.out.println("移除之后集合的大小:"+list.size());
// }
// System.out.println("清空之后list元素"+list);
/*
清空之前list元素[呵呵1, 呵呵2, 呵呵3, 呵呵4, 呵呵5]
0 1 2 3 4
-----------------------------
移除之前集合的大小:5
本次没移除前集合的所有元素:[呵呵1, 呵呵2, 呵呵3, 呵呵4, 呵呵5]
0 1 2 3 4
本次要移除角标为0的元素!
本次要移除的元素是:呵呵1
本次移除后所有集合的元素[呵呵2, 呵呵3, 呵呵4, 呵呵5]
0 1 2 3
移除之后集合的大小:4
-----------------------------
移除之后集合的大小:4
本次没移除前集合的所有元素:[呵呵2, 呵呵3, 呵呵4, 呵呵5]
0 1 2 3
本次要移除角标为1的元素!
本次要移除的元素是:呵呵3
本次移除后所有集合的元素[呵呵2, 呵呵4, 呵呵5]
0 1 2
移除之后集合的大小:3
-----------------------------
移除之后集合的大小:3
本次没移除前集合的所有元素:[呵呵2, 呵呵4, 呵呵5]
0 1 2
本次要移除角标为2的元素!
本次要移除的元素是:呵呵5
本次移除后所有集合的元素[呵呵2, 呵呵4]
0 1
移除之后集合的大小:2
这是集合的大小为2,而i的值为3,所以 循环结束
清空之后list元素[呵呵2, 呵呵4]
*/
//改进1
// for(int i = 0;i<5;i++){//这里需要将判断条件写死
// System.out.println("本次移除的元素:"+list.remove(0));
// }
//实际开发遇到的for循环一边遍历一边移除的问题
// System.out.println(list);
// for(int i = 0;i<list.size();i++){
// if(i==1){
// System.out.println("移除元素:"+list.remove(i));
// }
// if(i==3){
// System.out.println("移除元素:"+list.remove(i));
// }
// }
// System.out.println(list);
/*
[呵呵1, 呵呵2, 呵呵3, 呵呵4, 呵呵5]
0 1 2 3 4
1
移除元素:呵呵2
3
移除元素:呵呵5
[呵呵1, 呵呵3, 呵呵4]
0 1 2
*/
//改进2
//迭代器遍历 专门用来一边遍历一边移除
//根据集合对象获取迭代对象根据哪一个集合对象获取的迭代器那么该迭代器就只能遍历哪一个集合
// Iterator<String> iterator = list.iterator();
// //判断有没有下一个元素
// System.out.println(iterator.hasNext());
// //取出下一个元素
// System.out.println(iterator.next());
// System.out.println(iterator.next());
// System.out.println(iterator.next());
// System.out.println(iterator.next());
// System.out.println(iterator.next());
// System.out.println(iterator.next());//NoSuchElementException表示迭代器中没有更多的元素
//循环遍历改进3
/*
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
*/
//循环遍历改进4
/*
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){
if(iterator.next().equals("呵呵3")){
//next()方法执行一次就会往下走一次
System.out.println(iterator.next());//呵呵4
}
}
*/
/*
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){
String string = iterator.next();
if(string.equals("呵呵3")){
System.out.println(string);
}
}
*/
//用迭代器解决一边遍历一边移除的问题
System.out.println(list);
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){
//移除元素
//iterator.remove();//IllegalStateException非法状态异常
//迭代器的移除
//调用remove之前必须先next
iterator.next();
iterator.remove();
//集合的移除
//有问题
//用迭代器遍历时不要调用任何集合的操作元素增加或者删除的方法
//会引起内部指针混乱问题
//String string = iterator.next();
//list.remove(string);//ConcurrentModificationException非法修改
}
System.out.println(list);
}
}
public class Dog {
}