文章目录
一、ArrayList列表
1.1 定义与初始化
ArrayList<String> arr1 = new ArrayList<>();
ArrayList<String> arr2 = new ArrayList<String>();
- <> 中存放的是泛型(泛型:集合中存储的元素类型)。
- new调用构造方法进行实例化得到对象。
1.2 int类型的集合和数组的区别
集合 | 数组 | |
---|---|---|
元素类型 | Integer,必须为引用类型 | int,Integer都可以 |
长度 | 不定 | 固定 |
操作 | 基于方法调用(增加、删除等) | 基于索引(取值、赋值等) |
1.3 方法调用
1.3.1 add()方法
public boolean add(E e) {};
作用:给集合添加元素(元素依次添加到集合的后边)。
应用:
public void f1() {
ArrayList<String> arr = new ArrayList<>();
arr.add("pp");
arr.add("qq");
arr.add("rr");
arr.add("tt");
System.out.println(arr);
}
结果:
[pp, qq, rr, tt]
public void add(int index, E element) {}
作用:在索引为index的地方添加元素element。
应用:
public void f1() {
ArrayList<String> arr = new ArrayList<>();
arr.add("pp");
arr.add("qq");
arr.add("rr");
arr.add("tt");
System.out.println(arr);
arr.add(4, "99");
System.out.println(arr);
}
输出:
[pp, qq, rr, tt]
[pp, qq, rr, tt, 99]
注意:index的值不能超过arr.size(),否则会发生异常。
1.3.2 remove()方法
描述:
- 列表 remove() 方法:在列表中移除与索引匹配的第一项,如果这个元素不在列表中会报一个异常。
语法:
public E remove(int index) {}
参数
- Index为索引值。
应用:
public void f1() {
ArrayList<String> arr = new ArrayList<>();
arr.add("pp");
arr.add("qq");
arr.add("rr");
arr.add("tt");
System.out.println(arr);
arr.add(4, "99");
System.out.println(arr);
arr.remove(3);
System.out.println(arr);
}
结果:
[pp, qq, rr, tt]
[pp, qq, rr, tt, 99]
[pp, qq, rr, 99]
1.3.3 get()方法
- 作用:获取集合中索引的值,当索引超出集合长度时会报异常。
- 语法:
public E get(int index) {}
- 参数:index–要获取的集合元素的索引值。
实例:
public void f1() {
ArrayList<String> arr = new ArrayList<>();
arr.add("pp");
arr.add("qq");
arr.add("rr");
arr.add("tt");
System.out.println(arr.get(2));
}
输出:
rr
1.3.4 set()方法
- 作用:用参数元素替换动态数组中指定索引的元素。
- 语法:
public E set(int index, E element) {}
- 参数:index为要替换旧元素的索引号(索引值超出集合的长度是会产生异常),element为用来替换旧元素的新元素。
- 返回值:返回值为替换掉的旧元素。
实例:
public void f1() {
ArrayList<String> arr = new ArrayList<>();
arr.add("pp");
arr.add("qq");
arr.add("rr");
arr.add("tt");
System.out.println(arr);
System.out.println(arr.set(0, "ss"));
System.out.println(arr);
}
结果:
[pp, qq, rr, tt]
pp
[ss, qq, rr, tt]
1.3.5 contains()方法
- 作用:判断集合中是否包含参数元素。
- 语法:
public boolean contains(Object o) {}
- 参数:指定元素。
- 返回值:boolean类型,存在返回true,否则返回false。
代码示例:
public void f1() {
ArrayList<String> arr = new ArrayList<>();
arr.add("pp");
arr.add("qq");
arr.add("rr");
arr.add("tt");
System.out.println(arr);
System.out.println(arr.contains("tt"));
System.out.println(arr.contains("oo"));
}
结果:
[pp, qq, rr, tt]
true
false
1.3.6 addAll()方法
- 作用:将指定collection 中的所有元素添加到列表的尾部。如果List集合对象由于调用addAll方法而发生更改,则返回true。
- 语法:
public boolean addAll(Collection<? extends E> c) {}
- 参数:用于指定要将全部元素添加到列表中的collection。
- 返回值:boolean类型,对象发生更改返回true。
应用:
public void f1() {
ArrayList<String> arr = new ArrayList<>();
ArrayList<String> arr1 = new ArrayList<>();
arr.add("pp");
arr.add("qq");
arr.add("rr");
arr.add("tt");
arr1.add("rrrr");
System.out.println(arr);
System.out.println(arr1);
System.out.println(arr1.addAll(arr));
System.out.println(arr1);
}
结果:
[pp, qq, rr, tt]
[rrrr]
true
[rrrr, pp, qq, rr, tt]
1.3.7 containsAll()方法
- 作用:检查参数中的所有元素是否都出现在了集合中。
- 语法:
public boolean containsAll(Collection<?> c) {}
- 参数:用于指定要将全部元素与列表中元素检查的collection。
- 返回值:boolean类型,如果collection中的所有元素都包含在集合中,返回true。
实例:
public void f1() {
ArrayList<String> arr = new ArrayList<>();
ArrayList<String> arr1 = new ArrayList<>();
arr.add("a");
arr.add("b");
arr.add("c");
arr1.add("a");
arr1.add("a");
arr1.add("a");
System.out.println(arr);
System.out.println(arr1);
System.out.println(arr.containsAll(arr1));
arr1.add("v");
System.out.println(arr.containsAll(arr1));
}
结果:
[a, b, c]
[a, a, a]
true
false
1.4、遍历
1.4.1 遍历的两种方式
一、 for循环标准格式遍历集合
代码示例:
public static void main(String[] args) {
arr1.add("aa");
arr1.add("bb");
arr1.add("cc");
arr1.add("ee");
arr1.add("ff");
for (int i = 0; i < arr1.size(); i++) {
System.out.print(arr1.get(i) + " ");
}
}
输出:
aa bb cc ee ff
二、 增强型for循环遍历
代码示例:
public static void main(String[] args) {
arr1.add("aa");
arr1.add("bb");
arr1.add("cc");
arr1.add("ee");
arr1.add("ff");
for (String s : arr1) {
System.out.print(s+" ");
}
}
结果:
aa bb cc ee ff
1.4.2 遍历时删除/插入元素
1.4.2.1 使用foreach遍历
- 一次删除后,执行break/return,正确运行。
- 删除元素是倒数第二个,则不抛出异常,但最后一个元素未被遍历到。
- 除了上述2个情况,删除时会抛出异常。
代码1演示:
public class ArrayListBianLi2_1 {
public static ArrayList<String> arr1 = new ArrayList<>();
public static void main(String[] args) {
arr1.add("aa");
arr1.add("bb");
arr1.add("cc");
arr1.add("ee");
arr1.add("ff");
for (String s : arr1) {
System.out.println("-----" + s);
if ("cc".equals(s)) {
arr1.remove(s);
break;
}
}
}
}
结果:
-----aa
-----bb
-----cc
代码2展示:
package package12_22;
import java.util.ArrayList;
public class ArrayListBianLi2_1 {
public static ArrayList<String> arr1 = new ArrayList<>();
public static void main(String[] args) {
arr1.add("aa");
arr1.add("bb");
arr1.add("cc");
arr1.add("ee");
arr1.add("ff");
for (String s : arr1) {
System.out.println("-----" + s);
if ("ee".equals(s)) {//倒数第二个
arr1.remove(s);
break;
}
}
}
}
结果:
-----aa
-----bb
-----cc
-----ee
代码3演示:
package package12_22;
import java.util.ArrayList;
public class ArrayListBianLi2_1 {
public static ArrayList<String> arr1 = new ArrayList<>();
public static void main(String[] args) {
arr1.add("aa");
arr1.add("bb");
arr1.add("cc");
arr1.add("ee");
arr1.add("ff");
for (String s : arr1) {
System.out.println("-----" + s);
if ("ff".equals(s)) {
arr1.remove(s);
}
}
}
}
foreach遍历时删除/插入元素 是不允许的!(只要有元素个数的变化,就不允许)用foreach结构时改动元素数量会抛出异常。
1.4.2.2 使用标准循环,按照索引遍历正向遍历。
使用索引进行遍历时删除,必须注意索引号,避免遍历遗漏元素或者越界。
代码示例:
for (int i = 0; i < arr1.size(); i++) {
System.out.print("+++++"+arr1.get(i) + " "+arr1.size()+"\n");
String s = arr1.get(i);
if("bb".equals(s)) {
arr1.remove(s);
}
System.out.print("-----"+arr1.get(i) + " "+arr1.size()+"\n");
}
结果:
+++++aa 5
-----aa 5
+++++bb 5
-----cc 4
+++++ee 4
-----ee 4
+++++ff 4
-----ff 4
c没有被遍历,即:遗漏了被删除元素的最后一个元素。
原因:遗漏元素是因为删除元素后,List的size已经减1,但是i不变,则i的位置元素等于被跳过,不在循环中处理。
解决办法:调用remove()方法后,加上i–,则能避免这种错误。
1.4.2.3 逆向遍历
索引方式逆序遍历时删除,正确运行。
//逆向遍历
for (int i = arr1.size()-1; i>=0; i--) {
System.out.print("+++++"+arr1.get(i) + " "+arr1.size()+"\n");
String s = arr1.get(i);
if("bb".equals(s)) {
arr1.remove(s);
}
System.out.print("-----"+arr1.get(i) + " "+arr1.size()+"\n");
}
结果:
+++++ff 5
-----ff 5
+++++ee 5
-----ee 5
+++++cc 5
-----cc 5
+++++bb 5
-----cc 4
+++++aa 4
-----aa 4
总结:遍历用逆向,插入用正向。
1.4.2.4 迭代器iterator遍历(JDK7后用的少)
迭代器方式遍历时删除,正确运行。
代码:
arr1.add("aa");
arr1.add("bb");
arr1.add("cc");
arr1.add("ee");
arr1.add("ff");
Iterator<String> iterator = arr1.iterator();
while(iterator.hasNext()) {//是否存在未被遍历的元素
String str = iterator.next();
System.out.println(str);
if("bb".equals(str)) {
iterator.remove();
}
结果:
aa
bb
cc
ee
ff
1.5 判空
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<>();
ArrayList<String> list2 = null;
ArrayList<String> list3 = new ArrayList<>(0);
System.out.println(list2 == null);// true
System.out.println(list1 == list2); // false
System.out.println(list1.size());// 0
System.out.println(list3.size());// 0
System.out.println(list1.isEmpty());// true
System.out.println(list3.isEmpty());// true
}
输出:
true
false
0
0
true
true
1.6容量
1.6.1 容量与扩容
- ArrayList : Default Initial Capacity = 10 默认容量为10
- newCapacity = oldCapacity + (oldCapacity >>1); 扩大1.5倍
1.6.2 集合关系图
二、LinkedList链表
- LinkedList:ArrayList和Quene的特点都具有。
- LinkedList和ArrayList有很多相同的方法,比如get()、add()等。
2.1 方法调用
2.1.1 peek()方法
- 作用:返回队列头部的元素,队列为空时返回null。
- 语法:
public E peek() {}
- 返回值:链表里存储的数据类型。
- 参数:无。
代码示例:
public void f1() {
LinkedList<String> ls = new LinkedList<String>();
System.out.println(ls.peek());
ls.add("aa");
ls.add("bb");
ls.add("cc");
System.out.println(ls.peek());
}
结果:
null
aa
2.1.2 poll()方法
- 作用:返回并移除队列的头部元素,队列为空时返回null。
- 语法:
public E poll() {}
- 返回值:链表里存储的数据类型。
- 参数:无。
代码示例:
public void f1() {
LinkedList<String> ls = new LinkedList<String>();
System.out.println(ls.poll());
ls.add("aa");
ls.add("bb");
ls.add("cc");
System.out.println(ls);
System.out.println(ls.poll());
System.out.println(ls);
}
结果:
null
[aa, bb, cc]
aa
[bb, cc]
2.1.3 pop()方法
- 作用:从LinkedList表示的堆栈中弹出栈顶元素,链表为空时发生异常。
- 语法:
public E pop() {}
- 返回值:链表里存储的数据类型。
- 参数:无。
代码示例:
public void f1() {
LinkedList<String> ls = new LinkedList<String>();
ls.add("aa");
ls.add("bb");
ls.add("cc");
System.out.println(ls.pop());
System.out.println(ls);
}
结果:
aa
[bb, cc]
2.1.4 push()方法
- 作用:向LinkedList表示的堆栈栈推入一个元素。
- 语法:
public void push(E e) {}
- 返回值:void。
- 参数:要推入的元素。
代码示例:
public void f1() {
LinkedList<String> ls = new LinkedList<String>();
ls.add("aa");
ls.add("bb");
ls.add("cc");
ls.push("qqq");
System.out.println(ls);
}
结果:
[qqq, aa, bb, cc]
三、ArrayList和LinkedList的大致区别如下:
- ArrayList是实现了基于动态数组的数据结构,LinkedList基于双向链表的数据结构;
- 对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针;
- 对于新增和删除操作add和remove,LinkedList比较占优势,因为ArraylList要移动数据。