JAVA 基础学习笔记(9) 集合体系

前言

集合在应用层算不上很难,不过在数据结构方面还是有点难度的,老师似乎在这章停留了很久,而且听说Java八股文也会有它的一份,比如HashMap的底层原理,虽然还没学到那种背八股文的程度,但我能感觉到集合这章很重要。
再过两天就开学了,到时候就没有耐心随性地写博客了,所以这个基础笔记可能要等到下学期学校开java课程再课上摸鱼写吧,还有好多好多内容没写,泛型,多线程,反射,JDBC,MySQL,IO流,正则表达式😭😭😭😭

这篇博客也被我写崩了,也是自己基础不扎实,写的太慢了,以后在补充吧,先去学JavaWeb再说

在这里插入图片描述

集合的概念

其实我之前也上过学校的类C语言的数据结构课,不过学时太短了,根本没学进去。Java中的集合概念比数据结构中的概念更加清晰,尽管Java中的集合和类C语言数据结构书中的集合在概念上是相似的,都是指一组相关元素的容器。然而,它们在实现方式、具体操作和相关类库上可能存在一些差异。

C语言数据结构书中的集合,通常指的是一种抽象数据类型(Abstract Data Type,ADT),需要自己实现具体的操作和数据结构。在C语言中,可以使用数组、链表或树等数据结构来表示集合,需要手动管理内存和编写相关操作代码。

而Java中的集合是Java语言内置的集合框架,提供了一系列接口和实现类,封装了底层的数据结构和常用操作。Java的集合框架提供了更高层次的抽象,在使用时无需手动管理内存,并且提供了丰富的常用操作方法,方便开发人员使用。

也就是说类C语言数据结构书中的集合是需要自己组装的,而JAVA中的集合是已经提供好了完整的产品供你使用的。

在Java中,集合(Collection)是一种用于存储和操作一对象的容器。

列表(List):是有序的集合,允许重复元素。常见的列表实现类有ArrayList和LinkedList。列表可以根据索引访问元素,并支持在任意位置插入和删除元素。

集(Set):是不允许重复元素的集合。常见的集实现类有HashSet和TreeSet。集通常用于去重和检测元素是否存在。

队列(Queue):是一种先进先出(FIFO)的集合,通常用于处理按顺序排列的元素。常见的队列实现类有LinkedList和PriorityQueue。队列通常用于实现任务调度、事件处理等场景。

映射(Map):是一种键值对存储的集合,每个键对应一个值。常见的映射实现类有HashMap和TreeMap。映射用于存储一对一的关系,常用于缓存、索引和配置等。

栈(Stack):是一种后进先出(LIFO)的集合,通常用于实现逆序操作。Java中的Stack类继承自Vector类,但在实际开发中,通常使用Deque(双端队列)来替代Stack。

数组(Array):虽然不是集合框架中的一部分,但数组也是一种常见的数据结构。数组是一种固定长度、连续存储的数据结构,可以通过索引直接访问元素。

链表(Linked List):是一种基于节点存储的数据结构,每个节点包含数据和指向下一个节点的引用。链表支持高效的插入和删除操作,但访问元素需要遍历链表。

树(Tree):是一种层次结构的数据结构,其中每个节点最多有两个子节点。常见的树结构有二叉树(Binary Tree)和二叉搜索树(Binary Search Tree)。

图(Graph):是由节点和边组成的一种非线性数据结构,用于表示多个对象之间的关系。图可以用于表示网络、社交关系等复杂情况。

Java中的集合体系

(图是自己整理的,可能有误,望指出)
在这里插入图片描述

Collection接口:Collection接口是集合框架的一个顶层接口,它定义了一些通用的方法来操作集合中的元素,如添加、删除、查找等。常用的Collection接口的实现类包括List(列表)、Set(集)。

List接口:List接口是一个有序的集合,它允许重复的元素。List接口的常用实现类包括ArrayList(动态数组)、LinkedList(链表)和Vector(向量)等。

Set接口:Set接口是一个不包含重复元素的集合。Set接口的常用实现类包括HashSet(哈希集合)和TreeSet(树集)等。

Map接口:Map接口是一种键值对的映射集合。它通过键来访问和操作值,每个键只能在Map中存在一次。Map接口的常用实现类包括HashMap(哈希映射)和TreeMap(树映射)等。

部分类的介绍

LinkedList类:LinkedList类实现了List接口,并且使用链表数据结构来存储元素。它对于频繁的插入和删除操作比ArrayList更高效,但在随机访问方面较慢。

HashSet类:HashSet类是基于哈希表实现的Set接口的典型实现。它提供了快速的插入、删除和查找操作,但是不保证元素的顺序。

TreeSet类:TreeSet类是基于红黑树(一种自平衡二叉查找树)实现的Set接口的典型实现。它能够对元素进行排序,并提供高效的插入、删除和查找操作。

LinkedHashMap类:LinkedHashMap类是HashMap的一个子类,它保持了元素插入的顺序,并提供了按插入顺序或访问顺序遍历元素的功能。

ConcurrentHashMap类:ConcurrentHashMap类是HashMap的线程安全版本,它支持并发访问和更新操作,可以用于多线程环境。

实现List接口的三个子类

LinkedList:

  • LinkedList 是通过链表结构实现的 List 接口,并在链表中存储元素。每个节点都包含了对前一个和后一个节点的引用,从而实现了快速的插入和删除操作。
  • 由于 LinkedList 在内部使用了链表,所以对于随机访问的操作(例如根据索引获取元素),性能相对较差。需要遍历链表来查找对应位置的元素。
  • LinkedList 还实现了 Deque 接口(没接触过),因此可以充当双端队列 (deque),支持在队列两端进行高效的插入和删除操作。
  • LinkedList 不是线程安全的,因此在多线程环境中使用时需要进行额外的同步措施。

ArrayList

  • ArrayList 是基于数组实现的 List 接口,使用动态数组来存储元素。它可以自动扩容以适应元素的增长。
  • ArrayList 在内部使用一个可自动扩容的数组来存储元素,因此能够快速随机访问数组中的元素。
  • ArrayList 适用于大部分情况下的操作,尤其是随机访问的场景。但对于插入和删除操作,需要移动数组中的元素,因此性能较 LinkedLis略低。
  • ArrayList 不是线程安全的,同样需要在多线程环境中进行合适的同步处理。

Vector

  • Vector 是一个古老的类,也是基于数组实现的 List 接口,类似于 ArrayList。然而,与 ArrayList 不同,Vector 是线程安全的。

它们之间的一些区别总结:

  • LinkedList 适合频繁的插入和删除操作,但对于随机访问的操作性能较差。
  • ArrayList 提供了快速的随机访问,在频繁的遍历和随机访问场景中性能较好。
  • Vector 与 ArrayList 类似,但是它是线程安全的,可以用于多线程环境,但性能相比 ArrayList 偏低。

在现代 Java 应用中,ArrayList 是最常用的实现类,因为它在大多数场景下提供了较好的性能。LinkedList 更适用于频繁的插入、删除和双端操作的场景。Vector 过时且不推荐使用,因为它的同步开销较大。

实现Set接口的两个子类

HashSet

  • HashSet 是基于哈希表实现的 Set 接口,它提供了高效的插入、删除和查找操作。
  • HashSet 不保证元素的有序性,因为它使用哈希值来确定元素的存储位置,并依赖于对象的 hashCode() 方法。
  • HashSet 允许插入 null 元素,并保证集合中只有一个 null 元素。
  • HashSet 是非线程安全的,不适合在多线程环境中使用。如果需要在多线程环境中使用,可以使用 Collections.synchronizedSet() 方法将其包装为线程安全的版本。
  • TreeSet

  • TreeSet 是基于红黑树实现的 SortedSet 接口,它能够保持元素的有序性。
  • TreeSet 根据元素的自然顺序或自定义的比较器对元素进行排序,并提供了一些方法来支持有序集合的操作。
  • TreeSet 不允许插入 null 元素,因为插入 null 会导致无法确定元素的位置。
  • TreeSet 在内部使用红黑树数据结构,因此插入、删除和查找操作的时间复杂度为 O(log n)。
  • TreeSet 是非线程安全的,如果需要在多线程环境中使用,可以使用 Collections.synchronizedSortedSet() 方法将其包装为线程安全的版本。
  • 总结

  • HashSet 是最常用的 Set 实现类,提供了高效的插入、删除和查找操作,并适用于大多数情况。
  • TreeSet 提供了有序的元素集合,适用于对元素进行排序和按范围查找的需求。
  • 需要注意的是,HashSet 和 TreeSet 都不保证线程安全,如果在多线程环境中使用,需要进行适当的同步处理。

实现Map接口的四个子类

HashMap

  • HashMap 是基于哈希表实现的 Map 接口,它提供了较高的插入、删除和查找操作的性能。
  • HashMap 不保证键值对的有序性,因为它使用哈希值来确定键的存储位置,所以无法保证键值对的顺序。
  • HashMap 允许使用 null 作为键和值。
  • HashMap 是非线程安全的,不适合在多线程环境中使用。如果需要在多线程环境中使用,可以使用 Collections.synchronizedMap() 方法将其包装为线程安全的版本。

HashTable

  • Hashtable 是一个旧版的哈希表实现的 Map 接口,它与 HashMap 类似,但是它是线程安全的。
  • Hashtable 不允许使用 null 作为键或值。在插入或获取键或值时,都需要= 进行非空性检查。
  • Hashtable 提供了通过 Enumeration 进行遍历的方法,这在某些旧的代码中使用较多。
  • 尽管 Hashtable 是线程安全的,但由于其同步开销较大,因此在 Java 应用中,一般推荐使用 ConcurrentHashMap 来代替。

TreeMap

  • TreeMap 是基于红黑树实现的 SortedMap 接口,它能够保持键值对的有序性。根据键的自然顺序或者自定义的比较器对键进行排序。
  • TreeMap 在内部使用了红黑树数据结构,因此查找、插入和删除操作的时间复杂度为 O(log n)。
  • TreeMap 不允许使用 null 作为键,在插入或获取键时会抛出 NullPointerException。
  • TreeMap 是非线程安全的,如果需要在多线程环境中使用,可以使用 Collections.synchronizedSortedMap() 方法将其包装为线程安全的版本。
  • Properties

  • Properties 是 Hashtable 的子类,它专门用于处理属性文件。
  • Properties 允许将键值对存储在属性文件中,其中键和值都是字符串类型。
    Properties 提供了一些便捷的方法用于从属性文件中加载以及存储到属性文件中。
  • Properties 通常用于处理配置文件、国际化资源捆绑等场景。

总结:

  • HashMap 是最常用的 Map 实现类,提供了良好的性能,适用于大多数情况。
  • Hashtable 是旧版的线程安全哈希表实现,通常不推荐使用,可以用 ConcurrentHashMap 替代。
  • TreeMap 提供了有序的键值对,适用于特定的有序需求。
  • Properties 是用于处理属性文件的特殊 Map 实现类。

Collections

collections是一个工具类,它提供了很多方法来操纵集合,我们以ArrayList类的集合为例,了解一下常用的方法。

add:增加元素

ArrayList<Integer> numbers = new ArrayList<>();//<>尖括号里的是泛型的知识点,而Integer是int的包装类型,之后会学到的
        numbers.add(2);
        numbers.add(5);
        numbers.add(1);
        System.out.println(numbers);  // 输出: [2, 5, 1]

remove:删除指定元素

numbers.remove(1);//这个参数可以是索引,可以是Object类的对象
 System.out.println(numbers);//输出【2,1】

contains:查找元素是否存在

System.out.println(numbers.contains(1));//输出true

size:获取元素个数

System.out.println(numbers.size());//输出为2

isEmpty:判断是否为空

System.out.println(numbers.isEmpty());//输出false

clear:清空

numbers.clear();
System.out.println(numbers.isEmpty());//输出true

addAll:添加多个元素(以集合为一个整体添加)

ArrayList<Integer> numbers2 = new ArrayList<>();
        numbers2.add(7);
        numbers2.add(9);
        numbers2.add(2);
        numbers.addAll(numbers2);
        System.out.println(numbers);//输出【7,9,2】

containsAll:查看多个元素是否存在

 System.out.println(numbers.containsAll(numbers2));//输出为true

removeAll:删除多个元素

numbers.removeAll(numbers2);
 System.out.println(numbers);//输出【】

indexOf:查找元素索引

//由于前面把元素删完,再添加一次
numbers.add(4);
numbers.add(6);
numbers.add(1);
 System.out.println(numbers.indexOf(6));//返回索引位置,即1

sort:排序


numbers=numbers.sort();//这个需要自己重写比较器里的方法
//不过还可以这样用
Collections.sort(numbers);//默认是从小到大
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

罗不丢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值