Java中的Set、List、Map的区别
数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型),JAVA集合可以存储和操作数目不固定的一组数据。 所有的JAVA集合都位于 java.util包中! JAVA集合只能存放引用类型的的数据,不能存放基本数据类型。
JAVA集合主要分为三种类型:
- Set(集)
- List(列表)
- Map(映射)
Set、List和Map是Java集合框架中的三种不同的接口,它们各自有不同的特点和用途。
- Set :
- Set是一种集合,用于存储
不重复
的元素。 - Set接口的实现类通常使用哈希表或树等数据结构来实现元素的存储和去重。
- Set中的元素没有特定的顺序,即不保证元素的插入顺序和访问顺序。
- 常见的Set接口的实现类有HashSet、LinkedHashSet和TreeSet。
- Set是一种集合,用于存储
- List :
- List是一种有序集合,允许存储
重复
的元素。 - List接口的实现类通常使用数组或链表等数据结构来实现元素的存储和有序访问。
- List中的元素有索引,可以根据索引进行访问、插入和删除操作。
- List中的元素是有序的,即保持插入顺序。
- 常见的List接口的实现类有ArrayList、LinkedList和Vector。
- List是一种有序集合,允许存储
- Map :
- Map是一种
键值对
的映射集合,用于存储键值对关系。 - Map中的键是唯一的,值可以重复。
- Map接口的实现类通常使用哈希表、树或链表等数据结构来实现键值对的存储和查找。
- Map中的键值对没有特定的顺序,即不保证键值对的插入顺序和访问顺序。
- 常见的Map接口的实现类有HashMap、TreeMap。
- Map是一种
总结:
- Set用于存储不重复的元素,List用于存储有序的元素序列,Map用于存储键值对映射关系。
- Set和List都是集合,而Map是映射。
- Set和Map中的元素没有特定的顺序,而List中的元素是有序的。
Collection 接口 :Collection是最基本的集合接口,声明了适用于JAVA集合(只包括Set和List)的通用方法。 Set 和List 都继承了Conllection,Map
Collection接口的方法
Collection
接口是Java集合框架的根接口,它定义了操作集合的基本方法。下面是Collection
接口中的主要方法:
- int size():返回集合中的元素数量。
- boolean isEmpty():如果集合中没有元素,则返回true;否则返回false。
- boolean contains(Object o):如果集合中包含指定的元素,则返回true。
- boolean add(E e):将指定的元素添加到集合中。如果集合因为元素的存在而发生改变,则返回true。
- boolean remove(Object o):从集合中移除指定的元素。如果集合包含了该元素,则返回true。
- boolean containsAll(Collection<?> c):如果集合中包含指定集合中的所有元素,则返回true。
- boolean addAll(Collection<? extends E> c):将指定集合中的所有元素添加到集合中。如果集合因为添加元素而发生改变,则返回true。
- boolean removeAll(Collection<?> c):从集合中移除指定集合中的所有元素。如果集合因为移除元素而发生改变,则返回true。
- boolean retainAll(Collection<?> c):仅保留集合中包含在指定集合中的元素,移除其他元素。如果集合因为保留元素而发生改变,则返回true。
- void clear():从集合中移除所有的元素。
- Object[] toArray():返回包含集合所有元素的数组。
- T[] toArray(T[] a):返回包含集合所有元素的数组,并将其存储在指定的数组中。如果指定的数组大小足够大,并且集合可以适应指定的数组,则将元素存储在该数组中。否则,将分配一个新的数组,其运行时类型是指定数组的运行时类型,具有相同的大小。
Iterator接口方法
-
boolean hasNext():如果迭代器还有元素可以遍历,则返回true;否则返回false。
-
E next():返回迭代器中的下一个元素,并将迭代器的位置向后移动。
-
void remove() :从集合中移除迭代器最后返回的元素。这个方法只能在调用
next()
方法之后且在调用remove()
方法之前调用一次,否则会抛出IllegalStateException
异常。 -
Set(): Set是最简单的一种集合。集合中的对象不按特定的方式排序,并且没有重复对象。 Set接口主要实现了两个实现类:
- HashSet: HashSet类按照哈希算法来存取集合中的对象,存取速度比较快
- TreeSet:TreeSet类实现了SortedSet接口,能够对集合中的对象进行排序。
Set 的用法
Set
是一种集合类型,它表示一组唯一的对象,不允许重复。Set接口继承自Collection接口,常用的实现类有HashSet、LinkedHashSet和TreeSet。
Set接口的主要方法
- add(E e):将指定的元素添加到集合中。如果集合中已经包含了该元素,则不会添加,并返回false;否则将元素添加到集合中,并返回true。
- remove(Object o):从集合中移除指定的元素。如果集合中包含了该元素,则移除并返回true;否则返回false。
- contains(Object o):判断集合中是否包含指定的元素。如果集合中包含了该元素,则返回true;否则返回false。
- size():返回集合中元素的数量。
- isEmpty():判断集合是否为空。如果集合中没有元素,则返回true;否则返回false。
- clear():清空集合中的所有元素。
Set接口的主要实现类
- HashSet:基于哈希表实现的Set,不保证元素的顺序,不允许有重复元素。它提供了常数时间的基本操作,如添加、移除、包含等。
- LinkedHashSet:基于哈希表和链表实现的Set,它维护了元素的插入顺序,可以通过迭代器按照插入顺序遍历集合中的元素。
- TreeSet:基于红黑树实现的Set,它可以对元素进行排序,并且不允许有重复元素。元素可以根据它们的自然顺序或者通过提供的比较器进行排序。
HashSet()的常用方法
HashSet
是Set
接口的一个实现类,它基于哈希表
实现,不保证元素的顺序,不允许有重复元素。
- add(E e):将指定的元素添加到集合中。如果集合中已经包含了该元素,则不会添加,并返回false;否则将元素添加到集合中,并返回true。
- remove(Object o):从集合中移除指定的元素。如果集合中包含了该元素,则移除并返回true;否则返回false。
- contains(Object o):判断集合中是否包含指定的元素。如果集合中包含了该元素,则返回true;否则返回false。
- size():返回集合中元素的数量。
- isEmpty():判断集合是否为空。如果集合中没有元素,则返回true;否则返回false。
- clear():清空集合中的所有元素。
这些方法是HashSet
的基本用法,通过它们可以实现对集合中元素的添加、移除、判断、获取以及清空等操作。
由于HashSet不保证元素的顺序,因此遍历的结果可能是无序的。
TreeSet()的常用方法
TreeSet
是Set
接口的一个实现类,它基于红黑树(Red-Black tree)
实现,可以对元素进行排序。
- add(E e):将指定的元素添加到集合中。如果集合中已经包含了该元素,则不会添加,并返回false;否则将元素添加到集合中,并返回true。
- remove(Object o):从集合中移除指定的元素。如果集合中包含了该元素,则移除并返回true;否则返回false。
- contains(Object o):判断集合中是否包含指定的元素。如果集合中包含了该元素,则返回true;否则返回false。
- size():返回集合中元素的数量。
- isEmpty():判断集合是否为空。如果集合中没有元素,则返回true;否则返回false。
- clear():清空集合中的所有元素。
- first():返回集合中的第一个(最小)元素。
- last():返回集合中的最后一个(最大)元素。
- lower(E e):返回小于给定元素的最大元素,如果不存在,则返回null。
- higher(E e):返回大于给定元素的最小元素,如果不存在,则返回null。
- floor(E e):返回小于等于给定元素的最大元素,如果不存在,则返回null。
- ceiling(E e):返回大于等于给定元素的最小元素,如果不存在,则返回null。
- pollFirst():移除并返回集合中的第一个(最小)元素。
- pollLast():移除并返回集合中的最后一个(最大)元素。
- iterator():返回一个迭代器,可以在集合中迭代元素的顺序是按照元素的自然顺序。
这些方法是TreeSet
的基本用法,通过它们可以实现对集合中元素的添加、移除、判断、获取以及清空等操作,以及获取集合中的第一个元素、最后一个元素,以及执行与有序集合相关的操作。
由于TreeSet基于红黑树实现,因此元素在遍历时会按照它们的自然顺序或者自定义的比较器进行排序。
HashSet和TreeSet区别
HashSet
基于哈希表实现,无序且快速,适合查找;TreeSet
基于红黑树实现,有序且支持排序,适合有序集合操作。
HashSet
和TreeSet
是Java中Set
接口的两个主要实现类,它们之间有以下区别:
- 底层数据结构 :
HashSet
基于哈希表实现,使用哈希表存储元素,不保证元素的顺序,不允许有重复元素。TreeSet
基于红黑树实现,使用树结构存储元素,可以对元素进行排序,并且不允许有重复元素。
- 元素顺序 :
HashSet
不维护元素的顺序,即元素在集合中的顺序是不确定的。TreeSet
维护元素的排序顺序,可以根据元素的自然顺序或者提供的比较器进行排序。因此,TreeSet
中的元素是有序的。
- 性能 :
HashSet
的基本操作(添加、删除、包含)具有常数时间的性能,即O(1)。TreeSet
的基本操作的性能取决于红黑树的高度,通常情况下,添加、删除、包含等操作的时间复杂度是O(log n),其中n是集合中的元素数量。
- 使用场景 :
- 如果不需要元素的排序,只需简单地存储和检索元素,并且不关心元素的顺序,可以使用
HashSet
。 - 如果需要对元素进行排序,或者需要维护插入顺序,可以使用
TreeSet
。它适用于需要按照特定顺序遍历元素的场景。
- 如果不需要元素的排序,只需简单地存储和检索元素,并且不关心元素的顺序,可以使用
综上所述,选择HashSet
还是TreeSet
取决于您的需求,如果需要元素的排序或者需要维护插入顺序,可以选择TreeSet
;如果只需要简单的存储和检索元素,并且不关心元素的顺序,可以选择HashSet
。
List的用法
List
是Java集合框架中的一个接口,它表示有序的集合,可以包含重复元素。List
接口继承自Collection
接口,它提供了按照索引访问元素的功能。
List接口的主要方法
- int size():返回列表中的元素数量。
- boolean isEmpty():如果列表中没有元素,则返回true;否则返回false。
- boolean contains(Object o):如果列表包含指定的元素,则返回true。
- boolean add(E e):将指定的元素添加到列表的末尾。如果列表因为添加元素而发生改变,则返回true。
- boolean remove(Object o):从列表中移除指定的元素。如果列表包含了该元素,则返回true。
- E get(int index):返回列表中指定位置的元素。
- E set(int index, E element):用指定的元素替换列表中指定位置的元素,并返回原始元素。
- void add(int index, E element):在列表的指定位置插入指定的元素。
- E remove(int index):移除列表中指定位置的元素,并返回该元素。
- int indexOf(Object o):返回列表中第一次出现指定元素的索引,如果列表不包含该元素,则返回-1。
- int lastIndexOf(Object o):返回列表中最后一次出现指定元素的索引,如果列表不包含该元素,则返回-1。
- void clear():移除列表中的所有元素。
- List subList(int fromIndex, int toIndex):返回列表中指定范围的视图。
List接口的主要实现类
- ArrayList :基于动态数组实现的
List
,它允许快速随机访问元素。当需要频繁地访问列表中的元素,而不涉及插入和删除操作时,通常使用ArrayList
。由于它是基于数组实现的,因此在随机访问时具有较好的性能。但是,插入和删除操作可能会导致元素的移动,因此在大量插入和删除操作时性能可能会受到影响。 - LinkedList :基于双向链表实现的
List
,它允许高效地在列表的任意位置进行插入和删除操作。当需要频繁地执行插入和删除操作时,通常使用LinkedList
。由于它是基于链表实现的,因此在插入和删除操作时具有较好的性能。但是,随机访问时的性能可能不如ArrayList
,因为需要遍历链表来找到指定位置的元素。
ArrayList()常用方法
ArrayList
是Java中List
接口的一个主要实现类,它基于动态数组
实现,提供了一系列常用的方法来操作列表中的元素。以下是ArrayList
常用的方法:
- add(E e):将指定的元素追加到列表的末尾。
- add(int index, E element):将指定的元素插入到列表的指定位置。
- remove(int index):移除列表中指定位置的元素。
- remove(Object o):移除列表中第一个出现的指定元素。
- get(int index):返回列表中指定位置的元素。
- set(int index, E element):将列表中指定位置的元素替换为指定的元素。
- size():返回列表中的元素数量。
- isEmpty():如果列表中没有元素,则返回true;否则返回false。
- clear():移除列表中的所有元素。
- contains(Object o):如果列表包含指定的元素,则返回true。
- indexOf(Object o):返回列表中第一次出现指定元素的索引,如果列表不包含该元素,则返回-1。
- lastIndexOf(Object o):返回列表中最后一次出现指定元素的索引,如果列表不包含该元素,则返回-1。
- toArray():返回包含列表中所有元素的数组。
- addAll(Collection<? extends E> c):将指定集合中的所有元素追加到列表的末尾。
- addAll(int index, Collection<? extends E> c):将指定集合中的所有元素插入到列表的指定位置。
这些方法提供了对ArrayList
中元素进行添加、移除、获取、替换、查询等操作的支持,是使用ArrayList
时常用的方法。
LinkedList()常用方法
LinkedList
是Java中List
接口的另一个主要实现类,它基于双向链表
实现。以下是LinkedList
常用的方法:
- add(E e):将指定的元素追加到列表的末尾。
- add(int index, E element):将指定的元素插入到列表的指定位置。
- remove(int index):移除列表中指定位置的元素。
- remove(Object o):移除列表中第一个出现的指定元素。
- get(int index):返回列表中指定位置的元素。
- set(int index, E element):将列表中指定位置的元素替换为指定的元素。
- size():返回列表中的元素数量。
- isEmpty():如果列表中没有元素,则返回true;否则返回false。
- clear():移除列表中的所有元素。
- contains(Object o):如果列表包含指定的元素,则返回true。
- indexOf(Object o):返回列表中第一次出现指定元素的索引,如果列表不包含该元素,则返回-1。
- lastIndexOf(Object o):返回列表中最后一次出现指定元素的索引,如果列表不包含该元素,则返回-1。
- toArray():返回包含列表中所有元素的数组。
- addAll(Collection<? extends E> c):将指定集合中的所有元素追加到列表的末尾。
- addAll(int index, Collection<? extends E> c):将指定集合中的所有元素插入到列表的指定位置。
- addFirst(E e):将指定元素插入到列表的开头。
- addLast(E e):将指定元素追加到列表的末尾。
- removeFirst():移除并返回列表的第一个元素。
- removeLast():移除并返回列表的最后一个元素。
- getFirst():返回列表的第一个元素。
- getLast():返回列表的最后一个元素。
- peek():检查列表的第一个元素,但不移除它。
- peekFirst():检查列表的第一个元素,但不移除它。
- peekLast():检查列表的最后一个元素,但不移除它。
- poll():移除并返回列表的第一个元素,如果列表为空则返回null。
- pollFirst():移除并返回列表的第一个元素,如果列表为空则返回null。
- pollLast():移除并返回列表的最后一个元素,如果列表为空则返回null。
这些方法提供了对LinkedList
中元素进行添加、移除、获取、替换、查询等操作的支持,是使用LinkedList
时常用的方法。另外,LinkedList
还提供了一些与双向链表特性相关的方法,例如在链表的开头或末尾进行添加和移除操作。
ArrayList和LinkedList区别
ArrayList
基于数组实现,适合随机访问;LinkedList
基于链表实现,适合频繁插入和删除。
- 底层数据结构 :
ArrayList
基于动态数组实现,内部使用数组来存储元素。因此,它支持随机访问,可以通过索引快速访问元素。LinkedList
基于双向链表实现,内部使用链表来存储元素。因此,它不支持随机访问,访问元素时需要从头或尾部开始遍历链表。
- 插入和删除操作的性能 :
- 在
ArrayList
中,插入和删除元素的性能取决于元素移动的数量。如果插入或删除元素位置之后的元素需要移动,则性能较低。平均情况下,插入和删除的时间复杂度是O(n)。 - 在
LinkedList
中,插入和删除元素的性能不受影响,因为只需要修改相邻节点的指针即可。在链表的头部和尾部进行插入和删除操作的性能是常数时间的,即O(1);在中间位置进行插入和删除操作的性能取决于元素的位置,平均情况下为O(n/2),即O(n)。
- 在
- 随机访问的性能 :
- 在
ArrayList
中,由于支持随机访问,可以通过索引快速访问元素,其时间复杂度为O(1)。 - 在
LinkedList
中,由于不支持随机访问,访问元素时需要从头或尾部开始遍历链表,其时间复杂度取决于元素的位置,平均情况下为O(n/2),即O(n)。
- 在
- 空间占用 :
ArrayList
的空间利用率较高,因为它只在需要时扩展内部数组的大小,并且不会浪费额外的空间。LinkedList
的空间占用较高,因为除了存储元素本身外,还需要额外的空间来存储节点之间的指针。
- 适用场景 :
- 如果需要频繁地进行随机访问,可以选择
ArrayList
。 - 如果需要频繁地进行插入和删除操作,尤其是在集合的头部和尾部进行操作,可以选择
LinkedList
。
- 如果需要频繁地进行随机访问,可以选择
综上所述,选择ArrayList
还是LinkedList
取决于您的需求,如果需要频繁地进行随机访问,可以选择ArrayList
;如果需要频繁地进行插入和删除操作,尤其是在集合的头部和尾部进行操作,可以选择LinkedList
。
Map的用法
Map
是一种集合类型,它表示一组键值对的映射关系。Map
接口中的键和值都是对象,键是唯一的,但值可以重复。 Map
没有继承于Collection
接口从Map集合中检索元素时,只要给出键对象,就会返回对应的值对象。
Map接口的主要方法
- put(key, value):添加键值对到Map中。
- get(key):获取指定键对应的值。
- remove(key):移除指定键对应的键值对。
- containsKey(key):判断Map中是否包含指定的键。
- containsValue(value):判断Map中是否包含指定的值。
- keySet():获取Map中所有键的集合。
- values():获取Map中所有值的集合。
- entrySet():获取Map中所有键值对的集合。
- 遍历键值对:使用增强for循环或迭代器遍历Map中的键值对。
Map接口的主要实现类
- HashMap:基于哈希表实现的Map,不保证元素的顺序,不允许有重复键。
- TreeMap:基于红黑树实现的有序Map,元素按照键的自然顺序或者指定的比较器进行排序。
- LinkedHashMap:基于哈希表和链表实现的Map,维护了元素的插入顺序或者访问顺序。
- Hashtable :早期的哈希表实现的Map,线程安全但性能相对较低,已被
ConcurrentHashMap
取代。 - ConcurrentHashMap:并发环境下线程安全的哈希表实现的Map,提供了高并发性能
HashMap()常用方法
- put(K key, V value):将指定的键值对添加到HashMap中。
- get(Object key):返回指定键所映射的值,如果该键不存在,则返回null。
- remove(Object key):从HashMap中移除指定键及其对应的值。
- containsKey(Object key):判断HashMap中是否包含指定的键。
- containsValue(Object value):判断HashMap中是否包含指定的值。
- size():返回HashMap中键值对的数量。
- isEmpty():判断HashMap是否为空,如果HashMap中没有键值对,则返回true。
- clear():移除HashMap中的所有键值对。
- keySet():返回一个包含HashMap中所有键的Set集合。
- values():返回一个包含HashMap中所有值的Collection集合。
- entrySet():返回一个包含HashMap中所有键值对的Set集合,每个元素都是Map.Entry对象。
这些方法能够实现对HashMap中键值对的添加、获取、移除、判断、遍历等操作。
TreeMap()常用方法
- put(K key, V value):将指定的键值对添加到TreeMap中。
- get(Object key):返回指定键所映射的值,如果该键不存在,则返回null。
- remove(Object key):从TreeMap中移除指定键及其对应的值。
- containsKey(Object key):判断TreeMap中是否包含指定的键。
- containsValue(Object value):判断TreeMap中是否包含指定的值。
- size():返回TreeMap中键值对的数量。
- isEmpty():判断TreeMap是否为空,如果TreeMap中没有键值对,则返回true。
- clear():移除TreeMap中的所有键值对。
- firstKey():返回TreeMap中的第一个(最小)键。
- lastKey():返回TreeMap中的最后一个(最大)键。
- lowerKey(K key):返回小于指定键的最大键,如果不存在,则返回null。
- higherKey(K key):返回大于指定键的最小键,如果不存在,则返回null。
- floorKey(K key):返回小于等于指定键的最大键,如果不存在,则返回null。
- ceilingKey(K key):返回大于等于指定键的最小键,如果不存在,则返回null。
- keySet():返回一个包含TreeMap中所有键的Set集合。
- values():返回一个包含TreeMap中所有值的Collection集合。
- entrySet():返回一个包含TreeMap中所有键值对的Set集合,每个元素都是Map.Entry对象。
这些方法能够实现对TreeMap中键值对的添加、获取、移除、判断、遍历等操作,以及获取最小键、最大键、小于指定键的最大键、大于指定键的最小键等操作。
HashMap和TreeMap区别
- 底层数据结构 :
- HashMap:基于哈希表实现,使用数组和链表/红黑树组合实现,不保证元素的顺序。
- TreeMap:基于红黑树实现,保持元素的排序顺序。
- 元素顺序 :
- HashMap:不保证元素的顺序,因为其内部结构是无序的。
- TreeMap:元素按照键的自然顺序或者指定的比较器进行排序,保持有序性。
- 性能 :
- HashMap:基本操作的时间复杂度为O(1),但在极端情况下可能达到O(n)。
- TreeMap:基本操作的时间复杂度为O(log n),具有更稳定的性能。
- 适用场景 :
- HashMap:适用于需要快速添加、查找、删除键值对,并且不关心元素顺序的场景。
- TreeMap:适用于需要对元素进行排序,并且需要有序遍历元素的场景。
综上所述,选择HashMap还是TreeMap取决于需求。如果不需要元素的排序,并且需要快速的增删改查操作,可以选择HashMap;如果需要元素有序,并且需要有序遍历元素,可以选择TreeMap。