1.List集合的特殊方法
List接口是Collection接口的子接口,提供了一系列操作元素的方法。 常见的List集合实现类有ArrayList和LinkedList。ArrayList我们在前面已经介绍过了,这一章中着重介绍一下List集合的特有方法。
java
List<String> list = new ArrayList<>();
list.add("hello");
list.add("java");
list.add("world");
list.add(3,"hahaha"); //通过索引增加元素
System.out.println(list.remove(3)); //通过索引移除元素,并返回被移除的元素
System.out.println(list.set(1,"c++")); //用set函数通过索引修改元素,并返回修改前的元素
System.out.println(list.get(2)); //用get函数通过索引获取元素,并返回获取到元素的值
System.out.println(list);
1.增加元素
list.add(index,element) 方法增加元素
2.删除元素
list.remove(index)
3.修改元素
list.set(index,element)
4.获取元素
list.get(index)
2.遍历元素
1.for循环遍历
java
List<String> list = new ArrayList<>();
list.add("hello");
list.add("java");
list.add("world");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
2.foreach遍历
java
List<String> list = new ArrayList<>();
list.add("hello");
list.add("java");
list.add("world");
//法二foreach
for (String li :
list) {
System.out.println(li);
}
3.迭代器
java
List<String> list = new ArrayList<>();
list.add("hello");
list.add("java");
list.add("world");
Iterator<String> it = list.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
该代码段使用ArrayList和Iterator来遍历列表中的元素并打印出来。 首先,代码创建了一个ArrayList对象,并向其中添加了三个字符串元素("hello","java"和"world")。 然后,通过调用list的iterator()方法获取一个Iterator对象。Iterator是一个接口,用于遍历集合中的元素。 接下来,使用while循环和Iterator的hasNext()方法来检查是否还有下一个元素可遍历。 在循环的每次迭代中,使用Iterator的next()方法获取下一个元素,并将其打印出来。 最终,循环结束后,所有元素都被遍历并打印出来。输出结果为: hello java world
4.stream流
java
List<String> list = new ArrayList<>();
list.add("hello");
list.add("java");
list.add("world");
list.stream().forEach(System.out::println);
通过调用list的stream()方法获取一个流(Stream)对象。流是Java 8中引入的一种处理集合数据的方式。 接下来,使用Stream的forEach()方法来迭代每个元素,并使用System.out::println方法引用来打印每个元素。 最终,所有元素都被遍历并打印出来。输出结果为: hello java world
5.lambda表达式
java
List<String> list = new ArrayList<>();
list.add("hello");
list.add("java");
list.add("world");
list.forEach(System.out::println);
使用List的forEach()方法来循环遍历列表中的每个元素。 在forEach()方法中,我们使用System.out::println方法引用来打印每个元素。 最终,所有元素都被遍历并打印出来。输出结果为: hello java world
3.listIterator迭代器
与普通迭代器Iterator相比,listIterator提供了更多的功能。它可以向前和向后遍历集合中的元素,还可以修改集合中的元素,以及获取当前元素的索引。
java
List<String> list = new ArrayList<>();
list.add("JavaSE");
list.add("MYSQL");
list.add("JavaWeb");
list.add("JavaEE");
ListIterator<String> lt = list.listIterator();
while (lt.hasNext()){ //正向遍历
System.out.println(lt.next());
}
while (lt.hasPrevious()){
System.out.println(lt.next()); //逆向遍历
}
4. 并发性修改异常
并发性修改异常(ConcurrentModificationException)是Java集合框架中的一种异常,表示在迭代器遍历集合元素时,发生了结构性修改。结构性修改指的是改变集合大小或使迭代器失效的操作,如添加、删除或修改元素。
在Java集合框架中,有一些迭代器是通过快速失败机制实现的。这意味着如果在迭代器遍历集合期间进行了结构性修改,会立即抛出ConcurrentModificationException异常,而不是继续遍历。这是为了避免在并发环境下可能出现的不一致性和数据损坏。
例: 在一组列表里增加元素
java
List<String> list = new ArrayList<>();
list.add("JavaSE");
list.add("MYSQL");
list.add("JavaWeb");
list.add("JavaEE");
Iterator<String> it = list.iterator();
while(it.hasNext()){
String str = it.next();
if("MYSQL".equals(str)){
System.out.println("..........");
list.add("JDBC");
}
}
这段代码创建了一个字符串类型的ArrayList,并向其中添加了四个元素。接着,通过iterator()方法获取了该ArrayList的迭代器对象,并使用while循环遍历迭代器。
在循环中,首先使用hasNext()方法检查是否还有下一个元素,然后使用next()方法获取下一个元素。如果当前元素的值等于"MYSQL",则会打印出".........."。接着,在if条件中,代码尝试往列表中添加一个新元素"JDBC"。
然而,由于在迭代器遍历过程中对列表进行了结构性修改(添加元素),根据快速失败机制,会抛出ConcurrentModificationException异常。这是因为在这个案例中,通过迭代器遍历列表,而在遍历过程中修改了列表的结构。
解决该异常我们可以使用for循环,实现元素的添加
java
List<String> list = new ArrayList<>();
list.add("JavaSE");
list.add("MYSQL");
list.add("JavaWeb");
list.add("JavaEE");
for (int i = 0; i < list.size(); i++) {
if ("MYSQL".equals(list.get(i))){
list.add("JDBC");
}
}
System.out.println(list);
在循环中,首先通过list.get(i)获取索引为i的元素,然后判断是否等于"MYSQL"。如果相等,则在列表末尾添加一个新元素"JDBC"
还可以使用listIterator来解决
java
List<String> list = new ArrayList<>();
list.add("JavaSE");
list.add("MYSQL");
list.add("JavaWeb");
list.add("JavaEE");
ListIterator<String> lt = list.listIterator();
while (lt.hasNext()){
String str = lt.next();
if ("MYSQL".equals(str)){
lt.add("JDBC");
}
}
System.out.println(list);
在迭代器的循环中,首先通过lt.next()方法获取下一个元素,然后判断是否等于"MYSQL"。如果相等,则使用lt.add("JDBC")方法在当前元素之前插入一个新元素"JDBC"。
在这种情况下,迭代器的添加操作不会影响迭代的继续进行,并且不会引发ConcurrentModificationException异常。迭代器内部会自动处理这种并发性修改。
最后,打印输出列表的内容。由于使用迭代器进行了元素的插入操作,因此列表中会包含"JDBC"这个新元素。结果会输出修改后的列表内容。
5.LinkedList
LinkedList集合是Java中的一种实现了List接口的链表数据结构。它是由一个个节点组成的,每个节点都包含一个值和指向下一个节点的引用。
与ArrayList不同,LinkedList内部的数据结构是一个双向链表,每个节点既有指向下一个节点的引用,也有指向前一个节点的引用。这使得在LinkedList中插入、删除元素时的操作非常高效,因为只需要修改相邻节点的引用即可,而不需要移动其他元素。
LinkedList集合支持动态的增加或删除元素,因为它不需要连续的内存分配。由于链表的特性,LinkedList对于在列表的开头或结尾插入或删除元素效率较高,但对于通过索引访问元素的效率较低。如果需要频繁地使用索引来访问元素,建议使用ArrayList。
LinkedList还实现了Deque接口,因此它可以被当作双端队列来使用,支持在队列的两端进行插入、删除操作。
总之,LinkedList集合提供了一种灵活的、高效的链表数据结构,适用于需要频繁进行插入、删除操作的场景,但在索引访问方面的性能稍逊于ArrayList。
java
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
java
public class StuShow {
public static void main(String[] args) {
LinkedList<Student> stuList = new LinkedList<>();
stuList.add(new Student("Jack",19));
stuList.add(new Student("Kite",14));
stuList.add(new Student("bill",15));
stuList.add(new Student("lily",18));
for (int i = 0; i < stuList.size(); i++) {
System.out.println("姓名"+stuList.get(i).getName()+"年龄"+stuList.get(i).getAge());
}
for (Student stu : stuList) {
System.out.println("姓名"+stu.getName()+"年龄"+stu.getAge());
}
ListIterator<Student> it = stuList.listIterator();
while(it.hasNext()){
Student stu = it.next();
System.out.println("姓名"+stu.getName()+"年龄"+stu.getAge());
}
}
}
这段代码是一个示例,展示了如何使用LinkedList集合存储和遍历Student对象。
首先,在main方法中创建了一个LinkedList对象stuList,用于存储Student对象。然后,通过stuList.add方法依次添加了4个Student对象到集合中,每个对象包含姓名和年龄信息。
接下来,通过两种方式进行遍历集合中的元素。第一种方式是使用for循环和索引,通过stuList.size()方法获取集合的大小,使用get方法获取指定索引位置的Student对象,然后通过getName和getAge方法获取对象的姓名和年龄,并打印出来。
第二种方式是使用增强for循环,直接遍历stuList中的每个Student对象,并通过getName和getAge方法获取对象的姓名和年龄,并打印出来。
第三种方式通过ListIterator迭代器来遍历集合中的元素。首先,通过stuList.listIterator()方法获取ListIterator对象,然后使用while循环和it.hasNext()方法判断是否有下一个元素,如果有则通过it.next()方法获取下一个Student对象,再通过getName和getAge方法获取对象的姓名和年龄,并打印出来。
这段代码展示了LinkedList集合的常见用法,包括添加、遍历、获取元素等操作。