自学内容网 自学内容网

Java集合的重点

一、Java集合

Java集合包含一组接口和实现类,底层使用不同类型的数据结构,提供不同特点的存储方式,主要分为两大类:

Collection单列集合和Map键值对集合。

1.Collection接口用于表示单例集合,主要包括三个子接口:List、Set、Queue

•List是有序的、可重复的集合。它维护元素的插入顺序,可以包含重复元素;

主要实现类包括:

  • ArrayList:基于动态数组实现,提供随机访问和插入性能;
  • LinkedList:基于双向链表实现,适合频繁插入和删除操作;
  • Vector:类似ArrayList,基于动态数组实现,使用synchronized实现线程安全,性能略低;
  • Stack:Vector类的子类,提供了FILO先进后出的栈结构;
  • CopyOnWriteArrayList:基于动态数组实现,使用ReentrantLock实现线程安全;

•Set是不允许重复元素的集合;

主要实现类包括:

  • HashSet:基于HashMap实现,元素唯一,无序;
  • LinkedHashSet:HashSet的子类,基于LinkedHashMap实现,元素唯一且有序,同时保持了哈希表的性能;
  • TreeSet:基于TreeMap实现,元素唯一,自动排序或按照自定义规则排序;
  • Queue是用于对元素进行先进先出(FIFO)操作的队列集合;

主要实现包括:

  • LinkedList:基于双向链表实现;
  • LinkedBlockingQueue:线程安全的阻塞队列,适用于多线程环境;

2.Map接口用于表示键值对的集合,Map集合中的key键是唯一的,而value值可以重复。

Map的主要实现类包括:

  • HashMap:基于哈希表实现,提供快速的查找和插入性能;
  • LinkedHashMap:HashMap类的子类,内部多维护了一条双向链表,保存维护了元素的插入顺序;
  • TreeMap:基于红黑树实现,根据key键自动排序或按照自定义规则排序;
  • Hashtable:基于哈希表实现,key和value不允许为null。早期的线程安全实现类,使用synchronized实现线程安全;
  • ConcurrentHashMap:基于哈希表实现,使用synchronized+CAS实现线程安全;

二、List,Set,Map的区别?

  • List:集合中存储的元素是有序的,所以可以进行排序操作。另外,集合中的元素可以可重复;
  • Set:集合中存储的元素不可重复的;
  • Map:集合中的元素使用键值对(Key-Value)存储,Key是无序+不可重复的,Value可重复的;

三、ArrayList与Vector区别?

ArrayList与Vector都是基于动态数组实现的List接口的集合实现类,它们的区别主要包括:

初始容量:

  • ArrayList初始默认容量为0,添加第一个元素时,扩容为10;
  • Vector初始默认容量为10;

扩容方式:

  • ArrayList:在原有容量基础上,扩容0.5倍(新容量是原有容量的1.5倍);
  • Vector:在原有容量基础上,扩容1倍(新容量是原有容量的2倍);

线程安全:

  • ArrayList:线程不安全(可使用CopyOnWriteArrayList集合解决);
  • Vector:线程安全,操作方法使用synchronized(同步锁)实现线程同步;

执行效率:

  • Vector的方法都有同步锁,在方法执行时需要加锁、解锁,所以性能会低于ArrayList;

四、Arraylist与LinkedList区别?

ArrayList与LinkedList都是List接口的集合实现类,它们的区别主要包括:

底层数据结构:

  • Arraylist:底层使用的是Object[]数组;
  • LinkedList:底层使用的是双向链表;

插入和删除元素:

  • ArrayList:插入删除时需要复制数组内的元素,所以性能较差;
  • LinkedList:插入删除时,只影响相邻节点,所以性能较高;

查找和遍历元素:

  • ArrayList:由于是基于数组实现的,支持快速的随机访问。可以通过索引直接访问元素,时间复杂度为O(1)。
  • LinkedList:不支持快速的随机访问。需要从头或尾开始遍历链表,直到找到指定位置的元素,时间复杂度为O(n)

RandomAccess接口:

  • 使用Collections.binarySearch()方法,基于二分查找法,进行元素查找时:
  • ArrayList:实现了RandomAccess接口,使用indexedBinarySearch()(基于下标的二分查找),性能较好;
  •  LinkedList:没有实现RandomAccess接口,使用1teratorBinarySearch()(基于迭代器的二分查找),迭代器会产生额外遍历操作,性能较差;

五、ArrayList的扩容机制?

构造函数初始化时

  • 使用无参数构造方法创建ArrayList时,内部的动态数组被初始化为一个空数组。当向数组中添加第一个元素时,数组容量扩为10;
  • 使用有参数构造方法创建ArrayList时,内部的动态数组按照指定容量进行初始化创建;

添加元素容量不足时

  • 当数组容量不足时,调用grow()方法进行扩容,每次扩容后容量都会变为原来的1.5倍(在原有容量基础上,扩容0.5倍);
  • 扩容后,数组的最大容量不会超过Integer.MAX_VALUE;

六、HashSet、LinkedHashSet和TreeSet区别?

它们都是Set接口的实现类,区别主要包括:

  • HashSet:基于HashMap实现,元素唯一,无序;
  • LinkedHashSet:HashSet的子类,基于LinkedHashMap实现,元素唯一且有序,同时保持了哈希表的性能;
  • TreeSet:基于TreeMap实现,元素唯一,自动排序或按照自定义规则排序;

七、HashSet如何过滤重复元素?

  • HashSet内部使用一个HashMap作为数据结构,保存元素时,会使用这个HashMap的key来进行保存。key是唯一的,所以重复元素会自动过滤。

原文地址:https://blog.csdn.net/2301_76207358/article/details/140621726

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!