JAVA集合List,Queue,Map(二)

本文详细介绍了Java集合类的各种特性,包括List、Queue、Map等不同类型的集合及其具体实现类的特点和应用场景,对比了不同集合类之间的性能差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、List集合

List集合:元素有序,可重复的集合,每个元素都有对应的索引。

1. List接口和ListIterator接口

  • List接口时Collection接口的子接口。
  • List book = new ArrayList(); books.remove(new A());//List会调用该A对象的equals()方法依次与集合元素进行比较,如果equals()方法以某个元素作为参数时返回true,List将会删除该元素。
//按照字符串从短到长排列
books.sort((o1,o2)->((String)o1.length()-(String)o2.length()));
//将每个字符串的长度作为集合的元素
books.replaceAll(ele->((String)ele).length());
  • List中提供了listIterator()方法,ListIterator接口继承了Iterator接口,提供了专门操作List的方法,ListIterator接口再Iterator接口基础上增加了如下方法:
    boolean hasPrevious():是否有上一个元素
    Object previous():返回上一个元素 void
    add(Object o):插入一个元素
package TreeCreate;

import java.awt.List;
import java.util.ArrayList;
import java.util.ListIterator;

public class ListIteratorTest {
	public static void main(String[] args) {
		String[] books = {"Hello","Bonjour"};
		ArrayList bookList = new ArrayList();
		for(int i = 0; i < books.length; i++) {
			bookList.add(books[i]);
		}
		ListIterator lit = bookList.listIterator();
		while(lit.hasNext()) {
			System.out.println(lit.next());
			lit.add("-----");
		}
		System.out.println("下面开始反向迭代");
		while(lit.hasPrevious()) {
			System.out.println(lit.previous());
		}
	}
}

运行结果:
在这里插入图片描述

  • ArrayList和Vector实现类
    ArrayList和Vector是List类的两个经典实现。它们封装了一个动态的、允许再分配的Object[]数组。ArrayList或Vector对象使用initialCapacity参数来设置该数组的长度,当添加元素超过数组长度时,它们的initialCapacity会自动增加。
    ArrayList线程是不安全的,当多个线程访问同一个ArrayList集合时,如果有超过一个线程修改了ArrayList集合,则程序员需要手动保证集合的同步性。

3.固定长度的List

  • asLIst()方法:将一个数组或指定个数的对象转换成一个List集合。这个List集合是Arrays的内部类ArrayList的实例。

  • Arrays.ArrayList是一个固定长度的List集合,只能遍历该集合元素,不可以增加、删除集合中的元素。 List
    fixedList = Arrays.asList(“hello”,“Bonjour”);

二、Queue集合

- 1.PriorityQueue、Deque实现类

队列FIFO,Queue接口有一个实现类:PriorityQueue实现类,Queue还有一个Deque接口,Deque是一个“双端队列”,可以同时从两端插入和删除元素,因此它可以当队列和栈使用。

offer()将指定元素加入到队列的尾部。
peek()获取队列头部的元素,
poll()获取队列头部的元素,并删除该元素

PriorityQueue保存队列元素的顺序:元素大小。peek()或poll()方法时,取出的是最小的元素。

2.LinkedList实现类

LinkedList类是(List接口+Deque接口)的实现类,所以可以根据索引来随机访问集合中的元素,内部以链表的形式保存集合中的元素,(随机访问集合元素的性能差,但是插入、删除元素的性能好)还可以把它当成双端队列来使用,可以当成栈或队列来使用。

public class LinkedListTest {
	public static void main(String[] args) {
		LinkedList books = new LinkedList();
		books.offer("Hello");//队列的插入元素,
		books.push("Bonjour");//入栈操作
		books.offerFirst("Salut");//队列在对头插入元素
		for(int i = 0; i < books.size(); i++)
			System.out.println(books.get(i));
		System.out.println(books);
		System.out.println(books.peekFirst());
		System.out.println(books.peekLast());
		System.out.println(books.pop());
		System.out.println(books);
		System.out.println(books.pollLast());
		System.out.println(books);
	}
}

运行结果:
Salut
Bonjour
Hello
[Salut, Bonjour, Hello]
Salut
Hello
Salut
[Bonjour, Hello]
Hello
[Bonjour]

3.各种线性表的性能分析

  • ArrayList基于数组的线性表,LinkedList基于链的线性表。Queue代表了队列,Deque代表了双端队列(队列+栈)。
    LinkedList:有List的功能+双端队列+栈的功能。

  • ArrayList 比LinkedList性能好:
    ArrayList:基于数组的线性表,因为数组以一块连续内存区来保存所有的数组元素,所以数组在随机访问时性能最好。
    LinkedList:基于链表的线性表,在执行插入、删除操作时性能好。
    - 关于使用List集合的建议:

  • 遍历List元素:对于ArrayList和Vector集合,使用随机访问方法(get)来遍历。对于LinkedList集合,采用迭代器(Iterator)遍历。

  • 如果经常执行插入、删除操作,使用LinkedList集合。

  • 如果有多个线程需要同时访问List集合元素,可考虑使用Collections将集合包装成线程安全的集合。

三、Map(字典、关联数组)集合

1.Map:key-value,一一对应。
key 和 value可以是任何引用类型的数据。元素是无序的。
keySet()方法:返回Map里所有key组成的Set集合。key集和Set集合里元素的存储形式很像,value集和List相似:元素与元素之间可以重复,通过索引来获取元素。
Map中包括一个内部类:Entry,该类封装了一个key-value对。Entry包含了三个方法:
Object getKey()
Object getValue()
Object setValue()
如果添加key-value时,Map中已有key,那么新添加的value会覆盖原来的value.

import java.util.HashMap;
import java.util.Map;

public class MapTest {
	public static void main(String[] args) {
		Map map = new HashMap();
		map.put("hello", 1);
		map.put("Bonjour", 2);
		map.put("Salut", 3);
		System.out.println(map.put("Bonjour", 2222));
		System.out.println(map);
		System.out.println("是否包含hello:"+map.containsKey("hello"));
		System.out.println("是否包含值为3的value:"+map.containsValue(3));
		for(Object key:map.keySet()) {
			System.out.println(key+"->"+map.get(key));
		}
		map.remove("hello");
		System.out.println(map);
	}

}

运行结果:
2
{Salut=3, Bonjour=2222, hello=1}
是否包含hello:true
是否包含值为3的value:true
Salut->3
Bonjour->2222
hello->1
{Salut=3, Bonjour=2222}

2.HashMap和Hashtable的区别

  • Hashtable是线程安全的,Hash
    Map是线程不安全的,HashMap比Hashtable性能好;但如果多线程访问同一个Map对象时,使用hashtable更好。
  • Hashtable不允许使用null作为key和value值;但HashMap可以使用null。 HashMap中最多有一个key = null,但可以有很多value = null.

HashMap和Hashcode判断两个key相等的标准:两个key通过equals()方法比较返回true,hashCode值也相等。

3.LinkedHashMap实现类

使用双向链表来维护key-value对的次序,迭代次序与key-value对的插入顺序一致。因为需要维护元素的插入顺序,所以性能低于HashMap的性能。

4.使用Properties读写属性文件

Properties相当于一个key, value都是String类型的Map。

注意:

Set和Map关系密切,Java源码就是先实现了HashMap、TreeMap
等集合,然后通过包装一个所有的value都是null的Map集合实现了Set集合。

5.各Map的性能分析

  • 快---->慢: HashMap > Hashtable > TreeMap > LinkedHashMap
  • HashMap:为快速查询设计的(HashMap底层采用数组来存储key-value对)
  • 因为TreeMap 底层采用红黑树来管理key-value对,好处是:Tree
    Map中的key-value一直处于有序状态,无须进行排序操作。
  • LinkedHashMap慢是因为:它需要维护链表来保持Map中key-value的添加顺序

四、同步控制
HashSet, TreeSet, ArrayList, ArrayDeque, LinkedList, HashMap, TreeMap都是线程不安全的。

import java.awt.List;
import java.util.*;

public class SynchronizedTest {
	public static void main(String[] args) {
		Collection c = Collections.synchronizedCollection(new ArrayList());
		List list = (List) Collections.synchronizedList(new ArrayList());
		Set s = Collections.synchronizedSet(new HashSet());
		Map m = Collections.synchronizedMap(new HashMap());
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值