List
interface List<E> extends Collection<E>
一个有序集合也成为序列,每一个元素被插入的位置有精确的控制。
List是一个接口,ArrayList和LinkedList实现了List
List代表的是“线性表”,ArrayList代表的是“顺序表”,LinkedList代表的是“链表”
用户可以通过它们的正数索引(在列表中的位置)访问元素,并在列表中搜索元素。
List常用方法:
方法签名 | 功能描述 |
boolean add(E e) | 将e尾插到线性表中 |
void add(int index,E e) | 将e插入到index所在位置,index之后的所有元素,“逻辑”向后移动 |
E remove(int index) | 删除index位置的元素,后续元素左移,返回从列表中删除的元素 |
boolean remove(Object o) | 删除第一个遇到的o元素(本质上使用equals进行比较) |
int size() | 元素个数 |
E get(int index) | 返回index位置的元素 |
E set(int index ,E e) | 用 e 替换index 位置的元素 |
void clear() | 清空线性表 |
boolean isEmpty() | 判断线性表是否为空 |
boolean contains(Object o) | 判断o是否在线性表中("equals") |
int indexOf(Object o) | 返回出现的第一个o所在的下标("equals") |
int lastIndexOf(Object o) | 返回最后一个o的坐标("equals") |
List<E> subList(int fromIndex ,int toIndex) | 截取部分List [fromIndex,toindex) |
void sort(Comparator<? super E > c) | 对线性表进行排序,以传入的比较器进行元素的比较 |
boolean equals(Object o) | 判断两个线性表是否相等 |
Iterator<E> iterator() | 返回迭代器,进行从前往后的遍历 |
ListIterator<E> listIterator() | 返回列表的迭代器(按照适当的顺序) |
ListIterator<E> listIterator(int index) | 从指定位置开始,返回列表中的元素(按照正确的顺序)的迭代器 |
Object[] toArray() | 返回一个数组,包含线性表的所有元素 |
代码示例:
public class ListMethodsDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("World");
list.add("正在");
list.add("学习");
list.add("Java");
System.out.println(list);
//尾插
list.add("OK?");
System.out.println(list);
//在2号下标位置插入,后续元素逻辑后移
list.add(2,"我");
System.out.println(list);
//remove
boolean remove = list.remove("OK?");//删除第一个遇到的o元素
System.out.println(remove);
System.out.println(list);
//size
System.out.println(list.size());
//get
System.out.println(list.get(1));
//set
list.set(0,"Hi");
System.out.println(list);
//清空线性表
// list.clear();
System.out.println(list);
//判断list是否为空
boolean listEmpty = list.isEmpty();
System.out.println(listEmpty);
//contains
System.out.println(list.contains("学习"));//true
System.out.println(list.contains("我是"));//false
//indexOf
System.out.println(list.indexOf("我"));//2
//如果线性表中不存在就返回-1
System.out.println(list.indexOf("我是"));//-1
//lastIndexOf
System.out.println(list.lastIndexOf("我"));//2
System.out.println(list.lastIndexOf("我是"));//-1
//subList
//[1,4)
System.out.println(list.subList(1, 4));//[World, 我, 正在]
System.out.println(list);//截取之后,list不会发生改变
//sort,必须传入比较器进行排序
List<Integer> list1 = new ArrayList<>();
list1.add(1);
list1.add(6);
list1.add(4);
list1.add(9);
list1.add(5);
list1.add(2);
System.out.println(list1);
list1.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
//隐含着自动拆箱
//return o1.intValue()-o2.intValue();
return o1-o2;//升序
//return o2-o1;//降序
}
});
System.out.println(list1);
//equals方法
List<Integer> list2 = new ArrayList<>();
list2.add(1);
list2.add(6);
list2.add(4);
System.out.println(list1.equals(list2));//false
//iterator
Iterator<Integer> iterator = list1 .iterator();
while (iterator.hasNext()){//被调用6次
System.out.println(iterator.next());//next被调用5次
}
List<String> list3 = new ArrayList<>();
list3.add("A");
list3.add("B");
list3.add("C");
list3.add("D");
//toArray
Object[] objects = list3.toArray();
for (Object o :objects){
String s = (String) o;
System.out.println(s);
}
//toArray(new Object[0]) 和 toArray()是相同的功能
String[] strings = list3.toArray(new String[0]);
System.out.println(Arrays.toString(strings));
}
}
contains,indexOf,lastIndexOf 本质上调用的是equals方法:
代码示例:
class Person{
int id;
String name;
public Person(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (obj == null){
return false;
}
if (obj == this){
return true;
}
if (!(obj instanceof Person)){
return false;
}
Person p = (Person) obj;
//引用的比较使用的是equals,基本类型的比较使用的是==
return id == p.id;
}
}
public class ListEquals {
public static void main(String[] args) {
Person p1 = new Person(1,"小王");
Person p2 = new Person(1,"小王");
Person p3 = new Person(2,"小李");
List<Person> list1 = new ArrayList<>();
list1.add(p1);
/**
* 没有重写equals
*/
System.out.println(list1.contains(p1));//true
System.out.println(list1.contains(p2));//false
System.out.println(list1.indexOf(p2));//-1
System.out.println(list1.lastIndexOf(p2));//-1
System.out.println(list1.contains(p3));//false
/**
* 重写equals后
*/
List<Person> personList = new ArrayList<>();
Person person1 = new Person(1,"张三");
Person person2 = new Person(1,"李四");
personList.add(person1);
System.out.println(person1.equals(person2));//true
//contains,indexOf,lastIndexOf方法本质上都使用的是equals方法进行比较
//由于上面复写了equals,equals返回true,contains就会返回true
//和name没有关系,由于复写的equals只比较了id,只要id相等,就会返回true
System.out.println(personList.contains(person2));//true
System.out.println(personList.indexOf(person2));//0
}
}
iterator方法的使用,以及Iterable和Iterator:
Iterable(具有迭代能力)和Iterator(迭代器)都是接口。
如果一个类实现了Iterable接口,则表示这个类具有迭代的能力;
该类通过返回一个迭代器(Iterator),可以通过这个迭代器进行容器内的元素的迭代。
forEach本质上就是通过迭代器实现的,凡是支持Iterable能力的容器,都可以使用forEach。
同时存在多个迭代器时,迭代器之间是相互独立的
forEach遍历的同时,不能修改的线性表的结构;如果需要删除,需要使用迭代器来实现。
public class IteratorDemo2 {
public static void main(String[] args) {
List<String > list =new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");
Iterator<String> iterator = list.iterator();
// Iterator<String> iterator1 = list.iterator();
// iterator.next();
// iterator.next();
// //同时存在多个迭代器,迭代器之间是相互独立的
// System.out.println(iterator.next());//C
// System.out.println(iterator1.next());//A
//遍历的同时不能改变线性表的结构
//抛出异常:java.util.ConcurrentModificationException
/* for (String next : list){
if (next.equals("C")){
list.remove("C");
}
}*/
//如果需要,应该使用迭代器进行遍历,使用迭代器中的remove()
while (iterator.hasNext()){
String next = iterator.next();
if (next.equals("C")){
iterator.remove();
}
}
System.out.println(list);//[A, B, D, E]
}
}
ListIterator
既可以从后往前去遍历也可以从前往后遍历
public static void main(String[] args) {
List<String > list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
ListIterator<String> s = list.listIterator(list.size());
while (s.hasPrevious()){
String pre = s.previous();
System.out.println(pre);//D C B A
}
}