• java基础学习笔记总结


    Java的集合类被定义在Java.util包中,主要有 4种集合,分别为ListQueueSetMap,每种

    集合的具体分类如图
    List :可重复
    List 是非常常用的数据类型,是有序的 Collection ,一共有三个实现类,分别是 ArrayList
    Vector LinkedList
    1.ArrayList :基于数组实现,增删慢,查询快,线程不安全
    ArrayList 是使用最广泛的 List 实现类,其内部数据结构基于数组实现,提供了对 List 的增加
    add )、删除( remove )和访问( get )功能。
    ArrayList 的缺点是对元素必须连续存储,当需要在 ArrayList 的中间位置插入或者删除元素时,
    需要将待插入或者删除的节点后的所有元素进行移动,其修改代价较高,因此, ArrayList 不适合随
    机插入和删除的操作,更适合随机查找和遍历的操作。
    ArrayList 不需要在定义时指定数组的长度,在数组长度不能满足存储要求时, ArrayList 会创建
    一个新的更大的数组并将数组中已有的数据复制到新的数组中。
    2.Vector :基于数组实现,增删慢,查询快,线程安全
    Vector 的数据结构和 ArrayList 一样,都是基于数组实现的,不同的是 Vector 支持线程同步,即
    同一时刻只允许一个线程对 Vector 进行写操作(新增、删除、修改),以保证多线程环境下数据的 一致性,但需要频繁地对 Vector 实例进行加锁和释放锁操作,因此, Vector 的读写效率在整体上比
    ArrayList 低。
    3.LinkedList :基于双向链表实现,增删快,查询慢,线程不安全
    LinkedList 采用双向链表结构存储元素,在对 LinkedList 进行插入和删除操作时,只需在对应的
    节点上插入或删除元素,并将上一个节点元素的下一个节点的指针指向该节点即可,数据改动较
    小,因此随机插入和删除效率很高。但在对 LinkedList 进行随机访问时,需要从链表头部一直遍历
    到该节点为止,因此随机访问速度很慢。除此之外, LinkedList 还提供了在 List 接口中未定义的方
    法,用于操作链表头部和尾部的元素,因此有时可以被当作堆栈、队列或双向队列使用。
    2.1.2 Queue
    Queue 是队列结构, Java 中的常用队列如下。
    ArrayBlockingQueue :基于数组数据结构实现的有界阻塞队列。
    LinkedBlockingQueue :基于链表数据结构实现的有界阻塞队列。
    PriorityBlockingQueue :支持优先级排序的无界阻塞队列。
    DelayQueue :支持延迟操作的无界阻塞队列。
    SynchronousQueue :用于线程同步的阻塞队列。
    LinkedTransferQueue :基于链表数据结构实现的无界阻塞队列。
    LinkedBlockingDeque :基于链表数据结构实现的双向阻塞队列。
    Set :不可重复
    Set 核心是独一无二的性质,适用于存储无序且值不相等的元素。对象的相等性在本质上是对
    象的 HashCode 值相同, Java 依据对象的内存地址计算出对象的 HashCode 值。如果想要比较两个对
    象是否相等,则必须同时覆盖对象的 hashCode 方法和 equals 方法,并且 hashCode 方法和 equals 方法的
    返回值必须相同。
    1.HashSet HashTable 实现,无序
    HashSet 存放的是散列值,它是按照元素的散列值来存取元素的。元素的散列值是通过元素的
    hashCode 方法计算得到的, HashSet 首先判断两个元素的散列值是否相等,如果散列值相等,则接
    着通过 equals 方法比较,如果 equls 方法返回的结果也为 true HashSet 就将其视为同一个元素;如果
    equals 方法返回的结果为 false HashSet 就不将其视为同一个元素。
    2.TreeSet :二叉树实现
    TreeSet 基于二叉树的原理对新添加的对象按照指定的顺序排序(升序、降序),每添加一个
    对象都会进行排序,并将对象插入二叉树指定的位置。
    Integer String 等基础对象类型可以直接根据 TreeSet 的默认排序进行存储,而自定义的数据类
    型必须实现 Comparable 接口,并且覆写其中的 compareTo 函数才可以按照预定义的顺序存储。若覆
    compare 函数,则在升序时在 this. 对象小于指定对象的条件下返回 -1 ,在降序时在 this. 对象大于指
    定对象的条件下返回 1
    3.LinkHashSet HashTable 实现数据存储,双向链表记录顺序
    LinkedHashSet 在底层使用 LinkedHashMap 存储元素,它继承了 HashSet ,所有的方法和操作都
    HashSet 相同,因此 LinkedHashSet 的实现比较简单,只提供了 4 个构造方法,并通过传递一个标
    识参数调用父类的构造器,在底层构造一个 LinkedHashMap 来记录数据访问,其他相关操作与父类
    HashSet 相同,直接调用父类 HashSet 的方法即可。 2.1.4 Map
    1.HashMap :数组 + 链表存储数据,线程不安全
    HashMap 基于键的 HashCode 值唯一标识一条数据,同时基于键的 HashCode 值进行数据的存
    取,因此可以快速地更新和查询数据,但其每次遍历的顺序无法保证相同。 HashMap key value
    允许为 null
    HashMap 是非线程安全的,即在同一时刻有多个线程同时写 HashMap 时将可能导致数据的不一
    致。如果需要满足线程安全的条件,则可以用 Collections synchronizedMap 方法使 HashMap 具有线
    程安全的能力,或者使用 ConcurrentHashMap
    HashMap 的数据结构如图 2-2 所示,其内部是一个数组,数组中的每个元素都是一个单向链
    表,链表中的每个元素都是嵌套类 Entry 的实例, Entry 实例包含 4 个属性: key value hash 值和用
    于指向单向链表下一个元素的 next
     
    HashMap 常用的参数如下。
    capacity :当前数组的容量,默认为 16 ,可以扩容,扩容后数组的大小为当前的两倍,因此
    该值始终为 2 n
    loadFactor :负载因子,默认为 0.75
    threshold :扩容的阈值,其值等于 capacity×loadFactor
    HashMap 在查找数据时,根据 HashMap Hash 值可以快速定位到数组的具体下标,但是在找到
    数组下标后需要对链表进行顺序遍历直到找到需要的数据,时间复杂度为 O( n )
    为了减少链表遍历的开销, Java 8 HashMap 进行了优化,将数据结构修改为数组 + 链表或红黑
    树。在链表中的元素超过 8 个以后, HashMap 会将链表结构转换为红黑树结构以提高查询效率,因
    此其时间复杂度为 O(log N ) Java 8 HashMap 的数据结构如图
    2.ConcurrentHashMap :分段锁实现,线程安全
    HashMap 不同, ConcurrentHashMap 采用分段锁的思想实现并发操作,因此是线程安全的。
    ConcurrentHashMap 由多个 Segment 组成( Segment 的数量也是锁的并发度),每个 Segment 均继承自
    ReentrantLock 并单独加锁,所以每次进行加锁操作时锁住的都是一个 Segment ,这样只要保证每个Segment都是线程安全的,也就实现了全局的线程安全。
    ConcurrentHashMap 中有个 concurrencyLevel 参数表示并行级别,默认是 16 ,也就是说
    ConcurrentHashMap 默认由 16 Segments 组成,在这种情况下最多同时支持 16 个线程并发执行写操作,只要它们的操作分布在不同的Segment 上即可。并行级别 concurrencyLevel 可以在初始化时设置,一旦初始化就不可更改。ConcurrentHashMap 的每个 Segment 内部的数据结构都和 HashMap 相同。

     

    3.HashTable :线程安全
    HashTable 是遗留类,很多映射的常用功能都与 HashMap 类似,不同的是它继承自 Dictionary
    类,并且是线程安全的,同一时刻只有一个线程能写 HashTable ,并发性不如 ConcurrentHashMap
    4.TreeMap :基于二叉树数据结构
    TreeMap 基于二叉树数据结构存储数据,同时实现了 SortedMap 接口以保障元素的顺序存取,
    默认按键值的升序排序,也可以自定义排序比较器。
    TreeMap 常用于实现排序的映射列表。在使用 TreeMap 时其 key 必须实现 Comparable 接口或采用
    自定义的比较器,否则会抛出 java.lang.ClassCastException 异常。
    5.LinkedHashMap :基于 HashTable 数据结构,使用链表保存插入顺序
    LinkedHashMap HashMap 的子类,其内部使用链表保存元素的插入顺序,在通过 Iterator 遍历
    LinkedHashMap 时,会按照元素的插入顺序访问元素。
    异常的概念
    异常指在方法不能按照正常方式完成时,可以通过抛出异常的方式退出该方法,在异常中封装
    了方法执行过程中的错误信息及原因,调用方在获取该异常后可根据业务的情况选择处理该异常或
    者继续抛出该异常。
    在方法在执行过程中出现异常时, Java 异常处理机制会将代码的执行权交给异常处理器,异常
    处理器根据在系统中定义的异常处理规则执行不同的异常处理逻辑(抛出异常或捕捉并处理异
    常)。
    2.2.2 异常分类
    Java 中, Throwable 是所有错误或异常的父类, Throwable 又可分为 Error Exception ,常见的
    Error AWTError ThreadDeath Exception 又可分为 RuntimeException CheckedException
    Error Java 程序运行错误,如果程序在启动时出现 Error ,则启动失败;如果程序在运行过程中
    出现 Error ,则系统将退出进程。出现 Error 通常是因为系统的内部错误或资源耗尽, Error 不能被在
    运行过程中被动态处理。如果程序出现 Error ,则系统能做的工作也只能有记录错误的成因和安全
    终止。
    Exception Java 程序运行异常,即运行中的程序发生了人们不期望发生的事件,可以被 Java
    常处理机制处理。 Exception 也是程序开发中异常处理的核心,可分为 RuntimeException (运行时异
    常)和 CheckedException (检查异常),如图 2-7 所示。
    RuntimeException :指在 Java 虚拟机正常运行期间抛出的异常, RuntimeException 可以被捕获
    并处理,如果出现 RuntimeException ,那么一定是程序发生错误导致的。我们通常需要抛出该异常
    或者捕获并处理该异常。常见的 RuntimeException NullPointerException ClassCastException
    ArrayIndexOutOf BundsException 等。
    CheckedException :指在编译阶段 Java 编译器会检查 CheckedException 异常并强制程序捕获和
    处理此类异常,即要求程序在可能出现异常的地方通过 try catch 语句块捕获并处理异常。常见的
    CheckedException 有由于 I/O 错误导致的 IOException SQLException ClassNotFoundException 等。 该类异常一般由于打开错误的文件、SQL 语法错误、类不存在等引起。

     

    反射机制
    2.3.1 动态语言的概念
    动态语言指程序在运行时可以改变其结构的语言,比如新的属性或方法的添加、删除等结构上
    的变化。 JavaScript Ruby Python 等都属于动态语言; C C++ 不属于动态语言。从反射的角度来
    说, Java 属于半动态语言。
    2.3.2 反射机制的概念
    反射机制指在程序运行过程中,对任意一个类都能获取其所有属性和方法,并且对任意一个对
    象都能调用其任意一个方法。这种动态获取类和对象的信息,以及动态调用对象的方法的功能被称
    Java 语言的反射机制。
    2.3.3 反射的应用
    Java 中的对象有两种类型:编译时类型和运行时类型。编译时类型指在声明对象时所采用的类
    型,运行时类型指为对象赋值时所采用的类型。
    在如下代码中, persion 对象的编译时类型为 Person ,运行时类型为 Student ,因此无法在编译时
    获取在 Student 类中定义的方法:
    因此,程序在编译期间无法预知该对象和类的真实信息,只能通过运行时信息来发现该对象和
    类的真实信息,而其真实信息(对象的属性和方法)通常通过反射机制来获取,这便是 Java 语言中
    反射机制的核心功能。
    2.3.4 Java 的反射 API
    Java 的反射 API 主要用于在运行过程中动态生成类、接口或对象等信息,其常用 API 如下。
    Class 类:用于获取类的属性、方法等信息。
    Field 类:表示类的成员变量,用于获取和设置类中的属性值。
    Method 类:表示类的方法,用于获取方法的描述信息或者执行某个方法。
    Constructor 类:表示类的构造方法。
    2.3.5 反射的步骤
    反射的步骤如下。
    1 )获取想要操作的类的 Class 对象,该 Class 对象是反射的核心,通过它可以调用类的任意方
    法。
    2 )调用 Class 对象所对应的类中定义的方法,这是反射的使用阶段。
    3 )使用反射 API 来获取并调用类的属性和方法等信息。
    获取 Class 对象的 3 种方法如下。
    1 )调用某个对象的 getClass 方法以获取该类对应的 Class 对象:
    2 )调用某个类的 class 属性以获取该类对应的 Class 对象:

    3 )调用 Class 类中的 forName 静态方法以获取该类对应的 Class 对象,这是最安全、性能也最
    好的方法:

     

    我们在获得想要操作的类的 Class 对象后,可以通过 Class 类中的方法获取并查看该类中的方法
    和属性,具体代码如下:
    创建对象的两种方式
    创建对象的两种方式如下。
    使用 Class 对象的 newInstance 方法创建该 Class 对象对应类的实例,这种方法要求该 Class 对象
    对应的类有默认的空构造器。
    先使用 Class 对象获取指定的 Constructor 对象,再调用 Constructor 对象的 newInstance 方法创建
    Class 对象对应类的实例,通过这种方法可以选定构造方法创建实例。 创建对象的具体代码如下
     
    Method invoke 方法
    Method 提供了关于类或接口上某个方法及如何访问该方法的信息,那么在运行的代码中如何
    动态调用该方法呢?答案就通过调用 Method invoke 方法。我们通过 invoke 方法可以实现动态调
    用,比如可以动态传入参数及将方法参数化。具体过程为:获取对象的 Method ,并调用 Method
    invoke 方法,如下所述。
    1 ) 获 取 Method 对 象 : 通 过 调 用 Class 对 象 的 getMethod(String name, Class...
    parameterTypes) 返回一个 Method 对象,它描述了此 Class 对象所表示的类或接口指定的公共成员方法。name 参数是 String 类型,用于指定所需方法的名称。 parameterTypes 参数是按声明顺序标识该方法的形参类型的Class 对象的一个数组,如果 parameterTypes null ,则按空数组处理。
    2 )调用 invoke 方法:指通过调用 Method 对象的 invoke 方法来动态执行函数。 invoke 方法的具
    体使用代码如下:
    getMethod("setName",String.class) 获取一个 method 对象;接着使用 Class 对象获取指定的
    Constructor 对象并调用 Constructor 对象的 newInstance 方法创建 Class 对象对应类的实例;最后通过调
    method.invoke 方法实现动态调用,这样就通过反射动态生成类的对象并调用其方法。
    2.4 注解
    2.4.1 注解的概念
    注解( Annotation )是 Java 提供的设置程序中元素的关联信息和元数据( MetaData )的方法,
    它是一个接口,程序可以通过反射获取指定程序中元素的注解对象,然后通过该注解对象获取注解 中的元数据信息。
    2.4.2 标准元注解: @Target @Retention @Documented @Inherited
    元注解( Meta-Annotation )负责注解其他注解。在 Java 中定义了 4 个标准的元注解类型
    @Target @Retention @Documented @Inherited ,用于定义不同类型的注解。
    1 @Target @Target 说明了注解所修饰的对象范围。注解可被用于 packages types (类、
    接口、枚举、注解类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变
    量(循环变量、 catch 参数等)。在注解类型的声明中使用了 target ,可更加明确其修饰的目标,
    target 的具体取值类型如表 2-1 所示。

     

     

  • 相关阅读:
    java:观察者模式
    肖sir__mysql之三表__008
    面试:听说你用过 MQ,能具体说说吗?
    leetcode:6243. 到达首都的最少油耗【变种子树大小统计 + 从边的角度出发 + 思维转换】
    从统计语言模型到预训练语言模型---预训练语言模型(BERT,GPT,BART系列)
    2023计算机Android毕业设计选题推荐(1)
    无线智慧城市业务方案建设
    阿里云服务器被ddos攻击,不断运行脚本占据系统资源,依附在某些应用绑定运行。无法获取根源。
    python 2018全国自学考试第5章 第35题,求出完整数了我忽略了。我竟然成功了太好了 排名21297
    uniapp自动识别并切换到pad端、pc端【不断更新】【伸手党福利】
  • 原文地址:https://blog.csdn.net/chenyong6301567/article/details/126948235