ArrayList集合和LinkedList集合

集合的由来:数组长度是固定,当添加的元素超过了数组的长度时需要对数组重新定义,太麻烦,java内部给我们提供了集合类,能存储任意对象,长度是可以改变的,随着元素的增加而增加,随着元素的减少而减少 

 

数组和集合的区别

  • 数组既可以存储基本数据类型,又可以存储引用数据类型,基本数据类型存储的是值,引用数据类型存储的是地址值

  • 集合只能存储引用数据类型(对象)集合中也可以存储基本数据类型,但是在存储的时候会自动装箱变成对象

  • 数组长度是固定的,不能自动增长

  • 集合的长度的是可变的,可以根据元素的增加而增长

 

集合分两大类

Collection:单列集合

Map:双列集合

 

集合相比与数组可以存储多个数据类型数据,而且可以随时增减长度。

集合是通过调用size()方法来获取长度

 

迭代器

集合是用来存储元素,存储的元素需要查看,那么就需要迭代(遍历) 

迭代器是对集合进行遍历,而每一个集合内部的存储结构都是不同的,所以每一个集合存和取都是不一样,那么就需要在每一个类中定义hasNext()和next()方法,这样做是可以的,但是会让整个集合体系过于臃肿,迭代器是将这样的方法向上抽取出接口,然后在每个类的内部,定义自己迭代方式,这样做的好处有二,第一规定了整个集合体系的遍历方式都是hasNext()和next()方法,第二,代码有底层内部实现,使用者不用管怎么实现的,会用即可 

在迭代过程中不能操作集合中的元素,否则会抛出ConcurrentModificationException异常

 

ArrayList和LinkedList的区别,在于ArrayList查找快,LinkedList增删快。ArrayList的底层结构是数组,所以当需要查找某个元素的时候,只需要根据索引查找即可。但增删慢,比如说:在布置考场的时候,需要给每个桌子贴考号,但是当贴到后面的时候发现前面少贴了一个,这时需要把后面的考号重新撕下来,重新贴一遍。LinkedList增删快时因为他是链表结构,不需要顾及其他元素的位置,比如说:军训站队的时候,你不需要记住所有人的位置,你只需要知道你前后面人的位置,就知道你站在哪。LinkedList查找慢,是因为它只给了链表头和尾,当你需要找中间位置的元素,它是从前或后往中间找,所以查找慢

比较ArraysList和LinkedList的增删速度

		ArrayList<String> array = new ArrayList();
		LinkedList<String> link = new LinkedList();
		
		//ArrayList增加元素所需时间
		long start1 = System.currentTimeMillis();
		for (int i = 0; i < 500000; i++) {
			array.add("wuhan"+i);
		}
		long end1 = System.currentTimeMillis();
		
		//LinkedList增加元素所需时间
		long start2 = System.currentTimeMillis();
		for (int i = 0; i < 500000; i++) {
			link.add("wuhan"+i);
		}
		long end2 = System.currentTimeMillis();
		System.out.println("ArrayList增加元素所需时间:"+(end1-start1));//54
		System.out.println("LinkedList增加元素所需时间:"+(end2-start2));//32

比较ArraysList和LinkedList的查找速度

ArrayList<String> array = new ArrayList();
LinkedList<String> link = new LinkedList();
for (int i = 0; i < 1000000; i++) {
	array.add("wuhan"+i);
}
for (int i = 0; i < 1000000; i++) {
	link.add("wuhan"+i);
}
//ArrayList查找元素所需时间
long start1 = System.currentTimeMillis();
array.get(500000);
long end1 = System.currentTimeMillis();
		
//LinkedList查找元素所需时间
long start2 = System.currentTimeMillis();
link.get(500000);
long end2 = System.currentTimeMillis();
System.out.println("ArrayList查找元素所需时间:"+(end1-start1));//0
System.out.println("LinkedList查找元素所需时间:"+(end2-start2));//6

ArraysList

  • 查找快,修改也快

  • 初始容量为10

  • 底层结构是数组

  • 线程不安全,效率高

add(Object obj)

添加元素,可以是任意类型数据

ArrayList list = new ArrayList();
list.add(1);
list.add("a");
list.add(true);
System.out.println(list);//结果为[1, a, true]

contains(Object obj)

比较集合里面是否包含obj

ArrayList list = new ArrayList();
list.add(1);
list.add("a");
list.add(true);
boolean contains = list.contains(1);
boolean contains1 = list.contains("b");
System.out.println(contains);//结果为true
System.out.println(contains1);//结果为false

get(int index)

根据下标获取集合中的数据,返回类型是Object,因为ArrayList的底层结构是Objec类型数组,如果需要用其他类型数据来接收数据,需要强转,注意的是强制的类型必须是集合中元素的类型,比如说不可能把字符串a转换成整型1,否则会发生ClassCastException异常,解决此办法需要用到泛型。

泛型:规定集合中的数据的类型,把运行是异常提前到编译时期。

规定以后声明集合是需要带泛型。

ArrayList list = new ArrayList();
list.add(1);
list.add("a");
list.add(true);
Object object = list.get(1);
System.out.println(object);//结果为a

remove(int index),remove(Object o)

可以通过下标删除指定元素,也可以直接删除指定的元素,注意,如果元素类型都是int类型,如果你又想删除指定的元素,比如说元素是1,2,3。想删除数字1,但输入数字1的时候却删除的是数字2,是因为在源代码里面,remove(int index)方法是remove的重写方法的第一个,所以优先执行。

ArrayList list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
list.remove(1);
System.out.println(list);//结果为[a, c]

removeAll(Collection c)

删除所有元素

ArrayList list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
		
ArrayList list1 = new ArrayList();
list1.add("b");
list1.add("c");
list1.add("d");
		
list.removeAll(list1);
		
System.out.println(list);//结果为[a, e]

retainAll(Collection c)

仅保留包含c里面的集合的元素

ArrayList list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("d");
		
ArrayList list1 = new ArrayList();
list1.add("a");
list1.add("b");
list1.add("c");
		
list.retainAll(list1);
		
System.out.println(list);//结果为[a, b, c]

toArray()

把集合转换成数组,数组类型是Object

ArrayList list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");

Object[] array = list.toArray();
System.out.println(Arrays.toString(array));//结果为[a, b, c]

把数组转换成集合,使用Arrays的asList,数组转换成集合是不能更改长度的,增删都不行。

ArrayList list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");

Object[] array = list.toArray();
		
List<Object> asList = Arrays.asList(array);
		
System.out.println(asList);//结果为[a, b, c]

循环遍历集合。for循环---foreach循环---迭代器遍历

ArrayList list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
//for循环
for (int i = 0; i < list.size(); i++) {
	System.out.println(list.get(i));
}
//foreach循环
for (Object obj : list) {
	System.out.println(obj);
}
//迭代器遍历,迭代过程中不能增删元素,否则会报ConcurrentModificationException异常
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
	Object object = (Object) iterator.next();
	list.remove(object);
	System.out.println(object);
}

比较使用for循环和迭代器两者的快慢

ArrayList<String> list = new ArrayList();
for (int i = 0; i < 1000000; i++) {
	list.add("wuhan"+i);
}
//for循环打印所需要的时间
long start1 = System.currentTimeMillis();
for (int i = 0; i < list.size(); i++) {
	System.out.println(list.get(i));
}
long end1 = System.currentTimeMillis();
		
//迭代器打印所需要的时间
Iterator iterator = list.iterator();
long start2 = System.currentTimeMillis();
while(iterator.hasNext()) {
	System.out.println(iterator.next());
}
long end2 = System.currentTimeMillis();
System.out.println("for循环打印所需要的时间:"+(end1-start1));//for循环打印所需要的时间:5923
System.out.println("迭代器打印所需要的时间:"+(end2-start2));//迭代器打印所需要的时间:5100

 

LinkedList

  • 查询慢,修改也慢

  • 增删快

  • 初始容量为0

  • 底层结构是链表

  • 线程不安全,效率高

addFirst(Object obj)

在集合头部添加元素,返回类型是Object

addLast(Object obj)

在集合结尾添加元素,返回类型是Object

LinkedList list = new LinkedList();
list.add("a");
list.add("b");
list.add("c");
		
list.addFirst("d");
list.addLast("e");
		
System.out.println(list);//结果为[d, a, b, c, e]

offerFirst(E e)

在集合头部添加元素,返回类型是boolean

offer(E e)

在集合结尾添加元素,返回类型是boolean

LinkedList list = new LinkedList();
list.add("a");
list.add("b");
list.add("c");

boolean offerFirst = list.offerFirst("d");
boolean offer = list.offer("e");
		
System.out.println(list);//结果为[d, a, b, c, e]

element()

检索但不删除第一个元素

LinkedList list = new LinkedList();
list.add("a");
list.add("b");
list.add("c");

Object element = list.element();
		
System.out.println(element);//结果为a

poll()

检索并删除,一般指第一个元素

pollFirst()

检索并删除第一个元素

pollLast()

检索并删除最后一个元素

LinkedList list = new LinkedList();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
		
Object poll = list.poll();
Object pollFirst = list.pollFirst();
Object pollLast = list.pollLast();
		
System.out.println(list);//结果为[c, d]

pop()

弹出第一个元素

LinkedList list = new LinkedList();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
		
Object pop = list.pop();
System.out.println(pop);//结果为a
System.out.println(list);//结果为[b, c, d, e]

push(Object obj)

推送到此集合中,一般推送到第一个

LinkedList list = new LinkedList();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
		
list.push("f");
list.push("g");
		
System.out.println(list);//结果为[g, f, a, b, c, d, e]

在LinkedList中有一个特有的迭代器,继承自Itartor的子接口ListIterator

LinkedList list = new LinkedList();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
list.add("f");
		
ListIterator listIterator = list.listIterator(3);//根据索引迭代
		
while(listIterator.hasNext()) {//往后迭代
	System.out.print(listIterator.next()+" ");//结果为d e f,包含索引
}
LinkedList list = new LinkedList();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
list.add("f");
		
ListIterator listIterator = list.listIterator(3);//根据索引迭代
while(listIterator.hasPrevious()) {//往后迭代
	System.out.print(listIterator.previous()+" ");//结果为c b a,不包含索引
}

Vector

  • 线程安全,效率低

  • 初始容量为10

  • 底层结构是数组

Vector相对ArrayList查询慢(线程安全的)
Vector相对LinkedList增删慢(数组结构)

 

Vector和ArrayList的区别

  • Vector是线程安全的,效率低

  •  ArrayList是线程不安全的,效率高

共同点:都是数组实现的

 

ArrayList和LinkedList的区别

  • ArrayList底层是数组结果,查询和修改快

  • LinkedList底层是链表结构的,增和删比较快,查询和修改比较慢

共同点:都是线程不安全的

 

  • 查询多用ArrayList

  • 增删多用LinkedList

  • 如果都多ArrayList

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值