JavaSE|List、ListIterator 怼烎@ 2022-05-14 14:38 202阅读 0赞 ### JavaSE|List、ListIterator ### * List * * 成员方法 * List集合的两种遍历方式 * List 子类特点 * ListIterator * * 特有的成员方法 * ConcurrentModificationException * * 问题产生 * 产生原因 * 解决方法 # List # List是Collection的子接口。特点:有序(存储顺序和取出顺序一致),可重复。此**接口**的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。与 set 不同,列表通常允许重复的元素。 List 特点:**有序**(存储和取出的元素一致,与排序无关),**可重复的**。 ## 成员方法 ## 1. 添加功能 **void add(int index,E element)**:在指定位置添加元素。index**不能大于**size()。 **boolean add(E e)** :是向队尾添加元素。 2. 删除功能 **E remove(int index)**:根据索引删除元素,返回被删除元素。 3. 获取功能 **E get(int index)**:获取指定位置的元素。 List list = new ArrayList(); // 添加元素 list.add("hello"); list.add("world"); list.add("java"); // list集合特有的遍历功能:size()和get()结合使用 for (int x = 0; x < list.size(); x++) { // System.out.println(list.get(x)); String s = (String) list.get(x); System.out.println(s); } 1. 修改功能 **E set(int index,E element)**:根据索引修改元素,返回被修改的元素。 2. 列表迭代器 **ListIterator listIterator()**:List集合特有的迭代器。 ## List集合的两种遍历方式 ## * 传统的Iterator方式 * List的size()和get()方法结合使用 // 创建集合对象 List list = new ArrayList(); // 创建学生对象 Student s1 = new Student("林黛玉", 18); Student s2 = new Student("刘姥姥", 88); Student s3 = new Student("王熙凤", 38); // 把学生添加到集合中 list.add(s1); list.add(s2); list.add(s3); // 遍历 // 迭代器遍历 Iterator it = list.iterator(); while (it.hasNext()) { Student s = (Student) it.next(); System.out.println(s.getName() + "---" + s.getAge()); } System.out.println("--------"); // 普通for循环 for (int x = 0; x < list.size(); x++) { Student s = (Student) list.get(x); System.out.println(s.getName() + "---" + s.getAge()); } ## List 子类特点 ## * ArrayList:底层数据结构是数组,查询快,增删慢;线程不安全,效率高。 * Vector:底层数据结构是数组,查询快,增删慢;线程安全,效率低。 * LinkedList:底层数据结构是链表,查询慢,增删快。 具体使用哪个看需要,首先考虑安全因素(但即使需要线程安全,也不使用Vector),其次考虑查询多还是增删多。如果什么都不知道,就用ArrayList。 # ListIterator # List集合特有的迭代器。该迭代器继承了Iterator迭代器,所以,就可以直接使用hasNext()和next()方法。 ## 特有的成员方法 ## **1. Object previous()** 获取上一个元素。 **2. boolean hasPrevious()** 判断是否有元素。 通过上面两个方法,ListIterator可以实现逆向遍历,但是必须先正向遍历,才能逆向遍历,**所以一般无意义,不使用。** **3. void add(E e)** 将指定的元素插入列表(可选操作)。该元素直接插入到 **next 返回的下一个元素的前面**(如果有),或者 **previous 返回的下一个元素之后**(如果有);如果列表没有元素,那么新元素就成为列表中的唯一元素。 // 创建List集合对象 List list = new ArrayList(); list.add("hello"); list.add("world"); list.add("java"); // ListIterator listIterator() ListIterator lit = list.listIterator(); // 子类对象 while (lit.hasNext()) { String s = (String) lit.next(); System.out.println(s); } System.out.println("-----------------"); while (lit.hasPrevious()) { String s = (String) lit.previous(); System.out.println(s); } System.out.println("-----------------"); ## ConcurrentModificationException ## ### 问题产生 ### Q:我有一个集合,如下,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现。 A:代码实现如下: // 创建List集合对象 List list = new ArrayList(); // 添加元素 list.add("hello"); list.add("world"); list.add("java"); // 迭代器遍历 Iterator it = list.iterator(); while (it.hasNext()) { String s = (String) it.next(); if ("world".equals(s)) { list.add("javaee"); } } 上面代码报错:ConcurrentModificationException ### 产生原因 ### 迭代器是**依赖于**集合而存在的,在判断成功后,集合的中新添加了元素,而**迭代器却不知道**,所以就报错了,这个错叫**并发修改异常**。 其实这个问题描述的是:**迭代器遍历元素的时候,通过集合是不能修改元素的**。 ### 解决方法 ### * 法一:迭代器迭代元素,迭代器修改元素(ListIterator) 元素添加在刚才迭代的位置。 List list = new ArrayList(); list.add("hello"); list.add("world"); list.add("java"); ListIterator lit = list.listIterator(); while(lit.hasNext()) { String s = (String) lit.next(); if ("world".equals(s)) { lit.add("javaee"); } } System.out.println("list:" + list); // list:[hello, world, javaee, java] 上面代码发现javaee插入在world后面,而不是想象中的list尾部。这是由ListIterator的void add(E e)方法的性质决定的。 * 法二:集合遍历元素,集合修改元素(List的size()和get()方法) 元素添加在集合的末尾。 List list = new ArrayList(); list.add("hello"); list.add("world"); list.add("java"); for(int x = 0; x < list.size(); x++){ String s = (String) list.get(x); if ("world".equals(s)) { list.add("javaee"); } } System.out.println("list:" + list); // list:[hello, world, java, javaee]
还没有评论,来说两句吧...