本篇博客将详细讲解Java中的List。
我们之前实现过的顺序表,只能保存int类型的元素,如果现在需要保存指向String类型对象的引用的顺序表,请问应该如何解决?
这个时候就需要引入泛型这个概念了。
泛型的意义:
示例代码:
class MyArrayList<E> {
private E[] elem;
private int usedSize;
public MyArrayList() {
this.elem = (E[]) new Object[10];
}
public void add(E val) {
this.elem[usedSize] = val;
usedSize++;
}
public E get(int pos) {
return this.elem[pos];
}
}
public class TestDemo {
public static void main(String[] args) {
MyArrayList<String> myArrayList = new MyArrayList<>();
myArrayList.add("ABC");
myArrayList.add("DEF");
System.out.println(myArrayList.get(1));
}
}
执行结果为:
泛型是为了解决某些容器、算法等代码的通用性而引入,并且能在编译期间做类型检查。
泛型利用的是 Object 是所有类的祖先类,并且父类的引用可以指向子类对象的特定而工作。
泛型是一种编译期间的机制,即 MyArrayList<Integer> 和MyArrayList<String> 在运行期间是一个类型。
泛型是 java 中的一种合法语法,标志就是尖括号<>。
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
示例代码
Integer a = 123;//隐式的装包
int b = a;//隐式的拆包
Integer a2 = Integer.valueOf(123);//显式的装包
Integer a3 = new Integer(123);//显式的装包
int b2 = a2.intValue();//显式的拆包
在集合框架中,ArrayList是一个普通的类,实现了List接口,具体框架图如下:
说明
ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问。
ArrayList实现了Cloneable接口,表明ArrayList是可以clone的。
ArrayList实现了Serializable接口,表明ArrayList是支持序列化的。
和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者CopyOnWriteArrayList。
ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表。
方法 | 解释 |
---|---|
ArrayList() | 无参构造 |
ArrayList(Collection<? extends E> c) | 利用其他Collection构建ArrayList |
ArrayList(int initialCapacity) | 指定顺序表初始容量 |
示例代码
public static void main(String[] args) {
List<Integer> list1 = new ArrayList<>();//构造一个空的列表
List<Integer> list2 = new ArrayList<>(10);//构造一个具有10个容量的列表
list2.add(1);
list2.add(2);
list2.add(3);
ArrayList<Integer> list3 = new ArrayList<>(list2);//list3构造好之后,与list2中的元素一致
}
结论:
如果ArrayList调用,不带参数的构造方法,那么顺序表的大小是0。当第一次add的时候,整个顺序表才变为了10,当这10个放满了,开始扩容,以1.5倍的方式进行扩容。
如果调用的是给定容量的构造方法,那么顺序表的大小是所给的容量,放满之后还是以1.5倍进行扩容。
方法 | 解释 |
---|---|
boolean add(E e) | 尾插e |
void add(int index, E element) | 将e插入到index位置 |
boolean addAll(Collection<? extends E> c) | 尾插c中的元素 |
E remove(int index) | 删除index位置元素 |
boolean remove(Object o) | 删除遇到的第一个o |
E get(int index) | 获取下标index位置元素 |
E set(int index, E element) | 将下标index位置元素设置为element |
void clear() | 清空 |
boolean contains(Object o) | 判断o是否在线性表中 |
int indexOf(Object o) | 返回第一个o所在下标 |
int lastIndexOf(Object o) | 返回最后一个o的下标 |
List<E> subList(int fromIndex, int toIndex) | 截取部分list |
示例代码
List<String> list = new ArrayList<>();
list.add("abc");
list.add("def");
list.add("ABC");
list.add("EFG");
System.out.println(list);
System.out.println(list.size());//获取list中有效元素个数
System.out.println("=========更改指定元素==========");
System.out.println(list.get(1));
list.set(1,"xyz");
System.out.println(list.get(1));
System.out.println("=========插入指定元素==========");
list.add(1,"LMN");//在list的index位置插入指定元素,index及后续的元素统一往后移动一个位置
System.out.println(list);
System.out.println("=========删除指定元素==========");
list.remove("ABC");//删除指定元素,找到了就删除,该元素之后的元素统一往前移动一个位置
System.out.println(list);
if(list.contains("OPQ")) {
list.add("OPQ");
}
System.out.println("===查找指定元素第一次出现的位置===");
System.out.println(list.indexOf("EFG"));//indexOf从前往后找
System.out.println(list.lastIndexOf("EFG"));//lastIndexOf从后往前找
System.out.println("============================");
List<String> ret = list.subList(1,3);
System.out.println(ret);
list.clear();
System.out.println(list.size());
执行结果为:
示例代码
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
//直接打印
System.out.println(list);
//使用for循环
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + " ");
}
System.out.println();
//使用for-each
for (Integer s : list) {
System.out.print(s + " ");
}
System.out.println();
//迭代器打印——Iterator
Iterator<Integer> it = list.iterator();
while(it.hasNext()) {
System.out.print(it.next() + " ");
}
System.out.println();
//迭代器打印——ListIterator
ListIterator<Integer> it1 = list.listIterator();
while(it1.hasNext()) {
System.out.print(it1.next() + " ");
}
System.out.println();
执行结果为:
本篇博客到此结束。
上一篇博客:Java学习苦旅(十五)——异常
下一篇博客:Java学习苦旅(十七)——栈和队列