Java基础学习笔记

Java

  • 方法
    • 定义:完成特定功能的代码块
    • 格式
      • 修饰符
      • 返回值类型:结果的数据类型
      • 方法名
      • 参数
        • 实际参数
        • 形式参数
      • 方法体语句
      • 返回值
    • 调用
      • 有明确返回值的调用
        • 单独调用(无意义,不推荐)
        • 输出调用(有意义,但不够好)
        • 赋值调用(建议使用)
        • 注意事项
          • 不调用不执行
          • 方法与方法是平等关系,不能嵌套定义
          • 方法定义的时候参数之间用逗号隔开
        • void类型返回值的调用
          • 只有单独调用
    • 重载
      • 定义
        • 方法的功能相同,参数列表不同的情况,Java允许起一样的名字
          • 参数个数不同
          • 参数类型不同
      • 原理
        • JVM会根据不同的参数调用不同的功能
      • 特点
        • 与返回值无关,只看方法名和参数列表
  • 数组
    • 定义
      • 数组是存储同一种数据类型多个元素的集合,可以看做一个容器
      • 数组可以存基本类型和引用类型
      • 数组必须先初始化再使用
        • 初始化
          • 定义
            • 数组中的数组元素分配内存空间,并为每个数组元素赋值
          • 方式
            • 动态初始化
              • 只指定数组长度,系统分配
            • 静态初始化
              • 指定每个数组元素的初始值,系统决定数组长度
    • 内存分配
        • 存储局部变量
          局部变量:在方法定义中或方法声明上的变量都称为局部变量
        • 栈内存的数据用完就释放掉
        • 存储new出来的东西
        • 每一个new出来的东西都有地址值
        • 使用完毕变成垃圾,但是并没有立即回收,会在垃圾回收器空闲的时候回收
      • 方法区
      • 本地方法区(与系统有关)
      • 寄存器(给CPU使用)
    • 二维数组
      一个元素为一维数组的数组
  • 面向对象
    • 面向对象思想
      • 面向过程
        强调的是每个过程的步骤
      • 面向对象
        强调的是对象,然后由对象去调用功能
      • 思想特点
        • 更加符合我们思想习惯的思想
        • 复杂事情简单化
        • 执行者变成指挥者
      • 特征
        • 封装
        • 继承
        • 多态
      • 开发
        • 不断创建对象、使用对象、指挥对象做事情
      • 设计
        • 管理和维护对象之间的关系
    • 类与对象及其使用

      • 一组相关的属性和行为的集合,抽象概念
        • 成员变量
          位置不同,在类中方法外
        • 成员方法
          一样的格式
      • 对象
        该类事物的具体体现,具体存在的个体
    • 对象的内存图
      • 一个对象

 

      • 两个对象

 

      • 三个对象

 

    • 成员变量和局部变量的区别
      注意事项:局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则
      • 在类中的位置不同
        • 成员变量
          • 类中方法外
        • 局部变量
          • 方法内或者方法声明上
      • 在内存中的位置不同
        • 成员变量
          • 堆内存
        • 局部变量
          • 栈内存
      • 生命周期不同
        • 成员变量
          • 随着对象的存在而存在,随着对象的消失而消失
        • 局部变量
          • 随着方法的调用而存在,随着方法的调用完毕而消失
      • 初始值不同
        • 成员变量
          • 有默认的初始化值
        • 局部变量
          • 没有默认的初始化值,必须先定义、赋值,才能使用
    • 匿名对象
      • 应用场景
        • 仅仅只调用一次的时候可以使用,可以作为实际参数传递,调用多次的时候不合适,相当于两个不同的变量
      • 好处
        • 匿名对象调用完毕就是垃圾,可以被垃圾回收器回收
    • 封装
      隐藏对象的属性和实现细节,仅仅对外提供公共访问方式
      • 好处
        • 隐藏实现细节,提供公共的访问方式
        • 提高了代码的复用性
        • 提高了安全性
      • 封装原则
        • 将不需要对外提供的内容都隐藏起来
        • 把属性隐藏,提供公共方法对其访问
      • private关键字
        private修饰的成员只在本类中才能访问
        • 定义
          • 权限修饰符
          • 可以修饰成员(成员变量和成员方法)
        • 应用
          • 把成员变量用private修饰
          • 提供对应的getXxx()/setXxx()方法
    • this关键字
      代表所在类的对象引用
      • 方法被哪个对象调用,this就代表那个对象

 

      • 何时使用this
        • 局部变量隐藏成员变量
        • 其他与super一起记录
    • 构造方法
      给对象的数据进行初始化
      • 格式
        • 方法名与类名相同
        • 没有返回值类型,连void都没有
        • 没有具体的返回值
      • 注意事项
        • 如果没有给出构造方法,系统将自动提供一个无参的构造方法
        • 如果给出了构造方法,系统将不再提供默认的无参构造方法
          如果还想使用无参构造方法,就必须自己给出,建议永远自己给出无参构造方法
        •  
    • static关键字
      • 特点
        • 可以修饰成员变量,还可以修饰成员方法
        • 随着类的加载而加载
          回想main方法(main为静态方法)
        • 优先于对象存在
        • 被类的所有对象共享
          这也是我们判断是否使用静态关键字的条件
        • 可以通过类名调用,也可以通过对象名调用
          推荐使用类名调用,静态修饰的内容称为:与类相关的,类成员
      • main方法的格式讲解
        • public:公共的,访问权限是最大的,由于main方法是被jvm调用,所以权限要够大
        • static:静态的,不需要创建对象调用,类名可以调用,方便jvm的调用。
        • void:无返回值,main方法被jvm调用,返回内容无意义
        • main:是一个常见的方法入口。
        • string[] args:字符串数组,早期为了接收键盘录入的的数据
      • 注意事项
        • 在静态方法中是没有this关键字的
          静态是随着类的加载而加载,this随着对象的创建而存在
        • 静态方法只能访问静态的成员变量和静态的成员方法
          • 静态方法
            • 成员变量:只能访问静态变量
            • 成员方法:只能访问静态成员方法
          • 非静态方法
            • 成员变量:可以是静态的,也可以是非静态的
            • 成员方法:可以是静态的成员方法,也可以是非静态的成员方法
      • static内存图解

 

      • 工具类中使用静态

 

    • 如何制作一个类说明书
      • 写一个工具类
      • 对这个类加入文档注释
        /****/​​
      • 用工具解析文档注释
      • 格式
        javadoc -d 目录 -author -version XXXXXX.java
      • 普遍错误
        • 找不到可以文档化的公共或受保护的类:告诉我们权限不够
    • 如何使用Java帮助文档
      • 打开帮助文档,点击显示,找到索引,看到输入框
      • 输入框输入
      • 看包
        java.lang包下的类不需要导入,其他的全部需要导入
      • 看类的解释和说明,看该类的版本
      • 看类的结构
        成员变量 字段摘要构造方法 构造方法摘要成员方法 方法摘要​​
      • 学习构造方法
        • 有构造方法 即创建创建对象
        • 无构造方法 成员可能都是正态的
      • 看成员方法
        • 左边
          • 是否静态
            如果静态,可以通过类名调用
          • 返回值类型
        • 右边
          • 看方法名
          • 参数列表
    • 代码块
      Java中,使用{}括起来的代码被称为代码块,根据其位置和声明的不同么一分为局部代码块,构造代码块,静态代码块,同步代码块(多线程讲解)
      • 局部代码块
        在方法中出现
        • 限定变量生命周期,及早释放,提高内存利用率
      • 构造代码块
        在类中方法外出现
        • 多个构造方法中相同的代码放到一起,每次调用构造都执行,并且在构造方法前执行
        • 对对象进行初始化
      • 静态代码块
        在类中方法外出现,并加上static修饰
        • 用于给类进行初始化,在加载的时候就执行,并且只执行一次
        • 对类进行初始化
      • 执行顺序
        • 静态代码块(只执行一次)-->构造代码块(每次调用构造方法都执行)-->构造方法
    • 继承
      多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
      • 好处
        • 提高了代码的复用性
          多个类相同的成员可以放到同一个类中
        • 提高了代码的维护性
          如果功能的代码需要修改,修改一处即可
        • 类与类之间产生了关系,是多态的前提
          其实这也是继承的一个弊端:类的耦合性很强
      • 开发的原则:低耦合,高内聚
        • 耦合
          类与类的关系
        • 内聚
          自己完成某件事情的能力
      • 特点
        • 只支持单继承,不支持多继承
        • Java支持多层继承(继承体系)
      • 注意事项
        • 子类智能集成父类所有非私有的成员(成员变量和成员方法)
          体现了继承的另一个弊端:打破了封装性
        • 子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法
        • 不要为了部分功能而去继承
          如果有两个类AB。只有他们符合AB的一种,或者BA的一种,就可以考虑使用继承。继承其实体现的是一种关系“is a”
      • 继承中成员变最的关系
        • A:千类中的成员变量和父类中的成员变量名称不一样
        • B:子类中的成员变量和父类中的成员变量名称一样
          • 在子类方法中访问一个变量的查找顺序
            • a:在子类方法的局部范围找,有就使用
            • b:在子类的成员范围找,有就使用
            • C:在父类的成员范围找,有就使用
            • d:找不到则报错
      • super关键字
        用法与this相似
        • this与super的区别
          • this代表本类对应的引用
          • super代表父类存储空间的标识(可以理解为父类引用,可以操作父类的成员)
        • 使用方法
          • 调用成员变量
            this.成员变量 调用本类的成员方法super.成员变量 调用父类的成员方法
          • 调用构造方法
            this... 调用本类的构造方法super... 调用父类的构造方法
          • 调用成员方法
            this.成员方法 调用本类的成员方法super.成员方法 调用父类的成员方法
      • 继承中构造方法的关系
        • 子类中所有的构造方法默认都会访问父类中空参数的构造方法
          子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化。每一个构造方法的第一条语句默认都是:super()
        • 如果父类没有无参构造方法,解决方法
          • 在父类中加一个无参构造方法
          • 通过使用super关键字去显示的调用父类的带参构造方法
          • 子类通过this去调用本类的其他构造方法
            子类中一定要有一个去访问了父类的构造方法,否则父类数据就没有初始化
        • 注意事项
          • this(...)或者super(...)必须出现在第一条语句上
          • 如果不放在第一条语句上,就可能对父类的数据进行了多次初始化,所以必须放在第一条语句上。
      • 继承中成员方法关系
        • 子类中的方法和父类中的方法名不一样
        • 子类中的方法和父类中的方法名一样
          • 先调用子类中有无方法
          • 再看父类中有无这个方法
          • 如果没有就报错
      • 方法重写
        • 方法重载和重写
          • 方法重载
            本类中出现的方法名一样,参数列表不同的方法,与返回值无关
          • 方法重写
            子类中出现了和父类中一模一样的方法声明,也被称为方法覆盖,方法复写
        • 方法重写的应用
          当子类需要父类的功能,而功能主体有自己特有内容是,可以重写父类中的方法,这样,既沿袭了父类的功能,有定义了子类特有的内容​​
        • 注意事项
          • 父类中私有方法不能被重写
            父类私有方法子类根本无法继承
          • 子类重写父类方法时,访问权限不能更低
          • 父类静态方法,子类也必须通过静态方法进行重写
    • final
      由于继承中有方法重写,父类的功能会被子类覆盖,如果想使用父类功能,故有final
      • 特点
        • 可以修饰类,该类不能被继承
        • 可以修饰方法,该方法不能被重写
        • 可以修饰变量​,该变量不能被重新赋值,这个变量为常量
      • final修饰变量的初始化时机
        • 被final修饰的变量只能赋值一次
        • 在构造方法完毕前(非静态的常量)
    • 多态
      某一个事物在不同时刻表现出来的不同状态
      • 前提
        • 要有继承关系
        • 要有方法重写
          没有重写就没有意义
        • 要有父类引用指向子类对象
          f = new 子()
      • 成员访问特点
        • 成员变量
          编译看左边,运行看左边
        • 构造方法
          创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化
        • 成员方法
          编译看左边,运行看右边(由于方法重写)
        • 静态方法
          编译看左边,运行看左边(静态变量与类有关,不能算重写,所以访问还是左边的)
      • 好处
        • 提高代码维护性
          继承保证
        • 提高代码扩展性
          多态保证
      • 弊端
        • 不能用子类特有功能
        • 解决办法
          把父类的引用强制转换为子类的引用
      • 对象间转型问题
        • 向上转型
          Fu f = new Zi()
        • 向下转型
          Zi z = Zif //要求该f不许是能够转换为Zi
      • 多态继承的内存图

 

    • 抽象类
      没有方法体的方法为抽象方法,类中如果有抽象方法 ,该类必须定义为抽象类
      • 抽象类的特点
        • 抽象类和抽象方法必须用abstract关键修饰
        • 抽象类中不一定有抽象方法,但是有抽象方法的类必须定义为抽象类
        • 抽象类不能实例化
          • 因为它不是具体的
          • 抽象类有构造方法,但是不能实例化。构造方法用于子类访问父类数据的初始化
        • 抽象类的子类
          • 如果不想重写抽象方法,是一个抽象类
          • 重写所有的抽象方法,这个时候子类是一个具体的类
        • 抽象类的实例化其实是靠具体的子类实现的,是多态的方式
      • 抽象类的成员特点
        • 成员变量
          既可以是常量,也可以是变量
        • 构造方法
          有,用于子类访问父类数据的初始化
        • 成员方法
          既可以是抽象的,也可以是非抽象的
          • 抽象类成员方法特性
            • 抽象方法
              强制要求子类做的事情
            • 非抽象方法
              子类继承的事情,提高代码复用性
      • 几点小问题
        • 一个类如果没有抽象方法,定义为抽象类有什么意义
          • 不让创建对象
        • 抽象类不能和哪些关键字共存
          • private
            冲突
          • final
            冲突
          • static
            无意义
    • 接口
      为了体现事物功能的扩展性,Java提供了接口来定义这些额外功能,并不给出具体实现
      • 特点
        • 接口用关键字interface表示
          interface 接口名()
        • 类实现接口用implements表示
          class 类名 implements 接口名{ }
        • 接口不能实例化
          • 按照多态的方式来实例化
        • 多态出现的场景
          • 具体类多态(几乎没有)
          • 抽象类多态(常用)
          • 接口多态(最常用)
        • 接口的子类
          • 可以是抽象类,但是意义不大
          • 可以是具体类,要重写接口中所有抽象方法(推荐)
      • 接口成员特点
        接口名+Impl这种格式是接口的实现类格式
        • 成员变量:只能是常量,并且是静态的
          默认修饰符:public static final建议:自己手动给出
        • 构造方法:接口没有构造方法
          所有的类都默认继承自一个类:ObjectObject是类层次结构的根类。每个类都使用Object作为超类
        • 成员方法:只能是抽象方法
          默认修饰符:public abstract建议:自己手动给出​​
      • 接口与类
        • 类与类:继承关系,只能单继承,可以多层继承
        • 类与接口:实现关系,可以单实现,也可以多实现,并且还可以在继承一个类的同时实现多个接口
        • 接口与接口:继承关系,可以单继承,也可以多继承
      • 抽象类与接口的区别
        • 成员区别
          • 抽象类
            • 成员变量:可以变量,也可以常量
            • 构造方法:有
            • 成员方法:可以抽象,也可以非抽象
          • 接口
            • 成员变量:只可以常量
            • 成员方法:只可以抽象
        • 设计理念区别
          • 抽象类:被继承体现的是:“is a”的关系,抽象类中定义的是该继承体系的共性功能
          • 接口:被实现体现的是:“;like a”的关系,接口中定义的是该继承体系的扩展功能
    • 形式参数
      • 基本类型(太简单)
      • 引用类型
        • 类:需要的是该类的对象
        • 抽象类:返回的是该抽象类的子类对象
        • 接口:返回的是该接口的实现类对象
    • 链式编程
      • 每次调用完毕方法后,返回的是一个对象

    • 文件夹
      • 作用
        • 把相同的类名放在不同的包中
        • 对类进行分类管理
      • 定义
        • package 包名;
        • 多级包用.分开
      • 注意事项
        • package必须是程序的第一条可执行代码
        • package语句在一个java文件中只能有一个
        • 如果没有package,默认表示无包名
    • 权限修饰符
      • private
        本类
      • 默认
        本类、同一个包下(子类和无关类)
      • protected
        本类、同一个包下(子类和无关类)、不同包下(子类)
      • public
        本类、同一个包下(子类和无关类)、不同包下(子类)、不同包下(无关类)
    • 内部类
      把类定义在其他类的内部,这个类就被称为内部类
      • 访问特点
        • 内部类可以直接访问外部类的成员,包括私有
        • 外部类要访问内部类的成员,必须要创建对象
      • 内部类位置
        • 成员位置定义的类:成员内部类
          • 外部类名.内部类名 对象名 = 外部类对象.内部类对象;
          • 成员内部类的修饰符
            • private 为了保证数据的安全性
            • static为了让数据访问更方便(内部类用静态修饰是因为内部类可以看看做是外部类的成员)
              • 被静态修饰的成员内部类只能访问外部类的静态成员
              • 内部类被静态修饰后的方法
                • 外部类名.内部类名 对象名 = 外部类名.内部类名();
        • 局部位置定义的类:局部内部类
          • 可以直接访问外部类的成员
          • 可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
          • 注意事项
            • 局部内部类访问局部变量必须用final修饰
            • 原因:局部变量是随着方法的调用而调用,随着调用的完毕而消失,而堆内存的内容并不会立即消失。所以,我们加final修饰。加入final修饰后,这个变量成了常量。
        • 匿名内部类
          内部类的简化写法
          • 前提:存在一个类或接口,这里的类可以是具体类也可以是抽象类
          • 格式: new 类名或者接口名() {重写方法; }
          • 本质:是一个继承了该类或者实现了该接口的子类匿名对象
          • 开发中应用(安卓经常用)
  • 常见对象
    • Object类
      类层次结构的根类,每个类都使用Object作为超类。每个类都直接或者间接继承自Object
      • public int hashCode( )
        • 返回该对象的哈希码值
          一般是通过将该对象的内部地址转换成一个整数来实现的
      • public final class getClass( )
        • 返回此Object的运行时类
        • class 类的方法
          • public String getName( )以String的形式返回此Class对象所表示的实体(类、接口、数组类、基本类型或void)名称
      • public String toString( )
        • 返回该对象的字符串表示
        • toString( )方法的值等价于它 getClass( ).getName( ) + '@' + Integer.toHexString(hashCode())
        • 这个信息没有任何意义。建议所有子类都重写该方法,把该类的所有成员变量值组成返回即可
        • 重写最终版方案:自动生成toString( )方法
        • 直接输出一个对象的名称,其实就是调用该类的toString( )方法
      • public boolean equals(Object obj)
        • 指示其他某个对象是否与此对象“相等”
        • 默认情况下比较的是地址值。比较地址值一般来说意义不大,所以要重写该方法
        • 一般用来比较对象的成员值是否相等
        • 源码
          • {return (this==obj);}
        • “==”
          • 基本类型:比较的是值是否相同
          • 引用类型:比较的是地址值是否相同
        • equals
          • 引用类型:默认情况下,比较的是地址值
          • 不过可以根据情况自己重写该方法。一般重写都是自动生成,比较对象的成员变量值是否相同
        • 重写的代码优化
          • 提高效率
          • 提高程序的健壮性
          • 最终还是自动生成
        • 具体案例

 

      • protected void finalize( )
        • 当垃圾回收器确定不存在该对象的更多引用时,由对象的垃圾回收器调用此方法。
        • 用于垃圾回收,但是什么时候回收不确定
      • protected Object clone( )
        • 创建并返回此对象的一个副本
        • 重写该方法
        • Cloneable:此类实现了Cloneable接口,以指示Object.clone( )方法可以合法地对该类实例进行按字段复制
          • 这个接口为标记接口,告诉我们事先该接口的类就可以实现对象的复制了
        • 深度克隆(没有讲)
    • Scanner类
      • public final class System extends Object
      • 概述
        • JDK5以后用于获取用户的键盘输入
      • 构造方法
        • Scanner(InputStream source)
      • 成员方法
        • 基本格式
          • public boolean hasNextXxx( ) 判断是否还有下一个输入项,其中Xxx可以是int,double等,如果需要判断是否包含下一个字符串,则可以省略Xxx
          • public boolean nextXxx( ) 获取下一个输入项。Xxx的含义和上个方法中的Xxx相同
          • 默认情况下,Scanner使用空格,回车等作为分隔符
        • 常用方法
          • public int nextline( )
          • public String nextLine( )
        • 出现问题
          • 先获取一个数值,再获取一个字符串,会出现问题
        • 解决方法
          • 先获取一个数值后,再创建一个新的键盘录入对象获取字符串
          • 把所有的输入都先按照字符串获取,之后进行格式转换
    • String类
      • 特点
        • 字符串:字符串字面值“abc”也可以看成是一个字符串对象
        • 字符串直接赋值的方式:先到字符串常量池里去找,如果有就直接返回,没有就创建并返回
        • 字符串是常量,一旦被赋值,就不能被改变(值不能变)

 

      • 构造方法
        • public String( )
          空构造
        • public String(byte[] bytes)
          把字节数组转成字符串
        • public String(byte[] bytes, int index, int length)
          把字节数组的一部分转成字符串
        • public String(char[] value)
          把字符数组转成字符串
        • public String(char[] value, int index, int count)
          把字符数组的一部分转成字符串
        • public String(String original)
          把字符串常量值转成字符串
      • 注意问题
        • String s = new String("hello")和String s = “hello”的区别

 

          • 前者会创建两个对象,后者只会创建一个对象
        • 字符串相加
          • 如果是变量相加,先开空间,再拼接
            s1=“hello"s2​ ="world"​s3=s1+s2​
          • 如果是常量相加,先加,然后在常量池找,如果有就直接返回,否则就创建
            s3="hello"+"world"
      • 功能
        • 判断功能
          • boolean equals (Object obj) :比较字符串的内容是否相同
          • boolean equalsIgnoreCase (String str) :比较字符串的内容是否相同,忽略大小写
          • boolean contains (String str):判断大串中是否包含小串
          • boolean startswith (String str):判断字符串是否以某个指定的字符串开头
          • boolean endswith (String str):判断字符串是否以某个指定的字符串结尾
          • boolean isEmpty ( ):判断字符串是否为空
          • 注意
            • 字符串内容为空和字符串对象为空
              • 内容为空:String s=" " ;
                • 可以调用方法
              • 字符串对象为空:String s = null;
                • 不能调用方法,对象不存在,空指针异常
        • 获取功能
          • int length ( ):获取字符串的长度
          • char charAt (int index):获取指定索引位置的字符
          • int indexof (int ch):返回指定字符在此字符串中第一次出现的索引
            • 为什么是int类型,而不是char类型
            • 'a'和97其实都可以代表'a'
          • int indexof (String str):返回指定字符在此字符串中第一次出现的索引
          • int indexof(int ch,int fromIndex):返回指定字符在此字符串中从指定位置后第一次出现的索引
          • int indexof(string str,int fromIndex):返回指定字符在此字符串中从指定位置后第一次出现的索引
          • string substring(int start):从指定位置开始截取字符串
          • string substring(int start,int end):从指定位置开始到指定位置结束截取字符串(包含start这个索引)
          • 遍历获取字符串中的每一个字符

 

        • 转换功能
          • byte[ ] getBytes( ):把字符串转换为字节数组
          • char[ ] tocharArray( ):把字符串转换为字符数组
          • static string valueof(char[ ] chs):把字符数组转成字符串
          • static string valueof(int i):把int类型的数据转成字符串
            • 注意:String类的valueOf方法可以把任意类型的数据转成字符串
          • string toLowerCase( ):把字符串转成小写
          • string toUpperCase( ):把字符串转成大写
          • String concat (String str):把字符串拼接
        • 替换功能
          • String replace(char old,char new)
          • String replace(String old,String new)
        • 去除字符串两端空格
          • String trim( )
        • 按照字典顺序比较两个字符串
          • int compareTo(String str)
          • int compareToIgnoreCase(String str)
    • StringBuffer类
      • 如果对字符串进行拼接操作,每次拼接,都会构建一个新的String对象,耗时并且浪费空间,StringBuffer可以解决这个问题
      • 线程安全的可变字符序列
        • 线程安全
        • 效率低
      • 构造方法
        • public StringBuffer( ):无参构造方法
        • public StringBuffer(int capacity):指定容量的字符串缓冲区对象
        • public StringBuffer(String str):指定字符串内容的字符串缓冲区对象
      • 方法
        • public int capacity( ):返回当前容量(理论值)
        • public int length( ):返回长度(字符数)(实际值)
      • 功能
        • 添加功能
          • public StringBuffer append(String str)
            • 可以把任何类型添加到字符串缓冲区里面
            • 返回字符串缓冲区本身
          • public StringBuffer insert(int offset, String str)
            • 在指定位置把任意类型的数据插入到字符串缓冲区里面
            • 返回字符串缓冲区本身
        • 删除功能
          • public StringBuffer deleteCharAt (int index)
            • 删除指定位置的字符
            • 返回本身
          • public StringBuffer delete (int start, int end)
            • 删除从指定位置开始指定位置结束的内容
            • 返回本身
        • 替换功能
          • public StringBuffer replace(int start,int end,String str)
            • 从start开始到end用str替换
            • 返回本身
        • 反转功能
          • public StringBuffer reverse( )
        • 截取功能
          • public String substring(int start)
          • public String substring(int start, int end)
          • 返回值是String类型,本身没有发生改变
      • 注意问题
        • String、StringBuilder和StringBuffer
          • String
            • 内容不可变
          • StringBuffer
            • 可变的字符序列
            • 提供与StringBuffer兼容的API,但是不保证同步。
            • 作为StringBuffer的简易替换,用在字符串缓冲区被单个线程使用的时候
            • 在大多数实现中,比StringBuffer快
        • StringBuffer和数组的区别
          • StringBuffer
            • 数据最终是一个字符串数据
          • 数组
            • 数组可以放置多种数据,但是必须是同一种数据类型
        • 形式参数
          • String作为参数传递,效果和基本类型作为参数传递是一样的
    • Arrays类
      • 工具类,包含用来操作数组(比如排序和搜索)的各种方法,还包含一个允许将数组作为列表来查看的静态工厂
      • 方法
        • public static String toString(int[ ] a)
          • 把数组转成字符串
        • public static void sort(int[ ] a)
          • 对数组进行排序
          • 底层为快速排序方法
        • public static int binarySearch(int[ ] a, int key)
          • 二分查找
    • 基本类型包装类
      • 为了对基本数据类型进行更多,更方便的操作,Java针对每一种基本数据类型提供了对应的类类型,包装类类型
      • 数据类型的引用类型
        • Byte、Short、Integer、Long、Float、Boolean、Double
      • 用于基本类型与字符串之间的转换
      • Integer类
        • 构造方法
          • public Integer ( int value )
          • public Integer (String s)
            • 这个字符串必须是由数字组成的
        • 成员方法
          • int类型和String类型的相互转换
            • int——String
              • String.valueOf(number)
              • public static String toString (int i)
            • String——int
              • public static int parselnt (String s)
                • Interger.parseInt(s)
              • String -> Integer -> int
                • public int intValue ( )
          • public static Integer valueOf (int i)
          • public static Integer valueOf (String s)
          • 基本进制转换
            • 十进制到二,八,十六进制
              • public static String toBinaryString(int i)
              • public static String toOctalString(int i)
              • public static String toHexString(int i)
            • 十进制到其他进制
              • public static String toString(int i,int radix)
                • 进制的范围:(2-36)
                  • 0-9、a-z加起来36个
            • 其他进制到十进制
              • public static int parseInt(String s,int radix)
      • JDK5的新特性
        • 自动装箱:把基本类型转换为包装类类型
        • 自动拆箱:把包装类类型转换为基本类型
        • 注意
          • 在使用时,Integer x=null;上面代码就会出现NullPointerException
          • 建议先判断是否为Null,然后再使用
          • 通过查看源码,针对-128~127之间的数据,做一个数据缓冲池,如果数据是该范围内的,每次并不创建新的空间
    • Character类
      • 在对象中包装了 一个基本类型char的值
      • 提供了几种方法,以确定字符的类别(小写字母,数字等等),并将字符从大写转换成小写,反之亦然
      • 构造方法
        • Character(char value)
      • 类成员方法
        • public static boolean isUpperCase(char ch)
          • 判断给定的字符是否是大写字符
        • public static boolean isLowerCase(char ch)
          • 判断给定的字符是否是小写字符
        • public static boolean isDigit(char ch)
          • 判断给定的字符是否是数字字符
        • public static char toUpperCase(char ch)
          • 把给定的字符转换为大写字符
        • public static char tolowerCase(char ch)
          • 把给定的字符转换为小写字符
    • 正则表达式
      • 符合一定规则的字符串
      • 表达式的组成规则
        • 规则字符在java.util.regex Pattern类中
        • 常见组成规则
          • 字符
            • x 字符x 'a'表示字符a
            • \\ 反斜线字符\
            • \n 新行(换行)符 ('\u000A')
            • \r 回车符 (’\u000D‘)
          • 字符类
            • [abc] a、b或c
            • [^abc] a、b或c
            • [a-zA-Z] a到z或A到Z,两头的字母包括在内
          • 预定义字符类
            • . 任何字符
            • \d 数字[0-9] \D 非数字
            • \w 单词字符[a-zA-Z_0-9] \W 非单词字符
              在正则表达式里面组成单词的东西必须有这些东西组成
          • 边界匹配器
            • ^ 行的开头
            • $ 行的结尾
            • \b 单词边界
              就是不是单词字符的地方
          • 数量词
            • x?    x,一次或一次也没有
            • X*     x,零次或多次
            • x+      x,一次或多次
            • x{n}     x,恰好n次
            • x{n,}     x,至少n次
            • x{n,m}     x,至少n次,但是不超过m次
      • 判断功能
        • String类的public boolean matches(String regex)
      • 分割功能
        • public String[] split (String regex)
        • 根据给定的正则表达式的匹配拆分此字符串
      • 替换功能
        • public String replaceAll (String regex,String replacement)
          • 使用给定的replacement替换此字符串所有匹配给定的正则表达式的子字符串
      • 获取功能
        • Pattern和Matcher类的使用
          • 模式和匹配器的典型调用顺序
            • 把正则表达式编译成模式对象
              • Pattern p=Pattern. compile(regex)
            • 通过模式对象得到匹配器对象,这个时候需要的是被匹配的字符串
              • Matcher m = p.matcher(String)
            • 调用匹配器对象的功能
              • boolean b = m.matches( )
    • Math类
      • 包含执行基本数学运算方法,如初等指数,对数,平方根和三角函数
      • Math:用于数学运算的类。
      • 成员变量:
        • public static final double PI
        • public static final double E
      • 成员方法
        • public static int abs(int a):绝对值
        • public static double ceil(double a):向上取整
        • public static double floor(double a):向下取整
        • public static int max(int a,int b):最大值
        • public static double pow(double a,double b):a的b次幂
        • public static double random():随机数[0.0, 1.0)
          • 获取一个1-100之间的随机数
            • (int)(Math.random()*100+1)
          • 获取任意范围内的随机数
          • (int) (math.random()*start+end)
        • public static int round(float a):四舍五入
        • public static double sqrt(double a):正平方根
    • Random类
      • 此类的实例用于生成伪随机数流
      • 构造方法
        • public Random():没有给种子,用的是默认种子,是当前时间的毫秒值
        • public Random(long seed):给出指定的种子
      • 成员方法
        • public int nextInt(): 返回的是int范围内的随机数
        • public int nextInt(int n):返回的是[0,n)范围的内随机数
    • System类
      • System类包含一些有用的类字段方法,不能被实例化
      • 成员方法
        • public static void gc():运行垃圾回收器
        • public static void exit(int status):终止当前正在运行的Java虚拟机。参数用作状态码;按照惯例,非零的状态码表示异常终止
        • public static long currentTimeMillis():返回以毫秒为单位的当前时间
        • public static void arraycopy(Obiect src, int srcPos, Object dest, int destPos, int length):从指定源数组中赋值一个数组,复制从指定的位置开始,到目标数组的指定位置结束
          • src-源数组。
          • srcPos-源数组中的起始位置。
          • dest-目标数组。
          • destPos-目标数据中的起始位置。
          • 1ength-要复制的数组元素的数量。
    • BigInteger类
      • 可以让超过Integer范围内的数据进行运算
      • 构造方法
        • public BigInteger(String val)
      • 成员方法
        • public BigInteger add(BigInteger val):加
        • public BigInteger subtract(BigInteger val):减
        • public BigInteger multiply(BigInteger val):乘
        • public BigInteger divide(BigInteger val):除
        • public BigInteger[] divideAndRemainder(BigInteger val):返回商和余数的数组
    • BigDecimal类
      • 由于在运算的时候,float类型和double很容器丢失精度。所以,为了能精确的表示、计算浮点数,Java提供了BigDecimal
      • 构造方法
        • public BigDecimal(String val)
      • 成员方法
        • public BigDecimal add(BigDecimal augend)
        • public BigDecimal subtract(BigDecimal subtrahend)
        • public BigDecimal multiply(Bigpecimal multiplicand)
        • public BigDecimal divide(BigDecimal divisor)
        • public BigDecimal divide(BigDecimal divisor,int scale,int roundingMode):商,几位小数,如何舍取
    • Date类
      • 表示特定的瞬间,精确到毫秒
      • 构造方法
        • Date():根据当前的默认毫秒值创建日期对象
        • Date(long date):根据给定的毫秒值创建日期对象
      • 成员方法
        • public long getTime():获取时间,以毫秒为单位
        • public void setTime(long time):设置时间
      • 从Date得到一个毫秒值
        • getTime()
      • 把一个毫秒值转换为Date
        • 构造方法
        • setTime(long time)
    • DateFormat类
      • DateFormat是日期时间格式化子类的抽象类,它以与语言无关的方式格式化并解析日期或时间
      • 是抽象类,所以使用其子类SimpleDateFormat
      • Date -> String(格式化)
        • public final String format(Date date)
      • String -> Date(解析)
        • public Date parse(String source)
      • SimpleDateFormat构造方法
        • SimpleDateFormat
        • SimpleDateFormat():默认模式
          //Date--String//创建日期对象Date d=new Date();//创建格式化对象//simpleDateFormat sdf=new simpleDateFormat();//给定模式simpleDateFormat sdf=new SimpleDateFormat"yyyyMMddHH:mm:ss");//public final string formatDate dateStrings=sdf.formatd);system.out.printlns);
        •  SimpleDateFormat(String pattern):给定的模式
          y​ M​ d​ H​ m​ s
    • Calendar类
      • Calendar 类是一个抽象类,它为特定瞬间与一组诸如YEAR、MONTH、DAY_OF MONTH、HOUR等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。瞬间可用毫秒值来表示,它是距厉元(即格林威治标准时间1970年1月1日的00:00:00.000,格里高利历)的偏移量。
      • 成员方法
        • public int get(int field):返回给定日历字段的值。日历类中的每个日历字段都是静态的成员变量,并且是int类型。
  • 集合框架
    • 对象数组
      • 对象数组内存图解

 

    • 集合
      • 集合的由来
        • 我们学习的是面向对象语言,而面向对象语言对事物的描述是通过对象体现的,为了方便对多个对象进行操作,我们就必须把这多个对象进行存储。
        • 而要想存储多个对象,就不能是一个基本的变量,而应该是一个容器类型的变量,在我们目前所学过的知识里面,有哪些是容器类型的呢?
        • 数组和StringBuffer。但是呢?StringBuffer的结果是一个字符串,不一定满足我们的要求,所以我们只能选择数组,这就是对象数组。
        • 而对象数组又不能适应变化的需求,因为数组的长度是固定的,这个时候,为了适应变化的需求,Java就提供了集合类供我们使用。
      • 数组和集合的区别
        • 长度区别
          • 数组的长度固定
          • 集合长度可变
        • 内容不同
          • 数组存储的是同一种类型的元案
          • 而集合可以存储不同类型的元素
        • 元素的数据类型问题
          • 数组可以存储基本数据类型,也可以存储引用数据类型
          • 集合只能存储引用类型
      • 集合的继承体系结构图
        Java提供多种集合类,数据结构不同,但是有共性的内容(存储、获取、判断等),通过不断地向上提取,可以得到一个
        • Collection
          • List
            • ArrayList
            • Vector
            • LinkedList
          • Set
            • HashSet
            • TreeSet
        • 分析
          • 从具体到抽象
        • 实现
          • 从抽象到具体使用
        • 使用具体的看到一个继承体现
          • 从老大开始,在小弟。
      • Collection接口概述
        • Collection层次结构中的根接口。Collection表示一组对象,这些对象也称为collection的元素。一些collection允许有重复的元素,而另一些则不允许。一些collection是有序的,而另一些则是无序的。
      • Collection 功能概述
        • 添加功能
          • boolean add(Object obj):添加一个元素
          • boolean addAll(Collection c):添加一个集合的元素
        • 删除功能
          • void clear( ):移除所有元案
          • boolean remove(Object o):移除一个元素
          • boolean removeA1l(Collection c):移除一个集合的元素(是一个还是所有)
        • 判断功能
          • boolean contains(Object o):判断集合中是否包含指定的元素
          • boolean containsAll(Collection c):判断集合中是否包含指定的集合元素(是一个还是所有)
          • boolean isEmpty( ):判断集合是否为空
        • 获取功能
          • Iteratoriterator( )(重点)
            • Object next( ): 获取元素,并移动到下一个位置。
              • NoSuchElementException: 没有这样的元素,因为你已经找到最后了。
            • boolean hasNext( ):如果仍有元素可以选代,则返回true。
            • 示例

 

        • 长度功能
          • int size( ):元素的个数
          • 面试题:数组有没有1ength( )方法呢?字符串有没有1ength( )方法呢?集合有没有1ength( )方法呢?
        • 变集功能
          • boolean retainAll(Collection c):两个集合都有的元素?思考元素去哪了,返回的boolean又是什么意思呢?
            假设有两个集合ABAB做交集,最终的结果保存在A中,B不变。返回值表示的是A是否发生过改变。
      • 把集合转换为数组

 

        • object[ ] toArray( )
          • 把集合转成数组,可以实现集合的遍历
      • 集合的使用步骤:

 

 

        • A:创建集合对象

 

        • B:创建元素对象
        • C:把元素添加到集合
        • D:遍历集合
          • a:通过集合对象获取迭代器对象
          • b:通过选代器对象的hasNext()万法判断是否有元素
          • c:通过选代器对象的next()方法获取元素并移动到下一个位置
    • List集合
      • 有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。
      • 与set不同,列表通常允许重复的元素。
      • List集合的特有功能
        • 添加功能
          • void add(int index,Object element):在指定位置添加元素
        • 获取功能
          • Object get(int index):获取指定位置的元素
        • 列表迭代器
          • ListIterator listIterator():List集合特有的迭代器
          • 该迭代器继承了Iteration迭代器,所以就可以直接使用hasNext() 和next()方法
          • 特有功能
            • Object previous():获取上一个元素
            • boolean hasPrevious():判断是否有元素
            • 注意:ListIterator可以实现逆向遍历,但是必须先正向遍历,才能逆向遮历,所以一般无意义,不使用
        • 删除功能
          • Object remove(int index):根据索引册除元案,返回被删除的元素
        • 修改功能
          • Object set(int index,Object element):根据索引修改元素,返回被修饰的元素
    • 迭代器为什么不定义成一个类,而是一个接口
      • 假设送代器定义的是一个类,这样我们就可以创建该类的对象,调用该类的方法来实现集合的逼历。但是呢?我们想想,java中提供了很多的集合类,而这些集合类的数据结构是不同的,所以,存储的方式和遍历的方式应该是不同的。进而它们的遍历方式也应该不是一样的,最终,就没有定义迭代器类的。
      • 而无论你是那种集合,你都应该具备获取元素的操作,并且,最好在辅助于判断功能,这样,在获取前,先判断。这样就更不容易出错。也就是说,判断功能和获取功能应该是一个集合遍历所具备的,而每种集合的式又不太一样,所以我们把这两个功能给提取出来,并不提供县体实现,这种方式就是接口。
      • 那么,真正的具体的实现类在哪里呢?在真正的具体的子类中,以内部类的方式体现的。
      •  
    • 并发修改异常
      • 问题提出
        • 我有一个集合,如下,请问,我想判断里面有没有"world”这个元素,如果有,我就添加一个"javaee"元素,请写代码实现。
        • ConcurrentModificationException:当方法检到对象的并发修改,但不允许这种修改时,抛出此异常。
      • 产生原因
        • 迭代器是依赖于集合而存在的,在判断成功后,集合的中新添加了元素,而迭代器却不知道,所以就报错了,这个错叫并发修改异常。
        • 其实这个问题描述的是:迭代器遍历元素的时候,通过集合是不能修改元素的。
      • 解决方法
        • 迭代器选代元素,迭代器修改元素

 

          • 而Iterator选代器却没有添加功能,所以我们使用其子接口ListIterator
          • 元素是跟在刚才迭代的元素后面的
        • 集合遍历元素,集合修改元素(普通for)

 

          • 元素是在最后添加的
    • 常见数据结构
      • 数据的组织方式
        • 常见的数据结构的优缺点
    • List的子类特点
      • ArrayList
        • 底层数据结构是数组,查询快,增删慢。
        • 线程不安全,效率高。
      • Vector
        • 底层数据结构是数组,查询快,增删慢。
        • 线程安全,效率低。
        • Vector的特有功能:
          • 添加功能
            • public void addElement(Object obj)
              • 被add()替代
          • 获取功能
            • public object elementAt(int index)
              • --get()
            • public Enumeration elements()
              • --Iterator iterator(
          • boolean hasMoreElements( )
            • hasNext( )
          • object nextElement( )
            • next ( )
      • LinkedList
        • 底层数据结构是链表,查询慢,增删快。
        • 线程不安全,效率高。|
        • LinkedList的特有功能:
          • 添加功能
            • public void addFirst(Object e)
            • public void addLast(Object e)
          • 获取功能
            • public Object getFirst()
            • public Obeict getLast()
          • 删除功能
            • public object removeFirst()
            • public object removeLast()
    • 泛型
      • 泛型的由来
        • 早期的Object类型可以接收任意的对象类型,但是在实际的使用中,会有类型转换的问题。也就存在这隐患,所以Java提供了泛型来解决这个安全问题。
      • 是一种把类型明确的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。参数化类型,把类型当作参数一样的传递
      • 好处
        • 把运行时期的问题提前到了编译期间
        • 避免了强制类型转换
        • 忧化了程序设计,解决了黄色警告线
      • 格式
        • < 数据类型>
          • 必须是引用类型
        • 泛型类
          • 把泛型定义在类上
          • 格式:public class 类名<泛型类型1>
          • 注意:泛型类型必须是引用类型
        • 泛型方法
          • 把泛型定义在方法上
          • 好处
            • 方法可以接受任意类型
          • 格式:public<泛型类型>返回类型方法名(泛型类型)
        • 泛型接口
          • 把泛型定义在接口上
          • 格式:public interface 接口名 <泛型类型1...>
      • 泛型高级(通配符)
        • ?
          • 任意类型,如果没有明确,那么就是Object以及任意的Java类
        • ?extends E
          • 向下限定,E和子类
        • ? super E
          • 向上限定,E和父类
    • 增强for
      • 简化数组和Collection集合的遍历
      • 格式
        • for(元素数据类型 变量 : 数组或者Collection集合){使用变量即可,变量就是元素}
      • 弊端
        • 增强for的目标不能为null
          • 需要做一个判断
      • 增强for是用来代替迭代器的,会有并发异常
    • 静态导入
      • 格式
        • import static包名.…类名.方法名;
      • 可以直接导入到方法的级别
      • 注意事项
        • 方法必须是静态的
        • 如果有多个同名的静态方法,容易不知道使用谁?这个时候要使用,必须加前缀。由此可见,意义不大,所以一般不用,但是要能看懂。
    • 可变参数
      • 定义方法的时候不知道该定义多少个参数
      • 格式
        • 修饰符返回值类型方法名(数据类型... 变量名){ }
        • 注意
          • 这里的变量其实是一个数组
          • 如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最后一个
      • public static List asList (T...a)
        • 把数组转成集合
        • 注意事项
          • 虽然可以把数组转成集合,但是集合的长度不能发生改变
          • 即只能有改操作,不能删不能增加
    • 枚举
      • 是指将变量的值一一列出来,变量的值只限于列举出来的值的范围内。举例:一周只有7天,一年只有12个月等。
      • 回想单例设计模式:单例类是一个类只有一个实例
      • 那么多例类就是一个类有多个实例,但不是无限个数的实例,而是有限个数的实例。这才能是枚举类。
      • 格式
        • 只有枚举项的枚举类
        • public enum枚举类名{枚举项1,枚举项2,枚举项3..;}
      • 注意事项
        • 定义枚举类要用关键字enum·所有枚举类都是Enum的子类
        • 枚举类的第一行上必须是枚举项,最后一个枚举项后的分号是可以省略的,但是如果枚举类有其他的东西,这个分号就不能省略。建议不要省略
        • 枚举类可以有构造器,但必须是private的,它默认的也是private的。枚举项的用法比较特殊:枚举(“”);
        • 枚举类也可以有构造方法,但是枚举项必须重写该方法
        • 枚举在switch语句中的使用
      • 枚举中的方法
        • int compareTo(E o)
        • String name() int ordinal()
        • String toString()
        • T yalueOf(Classtype. String name)
        • values()
    • 多个对象共同使用一个成员变量,用静态变量。
    • Set集合
      • 一个不包含重复元素的collection
        更确切地讲,set 不包含满足el.equalse2)的元素对e1e2,并且最多包含一个null元素。正如其名称所暗示的,此接口模仿了数学上的set抽象。
      • 无序,唯一
        注意:虽然Set集合的元素无序,但是,作为集合来说,它肯定有它自己的存储顺序,而你的顺序恰好和它的存储顺序一致,这代表不了有序,你可以多存储一些数据,就能看到效果。
      • hashSet
        • 通过查看add方法的源码,我们知道了这个方法底层依赖两个方法:hashCode()和equals()
          • 步骤
            • 首先比较哈希值
            • 如果相同,继续走,比较地址值或者走equa1s( )
            • 如果不同,就直接添加到集合中
          • 注意
            • 如果类没有重写hashCode( )和equals( )这两个方法,默认使用的Object( )。一般来说不同相同。
            • 而String类重写了hashCode( )和equals( )方法,所以,它就可以把内容相同的字符串去掉。只留下一个。
        • 哈希表
          • 一个元素为链表的数组
          • 综合数组和链表的好处
        • 哈希值
          • 和对象的成员变量值相关
          • hashCode()和equals()方法自动生成
        • LinkedHashSet
          • 底层数据结构由哈希表和链表组成。
          • 哈希表保证元素的唯一性。
          • 链表保证元素有序。(存储和取出是一致)
      • TreeSet
        • 能够对元素按照某种规则进行排序
        • 排序方式
          • 自然排序 (元素具备比较性)
            • 让元素所属的类作为实现自然排序接口Comparable
            • 真正的比较是依赖于元素的compareTo( )方法,而这个方法是定义在Comparable里面的。所以,你要想重写该方法,就必须是先Comparable接口。这个接口表示的就是自然排序。

 

          • 比较器排序(集合具备比较性)
            • 让集合的构造方法接收一个比较器接口的子类对象Comparator
    • Map集合
      • 可以存储键值对的元素。
      • 一个映射不能包含重复的键;每个键最多只能映射到一个值
      • Map集合的数据结构仅仅针对键有效,与值无关
      • 与collection集合的区别
        • Map是双列的,Collection是单列的
        • Map的键唯一,Collection的子体系Set是唯一的
        • Map集合的数据结构值针对键有效,跟值无关
        • Collection集合的数据结构是针对元素有效
      • Map集合的功能概述
        • 添加功能
          • V put(K key,V value):添加元素
        • 删除功能
          • void clear():移除所有的键值对元素
          • V remove(Object key):根据键册除键值对元素,并把值返回i
        • 判断功能
          • boolean containsKey(Object key):判断集合是否包含指定的键
          • boolean containsValue(Object value):判断集合是否包含指定的值
          • boolean isEmpty():判断集合是否为空
        • 获取功能
          • Set> entrySet( ):Entry实体,返回的是键值对对象的集合
          • V get(Object key):根据键获取值
          • Set keySet():获取集合中所有键的集合
          • Collection values():获取集合中所有值的集合
        • 长度功能
          • int size():返回集合中的键值对的对数
      • Map集合的遍历
        • 根据键找值
          • 获取所有键的集合
          • 遍历键的集合,获取到每一个键
          • 根据键找值
        • 根据键值对对象找键和值
          • 获取所有键值对对象的集合
          • 遍历键值对对象的集合,获取到每一个键值对对象
          • 根据键值对对象找键和值
        • 遍历两种方式图解

 

      • HashMap集合
        • 基于哈希表的Map接口实现
        • 哈希表的作用是用来保证键的唯一性
        • LinkedHashMap
          • 是Map接口的哈希表和链接链表实现,具有可预知的迭代顺序
          • 由哈希表保证
          • 由哈希表保证键的唯一性
          • 由链表保证键盘的有序(存储和取出的顺序一致)
      • TreeMap
        • 基于红黑树(是一种自平衡的二叉树)的Map接口实现
        • 可以保证键的排序和唯一性
          • 排序
            • 自然排序
              • 元素具备比较性
            • 比较器排序
              • 集合具备
      • Hashtable
      • HashMap和Hashtable的区别
        • Hashtable:线程安全,效率低。不允许null键和null值
        • HashMap:线程不安全,效率高。允许null键和null值
    • List,Set,Map等接口是否都继承子Map接口
      • List,Set不是继承自Map接口,它们继承自Collection接口
      • Map接口本身就是一个顶层接口
    • Collections类概述
      • 针对集合操作的工具类
      • Collection 和 Collections的区别
        • Collection:是单列集合的顶层接口,有子接口List和Set
        • Collections:是针对集合操作的工具类,有对集合进行排序和二分查找的方法
      • Collections成员方法
        • public static void sort(List list):排序,默认情况下是自然排序
          • 如果同时有自然排序和比较器排序,那么以比较器排序为主
        • public static int binarySearch(List list,Ikey):二分查找
        • public staticT max(Collection coll):最大值
        • public static void reverse(List list):反转
        • public static void shuffle(List list):随机置换
  • IO流
    • IO流用于处理设备之间的数据传输
      • 读取客户端数据,写到服务器,上传操作
      • IO读取服务器数据,显示到客户端,下载操作
    • Java对数据的操作是通过流的方式
    • Java用于操作流的对象都在IO包中
    • 异常
      • Java程序在运行过程中出现的错误
      • 由来
        • 问题也是现实生活中一个具体事务,也可以通过java的类的形式进行描述,并封装成对象。其实就是Java对不正常情况进行描述后的对象体现。
      • 程序的异常:Throwable
        • 分类
          • 严重问题:Error
            • 不处理,这种问题一般都很严重,比如说内存溢出
          • 问题:Exception
            • 编译期异常
              • 不是RuntimeException的异常,必须处理的,不处理,编译不能通过
              • Java程序必须显示处理,否则程序就会发生错误,无法通过编译
            • 运行期异常
              • RuntimeException这种问题我们也不处理,因为是你的问题,而且这个问题出现肯定是我们的代码不够严谨,需要修正代码的。
              • 无需显示处理,也可以和编译时异常一样处理
        • 方法
          • public String getMessage()
            • 异常的消息字符串
          • public String tostring()
            • 返回异常的简单信息描述
              • 此对象的类的name(全路径名)
              • “:”(冒号和一个空格)
              • 调用此对象 getLocalizedMessage()方法的结果 (默认返回的是getMessage( )的内容)
          • printStackTrace( )
            • 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
          • printStackTrace(PrintStream s)
            • 通常用该方法将异常内容保存在日志文件中,以便查阅
      • 异常处理方案
        • try...catch...finally
          • 处理格式
            • 一个异常

 

            • 多个异常的处理
              • 每写一个try...catch
              • 写一个try,多个catch

 

              • 注意
                • 能明确的尽量明确,不要用大的来处理
                • 平级关系的异常谁前谁后无所谓,如果出现了子父关系,父必须在后面。
            • JDK7出现了一个系的异常处理方案

 

              • 注意:这个方法虽然简洁,但是不够好
                • 处理方式是一致的。(实际开发中,好多时候可能就是针对同类型的问题,给出同一个处理)
                • 多个异常间必须是平级关系。|
            • 注意
              • 一旦try里面出了问题,就会在这里把问题给抛出去,然后和catch里面的问题进行匹配,一旦有匹配的,就执行catch里面的处理,然后结束了try...catch,并且继续执行后面的语句。
          • 注意
            • try里面的代码越少越好
            • catch里面必须有内容
        • throws
          • 定义功能方法时,需要把出现的问题暴露出来让调用者去处理。那么就通过throws在方法上标识。
          • 格式
            • throws 异常类名
            • 注意
              • 这个格式必须跟在方法的括号后面
          • 小结
            • 编译期异常抛出,将来调用者必须处理。
            • 运行期异常抛出,将来调用可以不用处理。
        • throw
          • 如果出现了异常情况,我们可以把该异常抛出,这个时候抛出的应该是异常的对象
            •  
        • throws和throw的区别
          • throws
            • 用在方法声明后面,跟的是异常类名
            • 可以跟多个异常类名,用逗号隔开
            • 表示抛出异常,由该方法的调用者来处理throws表示出现异常的一种可能性,并不一定会发生这些异常
          • throw
            • 用在方法体内,跟的是异常对象名
            • 只能抛出一个异常对象名
            • 表示抛出异常,由方法体内的语句处理
            • throw则是抛出了异常,执行throw则一定抛出了某种异常
        • 如何处理异常
          • 原则
            • 如果该功能内部可以将问题处理,用try,如果处理不了,交由调用者处理,这是用throws
          • 区别
            • 后续程序需要继续运行就try
            • 后续程序不需要继续运行就throws
          • 举例
            • 感冒了就自己吃点药就好了,try
            • 吃了好几天药都没好结果得了H7N9,那就的得throw到医院
            • 如果医路没有特效药新最成Error
      • finally关键字
        • 被finally控制的语句体一定会执行
        • 注意
          • 如果在执行到finally之前jvm退出了,就不能执行了(System.exit(0))
        • 格式
          • try...catch...finally
        • finally的作用
          • 用于释放资源,在IO流操作和数据库操作中会见到
        • finally相关的面试题
          • final,finally和finalize的区别
            • final:最终的意思,可以修饰类,可以修饰成员变量,成员方法
              • 修饰类,类不能被继承
              • 修饰变量,变量是常量
              • 修饰方法,方法不能被重写
            • finally:是异常处理的一部分,用于释放资源
              • 一般来说,代码肯定被执行,但是如果在finally之前jvm退出了,就不会被执行
            • finalize:是Object类的一个方法,用于垃圾回收
          • 如果catch里面有return语句,请问finally的代码还会执行吗?如果会,是在return前还是return后?
            • 会,前,准确的说,应该是在中间

 

 

      • 自定义异常
        • Java不可能对所有的情况都考虑到,所以在实际的开发中,我们可能需要自己定义异常
        • 继承自Exception

 

        • 继承自RuntimeException
      • 异常注意事项
        • 子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。(父亲坏了,儿子不能比父亲更坏)
        • 如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常
        • 如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws
    • File类
      • 文件和目录路径名的抽象表现形式
      • 如果创建 文件或者目录忘记写盘符,那么默认是在项目路径
      • 构造方法
        • File(String pathname):根据一个路径得到file对象
        • File(String parent, String child):根据一个目录和一个子文件/目录得到File对象
        • File(File parent, String child):根据一个父file对象和一个子文件\目录得到File对象
      • 创建功能
        • public boolean createNewFile()
          • 创建文件,如果存在这样的文件,就不创建
        • public boolean mkdir()
          • 创建文件夹,如果存在这样的文件夹,就不创建
        • public boolean mkdirs()
          • 创建文件夹,如果父文件夹不存在,会帮你创建出来
        • 注意
          • 到底创建的是文件还是文件夹,方法不能调用错了
      • 删除功能
        • public boolean delete( )
          • Java中的删除不走回收站
          • 要删除文件夹,请注意该文件夹内不能包含文件或者文件夹
      • 重命名功能
        • public boolean renameTo(File dest)
      • 判断功能
        • public boolean is Directory()
          • 判断是否是目录
        • public boolean isFile()
          • 判断是否是文件
        • public boolean exists()
          • 判断是否存在
        • public boolean canRead()
          • 判断是否可读
        • public boolean canWrite()
          • 判断是否可写
        • public boolean isHidden()
          • 判断是否隐藏
      • 获取功能
        • 基本获取功能
          • public String getAbsolutepath()
            • 获取绝对路径
          • public String getpath()
            • 获取相对路径
          • public String getName()
            • 获取名称
          • public long length()
            • 获取长度,字节个数
          • public long lastModified()
            • 获取最后一次的修改时间,返回的是毫秒值
        • 高级获取功能
          • public String[ ] list( )
            • 获取指定目录下的所有文件或者文件夹的名称数组
          • public File[ ] listFiles( )
            • 获取指定目录下的所有文件或者文件夹的File数组
      • 文件名称过滤器
        • FilenameFilter接口
          • public String[ ] list(FilenameFilter filter)
          • public File[ ] listFiles(FilenameFilter filter)
    • 递归
      • 方法定义中调用方法本身的现象
      • 注意
        • 要有出口,否则就是死递归
        • 次数不能太多,否则就会内存溢出
        • 构造方法不能递归使用
      • 递归求阶乘内存图

 

      • 基本流
        • 就是能够直接读写文件的
      • 高级流
        • 在基本流的基础上提供了一些其他的功能
    • 字节流
      • 字节输入流
        • 读取数据
        • InputStream
          • FileInoutStream
            • 构造方法
              • FileInputStream(File file)
                • 通过打开一个到实际文件的连接来创建一个FileInputStream,该文件通过文件系统中的File对象file指定。
              • FileInput Stream(FileDescriptor fdobj)
                • 通过使用文件描述符fdobj创建一个FileInputStream,该文件描述符表示到文件系统中某个实际文件的现有连接。
              • FileInput Stream(String name)
                • 通过打开一个到实际文件的连接来创建一个FileInputStream,该文件通过文件系统中的路径名 nane指定。
            • 宇节输入流操作步骤:
              • 创建字节输入流对象
              • 用read( )方法读取数据,并把数据显示在控制台
                • int read( )
                  • 一次读取一个字节
                • int read(byte[ ] b)
                  • 一次读取一个字节数组
                  • 从此输入流中将最多b.length个字节的数据读入一个byte数组中。在某些输入可用之前,此方法将阻塞。
                  • 返回:读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回-1。
                  • 一般字节数组选择1024
              • 释放资源
      • 字节输出流
        • 写入数据
        • OutputStream
          • FileOutputStream
            • 构造方法
              • FileOutputStream(File file)
                • 创建一个向指定File对象表示的文件中写入数据的文件输出流。
              • FileOutputStrean(File file,boolean append)
                • 创建一个向指定File对象表示的文件中写入数据的文件输出流。如果第二个参数为true,则将字节写入文件末尾处。
              • FileOutputstream(String name)
                • 创建一个向具有指定名称的文件中写入数据的输出文件流。
              • FileOutputStrean(String name,boolean append)
                • 创建一个向具有指定名称的文件中写入数据的输出文件流。如果第二个参数为true,则将字节写入文件末尾处。
            • 字节输出流操作步骤
              • 创建字节输出流对象
                • FileOutputStream fos = new FIleOutputStream("fos.txt")
                • 创建字节输出流对象了做了几件事情:
                  • 调用系统功能去创建文件
                  • 创建fos对象
                  • 把fos对象指向这个文件
              • 写数据
                • public void write(int b)
                  • 写一个字节
                • public void write(byte[]b)
                  • 写一个字节数组
                • public void write(byte[]b,int off,int len)
                  • 写一个字节数组的一部分
              • 释放资源
                • fos.close()
                • 为什么一定要close()呢
                  • 让流对象变成垃圾,这样就可以被垃圾回收器回收了
                  • 通知系统去释放跟该文件相关的资源
              • 如何实现数据的换行
                • 为什么现在没有换行呢?因为你值写了字节数据,并没有写入换行符号。如何实现呢?写入换行符号即可。因为不同的系统针对不同的换行符号识别是不一样的。
                  • windows: \r\n
                  • linux: \n
                  • Mac:\r
                • 而一些常见的个高级记事本,是可以识别任意换行符号的。
              • 如何实现数据的追加写入
            • 加入异常处理的字节输出流
      • 字节缓冲流
        • 字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多,这是加入了数组这样的缓冲区效果,java本身在设计的时候,他考虑到了这样的设计思想(装饰设计模式后面讲解),所以提供了字节缓冲区流
        • 字节缓冲输出流
          • BufferedOutputStream
            • BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("bos. txt"));创建对象
            • bos.write("hello".getBytes());写入数据
            • bos.close();释放资源
        • 字节缓冲输入流
          • BufferedInputStream
            • BufferedInputstream bis=new BufferedInputstream(new FileInputStream("bos. txt"));
        • 构造方法
          • 构造方法可以执行缓冲区大小,但是我们一般用不上,因为默认缓冲区大小够了
        • 为什么不传递一个具体的文件或者文件路径,而是传递一个OutputStream对象呢?
          • 字节缓冲区流仅仅提供缓冲区,为高效而设计的。但是呢,真正的读写操作还得靠基本的流对象实现。
      • 计算机是如何识别什么时候该把两个字节转换为一个中文呢
        • 在计算机中中文的存储分两个字节:第一个字节肯定是负数。第二个字节常见的是负数,可能有正数。但是没影响。
      • 如何复制数据
        • 封装数据源
        • 复制数据

 

        • 释放资源
        • 效率低,因为读的是字节
    • 转换流
      • 由于字节流操作中文不是特别方便,所以,java就提供了转换流
      • Outputstreamwriter(OutputStream out)
        • 根据默认编码把字节流的数据转换为字符流
      • OutputStreamwriter(OutputStream out,String charsetName)
        • 根据指定编码把字节流数据转换为字符流
      • 转换流的简化写法
        • 转换流的名字比较长,而我们常见的操作都是按照本地默认编码实现的,所以,为了简化我们的书写,转换流提供了对应的子类。
          • FileWriter
          • FileReader
    • 字符流
      • 字符流=字节流+编码表
      • 字符输入流
        • 读取数据
        • Reader
          • InputStreamReader读数据
            • int read()
              • 一次读取一个字符
            • int read(char[] chs)
              • 一次读取一个字符数组
          • FileReader

 

      • 字符输出流
        • 写出数据
        • Writer
          • OutputStreamWriter写数据
            • public void write(int c)
              • 写一个字符
            • public void write(char[ ] cbuf)
              • 写一个字符数组
            • public void write(char[ ] cbuf,int off,int len)
              • 写一个字符数组的一部分
            • public void write(String str)
              • 写一个字符串
            • public void write(String str,int off int len)
              • 子一个字符串的一部分
          • FileWriter
          • flush
            • 刷新缓冲区,刷新之后流对象可以继续使用
          • close
            • 先刷新缓冲区,然后关闭流对象。关闭之后流对象不可以再使用了。
      • 字符缓冲流
        • 字符缓冲输出流
          • BufferedWriter
            • 特殊方法
              • public void newLine()
                • 根据系统决定换行符
        • 字符缓冲流输入流
          • BufferedReader
            • 特殊方法
              • public String readLine()
                • 一次读取一行数据
                • 包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回null
      • IO流图解
        •  
    • 操作基本数据类型的流
      • DatalnputStream(InputStream in )
        • 应用程序可以使用数据输入流将数据读入。
      • DataOutputStream(OutputStream out)
        • 数据输出流允许应用程序以适当方式将基本Java数据类型写入输出流中。
    • 内存操作流
      • 内存操作流一般用于处理临时信息,因为临时信息不需要保存,使用后就可以删除。
      • 操作字节数组
        • ByteArraylnputStream
          • BytearrayInputStrean 包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪read 方法要提供的下一个字节。
        • ByteArrayOutputStream
      • 操作字符数组
        • CharArrayReader
        • CharArrayWrite
      • 操作字符串
        • StringReader
        • StringWriter
    • 打印流
      • 字节流打印流
        • PrintStream
      • 字符打印流
        • PrintWriter
      • 打印流特点
        • 只有写数据的,没有读取数据。只能操作目的地,不能操作数据源。
        • 可以操作任意类型的数据。
        • 如果启动了自动刷新,能够自动刷新。
        • 该流是可以直接操作文本文件的。
      • 哪些流对象是可以直接操作文本文件的呢?
        • FileInputstream
        • FileOutputStream
        • FileReaderFilewriter
        • PrintStreamPrintWriter
        • 看API,查流对象的构造方法,如果同时有File类型和String类型的参数,一般来说就是可以直接操作文件的。
    • 标准输入输出流
      • System类中的字段:in,out。
      • 它们各代表了系统标准的输入和输出设备。默认输入设备是键盘,输出设备是显示器。
      • System.in的类型是InputStream.
      • System.out的类型是PrintStream是OutputStream的子类FilterOutputStream的子类.
    • 随机访问流
      • RandomAccessFile
      • RandomAccessFile类不属于流,是Object类的子类。但它融合了InputStream和OutputStream的功能。支持对随机访问文件的读取和写入。
      • 此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte数组。存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过getFilePointer 方法读取,并通过seek方法设置。
      • public RandomAccessFile(String name,String mode):第一个参数是文件路径,第二个参数是操作文件的模式。
        • 模式有四种,我们最常用的一手种叫”rw”,这种方式表示我既可以写数据,也可以读取数据
    • 合并流
      • SequenceInputStream
        • SequenceInput Strean 表示其输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。
    • 序列化流
      • 序列化流
        • ObjectOutputStream
        • 把对象按照流一样的方式存入文本文件或者在网络中传输。对象 --- 流数据
      • 反序列化流
        • ObjectInputStream
        • 把文本文件中的流对象数据或者网络中的流对象数据还原成对象。流数据 --- 对象
    • Properties集合
      • 属性集合类,是一个可以和IO流相结合使用的集合类。
      • 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。
      • Properties作为Map集合使用
      • Properties的特殊功能
        • public Object setProperty(String key,String value)
        • public String getProperty(String key)
        • public Set stringPropertyNames()
      • Properties和IO流的结合使用
        • public void load(Reader reader)
        • public void store(Writer writer,String comments)
    • NIO包下的IO流
      • JDK4出现NIO。新IO和传统的IO有相同的目的,都是用于进行输入输出的,但新IO使用了不同的方式来处理输入输出,采用内存映射文件的方式,将文件或者文件的一段区域映射到内存中,就可以像访问内存一样的来访问文件了,这种方式效率比旧IO要高很多。但是目前好多地方我们看到的还是旧IO的引用,所以我们仍以旧IO为主,知道NIO即可。
      • JDK7的IO改进
        • Path:路径
        • Paths:有一个静态方法返回路径
          • public static Path get(URI uri)
        • Files:提供了静态方法供我们使用
          • public static long copy(Path source,OutputStream out):赋值文件
          • public static Path write(Path path,Iterable<?extends CharSequence>lines,Charset cs,OpenOption… options):把集合的数据写到文件。
  • 多线程
    • 多线程概述
      • 进程
        • 正在运行的程序,是系统进行资源分配和调用的独立单位,每一个进程都有它自己的内存空间和系统资源。
      • 线程
        • 在同一个进程内又可以执行多个任务,而这每一个任务我就可以看出是一个线程。
        • 一个进程如果只有一条执行路径,则称为单线程程序。
        • 一个进程如果有多条执行路径,则称为多线程程序。
      • 多线程的意义
        • 单进程的计算机只能做一件事情,而多进程可以在一个时间段内执行多个任务
          • 多个任务不是同时进行的。因为单CPU在某一个时间点上只能做一件事情;是CPU做着程序间的高效切换让我们觉得是同时进行的
        • 提高CPU的使用率
        • 多线程的存在,不是提高程序的执行速度。其实是为了提高应用程序的使用率
        • 程序的执行其实都是在抢CPU的资源,CPU的执行权。
    • 多线程实现方案
      • 继承 Thread类
        • 步骤
          • 自定义类MyThread继承Thread类
          • MyThread类里面重写run()
            • 不是类中的所有代码都需要被线程执行的。Java提供了Thread类中的run()方法用来包含那些被线程执行的代码
            • 一般来说,被线程执行的代码肯定是比较耗时的
          • 创建对象
          • 启动线程
            • 调用run方法为什么是单线程
              • 因为run方法直接调用其实就相当于普通的方法调用,要看到多线程的效果,就必须使用start()
            • run( ) 和start( )的区别
              • run():仅仅是封装被线程执行的代码,直接调用时普通方法
              • start():首先启动了线程,然后再由JVM去调用该线程的run()方法
            • 获取和设置进程名称
              • public final String getName():获取线程的名称。
              • public final void setName(String name):设置线程的名称
            • 要获取main方法所在的线程对象的名称
              • 遇到这种情况,Thread类提供了public static Thread currentThread()
              • 即为System.out.println(Thread.currentThread().getName());
      • 实现Runnable接口
        • 步骤
          • 自定义类Runnable实现Runnable接口
          • 重写run()方法
          • 创建MyRunnable类的对象
          • 创建Thread类的对象,并把第三步的对象作为构造参数传递
        • 优点
          • 可以避免由于Java单继承带来的局限性。
          • 适合多个相同程序的代码去处理同一个资源的情况,把线程同程序的代码,数据有效分离,较好的体现了面向对象的设计思想。
    • 线程调度和线程控制
      • 调度模型
        • 分时调度模型
          • 所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间片
        • 抢占式调度模型
          • 优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的CPU时间片相对多一些。
        • Java使用的是抢占式调度模型。
      • 获取线程对象的忧先级
        • public final int getPriority():返回线程对象的优先级
        • 线程默认优先级为5
        • 线程优先级仅仅表示线程获取的CPU时间片的几率高,但是要在次数比较多,或者多次运行的时候才能看到比较好的效果
      • 线程控制
        • 线程休眠
          • public static void sleep(long milis)
          • 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。该线程不丢失任何监视器的所属权。
        • 线程加入
          • public final void join()
          • 等待该线程终止,只有该线程执行完了,其他线程才可以继续
        • 线程礼让
          • public static void yield()
          • 暂停当前正在执行的线程对象,并执行其他线程。
          • 让多个线程的执行更和谐,但是不能靠它保证一人一次。
        • 后台线程
          • public final void setDaemon(boolean on)
          • 将该线程标记为守护线程或用户线程。
          • 当正在运行的线程都是守护线程时,Java 虚拟机退出。该方法必须在启动程前调用。|
        • 中断线程
          • public final void stop()
            • 有不安全性,不建议使用
          • public void interrupt()
            • 把线程的状态终止,并抛出一个InterruptedException
    • 线程生命周期
      • 新建
        • 创建线程对象
      • 就绪
        • 线程有执行资格,但是没有执行权
      • 运行
        • 有执行资格,有执行权
        • 阻塞
          • 由于一些操作让线程处于了该状态。没有执行资格,没有执行权。
          • 而另一些操作却可以把它激活,激活后处于就绪状态
      • 死亡
        • 线程对象变成垃圾,等待被回收
      • 图解

 

    • 线程同步
      • 同步的前提
        • 多个线程
        • 多个线程使用的是同一个锁对象
      • 同步的好处
        • 同步的出现解决了多线程的安全问题
      • 同步的弊端
        • List list1 = new ArrayList ()当线程相当多时,因为每个线程都会去判断同步上的锁,这个是很耗费资源的,无形之中会降低程序的运行效率
      • 同步代码块
        • synchronized(对象) {需要同步的代码块}
        • 同步可以解决安全问题的根本原因就在那个对象上,该对象如同锁的功能
        • 同步代码块上的锁是任意对象
        • 多个线程必须是同一把锁
      • 同步方法
        • 格式
          • 同步关键字加在方法上
        • 同步方法锁对象
          • this
        • 静态方法及锁对象问题
          • 静态方法锁对象
            • 类的字节码文件对象(反射会讲)当前类.class对象
    • 线程安全的类
      • 线程不安全
        • List list1 = new ArrayList ()
      • 线程安全
        • List list2 = Collections.synchronizedList(new ArrayList ())
    • 死锁
      • 虽然我们可以理解同步代码块和同步方法的锁对象问题,但是我们并没有直接看到在哪里加上了锁,在哪里释放了锁,为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock
      • Lock
        • void lock()
        • void unlock()
      • ReentrantLock
      • 实例

 

      • 死锁(Dielock)问题
        • 同步弊端
          • 效率低
          • 如果出现了同步嵌套,就容易产生死锁问题
      • 死锁定义
        • 两个或两个以上的线程在争夺资源的过程中,发生的一种相互等待的现象。
    • 线程间通信
      • 不同种类的线程间针对同一个资源的操作
      • 线程安全
        • 是否有多线程环境
        • 是否有共享数据
        • 是否有多条语句操作共享数据
      • 解决办法
        • 加锁
          • 不同种类的线程都要加锁
          • 不同种类家的锁必须是同一把
      • 线程安全解决,但是存在如下的问题
        • 图解

 

      • 虽然数据安全了,但是呢,一次一大片不好看,我就想依次的一次一个输出
        • 通过Java提供的等待唤醒机制解决
        • Object类中提供了三个方法
          • wait():等待
          • notify():唤醒单个线程
          • notifyAll():唤醒所有线程
        • 为什么这些方法不定义在Thread类中呢?
          • 这些方法的调用必须通过锁对象调用,而我们刚才使用的锁对象是任意锁对象。
          • 所以,这些方法必须定义在Object类中。
    • 线程的状态转换图以及执行情况
      • 转换图

 

      • 执行情况
        • 新建--就绪--运行--死亡
        • 新建--就绪--运行--就绪--死亡
        • 新建--就绪--运行--其他阻塞--就绪--运行--死亡
        • 新建--就绪--运行--同步阻塞--就绪--运行--死亡
        • 新建--就绪--运行--等待阻塞--同步阻塞--就绪--运行--死亡
    • 线程组
      • 把多个线程组合到一起。
      • 它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制。
    • 线程池
      • 程序启动一个新线程成本是比较高的,因为它涉及到要与操作系统进行交互。而使用线程池可以很好的提高性能,尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池。
      • 线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用。
      • 在JDK5之前,我们必须手动实现自己的线程池,从JDK5开始,Java内置支持线程池,新增了一个Executors工厂类来产生线程池
        • public static ExecutorService newCachedThreadPool()
        • public static ExecutorService newFixefdThreadPool(int nThreads)
        • public static ExecutorService newSingleThreadExecution()
      • 实现线程池代码
        • 创建一个线程池对象,控制要创建几个线程对象
        • 这种线程池的线程可以执行
          • 可以执行Runnable对象或者Callable对象代表的线程
          • 做一个类实现Runnable接口
        • 调用如下方法即可
          • Future submit(Runnable task)
          • Future submit(Callable task)
        • 如果一定要结束线程池
          • 对象.shutdown()
        • 具体例子

 

    • 匿名内部类方式使用多线程
      • new Thread(){代码}.start();
      • new Thread(new Runnable(){代码...}).start();

 

    • 定时器的使用
      • 定时器是一个应用十分广泛的线程工具,可用于调度多个定时任务以后台线程的方式执行。在Java中,可以通过Timer和TimerTask类来实现定义调度的功能
      • Timer
        • public Timer()
        • public void schedule (TimerTask task, long delay)
          • 延迟一段时间delay开始
        • public void schedule(TimerTask task, long delay, long period)
          • 延迟一段时间delay开始,然后再隔一段时间period再次执行
      • TimerTask
        • public abstract void run()
        • public boolean cancel()
      • 开发中使用Quartz,它是一个完全由java编写的开源调度框架
    • 多线程常见面试题
      • 多线程有几种实现方案,分别是哪几种
        • 继承Thread类
        • 实现Runnable接口
        • 扩展一种:实现callab1e接口。这个得和线程池结合。
      • 同步有几种方或,分别是什么?
        • 同步代码块
        • 同步方法
      • 启动一个线程是run()还是start()?它们的区别?
        • run():封装了被线程执行的代码,直接调用仅仅是普通方法start()
        • start():启动线程,并由JVM自动调用run()方法
      • sleep()和wait()方法的区别
        • sleep():必须指时间;不释放锁
        • wait():可以不指定时间,可以指定时间;释放锁
      • 为什么wait(),notify(),notifyAll()等方法都定义在object类中
        • 因为这些方法的调用是依赖锁对象的,而同步代码块的锁对象是任意锁。
        • 而object代码任意的对象,所以,定义在这里。
  • 设计模式
    • 面向对象思想设计原则
      • 在实际的开发中,我们要想更深入的了解面向对象思想,就必须熟悉前人总结过的面向对象的思想的设计
      • 单一职责原则
        • 高内聚,低耦合
        • 每个类只有有一个职责,对外只能提供一种功能,而引起类变化的原因应该只有一个。在设计模式中,所有的设计模式都遵循这一原则。
      • 开闭原则
        • 一个对象对扩展开放,对修改关闭。
        • 其实开闭原则的意思就是:对类的改动是通过增加代码进行的,而不是修改现有代码。
        • 也就是说软件开发人员一旦写出了可以运行的代码,就不应该去改动它,而是要保证它能一直运行下去,如何能够做到这一点呢?这就需要借助于抽象和多态,即把可能变化的内容抽象出来,从而使抽象的部分是相对稳定的,而具体的实现则是可以改变和扩展的
      • 里氏替换原则
        • 核心思想:在任何父类出现的地方都可以用它的子类来替代。
        • 其实就是说:同一个继承体系中的对象应该有共同的行为特征。
      • 依赖注入原则
        • 核心思想:要依赖于抽象,不要依赖于具体实现。
        • 其实就是说:在应用程序中,所有的类如果使用或依赖于其他的类,则应该依赖这些其他类的抽象类,而不是这些其他类的具体类。为了实现这一原则,就要求我们在编程的时候针对抽象类或者接口编程,而不是针对具体实现编程。
      • 接口分离原则
        • 核心思想:不应该强迫程序依赖它们不需要使用的方法。
        • 其实就是说:一个接口不需要提供太多的行为,一个接口应该只提供一种对外的功能,不应该把所有的操作都封装到一个接口中。
      • 迪米特原则
        • 核心思想:一个对象应当对其他对象尽可能少的了解
        • 其实就是说:降低各个对象之间的耦合,提高系统的可维护性。在模块之间应该只通过接口编程,而不理会模块的内部工作原理,它可以使各个模块耦合度降到最低,促进软件的复用
    • 设计模式概述
      • 设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
      • 设计模式不是一种方法和技术,而是一种思想
      • 设计模式和具体的语言无关,学习设计模式就是要建立面向对象的思想,尽可能的面向接口编程,低耦合,高内聚,是设计的程序可复用学习设计模式能够促进对面向对象思想的理解,反之亦然,它们相辅相成。
    • 设计模式的几个要素
      • 名字
        • 必须有一个简单,有意义的名字
      • 问题
        • 描述在何时使用模式
      • 解决方案
        • 描述设计的组成部分以及如何解决问题
      • 效果
        • 描述模式的效果以及优缺点
    • 设计模式的分类
      • 创建型模式
        • 对象的创建
      • 结构型模式
        • 对象的组成(结构)
      • 行为型模式
        • 对象的行为
    • 简单工厂模式(接口)
      • 又叫静态工厂方法模式,它定义一个具体的工厂类负责创建一些类的实例
      • 优点
        • 客户端不需要在负责对象的创建,从而明确了各个类的职责
      • 缺点
        • 这个静态工厂类负责所有的对象的创建,如果有新的对象增加,或者某些对象的创建方式不同,就需要不断地修改工厂类,不利于后期的维护。
    • 单例模式(多线程)
      • 饿汉式
        • 类一加载就创建对象
      • 饱汉式
        • 用的时候,类才会创建对象
      • 保证类在内存中只有一个对象
        • 把构造方法私有化
        • 在成员位置自己创建一个对象
        • 通过一个公共的方法提供访问
        • 举例(饿汉式、懒汉式 ​)

 

 

        • 面试题:单例模式的思想是什么?写一个代码去体现
          • 开发:饿汉式(是不会出问题的单例模式)
          • 面试:懒汉式(可能会出问题的单例模式)
            • A:懒加载(延迟加载)
            • B:线程安全问题
              • a:是否多线程环境是
              • b:是否有共享数据是
              • c:是否有多条语句操作共享数据是
          • 最终版

 

      • Java体现Runtime类
    • 模版设计模式(抽象类)
      • 模版方法模式就是定义一个算法的骨架,而将具体的算法延迟到子类中来实现
      • 优点
        • 使用模版方法模式,在定义算法骨架的同时,可以很灵活的实现具体的算法,满足用户灵活多变的需求
      • 缺点
        • 如果算法骨架有修改的话,则需要修改抽象类
    • 装饰设计模式(IO流)
      • 装饰设计模式概述
        • 装饰模式就是使用被装饰类的一个子类的实例,在客户端将这个子类的实例交给装饰类。是继承的替代方案
      • 优点
        • 使用装饰模式,可以提供比继承更灵活的扩展对象的功能,它可以动态的添加对象的功能,并且可以随意的组合这些功能
      • 缺点
        • 正因为可以随意组合,所以就可能出现一些不合理的逻辑
  • 网络编程
    • 网络编程三要素
      • IP地址
      • 端口
      • 协议
    • Socket
      • Socket套接字
        • 网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。
        • 包含IP地址+端口
      • Socket原理机制
        • 通信的两端都有Socket
        • 网络通信其实就是Socket间的通信
        • 数据在两个Socket间通过IO传输
    • UDP
      • UDP协议发送数据
        • 创建发送端Socket对象
          • DatagramSocket()
        • 创建数据,并把数据打包
          • DatagramPacket(byte[] buf,int length,InetAddress address,int port)
        • 调用Socket对象的发送方法发送数据包
          • ds.send(dp)
        • 释放资源
          • ds.close()
      • UDP协议接受数据
        • 创建接收端Socket对象
          • DatagramSocket(int port)
          • 需要指定端口
        • 创建数据包(接受容器)
          • Datagrampacket(byte[] buf,int length)
        • 调用Socket对象的接收方法接收数据
          • public void receive(Datagrampacket p)
        • 解析数据,并且显示在控制台
          • public InetAddress getAddress():获取主机ip地址
          • public byte[] getData():获取数据缓冲区
          • public int getLength():获取数据的实际长度
        • 释放资源
          • ds.close()
        • 多次启动接收端
          • java.net.BindException: Address already in use:Cannot bind
          • 端口被占用。
    • TCP
      • TCP发送数据
        • 创建发送端的Socket对象
          • 如果这一步成功,就说明连接已经建立了
          • Socket(InetAddress address,int port)
          • Socket(String host,int port)
        • 获取输出流,写数据
          • public OutputStream getOutputStream()
        • 释放资源
      • TCP接受数据
        • 创建接收端的Socket对象
          • 如果这一步成功,就说明连接已经建立了
          • Socket(InetAddress address,int port)
          • Socket(String host,int port)
        • 监听客户端连接,返回一个对应的Socket对象
          • public Socket accept()
        • 获取输入流,读取数据显示在控制台
          • InputStream is=s. getInputStream();
          • byte[]bys=new byte[1024];
          • int len=is.read(bys);//阻塞式方法
          • string str=new String(bys,0,1en);
        • 释放资源
          • 只释放客户端资源,服务器端不需要释放资源
      • 图解

 

  • 类加载器和反射
    • 类的加载
      • 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。
      • 加载
        • 就是指将class文件读入内存,并为之创建一个Class对象。
        • 任何类被使用时系统都会建立一个Class对象。
      • 连接
        • 验证
          • 是否有正确的内部结构,并和其他类协调一致
        • 准备
          • 负责为类的静态成员分配内存,并设置默认初始化值
        • 解析
          • 将类的二进制数据中的符号引用替换为直接引用
      • 初始化
        • 就是我们以前讲过的初始化步骤
    • 类初始化时机
      • 创建类的实例
      • 访问类的静态变量,或者为静态变量赋值
      • 调用类的静态方法
      • 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
      • 初始化某个类的子类
      • 直接使用java.exe命令来运行某个主类
    • 类加载器
      • 负责将class文件加载到内在中,并为之生成对应的Class对象。
      • 虽然我们不需要关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行。
    • 类加载器的组成
      • Bootstrap ClassLoader 根类加载器
        • 也被称为引导类加载器,负责Java核心类的加载
      • Extension ClassLoader扩展类加载器
        • 负责JRE的扩展目录中的加载
      • Sysetm ClassLoader 系统类加载器
        • 负责在JVM启动是加载来自Java命令的class文件,以及classpath环境变量所指定的jar包和类路径
    • 反射
      反射:就是通过class文件对象,去使用该文件中的成员变量,构造方法,成员方法。
      • JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
      • 要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
      • 获取class文件对象的方式
        • Object类的getClass()方法
        • 数据类型的静态属性class
        • C1ass类中的静态方法
          • public static class forName (String className)
        • 开发中使用第三种,因为第三种是一个字符串,而不是一个具体的类名。这样我们就可以把这样的字符串配置到配置文件中。
      • 获取构造方法
        • public Constructor[] getConstructors():所有公共构造方法
        • public Constructor[] getDeclaredConstructors():所有构造方法
      • 使用构造方法
        • 通过构造方法对象创建对象
          • public T newInstance(Object...initargs)
          • 使用此Constructor对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。
        • 获取带参构造方法对象
          • public Constructor getConstructor(Class<?>... parameterTypes)
      • 获取私有构造方法并且使用
        • 如图

 

      • 获取成员变量并使用
        • 获取所有的成员变量
          • Field[] fields=c. getFields();
          • Field[] fields=c. getDeclaredFields();
        • 获取单个成员变量
        • 获取address并对其赋值
      • 获取方法并使用
        • 获取单个方法
          • public Method getMethod(String name,Class<?>..…parameterTypes)
            • 第一个参数表示的方法名,第二个参数表示的是方法的参数的class类型
          • getDeclaredMethod
          • public Object invoke(Object obj,Object...args)
            • 返回值是Object接收,第一个参数表示对象是谁,第二参数表示调用该方法的实际参数
        • 获取所有方法
          • getMethods
          • getDeclaredlethods
        • 暴力访问
          • method.setAccessible(true);
      • 通过反射运行配置文件内容
      • 动态代理
        • 在程序运行过程中产生了这个对象
          • 而程序运行过程中产生对象其实就是我们刚才反射讲解的内容,所以,动态代理其实就是通过反射来生成一个代理
        • 实现过程
          • 在Java中iava.lang.reflect包下提供了一个Proxy类和一个InyocationHandler接口,通过使用这个类和接口就可以生成动态代理对象。JK提供的代理只能针对接口做代理。我们有更强大的代理cglib
          • Proxy类中的方法创建动态代理类对象
            • public static Object newproxyInstance(Classloader.loader,Class<?>[] interfaces.Invocationlandler h)
            • 最终会调用avocationllandlex的方法
        • InvocationHandler
          • Object invoke(object pxoxy,lMethed aethod.Object[] areas)

你可能感兴趣的:(Java基础,学习笔记)