集合中的ArrayList类与LinkedList类

本文详细介绍了Java中ArrayList和LinkedList的基本操作,包括添加、删除、获取、设置元素,以及遍历和容量管理。对比了两者在数据结构、性能上的差异,并通过实例展示了在遍历过程中删除元素的注意事项。最后,讨论了ArrayList的容量增长策略和两者的关系图。
摘要由CSDN通过智能技术生成

一、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遍历
  1. 一次删除后,执行break/return,正确运行。
  2. 删除元素是倒数第二个,则不抛出异常,但最后一个元素未被遍历到。
  3. 除了上述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的大致区别如下:

  1. ArrayList是实现了基于动态数组的数据结构,LinkedList基于双向链表的数据结构;
  2. 对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针;
  3. 对于新增和删除操作add和remove,LinkedList比较占优势,因为ArraylList要移动数据。

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值