精华内容
下载资源
问答
  • Javase

    2019-10-11 10:21:54
    JAVASE个人总结 SVN版本控制 Tomcat服务器.## 标题 Maven项目管理. 十进制转换: // 转换为2进制 System.out.println(Integer.toBinaryString(n)); //toHexString 16进制 System.out.println(Integer.toHexString(n)...

    JAVASE个人总结

    SVN版本控制
    Tomcat服务器.## 标题
    Maven项目管理.
    十进制转换:
    // 转换为2进制
    System.out.println(Integer.toBinaryString(n));
    //toHexString 16进制
    System.out.println(Integer.toHexString(n));
    //o 8进制
    System.out.println(Integer.toOctalString(n));

    基本数据类型:

    4种整数类型:byte(8位最小数据单位),short(16位很少用),int(32位字节长度),long(64位字节长度)。
    2种浮点型:float(单精度),double(双精度)。
    1种字符类型:char(单引号)。
    1种布尔类型:boolean(true或者false)

    基本数据类型包装类:

    在Java的设计原则一切皆对象,Java基本数据类型就完全不符合这种思想,因为八种基本数据类型不是引用类型所以在1.5版本以后引入了及基本数据类型的包装类
    八种包装类分为两大类型:
    1.Number:Integer Short Long Doule Float Byte都是Number的子类表示一个数字
    2.Object:Character Boolean都是object的子类

    装箱与拆箱操作:

     将一个基本数据类型转换成包装类,称为装箱操作。
    

    将一个包装类转换成基本数据类型称为拆箱操作。
    方法的定义:(D:\IDEALX\SSE\src\com\methodarray\demo\three)
    定义在方法里面的变量叫局部变量
    实参:在调用方法时传入的参数(用于参与实际运算的参数);
    形参:方法定义的时候的参数(用于接收数据的参数);
    参数类型:就是参数的数据类型;
    参数名:变量名;
    方法体语句:完成功能的代码;
    形参列表可以为空,实参与形参要互相兼容;实参的范围要小于等于形参的范围;多 个参数用逗号分开;形参就是一个变量,实参就是一个值传参就是把一个值给形参赋 值;
    转型操作:
    在包装类中,可以将字符串变为指定的基本数据类型,一般在输入数据时使用较多
    在Integer类中将String变为int类型:public static int parseInt(String s)
    在Float类中将String类型变为float数据:public static float parseFloat(String s)
    上述字符串必须由数字组成 否则会发生错误
    享元模式:它使用共享对象,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似对象,他适用与当大量对象只是重复因而导致无法令人接受的使用大量内存。通常对象中的部分状态是可分享的的。常见的做法是把它们放到外部数据结构,当需要时再将他们传递给享元;

    方法的返回值:

    return:结束方法的;(如果没有返回值可以不写return return只能返回一个值 一个方法能有多个return 但是只能执行一个 需要判断);
    返回值:就是功能的结果,由return带给调用者;
    

    方法重载:在类中的多个方法方法名相同 参数个数和参数类型不同;返回值不能作为重载的条件;

    数组:(一组能够存储相同类型数据的集合)

    1.使用默认的初始化值来初始化数组中的每一个元素
    语法:数组元素类型 [] 数组名 = new 数组元素类型[(数组长度)];
    int [] arr = new int3;
    int [0] = 1;
    …;(或者for循环)
    2.先声明然后然后赋予默认的初始化值;
    语法:数组元素类型 [] 数组名;
    数组名= new 数组元素类型[(数组长度)];
    int [] arr;
    arr = new arr3;
    3.先声明再使用指定的值进行初始化
    语法:数组元素类型 [] 数组名 = new 数组元素类型[]{元素1,元素2};
    int [] arr = new int[]{10,20,30};
    4.将第三种简化:
    语法:数组元素类型 [] arr = {10,20,30};
    数组必须要有长度:arr.length;
    数组中的每个数据称为元素 每个元素的位置从0开始 数组中的位置称为下标
    通过下标访问元素要从0开始到数组长度-1
    int [] lastElement = arr[arr.length-1];

    数组遍历:(一次取出每一个元素)

    方式一: for循环
    for(int i = 0;i <数组长度;i++){数组中元素的类型 变量 = 数组名[i]};
    方式二:for earch
    for(数组元素类型 变量:数组名){数组元素的类型 临时变量 = 变量;}
    注意:数组越界异常(arrayindexoutofboundsexception)
    空指针异常(NullpointerException)
    数组的内存结构:
    int [] nums = new int[]{1,2,3,4,5}; //new 表示新创建
    栈内存:(大小固定)用于存储局部临时变量(基本数据类型)和引用变量 效率高
    堆内存:(大小不固定) 用于存储对象 灵活 数据量大
    数组是引用类型会存放在堆内存里
    多维数组
    Java中没有真正意义的二维数组 二维数组就是数组里的元素还是数组
    int [] [] = {{},{},{}}

    基本算法:

    冒泡排序算法:(稳定的算法)
    比较相邻的元素如果第一个比第二个大就交换他们两个
    每一对相邻元素做同样的工作,从第一对到结尾的最后一对,在这一点最后的元素应该是最大的,针对所有元素重复以上步骤,除了最后一个,
    持续每次对以上元素重复以上的步骤直到没有任何一对需要比较;
    选择排序:(不稳定的排序算法 比冒泡效率高)
    每一趟从待排序数组中选出最大或者最小的元素 顺序放在已经排好的数列的最后 直到排序完成;
    插入排序:
    每一步将待排序的记录 按其顺序码大小插入到前面已经排序好的子序列的合适位置(从后往前找合适的位置)直到全部插入完;
    二分查找法:(折半查找)
    前提是在已经排好序的数组中,通过将待查找的元素与中间索引值对应的元素进行比较,若大于中间索引值对应的元素,去右半部分查找,否则去左半部分查找,以此类推反复查找直到找到为止,找不到返回一个负数。

    Arrays工具类:

    常用方法:
    使用二分查找法:
    int index(用于接收) = Arrays.binarySearch(int [] array,int value)
    数组内容转成字符串的形式输出:
    Arrays.toString(int[] array);
    数组排序:Array.sort(int [] array);
    复制指定的数组:
    int [] num(需要一个新数组接收 ) = Arrays.copyOf(int [] array, int length);
    Arrays.copyOf(int [] array,int from,int to);(效率第二)
    System.arraycopy(Object src,int srcPos,Object dest,Object destPos,int length)(效率最高)
    比较两个数组是否想等:Arrays.equals();
    使用指定元素填充数组:Arrays.fill();
    面向对象:(特性:封装 继承 多态)
    面向过程:以步骤为单位,一步一步完成某个具体的事情
    面向对象:以对象为单位,通过调度组合不同的对象来完成某一个事情
    面向对象是一种编程思想(考虑调用组合)
    也是一种思考问题的思维方式
    先整体 再局部 先抽象 再具体 能做什么 再怎么做
    类:分类,类别(抽象概念 不是具体的);
    通过分类 我们可以区分不同的事物,类是一种具有相同属性(特性)与行为(方法)的事物集合;
    属性:一个个的特征
    方法:就是行为
    对象:类是一个共性的产物,是一个综合特征,而对象一个个性产物是一个个体的特征;抽象的可以表示具体的 类与对象二者是包含关系
    类和对象定义格式:
    class 类名{
    属性名称;int ***
    返回值类型 方法名(){}
    }
    类名 对象名 = new类名();
    访问类中的属性:
    对象名.属性;
    访问类中的方法:
    对象名.方法();
    匿名对象:直接new 类名.方法(只能用一次 用完后就会被释放)
    1.new关键字表示创建一个对象;
    2.new关键之表示实例化一个对象;
    3.new关键字表示申请内存空间;(如果使用一个没有申请内存空间的对象 会报空指针异常)
    对象在内存中的结构:

    小结:
    1.new关键字表示创建一个对象;表示实例化一个对象;表示申请内存空间
    2.一个对象在内存中的大小由该对象所有属性所占内存的总和。引用类型在32系统占四个字节在64位系统上占8个字节。加上额外的对象的隐形属性的大小;
    3.相同的类型才能赋值;
    4.不同的引用指向一个对象,任何一个引用改变对象的值,其他引用都会反映出来;
    5.在确定不使用对象时,要尽早释放对象:引用=null;
    6.当一个堆中的对象没有被任何引用变量所指向时,该对象 会被JVM的GC程序认为是垃圾对象从而被回收;

    面向对象的封装性:

    封装是面向对象的三大特性之一 封装就是隐藏实现细节仅对外提供访问接口
    优点:
    1.模块化
    2.隐藏信息
    3.代码重用
    4.插件化 易于调试
    5.具有安全性
    缺点:影响执行效率
    set方法:对外提供一个为属性设值的方法
    public void setName(String name){this.name=name;}
    get方法:对外提供一个获取属性的方法
    public String getName(){return name;}

    成员变量与局部变量:

    1.在类的位置不同
    成员变量:在类中定义;
    局部变量:在方法中定义或者方法的参数
    2.在内存中的位置不同
    成员变量:在堆内存(成员变量属于对象 对象进堆内存)
    局部变量:咋栈内存(局部变量属于方法 方法进栈内存)
    3.生命周期不同
    成员变量:随着对象的创建而存在,随着对象的销毁而消失
    局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
    4.初始化不同
    成员变量:有默认的初始化值 引用类型默认为null
    局部变量:没有默认初始化值 必须定义 赋值 才能使用
    局部变量和成员变量名可以一样 在方法中使用的时候 采用的是就近原则

    构造方法:

    1.构造方法就是类构造对象时调用的方法,用于对象的初始化工作
    2.构造方法是实例化一个类的对象时,也就是new时 最先调用的方法
    定义:
    构造方法是在类中定义的,构造方法定义格式:方法名与类名相同无返回值类型的声明 Dog dog = new Dog(); new Dog()表示调用了构造方法
    构造方法的重载:
    无参:public Dog(){}(默认存在, 如果有别的构造方法存在 不存在默认)
    一个参数:public Dog(String name){this.name = name;}
    多个参数:
    public Dog(Sting name,int age){
    this.name = name;
    ths.age = age;}
    方法与方法之间可以互相调用;
    小结:
    1.构造方法名称与类名相同 没有返回值声明;void也没有
    2.构造方法用于初始化数据(属性)
    3.每一个类中都会有默认的无参构造方法
    4.如果类中有带参数的构造方法那么默认的无参构造方法无效
    5.如果有显示的构造方法 还想保留默认的构造方法 那么需要写出来;
    6.构造方法可以有多个 但参数不一样 这叫构造方法的重载;
    7.在构造方法中调用另一个构造方法this(…)此句需要放在第一句;
    8.构造方法之间相互调用 必须要有出口;
    9.给对象初始化数据可以使用构造方法或者setter方法通常情况二者皆留
    10.一个好的编程习惯是要保留默认的构造方法(为了方便一些框架通过反射来创建对象)
    11.private 类名(){}构造方法私有化 当我们需求是为了保证该类只有一个对象时;通过权衡一个对象与产生多个对象的内存使用,来确定是否只需要一个对象;

    this关键字:
    使用this关键字可以调用类中的属性;调用类的方法或者构造方法;表示当前对象;方法被调用过程中 谁调用了方法this谁就是谁的当前对象;
    值传递与引用传递:
    值传递:值是具体值
    引用传递:值是一个地址
    对象一对一关系:

    static 关键字
    作用:
    1.修饰一个属性 :声明为static的变量实质上就是全局变量
    2.修饰一个方法:在一个类中static修饰一个方法 无需本类对象 即可调用
    3.可修饰一个类(内部类)
    1.静态变量或者方法不属于对象 但是要依赖类
    2.静态变量是全局变量,生命周期从类被加载后 一直到程序结束
    3.静态变量只存一份 存在于静态方法区
    4.静态变量是本类所有对象共享一份
    5.建议不要使用对象名调用静态数据,直接使用类名调用
    6.static修饰一个方法那么该方法属于类 不属于对象,直接用类名调用
    7.静态方法不能访问非静态数据

    所有对象共用一个属性或者方法时 可以定义为static
    main方法分析:
    public:公有的最大的访问权限
    static:静态的 无需创建对象
    void:表示没有返回值 无需向JVM返回结果
    main:方法名 固定的方法名
    String[] args:表示参数为字符串数组,可以在调用方法时传入参数
    代码块:
    1.普通代码块:直接写在方法中的代码块就是普通代码块
    2.构造块:在类中定义的代码块 在创建对象时被调用,优于构造方法;
    3.静态代码块(用的比较多):在类中使用static声明的代码块称为静态代码块 在第一次使用的时候被调用(创建对象)只会执行一次 优于构造块(项目开发经常使用静态代码块初始化只调用一次的数据)
    4.同步代码块
    单例设计模式:(保证一个类仅有一个实例 并提供一个访问他的全局访问点)
    1.构造方法私有化
    2.声明一个本类对象
    3.给外部提供一个静态方法获取实例

    实现方式:
    1.饿汉式 在类被加载后 对象被创建 一直到程序结束后释放 占用内存时间长 提高效率
    2.懒汉式 (多线程访问时会有安全问题)在第一次调用getinstance方法时对象被创建 程序结束后释放 首次占用内存时间短 效率较低
    在项目中为什么要使用单例 单例有什么好处?
    1.在设计一些工具类的时候·(通常工具类只有功能和方法 没有属性)
    2.工具类可能会被频繁的调用

    目的是为了节省重复创建对象所带来的内存消耗 从而来提高效率
    使用静态方法私有化+静态方法来实现工具类(可代替单例)此方法依赖对象

    对象数组与管理:
    对象数组就是数组里每一个元素都是类的对象,赋值时先定义对象,然后将对象直接赋给数组。EG:Chicken [] cs = new Chicken[10];

    继承

    继承:面向对象三大特征之一 从已经有的类创建新的类的过程
    被继承的类称为父类 继承父类的称为子类
    继承是指一个对象直接使用另一个对象的方法
    通过继承可以实现代码重用
    语法:
    访问权限 class 子类名 extends 父类名{}
    继承一个父类只能继承非私有的数据(属性和方法)
    1.Java中继承只能单继承
    2.允许多层继承即一个子类可以有一个父类 一个父类还有一个父类
    3.继承只能继承非私有的属性和方法
    4.构造方法不能被继承
    5.建子类对象时父类的构造方法也会被调用 因为子类要用到父类的数据就要通过构造方法来初始化数据
    子类创建对象时会调用父类的默认构造方法
    6.protected(访问修饰符 可以被子类继承方法和属性)
    7.创建对象会调用构造方法 调用构造方法不一定就是创建该类对象
    8.实例化子类对象 会先调用父类的构造方法,如果父类中没有默认的构造方法那么子类必须显示通过super(参数)来调用父类的带参构造方法 super也只能是子类的第一句
    优点:
    提高代码复用性
    提高代码维护性
    让类与类之间产生关系,是多态的前提
    缺点:
    增强了类与类之间的耦合性
    开发原则:高聚合 低耦合
    子类实例化过程:
    子类实例化时 会先调用父类的构造方法
    如果父类没有默认的构造方法,在子类的构造中必须显示调用父类的构造方法
    构造方法只是用于初始化类中的字段以及执行一些初始化代码
    调用构造方法不代表会生成对象
    方法重写:
    在Java中 子类可以继承父类的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动的继承父类的·方法,而需要做一些修改,这就需要方法的重载,又称为方法的覆盖,在子类和父类中,重写方法后。在调用时以创建的对象类型为准
    特性:
    1.发生在子父类中,方法重写的两个方法返回值 方法名 参数列表必须完全一致
    2.子类异常不能大于父类异常
    3.子类访问级别不能低于父类访问级别
    4.若父类方法被private static final 修饰 不能被子类继承
    方法重写的目的:
    若子类从父类继承过来的方法,不能满足子类特有的需求时,子类就需要重写父类特有的方法,方法重写也是程序扩展的体现
    经典试题:overloading与overriding的区别(重载与重写)
    重载:方法名相同 发生在同一个类中 方法名相同参数类表不同 返回值无关
    重写:发生在子父类中 方法名相同 参数列表相同 返回值相同 子类的访问修饰符级别要大于父类的 子类的异常声明必须小于或等于父类的异常声明;若父类方法被private static final 修饰 不能被子类继承

    super关键字:
    1.使用super调用父类的属性 可以从父类实例处获得信息
    2.使用super调用父类的方法 可以委托父类对象帮助完成某件事
    3.使用super调用父类的构造方法(super(实参)形式)必须在子类方法的第一句,调用父类中相应的构造方法,若不显示的写出来,默认调用1父类的无参super()
    final关键字:
    使用final声明一个属性就是常量 常量的命名规则是建议全大写 常量必须在定义时完成初始化 或者在默认构造器中初始化
    1.使用final关键字声明一个常量
    修饰属性或者局部变量,也称为常量
    2.使用final关键字声明一个方法
    该方法为最终方法,自能被子类继承不能被子类重写
    3.使用final声明一个类
    该类变为一个最终类,没有子类的类,final修饰的类无法被继承
    4.在方法的参数中使用final 在该方法内部不能修改参数值
    实际开发中常量类通常用于定义项目中一些公共的不变的数据;一般常量类和static一块使用;

    抽象类:

    基本概念:很多有相同特征和行为的对象可以抽象为一个类,很多有相同特征和行为的类可以抽象为一个类, 用abstract关键字声明抽象类
    abstract class Animal{public abstract void move();}抽象方法只有定义没有实现;继承抽象类的具体类 必须实现抽象方法
    1.抽象类可以没有抽象方法,有抽象方法的类必须是抽象类
    2.非抽象类继承抽象类必须继承所有的抽象方法;
    3.抽象类可以继承抽象类,可以不实现父类抽象方法
    4.抽象类可以有方法实现和属性
    5.抽象类不能被实例化
    6.抽象类不能被声明为final
    7.抽象类可以有构造方法

    接口:

    interface 接口名称{
    全局常量;
    抽象方法;
    }
    接口不是类 抽象类是类 都需要被具体类去实现
    接口中只有方法的定义 抽象一种行为
    interface Ieat{void eat();}
    1.接口是一组行为规范 定义 没有实现 定义接口用interface关键字
    2.使用接口可以使程序更加利于变化
    3.接口是面向对象编程体系的精髓之一
    4.面向对象设计法则:基于接口编程
    5.类只能单继承 一个类可以实现多个接口
    6.接口中只能定义常量和抽象方法
    7.抽象类实现接口可以不实现接口的方法
    8.接口中只能定义抽象方法接口中没有修饰符的话 默认为 public
    9.接口不能有构造方法
    面向对象原则:
    对修改关闭 对扩展开放 面向接口编程

    多态:

    三大特性之一
    什么是多态:对象在运行中的多种形态
    多态性可以分为两类:
    1.方法的重载与重写
    2.对象的多态性
    用父类的引用指向子类对象(用大的类型接收小的类型 向上转型 自动转换)
    Chicken home = new HomeChicken();
    在编程时针对抽象类型的编写代码,称为面向抽象编程(或者面向接口编程)
    父类通常定义为接口 抽象
    对象的多态性:
    对象的多态性从继承关系中的多个类继承而来
    向上转型:将子类实例转为父类实例
    父类 父类对象 = new 子类实例;自动转换
    向下转型:将父类实例转为子类实例
    子类 子类对象 = (子类)父类实例;强制转换
    多态小结:
    1.方法的重载和重写是多态性的表现
    2.多个子类就是父类中的多种形态
    3.父类引用可以指向子类引用 自动转型
    4.子类对象指向父类引用需要强制转换
    5.尽量使用父类引用
    instanceof关键字:
    用于检查对象是否为指定类型,通常把父类引用强制转换成子类引用时要使用,以避免发生类型转换异常(ClassCastExpection)
    语法:对象 instanceof 类型; 返回一个布尔值类型
    示例:if(homeChicken instanceof)
    父类设计法则:
    通过instanceof关键字,我们可以很方便的检查对象的类型,但如果一个父类的子类过多,这样还是很繁琐的;
    父类通常情况下都设计为抽象类或者接口,其中优先考虑接口,如果接口不能满足才考虑抽象类;
    一个具体类尽可能不去继承具体类,这样无需检查对象是否为父类对象

    模板方法模式:定义一个操作中的算法骨架,而将一些可变部分的实现延迟到子类中,模板方法模式使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。
    接口应用:策略模式
    定义了一系列算法,将每一种算法封装起来并可以相互替换使用,策略模式让算法独立于使用它客户应用而独立变化。
    把可变的行为抽象出来 定义一系列代码 好处是 这些行为可以在真正使用时相互替换
    OO原则设计:
    1.面向接口编程
    2.封装变化
    3.多用组合少用继承

    Object类:

    object类是类层次结构的根类。
    每个类都使用object类作为超类,所有对象(包括数组)都实现这个类的方法。所有类都是object类的子类。
    public void toString()方法:
    返回该对象的字符串表示(通常这个方法会返回一个以文本表示此对象的字符串。结果应是一个简单易懂的表达信息,建议所有子类都重写该方法)
    public boolean equals(Object obj)
    指示其他对象与此对象是否相等,equals方法在非空对象引用上实现相等关系
    ==比较的是对象的内存地址
    protected void finalize()throws Trowable
    当垃圾回收器确定不存在对该对象的更多引用时,有对象的垃圾回收器调用该方法,子类重写finalize方法,以配置系统资源或者执行其他清除
    public final Class<?>getClass
    返回此object类的运行时类

    简单工厂设计模式:
    简单工厂设计模式是由一个工厂对象决定创建出哪一种产品类实例。
    静态代理设计模式:
    代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。代理模式就是真实对象的代表。在访问对象时引入一定程度的间接性,因为这种间接性可以附加多种用途。
    适配器模式:
    适配器模式:将一个类的接口转换成客户希望的另一个接口,配适器模式使得原本由于接口不兼容而不能一起工作的类可以一起工作。
    设计原则:
    1.面向接口编程(面向抽象编程)
    2.疯转变化
    3.多组合,少继承
    4.对修改关闭,对扩展开放

    内部类:(前两个属于成员 后两个属于局部)
    依赖外部类对象的是:成员内部类 方法内部类 匿名内部类 内存泄漏
    静态内部类不依赖外部类对象 项目开发优先选择静态内部类
    内部类就是在类内部定义的类
    1.成员内部类格式:
    class Outer{
    class Inner{}
    } 编译以后会出现两个文件Outer.class 和 Outer$Sinner.class
    在外部创建成员内部类的实例 (成员内部类需要依赖外部类对象 通常情况下不建议这样实例化内部类的实例对象)
    Outer.Inner inner = outer.new Inner();
    建议在外部类中定义一个方法对外提供访问内部类接口
    2.方法内部类
    class Outer{
    public void doSomething(){
    class Inner{
    public void seeOuter(){}
    }
    }
    }
    内部类·可以·做一个类的成员外 还可以把类放在方法里定义;
    注:方法内部类只能在定义该内部类的方法内进行实例化。
    方法内部类对象不能使用该内部类所在方法的非final局部变量
    3.静态内部类:
    在一个类内部定义一个静态内部类:静态的含义是该内部类可以像其他静态成员一样,没有外部类对象时,也能访问它,静态嵌套嘞仅能访问外部类的静态成员和方法。
    class Outer{
    static class Inner{}
    }
    class Test{
    public static void main(String[] args){
    Outer.Inner n = new Outer.Inner();
    }
    }

    4.匿名内部类:

    D:\IDEALX\SSE\src\com\OOP\demo\five\Test13
    1.继承式匿名内部类
    2.接口式匿名内部类
    3.参数式匿名内部类
    要遵循以下原则:
    1.不能有构造方法,只能有一个实例
    2.不能定义任何静态成员,静态方法
    3.不能是private public static protected
    4.一定是在new的后面,用其隐含实现一个接口或者实现类一个类
    5.匿名内部类为局部的,所以局部内部类的所有限制都对其生效

    问:局部内部类访问局部变量必须用final修饰 为什么?

    当调用这个方法时,局部变量如果没用final修饰,他的生命周期和方法的声明周期是一样的,当方法调用时会入栈方法结束后弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有马上消失想用这个局部变量,显然已经无法使用了,如果用final修饰会在类加载的时候进入常量池,即使方法弹栈 常量池的常量还在,也就可以继续使用。JDK1.8取消了在局部内部类中使用的变量必须用显示的用final修饰,编译器会默认为这个变量加final
    内部类的作用:每个内部类都能独立的继承自一个(接口)的实现,无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计和编程问题就很难解决。从这个角度看,内部类使多重继承的解决方案变得完整。接口解决了部分问题而内部类有效的实现了“多继承”

    数据结构之链表:

    链表:一种常见的基础数据结构,是一种线性表,但是并不会按照线性的顺序储存数据,而是在没一个节点里存到下一个节点里的指针。

    递归算法:

    递归算法是一种直接或间接的调用自身算法的过程,在编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而易于理解
    递归算法就是方法本身调用自己
    1.递归必须要有出口
    2.递归内存消耗大,容易发生内存溢出
    3.层次调用越多越危险
    链表与数组:线性数据结构 链表大小可以随意扩展 数组不适合与插入删除操作
    数组适合查找,遍历,固定长度
    链表适合插入,删除,不宜过长 否则会导致遍历的性能下降

    面向对象原则总结:

    1.开闭原则
    一个软件实体如类,模块和函数应对扩展开放,对修改关闭
    2.合成聚合复用原则
    新对象的某些功能在已创建好的对象里已经实现,那么尽量使用已有对象提供的功能,使之成为新对象的一部分,而不要再重新创建。
    3.依赖倒置原则
    高层模块不应该依赖底层模块,二者都应该依赖其抽象,抽象不应该依赖细节 细节应该依赖抽象;
    4.接口隔离原则
    客户端不应该依赖他不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上;
    5.迪米特法则
    一个对象应该对其他对象保持最少的了解;
    6.里氏替换原则
    所有引用基类的的地方必须能透明的使用其子类对象
    7.单一职责原则
    不要存在多余一个导致类变更的原因,即一个类负责一个原则

    异常处理:

    catch写的时候应把小的异常写前面
    1.Throwable是异常的基类,分为error和Exception,在编程中关注Exception
    2.Exception分为编译器异常(受检)和运行期异常(非受检)
    3.异常导致程序中断 无法继续执行
    4.在开发中我们要把可能出现的异常用try语句块包起来
    5.异常处理可以让程序保持运行状态
    6.catch可以有多个顺序为从子类到父类大的放后边

    异常处理分析过程:
    1.一旦产生异常则系统会自动产生一个异常类的实例化对象
    2.此时如果存在try语句 则会自动找到匹配的catch语句执行,如果没有异常处理则程序退出 并由系统报告错误
    3.所有catch根据方法的参数匹配异常的实例化对象,如果匹配成功,则表示有此catch进行处理
    finally关键字:
    在进行异常处理后 finally语句作为异常的统一出口,不管是否产生异常 都要执行;
    finally是不管是否有异常都要执行
    final是定义常量 不可改变的
    异常处理:
    异常:异常是阻止当前方法或作用域执行的问题 在程序中导致程序中断的一些指令
    try(…){
    可能发生异常的代码
    }catch(异常类型 对象){
    异常操作处理
    }finally{
    异常统一出口
    }

    throw throws关键字:
    throws关键字主要在方法的声明上使用,表示方法不处理异常,而交给调用处处里,实际上对Java程序来讲如果没有加入任何异常处理默认由JVM进行异常的处理操作
    throw关键字表示在程序中手动抛出一个异常,因为从处理机制来看,所有异常一旦产生之后,实际上抛出的就是一个异常类的实例化对象,那么此对象也可以由throw直接抛出。
    异常处理与法规则:
    1.try语句不能单独存在,可以和catch,finally组成try … catch…finally try… catch try…finally三种结构,catch语句可以有一个或者多个finally语句最多有一个 三个关键字都不能单独使用
    2.三个代码块中变量的作用域相互独立而不能互相访问
    3.多个catch时候Java虚拟机会匹配其中一个异常类或其子类,就执行这个catch块而不再执行别的catch块;
    常见异常
    算术异常类:ArithmeticExecption
    空指针异常类:NullPointerException
    类型强制转换异常:ClassCastException
    数组负下标异常:NegativeArrayException
    数组下标越界异常:ArrayIndexOutOfBoundsException
    违背安全原则异常:SecturityException
    文件已结束异常:EOFException
    文件未找到异常:FileNotFoundException
    字符串转换为数字异常:NumberFormatException
    操作数据库异常:SQLException
    输入输出异常:IOException
    方法未找到异常:NoSuchMethodException

    自定义异常:
    自定义异常通常都是通过继承一个异常类来实现

    • 1.Throwable
    • 2.Exception
    • 3.RuntimeException
    • 自定义异常常常实现的是重写父类的构造方法
      *异常本身没有功能只是一个提示作用(有意义的标识)
      受检异常与非受检异常
      受检异常:定义方法时必须声明所有会抛出的exception;在调用这个方法时,必须捕获它的checked expection 不然就得把他的expection传下去;exception是从Java.lang.Exception类 衍生出来的。
      非受检异常:在定义方法时不需要声明会抛出runtime exception;在调用这个方法时不需要捕获这个runtime exception;runtime exception是从java.lang.RuntimeExceptioin或java.lang.error类衍生出来的、

    题:Exception与RuntimeException

    • Exception:受检异常,在编译期检查,在调用抛出这个异常的方法时 必须显示的使用try… catch…
    • RuntimeException:非受检异常 在运行期检查,在调用抛出这个异常时 可以不用显式的使用try…catch…
    • 在使用自定义异常时 根据实际的业务要求来决定使用哪个作为父类

    assert关键字,表示断言 当程序执行到某个固定位置的时候,程序中的某个变量的取值肯定是预期的结果,那么这种操作可以使用断言完成。
    断言语法:
    assert表达式;

    debug:
    断点:遇到断点,暂挂等候命令
    idea快捷键:
    F9 resume programe 恢复程序
    Alt+F10 show execution point 显示执行断点
    F8 Step Over 相当于eclipse的f6 跳到下一步
    F7 Step Into 相当于eclipse的f5就是 进入到代码
    Alt+shift+F7 Force Step Into 这个是强制进入代码
    Shift+F8 Step Out 相当于eclipse的f8跳到下一个断点,也相当于eclipse的f7跳出函数
    Atl+F9 Run To Cursor 运行到光标处
    ctrl+shift+F9 debug运行java类
    ctrl+shift+F10 正常运行java类
    alt+F8 debug时选中查看值

    常用类库:

    1.String可以表示字符串
    2.String类实际是由字符数组组成的
    两种赋值方式:
    1.直接赋值
    String name = “小白0”;
    2.通过关键字new调用String的构造方法赋值
    String name = new String(“小白”);
    /*四种情况分析:直接赋值字符串连接时,考虑编译器和运行期
    如果在编译器值可以被确定那么就使用已有的对象 否则回创建新的对象
    */
    String a = “a”;
    String a1 = a+1;
    String a2 = “a1”;
    System.out.println(a1==a2);false

        final String b = "b";
        String b1 = b+1;
        String b2 = "b1";
        System.out.println(b1==b2);true
    
        String c = getC();
        String c1 = c+1;
        String c2 = "c1";
        System.out.println(c1==c2);false
    
        final String d =getD();
        String d1 = d+1;
        String d2 = "d1";
        System.out.println(d1==d2);false
    }
    private static String getC(){
        return "c";
    }
    private static String getD(){
        return "d";
    }
    

    String常用方法:

    D:\IDEALX\SSE\src\com\classworks\demo\seven\Test02

    字符串操作————StringBuffer类
    实际开发中 经常会使用字符串连接操作 如果用string操作则用+来完成字符串的连接操作。不过代码性能会很低 因为String不可改变。
    常量相加没有性能问题(在编译器进行优化)
    StringBuffer解决字符串相加时带来的性能问题(常量与变量相加)
    StringBuffer的内部实现采用字符数组,默认数组长度为16,超过数组大小时,动态扩充的方法是原长度*2+2
    所以我们预知要添加的数据长度时 建议使用带初始化容量的构造方法,来避免动态扩充的次数从而提高效率
    线程安全的 会影响性能
    StringBuffer类的兄弟类StringBuilder
    一个可变的字符序列。此类提供一个与StringBuffer兼容的API,但是不保证同步。该类被设计用作 StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候(很普遍)如果可能建议先使用该类,因为大多数实现中比StringBuffer要快

    面试题 StringBuffer与StringBuilder的区别

    • StringBuffer线程安全性能低 适合多线程
    • StringBuilder线程不安全 性能高 适合单线程(情况较多)
      字符串相加操作
    • 1.多个常量相加没有性能问题在编译器优化了
    • 2.变量与常量相加会产生很多垃圾对象
      字符串相加,在编译后,会使用StringBuilder来优化代码,实现拼接
      程序国际化:
      internationalization:国际化程序可以这样理解:
      同一套代码可以在各个语言环境下使用。各个语言环境下只是语言显示不同程序本身的操作都是一样的,国际化程序完成的就是这个功能
      1.Locale类:
      locale类表示了特定的地理,政治和文化地区,需要locale来执行其任务的操作称为语言环境敏感的操作,它使用locale为用户量身定制信息。
      使用此类的构造方法来创建:Locale
      Locale(String language)
      Locale(String language,String country)
      通过静态方法创建Locale:getDefault()
      中国:CN 美国:US
      ResourceBundle类:
      国际化的核心显示在语言上,通常的做法是将其定义成若干个文件(文件后缀名为.properties),属性的文件格式采用key=value的格式进行操作;
      ResourceBundle类表示的是一个资源文件的读取操作,所有的资源文件需要使用ResourceBundle进行读取,读取的时候不需要加上文件后缀
      getBundle(String baseName)
      getBundle(String baseName,Locale locale)
      getString(String key)

    properties 属性文件或者配置文件 内容以键值对的形式存放
    .ResourceBundle工具类绑定属性文件 并指定locale对象 来自动选择哪个属性文件 默认使用与操作系统相同的语言环境 getString()方法从属性文件中使用key获取value 注意ResourceBundle只能读 不能写

    处理动态文本:
    进行动态文本处理,必须使用java.text.MessageFormat类完成,这个类是java.text.Format类的子类

    math和Random类
    Math类:包含了用于执行数学基本运算的方法,如初等指数,对数平方根和三角对数。
    使用的两种方式:
    1.直接使用(引入所在的包)
    2.使用import static java.lang.Math.abs;静态导入
    Math.abs() 取绝对值
    Math.random() 随机生成0-1之间的数
    Math.round() 返回最接近参数并等于某一整数的值
    Math.sqrt() 求平方根
    Random:此类实例用于生成伪随机数(按算法算的 有规律 不是完全随机)
    最常用:nextInt(int a)0-a之间 默认是0到int最大值

    日期操作类:元年1970
    1.Date类:
    类Date表示特定的瞬间,精确到毫秒,也是程序运行的当前时间
    Date date = new Date() 实例化Date表示当前时间

    2.Calender类
    Calender,日历类 使用此类可以将时间精确到毫秒显示
    两种实例化方式
    Calendar c =Calendar.getInstance();
    Calendar c =newGregorianCalendar();

    3.DateFormat类及子类SimpleDateFormat

    对象比较器:
    对两个或多个数据项进行比较,以确定他们是否相等或确定他们之间的大小关系及排列顺序称为比较。之前的比较:public static void sort(Object[] a);
    1.Comparable接口:此接口强行对实现它的每个类的对象进行整体排序。这种排序称为自然排序CompareTo被称为他的自然比较方法;
    2.Comparator:Comparable接口要求自定义类去实现,按照OO原则:对修改关闭 对扩展开放;
    Comparator接口:强行对某个对象collection进行整体排序的比较
    对象的克隆:
    将一个对象复制一份,称为对象的克隆技术。在object类中有一个Clone()方法
    protected Object clone() throws CloneNotSupportedException
    如果一个类的对象想要被克隆,则对象所在的类必须实现Cloneable接口,此接口没有定义任何方法,是一个标记接口
    Cloneable:

    • 对象需要具备克隆功能
    • 1.实现Cloneable接口(标记接口)
    • 2.重写Object类中的Clone方法
      System和RunTime工具类
      System代表系统,系统级的很多属性和控制方法都放置在该类的内部该类位于lang包
      1.成员变量:
      System类内包含in out err三个成员变量,分别代表标准输入流(从键盘输入),标准输出流(在显示屏)标准错误输出流;
      成员方法:
      System提供了一些系统级的操作方法
      (1)数组拷贝
      (2)public static long currentTimeMillis() 返回当前时间毫秒数 从1970年初开始
      做时间比较测试时使用

    Runtime rt = Runtime.getRuntime();
    System.out.println(“处理器数量”+rt.availableProcessors()+“个”);
    System.out.println(“Jvm总内存数”+rt.totalMemory()+“byte”);
    System.out.println(“Jvm空闲内存数”+rt.freeMemory()+“byte”);
    System.out.println(“Jvm最大可用内存数”+rt.maxMemory()+“byte”);

    数字处理工具类:
    BigInteger:可以超出Integer的范围;
    String val1 = “451168951689765”;
    String val2 = “45116369854265”;
    BigInteger b1 = new BigInteger(val1);
    BigInteger b2 = new BigInteger(val2);

        System.out.println(b1.add(b2));//+
        System.out.println(b1.subtract(b2));//-
        System.out.println(b1.multiply(b2));//*
        System.out.println(b1.divide(b2));// 除
        System.out.println(b1.remainder(b2));//取余
    

    BigDecimal:用于小数
    String val3 = “451.168951689765”;
    String val4 = “4511.69854265”;
    BigDecimal b3 = new BigDecimal(val3);
    BigDecimal b4 = new BigDecimal(val4);
    System.out.println(b3.add(b4));//+
    System.out.println(b3.subtract(b4));//-
    System.out.println(b3.multiply(b4));//*
    System.out.println(b3.divide(b4));// 除 有问题 待解决
    DecimalFormat:

    MD5工具类
    MD5的全称是Message-Digest=MessageAlgorithm 5(信息摘要算法)
    不可逆的 D:\IDEALX\SSE\src\com\classworks\demo\seven\Test12
    //确定计算方法
    MessageDigest md5=MessageDigest.getInstance(“MD5”);
    例子:
    String password = “admin123456”;//明文(原文)
    String savePassword = “pmq7VoTEWWLYh1ZPCDRujQ==”;//存储密文
    try {
    MessageDigest md5 = MessageDigest.getInstance(“MD5”);
    * 通过MD5计算摘要
    byte [] bytes = md5.digest(password.getBytes(“UTF-8”));
    System.out.println(Arrays.toString(bytes));
    String mdStr = new String(bytes);
    //System.out.println(mdStr);
    * a-z A-Z .0-9 BASE64算法
    * JDK1.8中
    String str = Base64.getEncoder().encodeToString(bytes);
    System.out.println(str);
    } catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
    }

    数据结构之二叉树实现原理:

    树是一种非线性的是数据结构,直观的看,他是数据元素(在树中称为节点)按分支关系组织起来的结构二叉树是每个子节点最多有两个子树的有序树、通常子树被称为左子树和右子树
    规则:
    1.选择第一个元素作为根节点
    2.之后如果元素大于根节点放在右子树,如果小于根节点放在左子树=放哪都行
    3.最后按照中序遍历的方式进行输出则可以得到排序的结果(左->根->右)

    lambda表达式:适合只有一个参数的接口
    lambda表达式也称为闭包是Java8发行版中最受期待的在Java语言层面上的改变,lambda允许把函数(方法)作为一个方法的参数(函数作为参数传递进方法中)或者把代码看成数据,Lambda用于简化Java中接口式的匿名内部类。被称为函数式的接口概念函数式接口就是一个具有一个方法的普通接口,这种接口可以被隐式的转化成lambda表达式;D:\IDEALX\SSE\src\com\classworks\demo\seven\Test14
    语法:(参数1,参数2…)->{…}

    * lambad表达式
         * 1.让代码更简洁
         * 2.匿名内部类会生成一个class文件 lambda不会单独生成class文件
    

    //无参数时:
    IEat iEat2 = ()->{//大括号可以省略 是return不能省
    System.out.println(“eat apple banana”);
    };
    iEat2.eat();
    //带参数 (参数类型可以省略 代码块中有多行代码)
    IEat iEat3 = (String thing)-> System.out.println(“eat…”+thing);
    iEat3.eat(“apple”);
    //带返回值的方法 只有一句实现代码块
    IEat iEat3 = (thing)->{
    System.out.println(“eat apple”+thing);
    return 10;
    };
    //加final 参数类型不能省
    IEat iEat3 = (final String thing)->{
    System.out.println(“eat apple”+thing);
    return 10;
    };
    接口中静态表达式也不影响lambda 默认方法与静态方法并不影响函数的接口契约可以任意使用

    文件与IO:

    File类:表示文件和目录路径名的抽象表示形式
    file类可以实现文件的创建删除重命名,得到路径创建时间等等,是唯一与文件本身操作有关的类
    //两种方式
    File file1 = new File(“D:\作业\test.txt”);
    File f1 = new File(“D:”+File.separator+“作业”+File.separator+“test.txt”);
    if (!f1.exists()){ //判断文件是否存在
    try {
    f1.createNewFile(); //创建文件
    System.out.println(“文件创建成功”);
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    “是否为文件夹”+f1.isDirectory()
    删除文件夹的时候必须保证里边没文件 否则删不掉
    System.out.println(f.length());
    System.out.println(f.getName());
    System.out.println(f.getPath());//相对路径
    System.out.println(f.getAbsolutePath());//绝对路径
    System.out.println(f.isHidden());//是否为可隐藏文件
    System.out.println(f.canRead());//是否为可读文件
    System.out.println(f.lastModified());//最后修改时间 以毫秒显示
    字节流:
    IO流概述:输入输出流(input/output)
    流是一组有顺序的·,有起点和终点的字节集合,是对数据传输总称的抽象。即数据在两个设备间的传输称为流
    流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便直观的进行数据操作
    IO流分为:
    根据处理数据类型不同分为:字符流和字节流
    根据数据流向不同分为:输入流和输出流
    字节流:
    字节操作流 每次执行写入操作会直接把数据写入到文件
    字节输出流:
    OutPutStream类定义
    public abstract class OutPutStream extends Object implements Closeable,Flushable
    此抽象类表示输出字节流的所有类的超类。输出流接受输出字节并将这些字节发送到InputStream类某个接收器,要向文件中输出使用FileOutPutStream类
    字节输入流:
    public abstract class InputStream extends Object implements Closeable
    此抽象类表示字节输入流所有类的超类。
    FileInputStream从文件系统中的某个文件中获取输入字节
    输出:

    • 0.确定目标文件
      * 1.构建文件输出流对象
      * 2.输出内容
      * 3.把内容写入文件
      * 4.关闭
      输入: * 0.确定目标文件
      * 1.构建文件输入流对象
      * 2.每次读取的字节长度
      * 3.把数组读取到数组中 并返回读取的字节数 当不等于-1(自己定的数值)时表示读取到数组
      * 4.根据读取到的字节数组 再转换为字符串内容
      * 5.g关闭
      字符流:*(不会有乱码问题)
      writer:写入字符流的抽象类,子类必须实现的方法仅有writer(char[],int,int),flush和close。但是大多数子类将重写此处定义的一些方法以求提供更高效率或者其他功能;
      与OutputStream一样,对文件的操作使用FileWriter类完成
      Reader:用于读取字符流的抽象类,子类必须实现的方法有reader(char[],int,int)和close,但是多数子类将重写此处定义的一些方法以求提供更高效率或者其他功能;使用FileReader类进行实例化
    • 每次操作单位是一个字符
    • 文件字符操作流 会自带缓存(临时写到内存里面)原理是默认大小为1024字节, 在缓存满后或手动刷新缓存(缓存清空在放入) 或关闭流时把字符写入文件
      字节流与字符流的区别:
      *重要**操作非文本文件使用字节流 操作文本文件建议使用字符流
      字符流的内部实现还是字节流
      在所有流操作里,字节永远是最基础的。任何基于字节的操作都是正确的。无论你是无本文件还是二进制文件。如果确认流里面只有可打印的字符,包括英文和各种国家的文字,也包括中文。那么可以考虑用字符流。由于编码不同,多字节的字符可能占用多个字节。比如GBK的汉字就占两个字节UTF-8的汉字占三个字节。所以字符流是根据指定编码,将一个或者多个字节转化为Java里面的nuicode的字符,然后进行操作。字符操作一般使用writer和reader等,字节操作一般都是InputStream OutputStream以及各种包类比如:bufferedInputStream bufferedOutputStream
      如果确定要处理的流是可打印的字符流那么使用字符流会简单一点。如果不确定用字节流总是不会错的
      文件复制
      从一个输入流中读取数据 然后通过输出流写入目标位置 一边读一边写

    字节字符流转换:
    转换流可以将字节流转换成字符流 也可以将字符流转换成字节流
    OutputStreamWriter:可以将输出的字符流转换为字节流的输出形式
    InoutStreamReader:将输入的字节流转换为字符流输入形式

    缓冲流:用buffer后得用flush刷新一下
    对文件或其他的目标频繁的读写操作,效率低,性能差
    使用缓冲流的好处是,能够高效的读写信息,原理是先数据缓冲起来,然后一起写入或者读取出来。
    字节缓存流:
    BufferedInputStream:为另一个输入流添加功能,在创建bufferedInputStream时,会创建一个内部缓冲区数组,用于缓冲数据。
    BufferedOutputStream:通过这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统;内部默认缓存大小为8KB每次写入时存储到缓存中的byte数组中,当数组存满时会把数组数据写入文件。 并且缓存下标归0
    字符缓存流:
    BufferedReader:从字符输入流中读取文本,缓冲各个字符,从而实现字符数组和行的高效读取、
    BufferedWrite:将文本写入字符输出流,缓冲各个字符,从而提供单个字符 数组和字符串的高效写入
    1.加入字符缓冲流,增强读取功能(readline)

    • 2.更高效的读取数据
    • FileReader:使用InPutStreamReader,解码过程byte->char默认缓存大小8KB
    • BufferedReader:默认缓存大小也是8KB可以手动指定缓存大小,
    • 可以把数据直接读取到缓存中,减少每次转换过程效率更高
      一定要带上Buffer
      打印流:
      打印流主要功能用于输出,在整个IO包里边打印流分为两种类型:
      字节打印流:PrintStream
      字符打印流:PrintWriter
      打印流可以很方便的输出

    对象流与序列化:
    对象流的两个类:
    ObjectOutPutStream将以Java对象的基本数据类型和图形写入OutPutStream
    ObjectInPutStream对以前使用ObjectOutPutStream写入的基本数据和对象进行反序列化;
    序列化一组对象:
    在序列化操作中,同时序列化多个对象时,反序列化也必须按顺序操作,序列化一组对象可采用,对象数组的形式,因为对象数组可以向Object进行转型操作。
    translent关键字:
    使用translent关键字声明一个实例变量,当对象存储时,它的值不需要维持
    如果一个类创建对象 需要被序列化,那么必须实现Serializable接口
    Serializable是个标记接口,没有任何意义为了告诉JVM该类对象可以被序列化
    需要被序列化的情况

    • 1.把对象保存到文件中(存到物理介质)
    • 2.对象需要在网络上传输时
      如果没有实现Serializable接口 会报java.io.NotSerializableException异常
      序列化:把对象写入文件:实际写入的是类名,属性名,属性类型,属性值等
      反序列化:从文件中把对象内容读取出来,还原成对象

    字节数组流:字节数组流是基于内存的操作流
    ByteArrayInputStream
    包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部设计器跟踪read方法要提供的下一个字节,关闭ByteArrayInputStream无效。此类中的方法在关闭此流后仍可被调用 不会产生异常
    ByteArrayOutputStream
    此类实现了一个输入流,其中的数据被写入一个Byte数组。缓冲区会随着数据的不断写入而增长。可使用toByteArray()和toString()获取数据;关闭ByteArrayOutputStream无效;此类中的方法在关闭此流后仍可被调用 不会产生异常
    字节数组流是基于内存的操作流 每部维护着一个字节数组 我们可以利用流的读取机制来处理字符串 无需关闭
    数据流:
    DataInputStream:
    数据输入流允许应用程序与机器无关方式从底层输入流中读取基本Java数据类型。应用程序可以使用数据输出流写入后,由数据输入流读取数据。DataInputStream对于多线程访问不一定是安全的。线程安全是可选的,它由此类方法的使用者负责
    DataOutputStream:
    数据输出流允许应用程序以适当方式将基本类型写入输出流中。然后,应用程序可以使用数据输入流将数据读入;
    合并流:D:\IDEALX\SSE\src\com\IO\demo\eight\Test11
    SequenceInputStream表示其他输入流的逻辑串联,它从输入流的有序集合开始,并从第一个输入流开始读取,直到达文件末尾,接着第二个输入流读取,以此类推,直到到达包含的最后一个输入流的文件末尾为止,‘
    字符串流:

    • 字符串流:以字符串为数据源来构造一个字符流
    • 作用:在web开发中 经常要从服务器上获取数据 数据的返回格式通常是一个字 符串(XML JSON)格式 我们需要
    • 要这个字符串构造成字符流然后用第三方的数据解析器解析出来
      1.StringReader
      其源为一个字符串的字符流
      2.StringWriter
      一个字符流,可以用其回收在字符串缓冲区中的输出来构造字符串,关闭StringWriter无效,此类的方法在关闭该流后仍可被调用而不会产生IOExce
    管道流:

    管道输入流应该连接到管道输出流,:管道输入流要提供写入管道输出流的所有数据字节。通常,数据某个线程从PipedlOutputStream对象读取,并由其他线程将其写入相应的PipedlInputStream。不建议对这两个对象使用单线程,因为这样可能死锁线程。管道输入流包含一个缓冲区,可在缓冲区限定的范围内将读操作和写操作分开。如果向链接管道输出流提供数据字节的线程不再存在,则认为该通道已经损坏。
    RandomAccessFile:绝大多数功能已经被内存映射文件取代
    RandomAccessFile是IO包类,从object直接继承而来。只可以对文件进行操作,可以对文件进行读取和写入,当模式为r(读)时不会报异常,当模式为rw(读写)时,当文件不存在时会自动创建文件,不会对原文件进行覆盖。
    RandomAccessFile有强大的读写功能,其内部是大型byte[]可以通过seek(),getFilePointer等方法进行操作的指针,方便对数据写入和读取还可以对基本数据类型进行直接读取
    properties工具类
    properties主要用于读取Java的配置文件,各种语言都有自己所支持的配置文件,配置文件中很多变量是经常改变的,这样做也方便了用户让用户脱离程序本身去修改相关变量配置
    1.getProperty(String key) 用指定的键在此属性列表中搜索属性,也就是通过key 得到Key对应的value
    2.load(InputStream inStream),从输入流中读取属性列表(键和元素对)通过对指定的文件进行装载来获取该文件的所有键值对以供getProperty(String key)搜索
    3.setProperty(String key,String value)调用Hashtable的方法put.他通过调用基类的put方法来设置键值对
    4.store(OutputStream out ,String comments)以适合使用load方法加载到properties表中的格式,将此properties表中的属性列表写入输出流,与load相反 该方法将键值对写入到指定的文件中去。
    5.clear()清除所有的键值对
    文件压缩与解压:
    ZipOutputStream 实现文件压缩
    ZipOutputStream(ZipOutputStream out)创建新的Zip输出流
    void putNextEntry(ZipEntry e)开始写入新的zip文件条目并将流定位到条目数据的开始处。
    ZipEntry(string name)使用指定名称穿件zip条目
    ZipInputStream实现文件的解压
    ZipOutputStream(ZipOutputStream in)创建新的zip输入流
    zipEntry getNextEntry()读取下一个zip文件条目并将流定位到该条目数据的开始处
    装饰者模式:
    意图:动态的给一个对象添加一些额外的职责,就增加功能来说装饰者模式比生成子类鞥灵活 装饰模式的设计理念主要是以对客户端透明的方式动态扩展对象的功能,是继承关系的一个替代(继承会产生大量的子类,而且代码有冗余)。装饰模式可以在不创造更多子类的情况下,将对象的功能加以扩展。装饰模式把客户端的调用委派到被装饰类。装饰模式的关键在于这种扩展完全是透明的
    抽象构件角色(Component):通常是一个抽象类或者一个接口,定义了一系列方法,方法的实现可以由子类实现或者自己实现。通常不会直接使用该类,而是通过继承该类或者实现该接口来实现特定的功能。(例如,对于动物类,有一个抽象方法输出所有的功能,基本功能包括:呼吸,觅食,睡觉等等)
    具体构件角色(Concrete Component):是Component的子类,实现了对应的方法,它就是那个被装饰的类。(具体构建角色可以建立很多个,例如狗,猫,鸟等等,如果是狗,我们可以装饰一些吼叫的功能,吃肉的功能;鸟可以装饰一些飞行的功能,带有翅膀的功能等等。当然这些需要在具体装饰角色中去具体定义)
    装饰角色(Decorator):是Component的子类,它是具体装饰角色共同实现的抽象类(也可以是接口),并且持有一个Component类型的对象引用,它的主要作用就是把客户端的调用委派到被装饰类。
    具体装饰角色(Concrete Decorator):它是具体的装饰类,是Decorator的子类,当然也是Component的子类。它主要就是定义具体的装饰功能,例如上面说的,对于鸟这个具体构建角色而言,除了具备抽象构件角色基本的功能,它还具有一些飞行的功能,带翅膀的功能。那么我们可以把这两个功能定义成一个具体装饰角色1,对于狗这个具体构件角色而言,我们可以把吼叫,吃肉这两个功能定义成一个具体装饰角色2,这样,如果我们再定义一个狼这样的具体构件角色的时候,就可以直接用具体装饰角色2来进行装饰。
    常见字符编码:
    GB2312/GBK
    中文的国际编码,专门用来表示汉语,是双字节编码
    常见编码:Iso8859-1 GB2312/GBK unicode UTF
    Iso8859-1
    单字节编码 最多只能表示0–255的字符范围,主要用在英文上
    unicode
    Java中就是使用的此编码,也是最标准的一种编码,使用16进制表示编码方式,单此编码不兼容Iso8859-1
    UTF犹豫unicode不支持ISO8859-1而且容易占用更大空间,而且对于英文字母也需要使用两个字节编码,这样使unicode不便于传输和存储,因此产生了UTF编码,UTF兼容了ISO8859-1编码,也可以用来表示所有语言字符,不过UTF是不定长编码,每个字节的长度从1-6个字节不等,一般在中文网页中使用可以节省空间
    乱码原因:
    1.程序使用的编码与本机不相同
    2.在网络中客户端与服务端编码不统一

    New IO

    为什么要使用NIO
    NIO是JDK1.4加入的新包,nio创建的目的是让程序员实现高速IO而无需编写本机自定义代码 NIO将最耗时的IO操作(填充和提取缓冲区)转移回操作系统因而可以极大地提高速度
    流与块的比较
    原来的IO库里与NIO最重要的区别是数据打包和传输方式,原来的IO以流的方式处理数据 而NIO以块的方式处理数据
    面向流的IO系统一次一个字节的处理数据,一个输入流产生一个字节的数据,一个输出流消费一个字节的数据 面向流的IO通常很慢 一个面向块的IO系统以块的形式处理数据。每一个操作都在一步中产生或者消费一个数据块。按块处理数据比按流处理处理数据快的多。但是面向块IO缺少一些面向流的IO的优雅性和简单性。

    缓冲区
    在NIO中所有数据都是用缓冲区处理的。在读取数据时 它是直接读取到缓冲区中的任何时候访问NIO中的数据都是将他放入缓冲区。缓冲区实质上就是一个数组。通常它是一个字节数组,但也可以使用其他种类的数组,但是一个缓冲区不仅仅是一个数组。缓冲区提供了对数据结构化访问,而且还可以跟踪系统的读写进程。
    缓冲区类型:除布尔 byteBuffer七种 最常用的是ByteBuffer

    通道:Channel
    Channel是一个对象,可以通过它读取和写入数据,拿NIO和IO比较 通道就像是流,所有数据都通过BUffer对象来处理永远不会将字节写入通道中,相反是将数据写入包含一个或多个字节的缓冲区。同样也不会直接从通道中读取字节,而是将字节从通道读入缓冲区,再冲缓冲区获取这个字节。

    • 比较IO操作的性能

    • 1.内存映射是最快的

    • 2.NIO读写文件

    • 3.使用了缓存的IO流

    • 4.无缓存
      path接口
      1.path表示的是一个目录名序列,其后还可以跟着一个文件名,路径中第一个部件是根部件时就是绝对路径,而允许访问的跟部件取决于文件系统
      2.以根部件开始的路径都是绝对路径,否则就是相对路径
      3.静态Paths.get方法接受一个或多个字符串,字符串之间自动使用默认文件系统的路径分隔符连接起来,这就解决了跨平台问题,接着解析连接起来的结果,如果不是合法路径就抛出异常InvalidPathException 否则就返回一个path对象
      Files工具类D:\IDEALX\SSE\src\com\IO\demo\eight\Test17NIO\PathFileDemo.java
      //Files工具类 写文件
      Path p4= Paths.get(“D:\app\aaa.txt”);
      String info =“小桥流水人家”;
      try {
      Files.write(p4,info.getBytes(“gb2312”),StandardOpenOption.APPEND);
      } catch (IOException e) {
      e.printStackTrace();
      }
      //写入
      try {
      byte[] bytes = Files.readAllBytes(p4);
      System.out.println(new String(bytes));
      } catch (IOException e) {
      e.printStackTrace();
      }

      //复制文件
       try {
      

      Files.copy(p2,Paths.get(“D:\app\Test\test01\001.jpg”),StandardCopyOption.REPLACE_EXISTING);
      } catch (IOException e) {
      e.printStackTrace();
      }
      //移动文件
      try {
      Files.move(p2,Paths.get(“D:\app\Test\test01\001.jpg”),StandardCopyOption.REPLACE_EXISTING);
      } catch (IOException e) {
      e.printStackTrace();
      }

       //删除文件
       try {
           Files.delete(p2);
       } catch (IOException e) {
           e.printStackTrace();
       }
      

    创建文件和目录
    //创建新目录一个部件,其他必须是已存在的
    Files.createDirectory(path);
    //创建路径中的中间目录,能创建不存在的中间部件
    5 Files.createDirectories(path);
    //创建一个空文件,检查文件存在,如果已经存在则抛出异常检查文件存在的原子性,因此在此过程中无法执行文件创建操作
    Files.createFile(path);
    //添加前后缀创建临时文件或者临时目录
    Path newPath = Files.File.createTempFile(dir,prefix,suffix);
    Path newPath = Files.File.creatFileDirectory(dir,prefix);

    集合框架:

    集合框架作用:
    在实际开发中,经常会对一组相同类型的数据进行统一管理操作。到目前为止,我们可以使用数组结构,链表结构,二叉树结构来实现。
    数组最大的问题在于数组中的元素个数是固定的,要实现动态数组很麻烦,自己实现链表结构或者二叉树结构来管理对象更是不方便
    JDK1.2以后Java完整的提供了类集合的概念,封装了一组强大的非常方便的集合框架API 提高了开发效率

    集合中分为三大接口:
    Collection Map Iterator
    Collection接口:
    Collection层次结构中的根接口,Collection表示一组对象,这些对象也称为collection的元素,一些collection允许有重复的元素,而另一些不允许。一些collection是有序的,另一些是无序的JDK不提供此接口的实现,它提供更具体的子接口(Set,List)实现。此接口通常用来传递collection,并在需要最大普遍性的地方操作这个collection。Public interface Collection
    LIst接口:
    public interface List extends Collection
    有序的collection。此接口的用户可以对列表中的每个元素的插入位置精确ed控制,用户可以根据元素的整数索引访问元素,并搜索元素。
    List接口是可变数组的实现,实现所有可选列表操作,并允许null在内的所有元素
    List

    • 1.有序
    • 2.允许多个null元素
    • 3.具体实现有:ArrayList Vector LinkedList
      ArrayList与Vector的区别
    • ArrayList实现方法
      1.采用动态数组实现 默认的构造方法创建了一个空的数组
      2.第一次添加元素扩展容量为10之后的扩充算法是:原来数组大小+原来数组的一半
      3.不适合插入与删除操作
    1. 为防止数组动态扩充次数过多 建议创建ArrayList 给定初始容量
      5.线程不安全适合单线程访问时使用
      Vector
      1.实现原理,采用动态数组实现,默认构造了一个大小为10的对象数组
      2.扩充的算法:当增量为0时,扩充是为原来大小的两倍,当增量大于0时,扩充为原来大小+增量
      3.不适合删除和插入操作
      4.为防止数组动态扩充次数过多 建议创建Vector 给定初始容量
      5.线程安全适合多线程时访问,效率较低

    LinkedList:
    List接口的列表实现。实现所有的可选的操作列表并允许所有元素包括null。除了实现list接口外,LinkedList类还为在列表的开头及结尾get remove元素提供了统一的命名方法。

    • LinkedList
      1.实现原理,采用双向链表结构
      2.适合插入,删除操作,性能高
      在实际开发中 如何选择
    • 1.安全性问题
    • 2.是否频繁的有插入和删除操作(LinkedList)
    • 3.是否是存储后遍历

    set:
    一个不包含重复元素的collection。更确切的讲,set包含满足e1.equal(e2)的元素对e1e2,并且最多包含一个null元素
    HashSet
    * 1.实现原理,基于哈希表(HaspMap)实现
    * 2.不允许重复 可以有一个null元素
    * 3.不保证顺序恒久不变
    * 4.添加元素时把元素作为HashMap的键存储 HashMap的value使用一个固定的object对象

    • 5.排除重复元素是通过equals来检查对象是否相同
      6.判断两个对象是否相同先
      7.自定义对象要认为属性值都相同时为一个对象 有这种需求时 要重写对象所在类的HashCode和equals方法
      (1)判断两个对象的HashCode是否相等如果不相等则认为两个对象也不相等结束如果相等转入 判断equals运算是否相等如果不相等,认为两个对象不相等 如果相等则两个对象相等
      • 排除重复元素是通过equals来检查对象是否相同
        HashCode
        HashCode方法是本地方法,它的实现是根据本地机器相关,当然我们可以在自己写的类中覆盖HashCode方法
        在Java的集合中判断两个对象是否相等的规则是:
        1.判断两个对象的HashCode是否相等
        如果不相等则认为两个对象也不相等结束
        如果相等转入2
        2.判断equals运算是否相等
        如果不相等,认为两个对象不相等
        如果相等则两个对象相等
    • 小结
      • 1.哈希表的存储结构:数组+链表 数组里的每个元素以链表的形式存储
      • 2.如何把对象存到哈希表中 先计算HashC的值,再对数组长度求余数 来决定对象要存储在数组中的哪个位置
      • 3.解决HashSet重复值的方式是 参考第六点

    TreeSet
    基于treeMap的NavigableSet实现。使用元素的自然顺序对元素进行排序,或者根据创建set时提供的Comporator进行排序,具体取决于使用的构造方法有序的,基于treeMap(二叉树数据结构) 对象必要比较大小,通过对象比较器来实现
    * 对象比较器还可以来去除重复元素 如果我们自定义的类 没有实现比较器结构 无法连接到treeSet集合
    LinkedHashSet
    具有可预知迭代顺序的Set接口的哈希表和连接列表的实现。此实现与HashSet的不同之处在于,后者维护着一个运行于所有条目的双重链接表,此链接列表确定了迭代顺序 ,即按照将元素插入到set中的顺序进行迭代,插入顺序不受在set中重新插入的元素的影响
    *Set接口

    • 1.无序的(不保证顺序)
    • 2.不允许重复元素
    • HashSet TreeSet LinkedHashSet
    • 如果要排序选择treeSet
    • 如果不要排序也不保证顺序用HashSet
    • 不要排序要保证顺序 用LinkedHashSet

    集合迭代器Iterator
    一般有四种
    1.Iterator
    2.ListIterator
    3.Enumeration
    4.foreach
    使用foreach输出时一定要注意,创建集合时要指定操作泛型的类型
    JDK8的四大核心函数式接口
    1.Consumer<T,R>接口 消费者接口
    2.Function接口 表示接受一个参数并1产生结果的函数
    3.Supplier接口 代表结果供应商
    4.Predicate接口 断言接口

    Stream
    Stream是元素集合,这点让Stream看起来有些类似Iterator
    可以支持顺序和并行的对原Stream进行汇聚操作;
    Stream可以看做是Iterator的高级版本

    Map
    将键映射到值的对象,一个映射不能包含重复的键:每个键最多映射一个值
    Map接口

    • 1.键值对存储一组对象
    • 2.Key不能重复(唯一)value可以重复
    • 3.具体实现类:HashMap TreeMap Hashable LinkedHashMap
      HashMap
      基于哈希表的map接口的实现,此实现提供所有可选的映射操作,并允许null值和null键,(除了非同步和允许使用null之外HashMap和Hashtable大致相同)此类不保证顺序,特别是它不保证该顺序恒久不变
      HashMap实现原理:
      • 1.基于哈希表(数组+链表+二叉树(红黑树))
      • 2.默认加载因子为0.75 默认数组大小16
      • 3.把对象存储到哈希表中 如何存储
      • 把key对象通过hash()方法计算hash值,然后用这个Hash值对数组长度取余默认为16 来决定该Key对象 在数组中存储的位置,当这个位置有多个对象时以链表结构存储,在JDK1.8后当链表长度大于8时 链表转化为红黑树结构存储 这样的目的是为了取值时提高效率存储数据量越大,性能越明显
        4扩充原理:当数组容量超过百分之七十五,那么表示该数组需要扩充如何扩充:
        扩充算法:当前数组容量<<1相当于乘2 扩大一倍 扩充次数过多会影响性能,每次扩充表示哈希表重新散列(重新计算每个对象的存储位置)开发中尽量要减少扩充次数带来的性能问题
        5.线程不安全适合单线程
        Hashtable:
        此类实现一个哈希表,该哈希表将键映射到相应的值。任何非null对象都可以用作键或者值。为了成功的将哈希表中存储或获取对象,用作键的对象必须实现HashCode方法和equals方法
    • JDK1.0开始
      • 基于哈希表实现(数组+链表)
      • 默认数组大小为11加载因子为0.75
      • 扩充方式:原数组大小<<1(*2)
      • 线程安全的 用在多线程时访问
        LinkedHashSet
        Map接口的哈希表和链接列表实现,具有可预知的迭代顺序。此实现与HashMap的不同之处在于,后者维护着一个运行于所有条目的双重链接列表
        LinkedHashMap是HashMap的子类,由于HashMap不能保证顺序恒久不变,此类使用一个双重链表来维护元素添加顺序。
        TreeMap
        基于红黑树的NavigableMap实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供Comparator进行排序,具体取决于使用的构造方法
        数据结构:数组,链表,二叉树(红黑树),哈希表(数组+链表+红黑树),栈,队列
        Java8map新特性D:\IDEALX\SSE\src\com\MapCollection\demo\nine\Test05

    Collections类
    排序操作(主要针对list接口)
    //Collections.reverse(list);//反转顺序
    //Collections.shuffle(list);//随机排序
    //Collections.sort(list);//自然顺序排序
    //Collections.swap(list,0,2);//两个位置交换
    //Collections.rotate(list,1);//右移一个位置
    查找和替换(针对collection接口)
    System.out.println(Collections.binarySearch(list,“zm”));
    //System.out.println(Collections.max(list));//最大值
    // System.out.println(Collections.min(list));//最小值
    //Collections.fill(list,“bin”);//填充
    //System.out.println(Collections.frequency(list,“zm”));
    Collections.replaceAll(list,“zm”,“bn”);

    Optional容器类(JDK1.8)
    Optional容器类:
    这是一个可以为null的容器对象,如果值存在isPresent()方法会返回true,调用get会返回该对象
    of:
    为非null的值创建一个Optional
    ofNullable:
    为指定的值创建一个Optional,如果指定的值为null则返回一个空的Optional
    ispresent
    如果值存在返回true否则返回false
    get
    如果Optional有值则返回 否则抛NoSuchElementException
    ifPresent
    如果Optional实例则为其调用consumer 否则不做处理
    orElse
    如果有值则将其返回,否则返回其他值
    orElseGet
    orElseGet与orElse方法类似,区别在于得到的默认值,orElse方法将传入的字符串作为默认值,orElseGet方法可以接受Supplier接口的实现用来生成默认值
    orElseThrow
    如果有值将其返回,否则抛出Supplier异常
    map:
    如果有值,则对其执行调用mapping函数得到返回值。如果返回值不为null,则创建包含mapping返回值的Optional作为map返回值,否则返回空Optional
    flatmap
    如果有值则对其执行调用mapping函数得到返回值。否则返回空Optionalflatmap与map方法类似,区别在于flatmap中的mapper返回值必须·是Optional,调用结束时,flatmap不会对结果用Optional封装;
    filter
    如果有值且满足断言条件返回包含该值的Optional,否则返回空Optional

    队列与栈

    Queue Deque接口
    队列Queue是一种特殊的线性表,是一种先进先出的数据结构。它只允许在表的前端进行删除操作,而在表的后端进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头,队列没有元素时称为空队列。
    LinkedList是QUeue的实现
    Boolean add(E e)将指定元素插入此队列(如果立即可行且不会违反容量限制),在成功时返回true,如果当前没有可用的空间则抛出IllegalStateException
    E element():获取 但不是移除此队列的头
    Boolean offer(E e)将指定元素插入此队列(如果立即可行且不会违反容量限制),当使用有容量限制的队列时,此方法通常优于add,后者可能无法插入元素,而只是跑出一个异常
    E peek():获取但不移除此队列的头:如果队列为空则返回null
    E poll();获取并移除此队列的头 如果队列为空则返回null
    E remove() 获取并移除此队列的头
    Deque:
    一个线性collection,支持在两端插入和移除元素。此接口即支持有容量限制的双端队列,也支持没有固定大小的限制的双端队列,接口定义在双端队列两端访问元素的方法。提供插入移除和检查方法;

    对象的多对多与一对多

    D:\IDEALX\SSE\src\com\MapCollection\demo\nine\Test08MN

    迭代器模式:
    提供一个方法按顺序遍历一个集合内元素,而不需要暴露其内部提示
    应用场景
    1.访问一个聚合的对象,而不需要暴露对象的内部表示
    2.支持对聚合对象的多种表示
    3.对遍历不同的对象,提供统一接口
    迭代器模式的角色构成
    1.迭代器角色Iterator:定义遍历元素所需要的方法一般来说有三个:取下一个元素的方法next();判断是否遍历结束的方法hasNext();移出当前对象的方法remove();
    2.具体迭代器角色Cnocrete Iterator:实现迭代器接口中定义的方法,完成集合迭代
    3.容器角色Aggregate:一般是一个接口,提供iterator()方法;
    4.具体容器角色ConcreteAggregate:就是抽象容器的具体实现类,如List接口的有序列表实现ArrayList,链表实现LinkedList

    Guava:
    guava对JDK集合的扩展
    1.不可变集合:用不变的集合进行防御性编程和性能提升
    2.新集合类型:multisets,multimaps,tables
    3.强大的集合工具:提供Java.util.Conllections中没有的集合工具
    4.扩展工具:让实现和扩展集合类变得容易,比如创建装饰器 实现迭代器
    功能
    1.只读设置
    2.函数式编程:过滤器
    3.函数式编程:转换
    4.组合式函数编程
    5.加入约束:非空 长度验证
    6.集合操作:交集 差集 并集
    7.Multiset:无序可重复
    8.multimap key可以重复
    9.Bimap:双向map键与值不能重复
    10双键的map:-》table->rowkey+columnkey+value

    多线程

    线程与进程
    1.进程
    程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态概念,而进程是程序在处理机上的一次执行过程,它是一个动态的概念。 进程是一个具有一定独立功能的,一个实体,每一个实体都有他自己的进程空间
    2.进程的状态
    进程执行时的间断性,决定了进程可能有多种状态,事实上运行的进程有三种基本状态
    (1)就绪状态(ready)
    (2)运行状态(running)
    (3)阻塞状态(blocked)
    3.线程
    线程实际上是在进程的基础上进一步划分,一个进程启动后,里面的若干程序又可以划分成若干线程。 线程:是进程中的一个执行路径,共享一个内存空间,线程之间可以自由切换,并发执行,一个进程最少有一个线程。 一个程序同时执行多个程序 提高效率
    并行:就是两个任务同时运行(CPU)
    并发:是指两个人任务同时请求运行,而处理器一次只能执行一个任务,就会把两个任务安排轮流执行,由于CPU时间片运行时间较短,就会感觉两个任务同时执行;

    线程实现的两种方式:推荐第二种
    1.继承Thread类
    class MyThread extends Thread{
    public void run(){
    逻辑处理
    }
    }
    MyThread mt = new MyThread();
    mt.start();//启动线程 有虚拟机启动
    2.实现Runnable接口
    class MyRunnable implements Runnable{
    public void run(){
    逻辑处理
    }
    }
    MyRunnable mr =new MyRunnable();
    Thread t = new Thread(mr);
    t.start();
    线程的休眠:
    public static void sleep(long millis)
    throws InterruptedException使当前正在执行的线程以指定的毫秒数暂停,释放CPU时间片具体取决于系统定时器和调度程序的精度和准确性。线程不会丢失任何显示器的所有权; millis—以毫秒为单位的睡眠时间长度
    异常:
    illegalArgumentException 如果millis为负数
    InterruptedException如果任何线程中断当前线程,当抛出此异常时,当前线程的中断状态将被清除

    join与中断线程:
    join方法:

    • 加入线程,让调用的线程先执行指定时间或执行完毕
    • 中断线程
    • 1.Interrupt方法来中断线程 设置一个中断标记()
    • 2.自定义标记的方式(推荐)
      public final void join() throws InterruptedExcception
      等待这个线程死亡 调用此方法的行为方式与调用完全相同 join();

    异常InterruptedExcception-如果任何线程中断当前线程当抛出此异常时,当前线程的中断状态将被清除
    public void interrupt()
    中断这个线程
    除非当前线程中断自身,这是始终允许的

    public static boolean interrupted()
    测试当前线程是否中断。该方法可以中断线程的中断状态。也就是说如果这个方法调用两次 第二次会返回false(除非当前线程再次中断)

    守护线程与yield
    public final void setDaemon(boolean on)
    将此线程标记为daemon线程或者用户线程。当运行的唯一线程都是守护线程时,Java虚拟机将退出
    public final boolean isDaemon()
    测试这个线程是否是守护线程
    public static void yield()
    暂停当前线程正在执行的对象,并执行其他线程
    优先级高提高该线程抢占CPU时间片的概率

    线程同步:
    1.多线程共享数据
    在多线程操作中,多个线程可能同时处理一个资源,这就是多线程中的共享数据
    2.线程同步
    解决数据共享问题,必须使用同步,就是指多个线程在同一时间段内只能有一个线程执行指定代码,其他线程等此线程执行完后才能执行
    1.多线程共享数据时会发生线程不安全情况
    2.多线程共享数据必须使用同步(轮流)
    3实现同步的三种方法
    (1)同步代码块
    synchronized(要同步的对象){
    要同步的操作
    }
    (2)同步方法
    public synchronized void method(){
    要同步的操作
    }
    (3)Lock(ReentrantLock)
    同步准则
    当编写synchronized块时,遵循这些准则在避免死锁和性能危险的风险方面大有帮助
    (1)使代码块保持简短,把不随线程变化的预处理和后处理移除synchronized块;多线程共享数据,会有安全问题,使用同步解决安全问题,但同时会牺牲性能,所以代码块要尽量保持简单,把不随数据变化的移出代码块
    (2)不要阻塞,如InputStream.read()
    (3)在持有锁的时候不要对其他对象调用方法
    死锁:
    过多的同步有可能出现死锁,死锁的操作一般是在程序运行的时候才有可能出现的。多线程中要进行资源共享,就需要同步,但同步过多,就可能造成死锁。

    • 题: sleep与wait的区别
    • sleep:让当前线程进入休眠状态,让出CPU的时间片,但是不释放对象监视器的所有权(对象锁)
    • wait:让线程进入等待状态,让出CPU的时间片,并释放对象监视器的所有权(对象锁) 等待其他线程通过Notify方法来唤醒

    线程生命周期与线程池
    1.New(初始化状态):指的是在高级语言,比如Java。在Java层面的线程被创建了,而在操作系统中的线程其实是还没被创建的,所以这个时候是不可能分配CPU执行这个线程的!所以这个状态是高级语言独有的,操作系统的线程没这个状态。我们New了一个线程,那时候它就是这个状态。
    2.Runnable(可运行/运行状态):这个状态下是可以分配CPU执行的,在New状态时候我们调用start()方法后线程就处于这个状态。
    3.Blocked(阻塞状态):这个状态下是不能分配CPU执行的,只有一种情况会导致线程阻塞,就是synchronized!我们知道被synchronized修饰的方法或者代码块同一时刻只能有一个线程执行,而其他竞争锁的线程就从Runnable到了Blocked状态!当某个线程竞争到锁了它就变成了Runnable状态。注意并发包中的Lock,是会让线程属于等待状态而不是阻塞,只有synchronized是阻塞。(感觉是历史遗留问题,没必要多一个阻塞状态和等待没差啊)。
    4.Waiting(无时间限制的等待状态):这个状态下也是不能分配CPU执行的。有三种情况会使得Runnable状态到waiting状态
    调用无参的Object.wait()方法。等到notifyAll()或者notify()唤醒就会回到Runnable状态。调用无参的Thread.join()方法。也就是比如你在主线程里面建立了一个线程A,调用A.join(),那么你的主线程是得等A执行完了才会继续执行,这是你的主线程就是等待状态。调用LockSupport.park()方法。LockSupport是Java6引入的一个工具类Java并发包中的锁都是基于它实现的,再调用LocakSupport.unpark(Thread thread),就会回到Runnable状态。
    5.Timed_Waiting(有时间限制的等待状态):其实这个状态和Waiting就是有没有超时时间的差别,这个状态下也是不能分配CPU执行的。有五种情况会使得Runnable状态到waiting状态
    Object.wait(long timeout)。Thread.join(long millis)。Thread.sleep(long millis)。注意 Thread.sleep(long millis, int nanos) 内部调用的其实也是Thread.sleep(long millis)。LockSupport.parkNanos(Object blocked,long deadline)。LockSupport.parkUntil(long deadline)。
    6.Terminated(终止状态):在我们的线程正常run结束之后或者run一半异常了就是终止状态!注意有个方法Thread.stop()是让线程终止的,但是这个方法已经被废弃了,不推荐使用,因为比如你这个线程得到了锁,你stop了之后这个锁也随着没了,其它线程就都拿不到这个锁了!这不玩完了么!所以推荐使用interrupt()方法。
    interrupt()会使得线程Waiting和Timed_Waiting状态的线程抛出 interruptedException异常,使得Runnabled状态的线程如果是在I/O操作会抛出其它异常。
    如果Runnabled状态的线程没有阻塞在I/O状态的话,那只能主动检测自己是不是被中断了,使用isInterrupted()。
    线程池:
    线程池是预先创建线程的一种技术。线程池在还没有任务之前,创建一定数量的线程,放入空闲队列,然后对这些资源进行复用,减少频繁的创建和销毁对象。线程池顶级接口是Executor,是一个执行线程的工具,线程池的接口是ExecutorService
    创建线程消耗很大
    Java.util.concurrent包:并发编程中很常用的类
    Executor接口:
    执行已提交的Runnable任务的对象·;
    ExecutorService接口
    Executor提供了管理终止的方法,以及可为跟踪一个或多个异步任务执行状况而生成Future的方法
    Executors类
    此包中所定义的 Executor、ExecutorService等的工厂和实用方法。
    //创建线程池(四种)第二种常用
    //1.创建一个单线程的线程池
    //ExecutorService es = Executors.newSingleThreadExecutor();
    //创建固定大小的线程池
    //ExecutorService es = Executors.newFixedThreadPool(2);
    //创建一个可缓存线程池,如果线程池大小超过了处理任务所需要的线程,那么就会回收空闲(60秒内不执行任务)
    //的线程
    //ExecutorService es = Executors.newCachedThreadPool();
    //创建一个大小无限的线程池,此线程池支持定时以及周期性执行任务的需求
    //ExecutorService es = Executors.newScheduledThreadPool(2);

    网络编程:

    1.计算机网络:
    把分布在不同地理区域的计算机以专门的外部设备用通信线路互连成一个规模大功能强的网络系统,从而使计算机可以方便快捷的互相传递信息,共享硬件软件数据信息等资源
    2.计算机网络主要功能:
    资源共享
    信息传输与集中处理
    均衡负荷与分布处理
    综合信息服务、综合业务数字网络ISDN等
    3.网络通信协议:
    要使计算机连成网络能够互通信息,需要对数据传输速率、传输代码、代码结构、传输控制步骤、出错控制等制定一组标准,这一组共同遵守的通信标准ius网络通信协议,不同计算机之间必须使用相同的通讯协议才能进行通讯;
    网络通信接口:
    为了使两个节点之间能进行对话,必须在他们之间建立通信工具(接口),使彼此之间能进行信息交换。接口包括两部分
    (1)硬件装置:实现节点之间的信息传送
    (2)软件装置:规定双方进行通信的约定协议
    TCP/Ip传输控制协议/因特网互联协议
    又叫网络通讯协议,这个协议是Internet最基本的协议、Internet国际互联网络的基础,简单地说就是由网络层的IP协议和传输层的TCP协议组成
    IP地址:网络中每台计算机的一个表识号 本地Ip172.0.0.1 localhost
    端口号:端口号范围0-65535之间,0-1023之间的端口数是用于一些知名的网络服务和应用
    七层协议: 应用层 表示层 会话层 传输层 网络层 数据结构层 物理层
    程序开发结构
    网络编程主要是指完成C/S程序的开发 程序开发有两种
    C/S 客户端/服务端(QQ)
    开发两套程序,需要同时维护
    B/S浏览器/服务器 Java基本以此为主
    开发一套程序,客户端使用浏览器访问,B/S一般稳定性较差 而且安全性也差
    C/S主要可以完成以下两种程序开发
    TCP:传输控制协议,采用三方握手的方式,保证正确的链接操作
    UDP:数据报协议,发送数据报 eg:QQ消息
    TCP协议:
    TCP是可靠协议,面向连接的协议。实现TCP程序,需要编写服务器·端和客户端,JavaAPI提供了Java.net包为实现网络应用程序提供类
    ServerSocket:此类实现服务器套接字
    Socket:此类实现客户端套接字‘ Socket是网络驱动层提供给应用程序编程的接口和一种机制
    实现服务器与客户端程序:
    服务器端:
    public class ServerSocket extends Object 此类实现服务器套接字。服务器套接字请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果
    ServerSocket(int port)创建绑定到特定端口的服务器套接字
    void set SoTimeout(int timeout) 通过指定超时值启用/禁用SO_TIMEOUT以毫秒为单位
    InetAddress getInetAddress() 返回此服务器套接字的本地地址
    Socket accept() 倾听并接受此套接字的连接
    //等待连接 会造成阻塞,如果没有客户端连接就一直在这等,如果连接成功则会理解返回socket对象 Socket socket = server.accept();
    客户端:
    public class Socket extends Object 此类实现客户端套接字。套接字是两台机器间通信的端点
    Socket(String host,int port)创建一个流套接字并将其连接到指定主机上的指定端口号
    InputStream getInputStream() 返回次套接字的输入流
    OutputStream getOutputStream() 返回此套接字的输出流
    void set SoTimeout(int timeout) 启用/禁用SO_TIMEOUT以毫秒为单位
    UDP协议
    UDP协议是一种无连接的协议,每个数据报都是一个独立信息,包括完整的源地址或目的地址它在网络上以任何可能的方式传往目的地,因此能否到达目的地,到达的时间及内容的正确性不能保证,数据大小在64kb之内
    DatagramPacket:表示数据报包
    DatagramSocket:发送和接收数据报包的套接字

    URL:统一资源定位符
    MINA:一个简洁易用的基于TCP/IP通信的Java框架
    http://mina.apache.org/downloads-mina_2_1.html
    一个简单的网络程序需要的最少jar包mina-core-2.0.16.jar slf4j-api-1.7.21.jar
    开发一个mina应用就是创建连接设定过滤规则编写自己的消息处理器

    反射与内省D:\IDEALX\SSE\src\com\FsheANx\demo\twelve\Test01

    反射: 通过对象获取类信息 把类信息映射成对象
    Class类是一切反射的根源 很多的类————Class类C是大写的
    得到class类对象的三种方式
    1.Object类中的getClass()方法
    2.类.class
    3.通过class类的forName()方法

    动态代理模式:
    就是通过代理类:proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期实现动态关联,比静态代理更加方便的对代理类处理
    主要使用java.lang.reflect包中的两个类
    1.InvocationHandler类
    public Object invoke(Object obj,Method method,Object[] obs)
    obj是代理类 method是代理方法 obs是被代理的方法的参数组
    2.proxy类
    protected Proxy(InvocationHandler h);
    static Class getProxyClass(ClassLoader loader,class[] interface);
    static Object newProxyInstance(ClassLoader loader,class[] interface,InvocationHandler h)
    动态代理类其实就是在运行时生成class所以必须提供一组interface,然后告诉它class已经实现了这些interface,而且在生成Proxy时必须提供一个handler来接管实际工作
    类加载过程:
    1.JVM将类加载过程分为三步:装载,链接和初始化 链接又分为三个步骤验证 准备 解析;
    装载:查找并加载二进制
    链接:
    验证:确保被加载类的正确性
    准备:为类的静态变量分配内存,并将其初始化为默认值
    解析:把类中的符号引用转换为直接引用
    初始化:为类的静态变量赋予正确的初始值
    2.类的初始化:
    1.创建类的实例,也就是new一个对象
    2.访问某个类或者接口的静态变量,或者对该静态变量赋值
    3.调用类的静态方法
    4.反射
    5.初始化一个类的子类
    6.JVM启动时标明的启动类,即文件名与类名相同的那个类
    类的加载:
    指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个这个类的java.lang.Class对象,用来封装类在方法区类的对象;

    JavaBean
    JavaBean就是Java组件广泛理解就是一个类 对于组件来说关键在于能够被IDE构建工具侦测其属性和事件的能力,
    javaBean命名规则
    1.对于一个属性为XXX的属性,通常要有get和set方法,任何浏览这些方法的工具都会把getset后边的第一个字母转换成小写
    2.对于布尔型属性,可以使用getset的方式也可以把get替换成is
    3.Bean的普通方法不必遵序以上规则,不过必须是public
    4.对于事件要使用swing中处理监听器的方式
    BeanUtils工具类:http://apache.org/

    内省
    内省是Java语言对Bean类属性、事件的一种缺省处理方法。例如A类中有name属性,那么我们可以通过getNamesetName来得到其值或者设置新的值

    AOP (Aspect Oriented Programming)
    AOP面向切面编程(切面:不是核心代码) 是面向对象编程的补充
    可配置AOP框架实现
    AOP使用场景:AOP用来封装横切关注点,具体使用:
    权限 缓存 错误处理 调试 记录跟踪 持久化 同步 事务等

    单例模式优化: D:\IDEALX\SSE\src\com\FsheANx\demo\twelve\Test06Singleton
    1.使用同步保证线程安全synchronized
    2.使用volatile关键字
    volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致现象。
    3.防止反射调用私有构造方法
    4.让单例序列化安全

    • 单例模式
    • 1.多线程访问的安全问题
    • 2.加上VOLATILE关键字保证变量的一致性
    • 3.防止反射调用私有构造方法
    • 4.让单例类可以被序列化

    泛型:
    当我们将一个对象放入集合时,集合不会记住此对象的类型,当再次从集合中取出此对象时,改变对象的编译类型变成了Object类型,但其运行时依然是本身类型,取出类型时需要人为强制类型转换到具体的目标类型 很容易出现类型转换异常 应该加入强制类型
    泛型最大特点就是类中的属性的类型可以由外部决定。泛型即参数化类型。参数 定义方法时有形参,调用方法时传递实参。参数化类型就是由原来具体的类型参数化,类似于方法中的变量参数,此类型也定义成参数形式,然后使用/调用传入具体类型
    在泛型接口,泛型类,泛型方法定义过程中,常用V T K等形式的参数表示泛型形参,由于接收来自外部使用时候传入的类型实参,从编码角度也称为参数化类型
    泛型只是作用于代码编译阶段,在代码编译过程中,对于正确检验泛型结果后,会将泛型的相关信息擦除,也就是说成功编译过的class文件不包含任何泛型信息,泛型信息不会进入到运行阶段
    通配符:?表示可以接收任意的泛型类,但是只接收输出并不能修改
    泛型上限就指一个操作泛型最大的操作父类 ?extends 类
    泛型的下限指的是只能设置其具体的类或者父类 ?super 类

    泛型方法
    泛型还可以定义在方法上,而且在方法上使用泛型,此方法所在的类不一定是泛型的操作类
    泛型嵌套使用:遍历map集合时<Entry<Integer,String>> entrys= map.entrySet();

    正则表达式
    正则表达式(Regular Expression)正则表达式使用单个字符串表示、匹配一系列符合某个句法规则的字符串。正则表达式通常用来被检索、替换那些符合某个模式的文本。
    java.util.regex包中提供Matcher类 通过解释Pattern 对character sequence执行匹配操作的引擎 Pattern类 正则表达式编译表示形式

    枚举
    枚举就是让某个变量的取值只能为若干个固定值中的一个,否则报错,枚举可以让编译器在编译时就可以控制源程序赋给非法值,使用普通变量的方式在开发阶段无法实现这一个目标。
    使用enum关键字定义的枚举类,实际上就相当于定义了一个类,此类继承了Enum类

    注解
    代码里做的特殊标记,这些标记可以在编译,类加载,运行时在不改变原有逻辑的情况下被读取,并执行相应的处理,通过使用Annotation,可以在源文件中嵌入一些补充信息。代码分析工具,开发工具和部署工具可以这些补充信息进行验证或者部署。Annotation类似于修饰符一样被使用,可以用于包 类 构造方法,方法 成员变量,参数局部变量的声明
    Annotation是一个接口

    自定义注解
    1.编写注解
    2.在类上应用注解
    3.对应用了注解的类进行反射操作的类
    语法: 访问控制权限 @interface Annotation名称{}
    在Anntation中定义变量 定义变量后在调用此Annotation时必须设置变量值 通过default指定变量默认值有了默认值可以不设值

    XML与JSON
    XML(Extensible Markup Language 可扩展标记语言)XML是一个以文本来描述数据的文档
    XML用途:
    1.充当显示数据(以XML充当显示层)
    2.存储数据(存储层)的功能
    3.以XML描述数据,并在联系服务器与系统的其余部分之间传递
    从某种角度讲XML是数据封装和消息传递技术
    JAVA解析XML通常有两种方式:DOM SAX

    SAX(Simple API for XML)
    SAX是读取和操作XML数据更快速更轻量的方法,SAX允许在读取文档时处理它,从而不必等待整个文档被存储之后才采取操作。它不涉及DOM所必须的概念和开销跳跃。SAXAPI是一个·基于事件的API,适用于处理数据流,即随着数据的流动而依次处理数据。SAXAPI在解析文档时发生一定的事件的时候会有通知,对其响应时不做保存的数据将会被抛弃
    SAXAPI中主要有四种处理事件的接口 ContenHandler DTDHandler EntityResolver
    ErrorHandler,实际上只要继承DefaultHandler类就可以,它实现了这四种事件处理器接口,然后提供每个抽象方法的默认实现

    • SAX解析特点:
    • 1.基于事件驱动
    • 2.顺序读取(从上至下依次读取)速度快
    • 3.不能任意读取节点(灵活性差)
    • 4.SAX更适用于在性能要求高的设备上使用
    • 5.解析时占用的内存小

    DOM(Document Object Model 文档对象模型)分三种
    DOM特性:定义一组接口,基于对象,与语言和平台无关将XML文档表示为树,在内存中解析和存储XML文档,允许随机访问文档的不同部分
    优点:由于树在内存中是持久的,因此可以修改后更新。它还可以在任何时候在树中上下导航,API使用起来也方便

    • Dom解析XML
      .基于树形结构,通过解析器一次性把文档加载到内存中,所有占用内存较大, 可以随机访问,更加灵活,更适合于web开发

    JDOM 下载地址http://www.jdom.org/downloads/index.html
    JDOM简化了与XML的交互并且比使用DOM实现更快,JDOM与DOM主要有两方面不同:
    1.JDOM仅使用具体类而不使用接口,在某些方面简化了API,但是业限制了灵活性。
    2.API大量使用了Collection类,简化了那些已经熟悉这些类的Java开发者使用

    • JDOM
      • 1.与DOM类似基于树形结构
      • 2.与DOM区别:
      • (1)第三方开源组件
      • (2)实现使用Java的collection接口
      • (3)比DOM更快

    DPOM4J解析XML http://dom4j.github.io/
    具有性能优异、功能强大、和极端易用的特点,同时它也是一个开放源代码的的软件,对主流的JAVA XML API进行性能功能评测
    基于树形结构,第三方组件(下载失败 没写代码)
    * 解析速度快 效率更高 使用Java中的迭代器实现数据读取,在web框架中使用较多(HiberNate)

    四种比较:
    JDOM DOM在性能测试时表现不佳,在测试10M文档时内存溢出
    SAX表现较好,这要依赖于它特定的解析方式,一个SAX检测即将到来的XML流,但并没有载入到内存
    DOM4J最强,许多开源项目都用

    通过对象生成XML
    java.beans.XMLEncorder和java.beans.XMLDecoder类
    步骤:
    1.实例化XML编码器
    XMLEncoder xmlEncoder = new XMLEncoder(new BufferedOutoutStream(new FileOutputStream(“a.xml”)))
    2.输出对象
    3.关闭
    xstream xpp3

    JSON(javascript Object Nation)一种轻量级的数据交换格式
    官网:http://www.json.org
    JSON数据格式特点
    JSON构建于两种结构1.名称/值 对的集合2.值的有序列表(数组)
    1.{“firstName”:“vince”,“second”:“ma”}
    2.{“user”:{“firstName”:“vince”,“second”:“ma”}}
    GOSN

    XML与JSON比较
    1.数据可读性基本相同
    2.同样拥有丰富的解析手段
    3.JSON相对于XML来讲,数据体积小
    4.JSON与JavaScript交互更加方便
    5.JSON对数据的描述性比XML差
    6.JSON远远比XML快
    适合场景
    1.数据传输:JSON比XML更有优势
    2.用于存储数据:XML描述性更强
    3.XML通常用做配置文件(web)

    需求分析 环境准备 项目框架搭建 功能实现 项目总结
    Java环境:JDK
    IDE:Eclipse IDEA
    GIT:代码版本控制器
    StarUML

    欢迎使用Markdown编辑器

    你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

    新的改变

    我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:

    1. 全新的界面设计 ,将会带来全新的写作体验;
    2. 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
    3. 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
    4. 全新的 KaTeX数学公式 语法;
    5. 增加了支持甘特图的mermaid语法1 功能;
    6. 增加了 多屏幕编辑 Markdown文章功能;
    7. 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
    8. 增加了 检查列表 功能。

    功能快捷键

    撤销:Ctrl/Command + Z
    重做:Ctrl/Command + Y
    加粗:Ctrl/Command + B
    斜体:Ctrl/Command + I
    标题:Ctrl/Command + Shift + H
    无序列表:Ctrl/Command + Shift + U
    有序列表:Ctrl/Command + Shift + O
    检查列表:Ctrl/Command + Shift + C
    插入代码:Ctrl/Command + Shift + K
    插入链接:Ctrl/Command + Shift + L
    插入图片:Ctrl/Command + Shift + G
    查找:Ctrl/Command + F
    替换:Ctrl/Command + G

    合理的创建标题,有助于目录的生成

    直接输入1次#,并按下space后,将生成1级标题。
    输入2次#,并按下space后,将生成2级标题。
    以此类推,我们支持6级标题。有助于使用TOC语法后生成一个完美的目录。

    如何改变文本的样式

    强调文本 强调文本

    加粗文本 加粗文本

    标记文本

    删除文本

    引用文本

    H2O is是液体。

    210 运算结果是 1024.

    插入链接与图片

    链接: link.

    图片: Alt

    带尺寸的图片: Alt

    居中的图片: Alt

    居中并且带尺寸的图片: Alt

    当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。

    如何插入一段漂亮的代码片

    博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

    // An highlighted block
    var foo = 'bar';
    

    生成一个适合你的列表

    • 项目
      • 项目
        • 项目
    1. 项目1
    2. 项目2
    3. 项目3
    • 计划任务
    • 完成任务

    创建一个表格

    一个简单的表格是这么创建的:

    项目Value
    电脑$1600
    手机$12
    导管$1

    设定内容居中、居左、居右

    使用:---------:居中
    使用:----------居左
    使用----------:居右

    第一列第二列第三列
    第一列文本居中第二列文本居右第三列文本居左

    SmartyPants

    SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:

    TYPEASCIIHTML
    Single backticks'Isn't this fun?'‘Isn’t this fun?’
    Quotes"Isn't this fun?"“Isn’t this fun?”
    Dashes-- is en-dash, --- is em-dash– is en-dash, — is em-dash

    创建一个自定义列表

    Markdown
    Text-to- HTML conversion tool
    Authors
    John
    Luke

    如何创建一个注脚

    一个具有注脚的文本。2

    注释也是必不可少的

    Markdown将文本转换为 HTML

    KaTeX数学公式

    您可以使用渲染LaTeX数学表达式 KaTeX:

    Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n1)!nN 是通过欧拉积分

    Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t   . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=0tz1etdt.

    你可以找到更多关于的信息 LaTeX 数学表达式here.

    新的甘特图功能,丰富你的文章

    Mon 06 Mon 13 Mon 20 已完成 进行中 计划一 计划二 现有任务 Adding GANTT diagram functionality to mermaid
    • 关于 甘特图 语法,参考 这儿,

    UML 图表

    可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:

    张三 李四 王五 你好!李四, 最近怎么样? 你最近怎么样,王五? 我很好,谢谢! 我很好,谢谢! 李四想了很长时间, 文字太长了 不适合放在一行. 打量着王五... 很好... 王五, 你怎么样? 张三 李四 王五

    这将产生一个流程图。:

    链接
    长方形
    圆角长方形
    菱形
    • 关于 Mermaid 语法,参考 这儿,

    FLowchart流程图

    我们依旧会支持flowchart的流程图:

    Created with Raphaël 2.2.0 开始 我的操作 确认? 结束 yes no
    • 关于 Flowchart流程图 语法,参考 这儿.

    导出与导入

    导出

    如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。

    导入

    如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
    继续你的创作。


    1. mermaid语法说明 ↩︎

    2. 注脚的解释 ↩︎

    展开全文
  • javaSE

    2019-09-27 14:28:16
    3、JVM(全称Java Virtual Machine)虚拟出来的一台计算机,用来运行Java程序 4、它们的关系 JDK包含JRE。(程序员装JDK) JRE包含JVM。(客户端装JRE) JVM是核心。 JVM的作用:将java程序翻译给操作系统,操作...

    java基础

    一、java语言的概念

    1、介绍:	
    	(1)java是一门编程语言,用来编写程序、软件。特点:跨平台(不分操作系统,口号是:一次编译,到处运行。例如:在一个操作系统编写程序,拿到另外一个操作系统照样运行)。
    	(2)编程语言:所谓编程语言,是 计算机的语言,人们可以使用编程语言对计算机下达命令,让计算机完成人们需要的功。
    	
    2、程序的开发(主要有三类)
    	(1)手机上的软件
    		例如:贪吃蛇、扫雷、手机上的游戏。
    	(2)桌面上的应用
    		桌面上的程序必须下载安装包,安装后才能点击运行。
    		例如:QQ、IDEA、
    	(3)WEB应用程序
    		必须通过浏览器,输入网址,进行访问。
    		例如:淘宝/天猫、京东、百度。		
    
    

    二、java的发展史()

    	java语言是美国sun公司,1995年推出的高级编程语言。java之父:詹姆斯*高斯林。后被oracle收购。
    

    三、计算机基础知识

    1、二进制

    1、二进制
    	0 、1 组成(逢二进一)
    2、十进制
    	 0~9组成(逢十进一)
    3、十六进制
    
    
    4、计算器
    	(1)打开计算器或者输入(calc)
    	(2)选择【程序员模式】
    5、数学算法
    	(1)十进制转二进制(除2取余法)。不断的除以2直到0。然后倒着取余数。
    	(2)二进制转十进制(使用的是1248编码)。将二进制中1对应的十进制值加起来求和。	
    

    2、字节

    1)、它是计算机的计量单位。用来计算一个文件,或者一个程序在计算机中存储的大小。
    2)、一个字节可以存8位的0/1。(一个英文字母就是一个字节)。
    3)、单位的换算:
    	1Byte  =  8 bit(位)  1个英文字母
    	1KB = 1024 Byte   1首歌的歌词
    	1MB = 1024KB    1/3 首歌
    	1GB = 1024 MB    半部电影
    	1TB = 1024 GB     500部电影
    
    

    3、DOS命令行

    	1)、启动
    		(1)Win + R
    		(2)输入 cmd 加回车
    	2)、常用命令
    		(1)切换盘符(盘符加 : 不区分大小写)。例如  c: 打开C盘、D:打开D盘。
    		(2)dir  显示当前文件夹下面的内容。
    		(3)cd   改变当前打开的文件夹。例如:cd  文件夹名称  进入文件夹。cd  .. 返回上一级文件夹 。
    		(4)cls  清除屏幕显示内容
    		(5)exit 输入退出窗口命令
    

    四、JDK、JRE、JVM

    1、JDK(全称Java Development Kit)java开发包。
    2、JRE(全称Java Runtime Environment)java运行环境。
    3、JVM(全称Java Virtual Machine)虚拟出来的一台计算机,用来运行Java程序
    4、它们的关系
    	JDK包含JRE。(程序员装JDK)
    	JRE包含JVM。(客户端装JRE)
    	JVM是核心。
    	JVM的作用:将java程序翻译给操作系统,操作系统按照要求做事情。	
    

    五、JDK下载安装(JDK网站)

    1、官网  http://www.oracle.com  英文。http://www.oracle.com/cn 中文 download下载
    2、安装一直下一步就行。
    3、注意事项
    	 a.不要安装到c盘
    	 b.路径上不能有中文
    	 c.也不要有空格
    4、安装后测试
    	在cmd到bin路径 输入 java - version  回车。
    

    六、入门Demo

    ###1、入门代码

    /*
    注意事项:
    	1、文件名必须跟类名一样.否则编译报错。
    	2、代码全部使用英文输入,不能中文符号。
    */
    public class HelloWorld{
    	public static void main(String[] args){
    		System.out.println(“HelloWorld”);
    	}
    }
    

    2、文件编译运行

    1、开发流程
    	(1)新建一个文本文件.txt,后缀名改成.java
    	(2)编译 :必须在.java文件路径下操作。命令格式   javac   文件名.java
    	(3)运行 :必须在.class文件路径下操作。命令格式    java 文件名 
    2、java命令介绍
    	javac 编译器(用来编译java文件,编译后会产生class文件)
    	java  解释器(用来运行class文件,读取class文件的内容)
    

    3、程序结构说明

    public class 类名{} //1、 定义一个类,java代码都写到类中
    public static void main(String[] args){}  //2、定义一个main方法,程序的入口
    System.out.println(...);  //3、打印换行  可以写多个打印语句
    System.out.print(...);  //4、打印不换行  可以写多个打印语句
    

    4、java标识符(驼峰规范)

    (1)标识符:就是给类、方法、变量起名。(必须遵守java的规则,否则编译报错)
    (2)规则:
    	可以使用英文字母、数字、中文、$ 和 _ 来定义。但是不能以数字开头。不能是关键字、但是可以包含关键字。
    
    (3)开发规范:(1、见面知意。2、使用驼峰命名)
    	a、大驼峰命名(用在类上)每个单词首字母大写。
    	b、小驼峰命名(用在方法、变量上)第一个单词全部小写,第二个单词起首字母大写。
    

    5、常量与变量

    (1)常量概述
    	程序运行期间,固定不变/不可改变的量。
    (2)常量的分类(有六类)
    	1、整数常量 
    	2、浮点常量
    	3、布尔常量
    	4、字符常量
    	5、字符串常量
    	6、空常量 
    
    (3)变量概述:在运行期间,可变的量。
    (4)变量的注意事项	
    	1、变量使用必须先定义后使用。
    	2、变量等号两边的类型必须一致
    	3、变量的使用不能超出作用域。(作用域:在类中的{}中)
    	4、定义变量,变量名不能一样
    	5、整数加上L表示long  浮点数加上F表示float
    	6、可以在一个语句中定义类型相同的变量
    

    6、数据类型

    
    (1)java使用关键字来表示数据在程序中的类型。主要分为(1、基本类型。2、引用类型)
    (2)基本类型:(四类八种)
    	整型   
            byte   		1字节     -128 ~127
            short    	2字节      
            int (默认) 4字节      -21亿~21亿
            long	    8字节
        浮点型  
        	float      		  4字节
        	double(默认)	   8字节
        布尔型
        	boolean  1字节  取值true 和 false
    	字符型
    		char    2个字节
    
    (3)引用类型:
    		字符串、数组、类、接口
    

    7、类型的转换

    (1)、自动转换(将小类型转成大类型,不需要做任何处理,自动完成)
    (2)、强制转换(大类型转小类型)
    		格式: 小类型 变量名 = (小类型)大类型的值;(必须手动处理,否则会报错)		
    
    (3)、强制转换的注意事项
    	1、数据丢失(会产生高位截肢)
    	2、精度丢失(将浮点数转换成整型,无条件丢掉小数部分)
    

    8、ascii码表(char 与 int 的互转)

    (1)编码表概述
    	编码表就是,将人类的文字和一个十进制数进行对应起来,组成一张的表格。
    (2)ASCII码表:它是美国标准信息交换代码表。
    (3)特点:
    	一个字符对应一个整数,将整数进行二进制化,保存到计算机中。
    (4)主要对应的字符和编号
    		小写  a   97 ,大写 A   65  ,字符 0   48 。	
    (5)总结
    	计算机中不存储汉字、字母,只存二进制,汉字、字母会通过码表进行转换成二进制存储到计算机中。
    

    9、运算符

    1、算数运算符	
    	+ :(1)数值表示求和。(2)连接字符串。(当+号两边只要有一边出现字符串就会拼接成字符串)
    	- :减
    	* :乘
    	/ :除
    	%模 取余:(两个数先做除法,取相除剩下的余数,只能是两个整数才能用)
    	++自增1
    	-- 自减1
    2、赋值运行符
    	+= , -= ,*= ,/= ,%=
    3、比较运行符(会得到一个boolean值)
    	>  大于  <  小于  >= 大于或者等于   <= 小于或者等于   ==  是否相等   !=  是否不等
    4、逻辑运算符(常用的逻辑运算符)
    	(1)&& 双与  并且 (2)||  双或 或者  (3)! 非 取反
    
    5、三元运算符
    	(1)概述和特点
    		Java中唯一个需要三个表达式参与运算的”运算符”。在比较两个数大小的情况,三元运算符比if-else简化
    	(2)规则:
    		a、结果必须被使用,直接打印或者赋值给一个变量
    		b、冒号前后两个表达式的值的类型必须一致
    

    七、执行语句

    1、执行语句概述

    执行语句分三种: 
    	1、顺序结构(从上到下执行)
    	2、选择结构(让代码有选择性的执行)【有 if语句  ,switch语句】
    	3、循环结构(执行重复的代码)【for语句、while语句、do while语句】
    

    2、if 语句

    //第一种格式
        if(/*布尔表达式*/){
    		//true就执行语句,false就不执行
        }
    //第二种格式
    	   if(/*布尔表达式*/){
            	//true执行语句,
            }else{
            	//false执行默认语句体
            }
    //第三种格式
          if(/*布尔表达式1*/){
         	//表达式1成立,执行语句体1
          }else if (/*布尔表达式2*/){
          	//表达式2成立,执行语句体2
          else{
          	//都不成立,执行默认语句体
          }
    

    3、switch语句

    /*
    注意事项:	
    	表达式的结果只能是byte、short、char、int、String
    执行流程:
    	匹配上哪一个分支 ,就执行它的语句体。
    switch穿透性:
    	如果你省略了标准格式中的break,就会发生穿透性。直接执行分支的语句体,不作匹配,直到碰见break。
    使用场景:
    	当多个分支需要执行相同的语句体时,使用穿透性可以简化代码。
    */
    	switch(/*表达式*/){
                case  //常量1:
                  //执行语句体1
                  break;
                case  //常量2
                  //执行语句体2
                  break;
                case  //常量3 可以有多个sase
                  //执行语句体3
                  break;
                default:
                  //执行默认语句体
                  break;
          }
    

    4、for语句

    /*
    	使用场景:
    		计数器有明确的范围。例如1~100
    */
      for(/*①初始化语句; ②循环条件;  ④步进表达式*/){
          //被重复执行的代码 -③循环体
      }
    

    5、while语句

    /*
    	特点:
    		循环条件为true会一直执行,值为false跳出循环。
         使用场景:
         	计数器的范围不明确的时候使用。例如:不知道有具体的多少数量。IO读取一个文件夹没有具体的数量要求。
    */
    //	①初始化语句
    while(/*②循环条件*/){
        //④循环体
        //③步进语句
    }
    

    6、do while语句

    /*
    	特点:
    		执行第一次循环体时,不用进行循环条件的判断。所以无论循环条件是否满足至少执行一遍	
    */
    //格式
    //①初始化语句
    do{
      /*③循环体
      ④步进*/
    }while(/*②循环条件*/);
    
    

    7、break、continue关键字

    break作用:在循序中使用。会立刻跳出当前的循环。
    continue作用:立刻跳过本次循环。它只能在循环中使用。
    

    八、方法

    1、方法的作用与执行流程

    1、方法的作用
    	将相同的代码放在一起(封装),通过调用来使用,达到重复使用代码的目的。
    
    2、方法的执行流程
    	(1)、从调用处找到这个方法
    	(2)、传参,将调用处的实际数据传给参数列表
    	(3)、执行方法体计算得到结果
    	(4)、通过return 返回值; 将结果交给调用处
    

    2、方法的重载(overload)

    1、方法重载概述
    	在同一个类中,允许存在多个名字相同的方法。 
    2、规则(根据参数列表来进行区分)
    	(1)	参数类型必须不同。
    	(2)	参数个数必须不同。
    	(3)	顺序必须不同。
    

    3、参数基本、引用类型的区别

    1、基本类型	
    	在main方法中定义两个变量,当做参数传给方法中。交换后。打印变量是main方法中变量原来的值。
    2、引用类型
    	把引用类型当做参数传递到方法中,做修改后。引用类型会变。
    3、执行原理
    	(1)注意:调用处调用方法传参,实际是将参数赋值一份给方法中参数(将实参复制一份给形参)。
    	(2)基本类型
    		方法中进行修改形参,不影响实参。方法在栈中执行完就会释放,但是实参还在。
    	(3)引用类型
        	引用类型是将地址赋值赋值一份传给方法中。地址是存在堆中。方法内修改形参,实参会有影响。因为调用处加载引用类型,依然是根据地址进行获取数据。
    

    九、数组

    1、数组概述与特点

    1、概述
    	数组相当于一个容器,定义一个可以存储多个数据。
    2、特点
    	(1)数据类型必须一致。
    	(2)数组一旦创建,长度是固定不变的。
    	(3)它是通过索引进行操作里面的存储的具体值。
    
    

    2、数组的三种格式

    1、使用格式(1、3种。2、等号两边的数据类型必须一致。3、长度:必须大于0  否则 编译正常,运行报错)
    	(1)第一种:(我们来指定长度)
    		数据类型[]  数组名 =  new 数据类型[长度];
    	(2)第二种:(1、内容由我们指定。2、长度由系统计算。3、等号右边的[]不能写长度)
        	数据类型[]  数组名 =  new 数据类型[]{元素1,元素2,元素3...}
        (3)第三种:
        	数据类型[] 数组名 = {元素1,元素2,元素3...}
    

    3、常见的数组异常

    1、数组越界异常: ArrayIndexOutOfBoundsException
    2、数组空指针异常:NullPointerException
    

    十、JVM内存

    1、JVM内存分5块
    	(1)栈 Stack
    	(2)堆内存 Heap
    	(3)方法区 Method Area
    	(4)寄存器(CPU)
    	(5)本地方法区(操作系统)
    	
    2、栈的作用:保存变量、运行方法。
    3、堆的作用:保存所有new出来的地址。例如:数组,对象等。
    4、方法区的作用:保存java运行出来的class文件。和class文件里面的方法。
    
    5、方法区和栈的关系:方法区保存方法。栈是运行方法。没有掉用的方法保存在方法区中,调用的时候加载到栈中。
    

    十一、java对象

    1、面向对象概述

    1、介绍:
    	面向对象是一种思想。早期的计算机编程是基于面向过程,
    2、例如:
    	面向过程:把衣服脱下来-->找一个盆-->放点洗衣粉-->加点水-->浸泡10分钟-->揉一揉-->清洗衣服-->拧干-->晾 起来 。(全部的步骤叫做面向过程)
    	
    	面向对象:把衣服脱下来-->打开全自动洗衣机-->扔衣服-->按钮-->晾起来(洗衣机就是对象)
    3、总结:
    	它可以将复杂的事情简单化,并将我们从执行者变成了指挥者。
    

    2、java对象的三大特征【】

    (1)封装:相同属性和行为,进行单独的抽取封装。
    (2)继承:子类继承该类的属性和行为,使得子类对象有与父类相同的属性、行为。
    (3)多态:一种事物的多种形态。
    

    3、成员变量局部变量

    1、区别(有4个方面)
    	(1)在类中的位置不同 
        	a、成员变量:类中,方法外 
        	b、局部变量:方法中或者方法声明上(形式参数)
    	(2)作用范围不一样 
    		a、成员变量:类中 
    		b、局部变量:方法中 
    	(3)初始化值的不同 
        	a、成员变量:有默认值 
        	b、局部变量:没有默认值。必须先定义,赋值,最后使用 
    	(4)在内存中的位置不同 
        	a、成员变量:堆内存 
        	b、局部变量:栈内存 
    	(5)生命周期不同 
             a、成员变量:随着对象的创建而存在,随着对象的消失而消失
    		b、局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
    

    十二、static关键字

    1、介绍:
    	它是java的一个关键字,它可以用来修饰的成员变量和成员方法。
    2、特点:
    	(1)被修饰过的成员变量、成员方法可以直接调用。
    	(2)被修饰过的成员变量在内存中只会存储一份
    3、静态原理
        (1)是随着类的加载而加载的,且只加载一次。 
        (2)存储于一块固定的内存区域(静态区),所以,可以直接被类名调用。
        (3)它优先于对象存在,所以,可以被所有对象共享。
    4、静态代码块
    	(1)位置:类中方法外。 
    	(2)执行:随着类的加载而执行且执行一次,优先于main方法和构造方法的执行。
    	(3)作用:给类变量进行初始化赋值。
    5、注意事项
    	(1)static 修饰成员,直接调用
    	(2)静态访问静态
    	(3)非静态访问所有
    

    十三、继承、抽象类

    1、继承概述(extends)

    1、概述:
    	定义一个类对多个类中存在相同属性和行为,进行单独的抽取封装。子类继承该类的属性和行为,使得子类对象有与父类相同的属性、行为。子类可以直接 访问父类中的非私有的属性和行为。 
    2、好处:
    	1. 提高代码的复用性。 
    	2. 类与类之间产生了关系。	
    3、特点
    	只能是单继承,一个类继承一个类。
    

    2、方法的重写(Override)

    1、规则:
    	(1)继承关系中,子类定义一个与父类一模一样的方法。
    	(2)方法名必须一样。
    	(3)返回值类型必须一样。
    	(4)参数列表必须一样。
    	(5)子类方法权限必须>=父类。
    2、不遵守规则
    	编译不报错,重写失败,子类增加一个方法。
    3、权限	
    	public > protected  >默认 > private
    	
    

    4、继承内存执行

    	先在内存中创建父类,在创建子类。子类对象会把父类对象包含进行去。读取会先读取子类,就近原则。
    

    5、this和super

    1、介绍
    	(1)其实this、super是只内存空间。
    	(2)this:指向子类对象空间的引用。(如果成员变量与局部变量重名,使用this区分)
    	(3)super 指向父类对象空间的引用。
    	(4)成员变量:定义在类中方法外。
    	(5)局部变量:定义在方法中。
    2、注意事项
    	this、super只能子类中方法中使用。
    	
    3、this()、super()
    	(1)this() 表示执行本类的构造方法
    	(2)super() 表示执行父类的构造方法
    	(3)如果有参数,必须传参数
    	(4)只能在子类构造方法的第一行使用
    	(5)同子类构造方法中,只能调用super()或者this()。其中的一个。
    

    6、抽象类(abstract )

    1、概述:
    	(1)java抽象关键字abstract。可以修饰类、方法。被修饰的类叫抽象类,修饰的方法叫抽象方法。子类继承抽象类必须重写父类的抽象方法,(开发中表示强制的意思)。
    	(2)抽象方法 : 没有方法体的方法。
    	(3)抽象类:包含抽象方法的类。
    2、规则:
    	(1)抽象类中可以没有抽象方法。
    	(2)抽象方法必须在抽象类中。
    3、格式:
    	类:public abstract class 类名{}
    	方法:public abstract 返回值类型 方法名(参数列表);
    
    4、注意事项:	
    	(1)抽象类不能直接创建。(不能直接new)。
    	(2)抽象类可以不写抽象方法。
    	(3)使用抽象类,直接使用它的子类。
    	
    

    十四、接口、多态

    1、接口(interface )

    1、概述:
    	接口就是对一类事物进行连接java语言一个规范。其他语言想要连接必须实现java提供的接口。
    2、特点:
    	(1)接口关键字(interface)实现关键字(implments)
    	(2)面向对象的特征之一。
    	(3)补救抽象类的扩展性不足。
    	(4)提高代码的复用性和扩展性。
    	(5)是多态的前提。
    
    3、接口格式:
        public interface 接口名{
        	静态常量
            抽象方法
            默认方法
            静态方法
            私有非静态方法  
            私有静态方法
        }
    4、使用:
    	(1)接口不能直接使用,想要使用只能使用它的实现类。
    	(2)抽象方法,实现类,子类必须无条件覆盖重写(否则必须是抽象类)
    	(3)默认方法,覆盖重写,冲突。否则可以不覆盖重写
    5、注意事项:
    	(1)不能成员变量
        (2)不能get/set公有普通方法
        (3)不能构造方法
        (4)不能静态代码
    
    

    2、继承、实现区别

    1、优先级:
    	父类优先级高于接口,子类优先级高于父类。
    2、区别:
    	继承:一个类只能有一个父类  类与类 单继承。
    	实现:一个接口 能继承多个接口  接口与接口可以多继承。
    

    3、多态

    1、概述:
    	是指同一行为,具有多个不同表现形式。例如:树有不同的种类: 杨树、松树、柏树。那么具体的树就是多态。
    
    2、java中类的多态。
    	(1)必须存在继承关系。
    	(2)子类不能是抽象类。
    	(3)父类可以不是直接父类。可以是间接父类
    
    3、java中接口的多态
    	(1)子类/实现类必须实现这个接口
    	(2)子类不能是抽象类
    	
    4、多态的好处
    	(1)提高代码的复用性与扩展性。
    	(2)定义方法变量的参数,或者返回值的时候可以使用多态。有接口写接口,有父类写父类。
    5、多态运行时特点:
    	(1)成员变量编译看左边,运行看左边(子类和父类有相同名字的变量时候)
    	(2)成员方法编译看左边,运行看右边()
    6、弊端:
    	子类对象保存成父类类型时,不能调用子类的成员。
    
    7、多态的形态转换
    	(1)向上转型
    		父类转成子类型
    		子类类型   对象名 =(子类类型) 父类
    	(2)向下转型
    		子类类型转成父类
    		父类  对象名 =  子类对象
    8、手动转型注意:
    	(1)格式
    		子类类型   对象名 =(子类类型) 父类
      	(2)手动转换有风险	
    		假如这两个类型并没有任何继承关系,不符合类型转换的定义。 报ClassCastException异常
    
    9、instanceof 关键字	
    	(1)java提供了instanceof关键字、给引用变量做类型的校验。我们可以使用它来规避下来转型的风险,用来判断当前对象是不是这个类创建的。返回值是true或者false。
    	(2)格式
    		类  instanceof  类或者接口。返回值是boolean类型。
    

    十五、final、权限访问符

    1、final关键字

    1、概述与特点
    	(1)final表示的最终的,最后的。
    	(2)可以用来修饰类、方法、成员变量、局部变量。
    	(3)final修饰的类,不能有子类。它不能和abstract 同时修饰类(会产生冲突)
    	(4)final修饰修饰的方法,不以被子类覆盖重写。
    	(5)final修饰变量,一旦赋值不能再赋值。
    	
    

    2、权限访问符

    1、关系
    	public  >  protected  >  默认  > private
    2、使用范围(其实是指包的访问范围)
    	(1)public :公有的,任何地方都可以访问。
    	(2)protected:受保护的, 同包才可以访问。特点是强调子类访问,也就是子类在任何包下都可以访问。 
    	(3)默认 :同包才可以访问。
    	(4)private :私有的,只有本类可以访问。
    

    3、内部类

    1、理解:
    	一个类中定义另外一个类,好处:更好的面向对象,用类描述事物。
    2、格式:
    	public class 外部类名{
            public class 成员内部类名{
            }
            public void method(){
            }
        }  
    3、使用:
    	格式一:
    		外部类名.内部类名  对象名 = new 外部类名() .new 内部类名();
    	格式二:(简化版)
    		外.内  对象名 = new 外().new 内();
    		外.this.成员变量名
    

    4、局部内部类

    1、理解:
    	方法中创建类。
    2、格式:
    	public class 外部类名{
            public void method(){
              class 局部内部类{
              //
              }
            }
        }
     3、规则:
     	(1)直接class,前面不能有修饰符。
     	(2)局部内部类,只能在这个方法中使用,其他方法不能使用。
    

    5、匿名内部类

    1、概述
    	匿名内部类是内部类的简化写法,它本质是一个带具体实现的。继承父类或者父接口。
    2、匿名内部类的前提
    	匿名内部类必须继承一个父类或者实现一个父接口。 
    3、格式
    	格式一:
    		new 抽象类/接口(){
            	//重写所有的抽象方法
            }.调用的方法名();
         格式二:
            //开发中会给new出来的对象赋值一个变量,表示起了一个名字
                  抽象类/接口  对象名 = new 抽象类/接口() {
                  		//重写所有的抽象方法
                  };
                使用里面的方法的时候,直接对象名.方法名进行调用。 
    

    6、内部类的区分

    	在out文件夹中带有 $ 符号的就是内部类。它是java生产的。  
    

    十六、基础类

    1、Scanner类(键盘输入)

    1、作用:
    	(1)一个可以解析基本类型和字符串的简单文本扫描器。用户输入的数据一般是通过键盘  System.in
    	(2)用来读取键盘输入的信息。
    2、使用:
    	(1)在 java.util 包下
    	(2)创建对象
    		Scanner sc = new Scanner(System.in);
    	(3)接受键盘输入的信息(键盘输入什么类型,就用什么类型接受)	
    		例如:int  i  = sc.nextInt()   接收一个键盘录入的整数
    

    2、Random类(随机数)

    1、作用:
    	让程序产生随机的整数
    2、使用:
    	(1)在 java.util 包下
    	(2)创建对象
    		Random rd = new Random();
    	(3)生产随机数
        	int i = rd.nextInt()//nextInt()
        (4)nextInt方法介绍
        	(1)它可是无参
        	(2)它可以接受int类型的参数。例如:参数是100 。表是生产 0~99 之间的随机数。
    

    3、String字符串类

    1、特点:
    	(1)不可变性
    	(2)共享性
    	(3)字符串的底层是字符数组
    2、常量池:
    	(1)字符串时存储在“字符串常量池”中,常量池在堆中。	
    
    3、创建方式:
    		格式一:String 字符串对象名 = new String();
    		格式二:String 字符串对象名 = new String(字符串);
    		格式三:String 字符串对象名 = new String(字符数组);
    		格式四:String 字符串对象名 = new String(字节数组);
    4、常用方法:
    	(1)判断功能
    		equals:比较字符串是否相同区分大小写。
    		equalsIgnoreCase:比较字符串是否相同不区分大小写。
    	(2)获取功能
    		length:  获取字符个数。
    		charAt:  获取索引对应字符。
    		indexOf: 获取字符对应的索引,第一次出现。
    		substring:截取字符串的一部分。
    	(3)转换功能
    		toCharArray:用于将字符串转成字符数组。
    		getBytes:用于将字符串转换成字节数组。
    		replace:将字符串中,参数A字符,全部替换参数B字符。
    	(4)切割功能
    		split:对当前字符串进行分割。
    		
    	(5)包含方法:
        	startsWith():是否包含。
    

    4、Arrays类(数组工具类)

    1、作用:
    	该类包含用于操作数组的各种方法(如排序和搜索)
    2、使用:
    	(1)在 java.util 包下
    	(2)方法全是静态的。直接:类名.静态成员方法名()就行。
    3、常用方法:
    	toString:将数组中的数据转换成字符串。
    	sort:对数组里面的数据,进行从小到大排序。
    	
    

    5、Math类

    1、作用:
    	它里面包含基本的数学算法。(可以用来取 绝对值、取整)
    2、使用:
    	在java.lang包下,表示不用导包直接使用。
    3、常用方法:
    		abs:取绝对值。负数绝对值是正数。正数绝对值是正数。例如: -3.14 绝对值  3.14
    		ceil:向上取整。
    		floor:向下取整。
    		round:四舍五入。
    
    展开全文
  • javase笔记

    2021-07-30 11:35:52
    名称:Computer,全称电子计算机,俗称电脑。 定义:能够按照程序运行,自动、高速处理海量数据的现代化智能电子设备。 组成:由硬件和软件组成。 形式:常见显示有台式计算机、笔记本计算机、大型计算机等。 应用:...

    笔记参考来源狂神说Java视频

    预科准备

    什么是计算机

    1. 名称:Computer,全称电子计算机,俗称电脑。
    2. 定义:能够按照程序运行,自动、高速处理海量数据的现代化智能电子设备。
    3. 组成:由硬件和软件组成。
    4. 形式:常见显示有台式计算机、笔记本计算机、大型计算机等。
    5. 应用:科学计算、数据处理、自动控制、计算机辅助设计、人工智能、网络等领域。

    硬件及冯诺依曼结构

    计算机硬件

    组成:cpu,主板,内存,电源,主机箱,硬盘,显卡,键盘、鼠标,显示器。

    冯诺依曼结构

    在这里插入图片描述

    软件及软件开发

    计算机软件

    Windows常用快捷键

    Alt+f4关闭窗口 Shift+Delete永久删除 ctrl+w自动保存

    死机:任务管理器结束进程

    基本的Dos命令

    打开CMD的方式

    1. 开始+系统+命令提示符
    2. win键+R+输入cmd (推荐使用)
    3. 在任意的文件夹下,按住Shift键+鼠标右击,打开命令行窗口
    4. 在资源管理器地址栏路径前面加 “cmd ”
    5. 管理员运行方式:命令提示符右键以管理员身份运行(最高权限运行)

    常用的Dos命令

    # 盘符切换 E:
    # 查看当前目录下所有文件 dir
    # 切换目录 cd /d E:\idea
    # 返回上一级目录 cd ..
    # 进入同级目录下的下一级目录 cd tmp(该目录下的文件名)
    # 清屏 cls (clear screen)
    # 退出终端 exit
    # 查看电脑当前IP地址 ipconfig
    
    # 打开计算器 calc
    # 打开画图 mspaint
    # 新建记事本 notepad
    
    # 在当前目录新建文件夹 md test(文件夹名)
    # 新建文件 cd> a.txt(文件名)
    # 删除文件 del a.txt(文件名)
    # 删除目录 rd test(目录名)
    
    # ping命令(复制链接进入Dos直接单击鼠标右键粘贴)
    	ping www.baidu.com
    1234567891011121314151617181920
    

    计算机语言发展史

    • 第一代语言:机器语言
    • 第二代语言:汇编语言
    • 第三代语言:高级语言

    高级语言

    C、C++、Java、C#、Python、PHP、JavaScript …

    大体上分为:面向过程面向对象两大类

    • C语言是典型的面向过程的语言,C++,Java是典型的面向对象的语言


    Java入门

    Java帝国的诞生

    在这里插入图片描述
    在这里插入图片描述

    Java特性与优势

    • 简单性
    • 面对对象
    • 可移植性
    • 高性能
    • 分布式
    • 多态性
    • 多线程
    • 安全性
    • 健壮性

    Java三大版本

    • Write Once,Run Anywhere

    • JavaSE: 标准版 (桌面程序,控制台开发…)

    • JavaME: 嵌入式开发 (手机,小家电…),已经凉了

    • JavaEE: E企业级开发 (Web端,服务端开发…),JavaSE为基础

    JDK JRE JVM

    • JDK:Java Development Kit (Java开发者工具,包括 JRE,JVM)
    • JRE:Java Runtime Environment (Java运行时环境)
    • JVM:Java Virtual Machine (Java虚拟机,跨平台核心)

    img

    安装开发环境

    卸载JDk

    1. 删除Java安装目录
    2. 删除环境变量JAVA_HOME
    3. 删除path下关于JAVA的目录
    4. Java -version

    安装JDK

    1. 百度搜索JDK8,找到下载地址
    2. 同意协议,下载电脑对应的版本,如64位操作系统下载 jdk-8u281-windows-x64.exe
    3. 双击安装JDK
    4. 记住安装路径
    5. 配置环境变量
      1. 我的电脑-》属性-》系统高级设置-》环境变量
      2. 系统变量 新建–> JAVA_HOME 输入对应的jdk安装路径
      3. path变量–>% JAVA_HOME%\bin
    6. 测试是否成功 cmd–>Java -version


    Java基础

    注释

    1. 单行注释 //
    2. 多行注释 /* */
    3. 文档注释 /** */

    标识符和关键字

    • Java 所有的组成部分都需要名字。类名、变量名、方法名都被称为标识符

    关键字

    在这里插入图片描述

    标识符注意点

    • 所有标识符都应该以 字母、$(美元符)、_(下划线) 开头
    • 首字母之后可以是 字母、$、_ 或数字任何字符组合
    • 关键字不能作为变量名或方法名
    • 标识符大小写敏感
    • 可以用中文命名,但不建议使用,即使用拼音命名也Low

    数据类型

    • 强类型语言
      • 要求变量的使用要严格符合规定,所有变量都必须先定义后才能使用
    • 弱类型语言:JavaScript,Python
    • Java的数据类型分为两大类
      • 基本类型(primitive type),有8大基本类型,此外都是引用类型
      • 引用类型(reference type)

    在这里插入图片描述

    //整数
    int num1 = 10; //最常用,只要别超过21亿(2^31-1)
    byte num2 = 20; //-128~127
    short num3 = 30;
    long num4 = 30L; //long类型数字后面要加个L(尽量用大写,小写l容易与1搞混)
    12345
    //小数:浮点数
    float num5 = 50.1F; //float类型数字后面要加个F
    double num6 = 3.141592653589793238;
    123
    //字符
    char name = '国';
    //字符串, String不是关键字,是类
    //String namea = "薛之谦";
    1234
    //布尔值:是非
    boolean flag = true
    12
    

    什么是字节

    • 位(bit):是计算机内部数据存储的最小单位,11001100是一个八位二进制数
    • 字节(byte, B):是计算机中 数据处理 的基本单位,习惯上用大写B表示
    • 1B(byte) = 8bit,1字节等于8位
    • 字符:指计算机中使用的字母,数字,字和符号
      • 1bit表示1位
      • 1Byte表示一个字节 1B=8b
      • 1024B = 1KB, 1024KB = 1M, 1024M = 1G

    扩展及面试题

    //整数扩展: 二进制0b		八进制0		十进制		十六进制0x
    int i = 10;
    int i2 = 010; //八进制 8
    int i3 = 0x10; //十六进制 16
    1234
    //浮点数扩展:
    //面试题:银行业务字母怎么表示钱? BigDecimal(数学工具类)
    //float double是有问题的,最好避免使用浮点数进行比较
    float f = 0.1f; 	//0.1
    double d = 1.0/10;  //0.1
    System.out.println(f==d); //false
    //浮点数 位有限,舍入误差,大约
    //最好避免使用浮点数进行比较
    float f1 = 23131313131f;
    float f2 = f1+1;
    System.out.println(f1==f2); //true
    1234567891011
    //字符扩展:所有字符本质还是数字
    char c1 = 'a';
    char c2 = '中';
    
    System.out.println(c1);		//a
    System.out.println((int)c1);//强制类型转换,97
    System.out.println(c2);		//中
    System.out.println((int)c2);//强制类型转换,20013
    
    //编码 Unicode表(97=a,65=A)2字节 0-65536
    //U000~UFFFF 十六进制(u0061=a,相当于十进制的97)
    System.out.println('\u0061');  //a '\'是转义字符
    123456789101112
    //布尔值扩展
    boolean flag = true;
    if(flag==true){} //新手
    if(flag){}	//老手这样写 Less is More(代码要精简易读)
    1234
    

    类型转换

    • 由于Java是强类型语言,所以要进行有些运算的时候,需要用到类型转换。
    • 容量高–>低:
      在这里插入图片描述
    • 运算中,不同类型的数据先转化位同一类型,再进行运算。
      • 强制转换,(类型)变量名,容量由高到低
      • 自动转换,容量由低到高
    //强制转换 (类型)变量名 高--低
    //自动转换 低--高
    int i = 128;
    byte b = (byte)i; //强制转换 内存溢出 -128~127
    double d =i; //自动转换
    
    System.out.println(i); //128
    System.out.println(b); //-128
    System.out.println(d); //128.0
    /*
       注意点:
       1.不能对布尔值进行转换
       2.不能把对象类型转换为不相干的类型
       3.在把高容器转换到低容量的时候,强制转换
       4.可能存在内存溢出,或者精度问题
     * */
    System.out.println((int)23.7); //23 丢失精度
    char c = 'a';
    int n = c+1;
    System.out.println(n); //98
    System.out.println((char)n); //b
    123456789101112131415161718192021
    //当操作数比较大时,注意溢出问题
    //JDK7新特性,数字之间可以用下划线分割
    int money = 10_0000_0000; //10亿,下划线不会被打印出来
    System.out.println(money); //1000000000
    int years = 20;
    
    int total = money*years;  //数据大,溢出
    System.out.println(total); //-1474836480
    
    long total2 = money*years; //默认是int,转换前就有溢出问题
    System.out.println(total2); //-1474836480
    
    long total3 = money*(long)years; //先把一个数转Long
    System.out.println(total3); //20000000000
    1234567891011121314
    

    变量、常量、作用域

    • 变量是什么:就是可以变化的量
    • Java是一种强类型语言,每个变量都必须声明其类型
    • Java变量是程序中最基本的存储单元,要素包括变量名,变量类型和作用域
    //数据类型 变量名 = 值;
    type varName [=value][{,varName[=value]}];
    //可以使用逗号隔开同多个类型的变量,但不建议在一行定义多个变量
    123
    

    变量作用域

    • 类变量(static)
    • 实例变量
    • 局部变量
    public class Variable{
        static int 	allClicks = 0; //类变量
        String str = "hello world"; //实例变量
        public void method(){
            int i=0; //局部变量
        }
    }
    1234567
    

    常量

    • 常量:初始化后不能再改变的值,不会变动的值。
    • 可以理解为一种特殊的变量,其值被设定后,在程序运行过程不允许被更改。
    //常量一般用大写字符
    final 常量名=;
    final double PI=3.14;
    123
    //修饰符 不存在先后顺序,static可以写final后面
    static final doube PI=3.14; //类变量,该类下的全局范围
    12
    

    变量的命名规范

    • 所有变量、方法、类名:见名知意
    • 类成员变量:首字母小写+驼峰原则:lastName
    • 局部变量:首字母小写+驼峰原则
    • 常量:大写字母和下划线:MAX_VALUE
    • 类名:首字母大写+驼峰原则:Man,GoodMan
    • 方法名:首字母小写+驼峰原则:run(),fastRun()

    运算符

    在这里插入图片描述

    int a=10;
    int b=20;
    System.out.println(a/b); //0
    System.out.println((double)a/b); //0.5
    
    long c=12300000000;
    System.out.println(a+b); //int
    System.out.println(a+c); //long 自动转换式子中容量大的数据类型
    12345678
    

    自增自减运算符

    // ++自增 --自减 单目运算符
    int a = 3;
    int b = a++; //b=a,a=a+1 先赋值 即b=3 a=4
    int c = ++a; //a=a+1,c=a 先自增 即a=5 c=5
    
    System.out.println(a); //5
    System.out.println(b); //3
    System.out.println(c); //5
    12345678
    //幂运算 2^3 2*2*2=8
    double pow = Math.pow(2,3); // (底数,指数)double型
    System.out.println(pow); //8.0
    123
    //扩展:笔试题 i=5 s=(i++)+(++i)+(i--)+(--i) s=?
    int i=5;
    int s=(i++)+(++i)+(i--)+(--i);
    System.out.println(s); //24
    1234
    

    逻辑运算符

    • && 逻辑与运算:两个变量都为真,结果为true
    • || 逻辑与运算:两个变量有一个为真,结果为true
    • ! 取反,真变为假,假变为真
    // 与(snd) 或(or) 非(取反)
    boolean a = true;
    boolean b = false;
    
    System.out.println(a&&b); // false
    System.out.println(a||b); // true
    System.out.println(!(a&&b)); // true
    
    int c=5;
    boolean d = (c<5)&&(c++<5); //第一个值为false,后面就不进行判定了
    System.out.println(d); //false
    System.out.println(c); //5 c++未执行
    123456789101112
    

    位运算

    /*
        A = 0011 1100
        B = 0000 1101
    
        A&B 0000 1101 按位与
        A|B 0011 1101 按位或
        A^B 0011 0001 异或
        ~B  1111 0010 非
    
        面试题:2*8 怎么算最快? 2<<3
        <<左移  *2 效率极高!!
        >>右移  /2
       */
    System.out.println(2<<3); // 16
    1234567891011121314
    

    三元运算符

    int a = 10;
    int b = 20;
    
    a+=b; // a = a+b
    a-=b; // a = a-b
    
    System.out.println(a); //10
    //字符串连接符 + ,转化为String类型,然后拼接    注意!!
    System.out.println(""+a+b); //1020
    System.out.println(a+b+""); //30 先进行运算,再转为String拼接
    System.out.println(a+b+"str"); //30str
    1234567891011
    // x ? y : z
    //如果x为真,则结果为y,否则为z
    //if(x) y; else z;
    int score = 80;
    String type = score<60?"及格":"不及格";
    System.out.println(type); //及格
    123456
    

    包机制

    • 为了更好地组织类,Java提供了包机制,由于区分类名的命名空间
    • 包的语法格式:
    package pkg1[.pkg2[.pkg3...]];
    1
    
    • 一般利用公司域名倒置作为包名;com.kuangstudy.www
    • 为了能够使用一个包的成员,需要在Java程序中导入该包
    import package1[.package2...].(className|*); //通配符* 导入包下所有的类
    1
    
    • 参考:阿里巴巴Java开发手册

    JavaDoc生成文档

    • javadoc命令是用来生成自己API文档的
    • 参数信息
      • @author 作者名
      • @version 版本号
      • @since 指明最早用的jdk版本
      • @param 参数名
      • @return 返回值情况
      • @throws 异常抛出情况
    • API文档:https://docs.oracle.com/javase/8/docs/api/
    /**
     * @author Kuangshen
     * @version 1.0
     * @since 1.8
     */
    public class Demo05 {
        String name;
    
        /**
         * @author kuangshen
         * @param name
         * @return
         * @throws Exception
         */
        public String test(String name) throws Exception{
            return name;
        }
        
    }
    12345678910111213141516171819
    
    
    1. 打开某个类所在文件夹下的cmd命令行
    2. 输入:javadoc -encoding UTF-8 -charset UTF-8 Doc(类名).java
    3. 会自动生成该类有关的API文档,查看文件夹发现多了一些文件
    4. 打开 index.html(首页)查看文档注释


    Java流程控制

    用户交互Scanner

    • 之前我们学的基本语法并没有实现程序和人的交互,Java给我们提供了一个工具类,可以获取用户的输入java.util.Scanner是Java5的新特征,我们通过Scanner类来获取用户的输入。
    • 基本语法
    Scanner s = new Scanner(System.in);
    1
    
    
    • 通过Scanner类的 next()与 nextLine()方法获取用户的字符串,读取前一般用hasNext()与hasNextLine()判断是否还有输入的数据。
    //创建一个扫描器对象
    Scanner scanner = new Scanner(System.in);
    
    System.out.println("使用next方式接收");
    //判断用户有没有输入字符串
    if(scanner.hasNext()){  //使用hasNextLie()会接收一行 "hello word"
        //使用next方式接收
        String str = scanner.next(); 
        System.out.println("输入的内容为:"+str);
        //input: hello word
        //输入的内容为:hello
    }
    //凡是属于IO流的类如果不关闭会一直占用资源
    scanner.close();
    1234567891011121314
    
    

    next()

    1. 一定要读取到有效字符才可以结束输入
    2. 对输入有效字符之前遇到的空白,next()方法会将其去掉
    3. 只有输入有效字符后才将其后面输入的空白作为结束符
    4. next()不能得到带有空格的字符串

    nextLine()

    1. Enter作为结束符,即返回输入回车之前所有的字符
    2. nextLine()可以获取空白
    //从键盘接收数据
    Scanner scanner = new Scanner(System.in);
    System.out.println("请输入数据:");
    
    String str = scanner.nextLine();
    System.out.println("输入的内容为:"+str);
    scanner.close();
    1234567
    System.out.println("请输入整数:");
    if(scanner.hasNextInt()){
        int i=scanner.nextInt();
        System.out.println("输入的整数为:"+i);
    }else {
        System.out.println("输入的不是整数数据");
    }
    1234567
    

    顺序结构

    • Java的基本结构就是顺序结构,除非特别指明,否则就按语句一条一条执行。
    • 顺序结构是最简单的算法结构。
    • 语句语句之间是按从上到下执行的,它是由若干个依次执行的处理步骤组成的,它是如何一种算法都离不开的一种基本算法结构。

    选择结构

    • if单选择结构 if( )
    • if双选择结构 if( ){ }else{ }
    • if多选择结构 if( ){ }else if{ }else{}
    • 嵌套的if结构 if( ){ if( ) }
    int a = 80;
    if(a>60){
        System.out.println("及格");
        if(a>80) System.out.println("且优秀");
    }else if(a>0){
        System.out.println("不及格");
    }else {
        System.out.println("缺考");
    }
    123456789
    

    switch多选择结构

    char grade = 'C'; //JDK新特性 可以是字符串(字符本质还是数字)
    switch (grade){
        case 'A':
            System.out.println("优秀");
            break; //可选,跳出当前结构
        case 'B':
            System.out.println("良好");
            break;
        case 'C':
            System.out.println("合格");
            break;
        default: //默认,以上值没匹配到
            System.out.println("不及格");
            break;
    }
    123456789101112131415
    

    IDEA反编译之后.class文件与源代码对比

    在这里插入图片描述

    循环结构

    • while循环
    //计算1+2+3+...+100
    int i=0;
    int sum=0;
    while(i<100){
        i++;
        sum+=i;
    }
    System.out.println(sum); //5050
    12345678
    
    
    • do…while循环
    //先执行后判断,至少执行一次
    do{
        i++;
        sum+=i;
    }while(i<100) //跟上面效果一样
    12345
    
    
    • for循环
    //(初始化;条件判断;迭代)
    for(int i=0;i<100;i++){
        i++;
        sum+=i;
    }
    for(; ; ){...} //死循环
    123456
    //练习:输出1-1000能被5整除的数,每行输出3个
    for (int i = 1; i <= 1000; i++) {
        if(i%5==0){
            System.out.print(i+"\t"); //输出完不换行
        }
        if(i%(3*5)==0){
            System.out.println();
        }
    }
    123456789
    //练习2:输出九九乘法表
    for(int i=1;i<=9;i++){
        for(int j=1;j<=i;j++){
            System.out.print(j+"*"+i+"="+i*j+"\t");
        }
        System.out.println();
    }
    1234567
    
    

    增强for循环

    int [] numbers = {10,20,30,40,50}; //定义一个数组
    for (int x:numbers){
        System.out.println(x); //遍历数组的元素 10 20 30 40 50
    }
    //相当于
    for(int i=0;i<5;i++){
        System.out.println(numbers[i]);
    }
    12345678
    
    

    break & continue

    • break可用在任何循环的主体部分,由于强行退出循环,也可以用在switch语句。
    • continue用于循环语句中,终止某次循环过程,跳过剩余语句,之间进行下一次循环条件判断。
    • 标签:后面跟一个冒号的标识符 label:
    //打印101-150之间所有的质数
    int count = 0;
    outer:for(int i=101;i<=150;i++){
        for (int j=2;j<i/2;j++){
            if(i%j==0)
                continue outer; //不建议使用标签
        }
        System.out.print(i+" ");
    }
    123456789
    
    

    流程控制练习

    //打印等腰空心三角形
    /*  例如:输入为4时
              *
             * *
            *   *
           * * * *
    */
    Scanner scanner = new Scanner(System.in);
    int n = scanner.nextInt(); //n为三角形高
    for(int i=1;i<=n;i++){
        for(int j=1;j<=2*n-1;j++){
            if(i!=n){ //若不为最后一行
                if(i+j==n+1)
                    System.out.print("*"); //三角形左腰边
                else if(i+j==n+2*i-1)
                    System.out.print("*"); //三角形右腰边
                else System.out.print(" ");
            }
            else if(j%2!=0){  //最后一行,底边
                System.out.print("*");
            }else {
                System.out.print(" ");
            }
        }
        System.out.println(); //换行
    }
    1234567891011121314151617181920212223242526
    


    Java方法

    方法的定义

    • Java的方法类似与其他语言的函数,是一段用来完成特定功能的代码片段

    • 方法包含一个方法头和一个方法体

      • 修饰符:可选,定义了方法的访问类型,告诉编译器如何调用该方法。

      • 返回值类型:方法可能会返回值。returnValueType是方法返回值的数据类型。有些方法没有返回值,则returnValueType为关键字void。

      • 方法名:是方法的实际名称,方法名与参数表共同构成方法签名。

      • 参数类型

        :像一个占位符。方法被调用时,传递值给参数,该值称为实参或变量。参数列表是指方法的参数类型、顺序和参数个数。参数是可选的,方法可以不包含任何参数。

        • 形式参数:在方法被调用时用于接收外界输入的数据。
        • 实参:调用方法时实际传给方法的数据。
      • 方法体:方法体包含具体的语句,定义该方法的功能。

    修饰符 返回值类型 方法名(参数类型 参数名,...{
       方法体...
       return 返回值;
    }
    1234
    

    方法的调用

    • 调用方法:对象名.方法名(实参列表)。
    • Java支持两种调用方法的方式,根据方法是否返回值来选择。
    • 当方法返回一个值的时候,方法调用通常被当成一个值
    int larger = max(30,40);
    1
    
    
    • 如果方法返回值是void,方法调用一定是一条语句。
    • 扩展:值传递和引用传递 ( Java都是值传递)。
    • 调用其他类的方法,除非是static静态方法,不然必须实例化这个类(new)
    public class Demo01 {
       
        public static void main(String[] args) {
            int add = Demo01.add(1,2); // 通过类名直接调用静态方法
            System.out.println(add); // 3
        }
    	// static静态方法,否则就要new实例化来调用
        public static int add(int a,int b){
            return a+b;
        }
    }
    1234567891011
    
    

    值传递 &引用传递

    在这里插入图片描述


    在这里插入图片描述

    方法的重载

    • 重载是在一个类中,有相同的方法名,参数列表不同的方法。
    • 方法重载的规则:
      • 方法名称必须相同
      • 参数列表必须不同(个数、参数类型、或排序不同)
      • 返回类型可以相同也可以不相同
      • 仅仅返回类型不同不足以成为方法的重载
    • 实现理论
      • 方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错。

    命令行传参

    • 有时候你希望运行一个程序时候传递给它消息,这要靠传递命令行参数给main()函数实现。
    public static void main(String[] args) {
        //args.length 数组长度
        for (int i = 0; i < args.length; i++) {
            System.out.println("args["+i+"]: "+args[i]);
        }
    }
    123456
    
    

    找到当前类的文件夹,打开cmd.

    在这里插入图片描述

    可变参数

    • Jdk1.5开始,Java支持传递同类型的可变参数给一个方法。
    • 在方法声明中,在指定参数类型后加一个省略号 (…)。
    • 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。
    //打印最大值
    public static void printMax(int... num){
        if(num.length==0){
            System.out.println("没有值传入");
            return;
        }
        int result = num[0];
        for (int i = 1; i < num.length; i++) {
            if(num[i] > result){
                result = num[i];
            }
        }
        System.out.println("最大值是:"+result);
    }
    public static void main(String[] args) {
        printMax(1,2,3,4); //最大值是:4
        printMax(new int[]{1,2,3,4,5}); //最大值是:5
    }
    123456789101112131415161718
    
    

    递归

    • 递归就是:A方法调用A方法,自己调用自己!
    • 递归策略只需少量的代码可描述解题过程中多次重复计算,大大减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。
    • 递归结构
      • 递归头:什么时候不调用自身方法,没有头 将陷入死循环。
      • 递归体:什么时候需要调用自身方法。
    //阶乘 n! n*(n-1)*...*2*1
    public static int f(int n){
        if(n==1) return 1;
        return n*f(n-1); //递归:调用自身
    }
    public static void main(String[] args) {
        System.out.println(f(5)); //5!= 120
    }
    12345678
    


    Java数组

    数组的定义

    • 数组是相同类型数据的有序集合
    • 数组描述的是相同类型的若干数据,按照一定先后次序排序组合而成
    • 其中,每一个数据称作一个数组元素,每个数组元素可以通过下标访问它们

    数组的声明创建

    • 首先必须声明数组变量,才能在程序中使用数组。
    dataType[] arrayRefVar; //首选
    dataType arrayRefVar[]; //效果相同,但不是首选
    12
    
    • Java语言使用new操作符来创建数组,语法如下
    dataType[] arrayRefVar = new dataType[arraySize]; //int[] nums=new int[10]
    1
    
    • 数组的元素是通过索引访问的,数组索引从0开始
    • 获取数组长度:arrays.length
    int[] nums; //1.声明一个数组
    nums = new int[3]; //2.创建一个数组
    //3.给数组元素赋值
    nums[0]=1;
    nums[1]=2;
    nums[2]=3;
    for (int num : nums) { //打印数组所有元素
        System.out.println(num);
    }
    123456789
    

    内存分析

    在这里插入图片描述


    在这里插入图片描述


    数组的三种初始化

    • 静态初始化
    //静态初始化:创建+赋值
    int[] a={1,2,3};
    Man[] mans={new Man(1,1),new Man(2,2)}
    123
    
    
    • 动态初始化
    //包含默认初始化
    int[] a=new int[2]; //默认值为0
    a[0]=1;
    a[1]=2;
    1234
    
    
    • 默认初始化
      • 数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。

    数组的基本特点

    1. 其长度是确定的,数组一旦被创建,它的大小就是不可改变的。

    2. 其元素必须是相同类型,不允许出现混合类型。

    3. 数组中的元素可以是任何数据类型,包括基本类型和引用类型。

    4. 数组变量属于引用类型,数组也可以看作对象,其中每个元素相当于该对象的成员变量。

      数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,

      数组本身是在堆中的

    数组边界

    在这里插入图片描述

    数组的使用

    • For-Each循环
    int[] arrays = {1,2,3,4,5};
    //打印全部的数组元素 JDK1.5 没有下标
    for (int array : arrays) {
        System.out.println(array);
    }
    12345
    
    
    • 数组作方法入参
    //打印数组元素
    public static void printArray(int[] a){
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" ");
        }
    }
    123456
    
    
    • 数组作返回值
    //反转数组
    public static int[] reverse(int[] arrays){
        int[] result = new int[arrays.length];
        //反转的操作
        for (int i = 0; i < arrays.length; i++) {
            result[i] = arrays[arrays.length-i-1];
        }
        return result;
    }
    123456789
    
    

    多维数组

    • 多维数组可以看成数组的数组,比如二维数组就是一个特殊的数组,其每一个元素都是一个一维数组。
    int arr[][] = new int[3][2]; //二维数组,三行两列
    1
    
    

    在这里插入图片描述

    int[][] array = {{1,2},{3,4},{5,6}};
    //打印二维数组所有元素
    for (int i = 0; i < array.length; i++) { //arrays.length=3
        for (int j = 0; j < array[i].length; j++) {
            System.out.print(array[i][j]+" ");
        }
        System.out.println();
    }
    12345678
    
    

    Arrays类

    • 数组的工具类java.util.Arrays
    • 由于数组对象本身并没有什么方法可以供我们使用,但API提供了一个工具类Arrays供我们使用。
    • Array类中的方法都是static修饰的静态方法,使用时直接使用类名进行调用,可以不用对象调用。
    • 常用功能
      • 给数组赋值:fill方法。
      • 排序:sort方法,升序。
      • 比较数组:equals方法比较数组中元素值是否相等。
      • 查找数组元素:binarySearch对排序好的数组进行二分查找法操作。
    int[] a = {1,2,3,4,9000,32145,451,21};
    System.out.println(a); // [I@28d93b30 (hashcode)
    
    //Arrays.toString 打印数组元素
    System.out.println(Arrays.toString(a)); //[1, 2, 3, 4, 9000, 32145, 451, 21]
    
    //二分法查找某值 返回下标
    System.out.println(Arrays.binarySearch(a, 9000)); // 4
    
    //填充
    Arrays.fill(a,2,4,0); //数组[a[2]~a[4])之间填充0
    System.out.println(Arrays.toString(a)); //[1, 2, 0, 0, 9000, 32145, 451, 21]
    
    //升序排序
    Arrays.sort(a);
    123456789101112131415
    

    冒泡排序

    • 冒泡排序是八大排序最出名的排序算法。
    • 代码:两层循环,外层冒泡轮数,里层依次比较。
    • 当我们看到嵌套循环,应该立马就可以得出这个算法的时间复杂度为O(n2)
    //冒泡排序
    //1.比较数组中两个相邻的元素,如果第一个数大于第二个数,交换它们位置
    //2.每一次比较,都会产生一个最大或最小的数字(升序为最大数)
    //3.下一轮则可以少一次排序
    //4.依次循环,直到结束
    public static int[] sort(int[] array){
        int temp=0;
        //外层循环,次数length-1
        for (int i = 0; i < array.length-1; i++) {
            //内层循环:如果第一个数大于第二个数,交换它们位置
            for (int j = 0; j < array.length-1-i; j++) {
                if(array[j]>array[j+1]){
                    temp=array[j];
                    array[j]=array[j+1];
                    array[j+1]=temp;
                }
            }
        }
        return array;
    }
    
    public static void main(String[] args) {
        int[] a={8,1,35,47,19,-2};
        int[] sort = sort(a);
        System.out.println(Arrays.toString(sort)); //[-2, 1, 8, 19, 35, 47]
    }
    1234567891011121314151617181920212223242526
    
    • 思考:如何优化?

    稀疏数组

    在这里插入图片描述


    在这里插入图片描述


    //创建一个二维数组 11*11  0:没有棋子,1:黑棋  2:白棋
    int[][] array1 = new int[11][11];
    array1[1][2] = 1;
    array1[2][3] = 2;
    //输出原始的数组
    System.out.println("原始的数组:");
    for (int[] array : array1) {
        for (int i : array) {
            System.out.print(i+"\t");
        }
        System.out.println();
    }
    
    //转换为稀疏数组保存
    //1.有效值的个数
    int sum = 0; //有效值总数
    for (int i = 0; i < 11; i++) {
        for (int j = 0; j < 11; j++) {
            if(array1[i][j]!=0){
                sum++;
            }
        }
    }
    //2.创建一个稀疏数组
    int[][] array2 = new int[sum+1][3];
    array2[0][0] = 11;
    array2[0][1] = 11;
    array2[0][2] = sum;
    
    //3.遍历二维数组,将有效值存放到稀疏数组
    int count = 0;
    for (int i = 0; i < array1.length; i++) {
        for (int j = 0; j < array1[i].length; j++) {
            if(array1[i][j]!=0){
                count++;
                array2[count][0] = i;
                array2[count][1] = j;
                array2[count][2] = array1[i][j];
            }
        }
    }
    
    //4.输出稀疏数组
    System.out.println("稀疏数组:");
    for (int i = 0; i < array2.length; i++) {
        for (int j = 0; j < array2[i].length; j++) {
            System.out.print(array2[i][j]+"\t");
        }
        System.out.println();
    }
    /* 结果:
    输出原始的数组
    0	0	0	0	0	0	0	0	0	0	0	
    0	0	1	0	0	0	0	0	0	0	0	
    0	0	0	2	0	0	0	0	0	0	0	
    0	0	0	0	0	0	0	0	0	0	0	
    0	0	0	0	0	0	0	0	0	0	0	
    0	0	0	0	0	0	0	0	0	0	0	
    0	0	0	0	0	0	0	0	0	0	0	
    0	0	0	0	0	0	0	0	0	0	0	
    0	0	0	0	0	0	0	0	0	0	0	
    0	0	0	0	0	0	0	0	0	0	0	
    0	0	0	0	0	0	0	0	0	0	0	
    稀疏数组
    11	11	2	
    1	2	1	
    2	3	2	
    */
    1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
    

    面向对象

    初识面向对象

    面向过程&面向对象

    • 面向过程思想
      • 步骤清晰简单,第一步做什么,第二部做什么…
      • 面向过程适合处理一些较为简单的问题
    • 面向对象思想
      • 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
      • 面向对象适合处理复杂的问题,适合处理需要多人协作的问题!
    • 对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。

    什么是面向对象

    • 面向对象编程(Object-Oriented Programming, OOP)
    • 本质:以类的方式组织代码,以对象的组织(封装)数据。
    • 抽象
    • 三大特性
      • 封装
      • 继承
      • 多态
    • 从认识论的角度考虑是先有对象后有类。对象是具体的事物,类是对象的抽象。
    • 从代码运行角度考虑是先有类后有对象。类是对象的模板

    类与对象的关系

    • 类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但并不能代表某一个具体的事物。
      • 动物、植物、手机、电脑…
      • Person类、Pet类、Cat类等,都是用来描述/定义某一具体的事物应该具备的特点和行为。
    • 对象是抽象概念的具体实例,如张三是人的一个具体实例、张三家里的狗旺财就是狗的一个具体实例。

    创建与初始化对象

    • 使用new来创建对象。

    • 使用new关键字创建的时候,除了分配内存之外,还会给创建好的对象进行默认的初始化,以及对类中构造器的调用。

    • 类中的

      构造器

      也被称为构造方法,创建对象时必须要调用。有以下特点:

      • 必须和类的名字相同
      • 没有返回类型,也不能写void
    • 一个类即使什么都不写,也会存在一个默认的构造方法

    构造器

    public class Person {
        //一个类即使什么都不写,也会存在一个默认的无参构造方法
        //显示地定义构造器
        String name;
        
        //作用:1. 使用new关键字,本质是在调用构造器
        //2. 用来初始化对象的值
        public Person(){} //无参构造
        
        //有参构造 3.一旦定义了有参构造,无参就必须显示定义
        public Person(String name){
            this.name=name;
        }
    	//Alt+insert 快捷键插入构造方法
    }
    123456789101112131415
    
    

    内存分析

    //定义一个宠物类
    public class Pet {
        public String name; //默认 null
        public int age; 	//默认 0
        //无参构造
    
        public void shout(){
            System.out.println("叫了一声");
        }
    }
    12345678910
    //应用类,创建调用对象
    public class Application {
        public static void main(String[] args) {
            
            Pet dog = new Pet();
    
            dog.name = "旺财";
            dog.age = 3;
            dog.shout();
        }
    }
    1234567891011
    
    • 对象通过引用类型来操作:栈 - - ->堆

    在这里插入图片描述
    在这里插入图片描述

    封装

    • 该露的露,该藏的藏
      • 我们程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据细节由自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。
    • 封装(数据的隐藏)
      • 通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,称为信息隐藏。
    • 作用
      1. 提高程序的安全性,保护数据
      2. 隐藏代码的实现细节
      3. 统一接口
      4. 系统可维护性增加了

    在这里插入图片描述

    继承

    • 继承的本质是对某一批类的抽象,从而实现对世界更好地建模。
    • extends的意思是”扩展“。子类是父类的扩展,使用关键字extends来表示。
    • Java中类只有单继承,没有多继承!一个类只能继承一个父类。
    • 继承是类与类之间的一种关系,此外还有依赖、组合、聚合等。
    • 继承关系的两个类,一个为子类(派生类),一个为**父类(基类)**子类继承父类。
    • 子类和父类之间,从意义上讲应该具有”is a“的关系。
    //学生类(子类)继承 人类(父类)
    public class Student extends Person{ /*Person extends Object*/
        ...
    }
    1234
    
    • 子类继承了父类,就会拥有父类的全部方法,而private私有属性及方法无法继承
    • 在Java中,所有类,都默认直接或间接继承Object类 (Ctrl+H 可以查看类关系)
    • 被final修饰的类,无法被继承(断子绝孙)。

    super & this

    1. super()调用父类的构造方法,必须在构造方法的第一个
    2. super必须只能出现在子类的方法或构造方法中
    3. **super()this()**不能同时调用构造方法,因为this也必须写在第一行
    • super与this的区别:super代表父类对象的引用,只能在继承条件下使用;this调用自身对象,没有继承也可以使用。
    super(); //隐藏代码,默认调用了父类的无参构造,要写只能写第一行
    1
    

    在这里插入图片描述


    在这里插入图片描述

    方法的重写

    • 重写:子类的方法必须与父类方法必须一致,方法体不同。
    • 重写是方法的重写,与属性无关
    • 重写方法只与非静态方法有关,与静态方法无关(静态方法不能被重写)
    public class B {
        public static void test(){ //静态方法
            System.out.println("B==>test()");
        }
    }
    12345
    public class A extends B{ //继承
        public static void test(){
            System.out.println("A==>test()");
        }
    }
    12345
    public class Application {
        public static void main(String[] args) {
            //方法的调用之和左边定义的类型有关
            A a = new A();
            a.test(); //打印 A==>test()
    
            //父类的引用指向了子类,但静态方法没有被重写
            B b = new A();
            b.test(); //打印 B==>test()
        }
    }
    1234567891011
    

    修改A.java, B.java

    public class B {
        public void test(){ //非静态方法
            System.out.println("B==>test()");
        }
    }
    public class A extends B{
        @Override //重写了B的方法
        public void test() {
            System.out.println("A==>test()");
        }
    }
    1234567891011
    //父类的引用指向了子类
    B b = new A(); //子类重写了父类的方法,执行子类的方法
    b.test(); //打印变成了 A==>test()
    /* 
    静态方法是类的方法,非静态方法是对象的方法
    有static时,b调用了B类的方法,因为b是b类定义的
    没有static时,b调用的是对象的方法,而b是A类new出来的对象,调用A的方法
    */
    12345678
    
    • 静态方法属于类,非静态方法属于对象
    • 注意点:
    1. 方法名、参数列表必须相同
    2. 修饰符范围可以扩大,不能缩小(public>protect>private)
    3. 抛出的异常 范围可以被缩小,不能扩大
    4. 被**static(属于类,不属于实例),final(常量方法),private(私有)**修饰的方法不能重写

    多态

    • 动态编译:类型
    • 即同一方法可以根据发送对象的不同而采用不同的行为方式
    • 一个对象的实际类型是确定的,但可以指向对象的引用可以有很多
    • 多态存在条件
      • 有继承关系
      • 子类重写父类方法
      • 父类引用指向子类对象

    在这里插入图片描述


    • 注意点:
      1. 多态是方法的多态,没有属性的多态
      2. 父类和子类,有联系 类型转换异常: ClassCastException
      3. 存在条件:继承关系,方法需要重写,父类引用指向子类对象!

    instanceof和类型转换

    • instanceof 引用类型比较,判断一个对象是什么类型
    public static void main(String[] args) {
    
        // Object > String
        // Objest > Person > Student
        // Objest > Person > Teacher
        Object object = new Student();
    	// X instanceof Y,X引用指向的对象是不是Y的子类
        System.out.println(object instanceof Student); //true
        System.out.println(object instanceof Person); //true
        System.out.println(object instanceof Teacher); //false
        System.out.println(object instanceof Object); //true
        System.out.println(object instanceof String); //false
    	
        //类型之间的转化:父-子(高-低),低可以转换为高
        Person obj = new Syudent(); //只能用Person方法(重写了用子类重写过的方法)
        (Syudent)obj.go(); //强转之后可以用Student方法(Student->go())
    }
    1234567891011121314151617
    

    类型转换

    1. 父类引用指向子类的对象
    2. 把子类转换为父类,向上转型,会丢失自己原来的一些方法
    3. 把父类转换为子类,向下转型,强制转换,才调用子类方法
    4. 方便方法的调用(转型),减少重复的代码,简洁。

    Static

    • 静态变量可以直接用类名访问,也称类变量。
    • 静态变量(或方法)对于类,所有对象(实例)所共享。
    • 静态区代码 加载类时一起被初始化,最早执行且只执行一次(第一次new)。
    • Math->随机数:
    //静态导入包
    import static java.lang.Math.random;
    
    public class Application {
        public static void main(String[] args) {
    
            //第一种随机数,不用导包
            System.out.println(Math.random()); //0.7562202902634543
    
            //第二种随机数,静态导入包
            System.out.println(random()); //0.5391606223844663
        }
    }
    12345678910111213
    

    抽象类(abstract)

    • abstract修饰的类就是抽象类,修饰的方法就是抽象方法。
    • 抽象类中可以没有抽象方法,但有抽象方法的类一定要声明为抽象类。
    • 抽象类不能使用new来创建对象,它是用来让子类继承的。
    • 抽象方法只有方法的声明,没有实现,让其子类实现。
    • 子类继承抽象类,必须实现抽象类的所有方法,否则该子类也要声明为抽象类。
    //abstract 抽象类 类只能单继承(接口可以多继承)
    public abstract class Action {
    
        //约束~有人帮我们实现~
        //抽象方法只有方法名,没有方法的实现
        public abstract void doSth();
    
        //1.不能new抽象类,只能靠子类去实现它,仅作为一个约束
        //2.抽象方法只能出现在抽象类中,抽象类可以有普通方法
        //3.抽象类有构造器,可以派生子类
        //4.抽象类的意义:约束,提高开发效率。但是类只能单继承,所以有局限 用的不多
    }
    123456789101112
    

    接口(interface)

    • 普通类:只有具体实现

    • 抽象类:具体实现和规范(抽象方法)都有

    • 接口:只有规范,没有方法实现,专业的约束!约束与实现分离:面向接口编程~

    • 接口就是规范,定义的是一组规则,"你是什么…必须做什么…"的思想。

    • 接口的本质是约束,就像人间法律一样,制定好大家都遵守。

    //interface接口,接口都要有继承类
    //实现类(implements 可以继承多个接口)
    //多继承,利用接口实现多继承
    public interface UserService {
        //定义的属性都是常量,默认修饰 public static final
        public static final int AGE = 99; //一般不用
        //所有的定义的方法都是抽象的 默认public abstract
        public abstract void run();
        void add();
        void query();
        void delete();
    }
    123456789101112
    

    注意点

    • 接口没有构造方法,不能被实例化
    • 实现类必须要重写接口中的方法
    • 实现类(implements) 可以实现多个接口

    内部类

    • 内部类就是在一个类的内部再定义一个类,比如A类中定义了一个B类,那么B就是A的内部类,而A相对B来说就是外部类
      1. 成员内部类:可以操作外部类的私有属性及方法
      2. 静态内部类:static修饰,不能访问外部类私有属性
      3. 局部内部类:外部类的方法里定义的类
      4. 匿名内部类:没有名字初始化类

    在这里插入图片描述



    异常

    • 软件程序在运行过程中,经常可能遇到异常问题,异常英文(Exception),意思是例外,这些例外情况需要我们写程序做出合理的处理,而不至于让程序崩溃。
    • 异常指程序运行中出现的不期而至的各种状况:文件找不到,网络连接错误,非法参数等。
    • 异常发生在程序运行期间,它影响了正常的执行流程。

    在这里插入图片描述

    简单分类

    • 检查型异常:最具代表性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如用户要打开一个不存在的文件时引发的异常,这些异常在编译时不能被简单地忽略。
    • 运行时异常:是可能被程序员避免的异常,与检查性异常相反,运行时异常可以在编译时忽略。
    • 错误Error:错误不是异常,而是脱离程序员控制的问题。错误在代码经常被忽略。例如当栈溢出,一个异常就发生了,它们在编译也检查不到。

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    异常处理机制

    • 抛出异常
    • 捕获异常
    • 异常处理关键字:try、catch、finally、throw、throws
    public static void main(String[] args) {
        int a = 1;
        int b = 0;
    
        try { //try监控区域
            System.out.println(a/b);
        }catch (ArithmeticException e){ //catch 捕获异常
            System.out.println("程序出现异常,变量b不能为0");
        }catch (Exception e){
            e.printStackTrace();
        }finally { //一定会执行,处理善后工作,如关闭资源
            System.out.println("finally");
        }
        
        if(b==0){ //抛出异常一般在方法中使用
            throw new ArithmeticException(); //主动抛出异常
        }
    }
    //Ctrl+Alt+T 快捷键插入 try-catch
    12345678910111213141516171819
    

    自定义异常

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    如果本篇文章对你有帮助,不妨点个赞再走吧!

    展开全文
  • JavaSE 笔记

    2021-05-22 16:29:16
    面向对象思想 1).在Java中我们可以将一些“零散的变量”统一定义到“一个类”中,要使用这些变量,就直接new一个此类对象即可 2).“类”是一个我们自己定义的“新类型”,它属于一种“复合类型”,是由很多其他类型...

    基础内容

    1. Java的基本数据类型: byte short int long float double char boolean
    2. 引用类型:所有的“类”类型、“接口”类型、“数组”类型
    3. 算术运算符:+、-、*、/、%、++、–
    4. 比较运算符:>、<、>=、<=、==、!=
    5. 逻辑运算符:&&、||、&、|
    6. 赋值运算符:=、+=、-=、*=、/=、%=
    7. 三元运算符:布尔表达式 ? 表达式1 :表达式2
    8. 基础语法:(条件语句)if switch (循环语句)for while do while

    面向对象思想

    面向对象思想概述

    1. 在Java中我们可以将一些“零散的变量”统一定义到“一个类”中,要使用这些变量,就直接new一个此类对象即可
    2. “类”是一个我们自己定义的“新类型”,它属于一种“复合类型”,是由很多其他类型组成的。 “类”种可以定义:变量、方法
    3. 所有属于“这一类”的:变量、方法都可以定义在这个“类”中。 “Java中的类”就是描述了“现实世界”的“某一类事物”的:属性、行为。

    类和对象的概念

    1. “类”:是一个“模板”,在Java中就是一个class文件,也是我们定义的新类型,但仅仅是定义。
    2. “对象”:是参照“类”创建的,在内存中有具体的内存空间的,可以存储具体的值的。

    类和对象的使用

    1.定义类

    1).成员属性:可以定义任意多个;
    2).成员属性的数据类型:可以是任何的Java类型(基本类型、引用类型)定义成员属性时,可以不赋“初始值”,也可以赋“初始值”。
    3).成员方法:

    	1).不加static。
    	2).可以定义“返回值类型”和“形参”。
    	3).“成员方法”可以访问“成员变量”。
    

    4).“成员属性”和“成员方法”的定义位置:必须在“类体中”,没有“前后顺序关系”。

    2.创建对象

    1).类只需要定义一个,根据这个类,可以创建任意多的对象。
    2).调用类中的“成员属性”和“成员方法”,必须通过“对象名”(目前)

    3.成员变量的默认值

    1).什么是“成员变量(成员属性)”:定义在“类体”中,方法外的变量叫“成员变量”。
    2).“成员变量”在定义时,不需要赋初始值,当创建此类对象时,JVM会自动为“成员变量”赋初始值

    成员变量和局部变量的区别

    成员变量局部变量
    位置类中,方法外方法中或者方法声明上(形式参数)
    作用范围类中方法中
    初始化值有默认值没有默认值。必须先定义,赋值,最后使用
    在内存中的位置
    生命周期随着对象的创建而存在,随着对象的消失而消失随着方法的调用而存在,随着方法的调用完毕而消失

    封装

    1.将“成员属性私有化”,然后提供公有的,对这个成员属性赋值/获取值的方法。
    2.“封装”的作用:以“方法”的形式操作“成员属性”,这样可以保护成员属性的值。
    3.private关键字:private修饰成员属性,表示:将成员属性“私有化”,表示此成员属性只能被本类内部的其它成员方法,不能被其它类访问。
    4.this关键字:

    	this关键字:用在“非静态方法中(没有staitc的方法)”,它存储的是“当前调用对象的地址”。
    	作用:通过this可以直接访问本类的成员。
    			尤其是:在方法中,当“局部变量”覆盖“成员变量”时,要访问被覆盖的成员变量,必须使用“this.成员变量名”形式去访问。
    

    构造方法

    1.构造方法的概念

    	“构造”:指:创建对象。也就是:new一个对象。
    	“方法”:指:类中的一个方法。
    	“构造方法”:指:在创建对象时,JVM会自动调用的一个“特殊的方法”。
    	
    任何的类都必须要有至少一个构造方法,如果我们程序员不定义构造方法,编译器会自动为我们的类添加一个“默认”的构造方法,它什么都不做。
    构造方法的执行:每次创建此类对象时,由JVM自动调用执行。
    构造方法的作用:通常做一些“成员变量的初始化”操作。
    

    2.构造方法的重载

    定义多个构造方法,但它们的形参列表不能完全一样
    

    继承

    1.继承的概念及作用

    	1).继承:“被继承的类”叫“父类/超类/基类”
    			“继承父类的类”叫“子类”
    	2).“子类”继承“父类”使用关键字:extends
    	3).继承的“好处”:代码复用
    

    2.继承中子父类构造器的访问特点

    	1).当创建子类对象时,会调用父类的构造方法,因为子类构造方法第一句话默认给添加了:super()——调用父类无参构造。
    	2).父类中没有无参构造,子类的构造方法中,应该显示的使用super(参数)调用父类有参构造。(super(参数)调用父类构造的代码必须写在:子类构造方法的第一行。)
    

    3.继承中子父类成员访问特点及重写的概念

    1).父类中的“私有成员”可以被继承,但不能被子类访问
    2).通过子类访问成员时,总体规则:先在子类中找,如果有,就用子类的,如果没有,就到父类中找。
    3).重写:当子类需要保留父类的功能,但想更改父类此功能的具体行为,这时子类可以“重写(覆盖)”父类的方法。
    [重载:指在一个类中,定义多个同名的方法,但形参列表不完全相同,这种形式叫:重载]
    [重写:子类定义跟父类一模一样的方法,这种形式叫:重写]
    

    4.继承的特点

    1).父类的“私有成员”可以被继承,但不能被访问
    2).父类的“构造方法”不能被继承
    3).Java中不允许“多继承”——子类同时继承多个父类
    4).Java可以“多级继承” class B extends A{} class C extends B
    

    5.this和super关键字

    1).this关键字:可以用在“任何类”中,可以访问本类的:成员属性、成员方法、构造方法。
    2).super关键字:用在“子类”中,可以访问父类的:成员属性、成员方法、构造方法。
    	子类成员覆盖了父类的成员,在子类中,要访问被覆盖的父类成员时,必须用super.父类成员
    	在子类中调用父类的构造方法时,必须用super()
    

    抽象类

    1.抽象类和抽象方法,使用关键字:abstract来定义。
    2.抽象类的特点

    1).抽象类不能被创建对象。它就是用来做“父类”的。
    2).抽象类中可以定义:
    			成员属性--存储数据
    			成员方法(get/set)--被子类继承的
    			构造方法--初始化
    			抽象方法--强制子类重写
    3).抽象类不能被创建对象,但可以有“构造方法”——作用:初始化成员变量的。
    4).子类继承抽象类,仍然是“单继承”,而且必须重写抽象类中所有的抽象方法,否则子类必须被定义为“抽象类”。
    5).抽象类中:可以没有抽象方法。
        但如果一个类中有抽象方法,那么这个类,必须是“抽象类”。
    

    3.模板设计模式

    利用抽象类的特点,将父类(抽象类)设计成为一个“模板”——实现了大部分的内容,少部分的内容,由子类去实现。
    

    final关键字

    1.final关键字概述

    	1).final:表示“最终的”,可以修饰:1).类;2).成员属性;4).成员方法;5).局部变量
    	2).应用的位置:
    		1).类:
    			表示:“最终类”——不能被“继承”。
    		2).成员属性、局部变量:
    			a).修饰“基本类型”:常量。表示“值”不能被改变;
    			b).修饰“引用类型”:表示“引用(地址)”不能被改变(堆空间中的内容可以被改变)
    		3).成员方法:表示:“最终方法”——不能被“重写”(但可以被继承)
    

    static关键字

    static表示:静态的。可以修饰:成员属性,成员方法。(静态成员属性、静态成员方法可以被继承)
    如果要创建此类对象,“静态的成员”总是会先于“普通成员”被分配内存;(静态成员有空间的时候,普通成员还没有内存空间)
    “静态成员方法”只能访问“静态成员变量”,不能访问“普通成员变量”。
    “普通成员方法”可以访问“静态成员变量”,也可以访问“普通成员变量”。
    

    static关键字_静态代码块

    “静态代码块”的作用:初始化静态成员变量——有些成员变量不能在定义时初始化完毕。
    1).静态成员总是先于普通成员进入内存;
    2).静态代码块总是在第一次使用这个类时,被执行一次,而且只执行一次。它优先于构造方法被执行。
    

    接口

    1.接口的概念

    1.接口:它是一种比“抽象类”更特殊的一种“引用数据类型”,它里面主要可以定义“抽象方法”
    2.接口的定义:使用关键字:interface
    3.接口也会被编译成class文件。
    4.接口跟抽象类一样:不能被创建对象。接口的作用:做“父级的类型”,被子类实现,进行“功能扩展”。
    5.接口中的成员:
    	1.公有、静态、常量【很少使用】【JDK8以前就有】——可以被子类继承
    	2.公有、抽象方法【最常用】【JDK8以前就有】——可以被子类继承,并强制子类重写
    	3.公有、默认方法【类库中比较多】【JDK8开始】——被子类继承,子类可以重写,也可以不重写(跟父类的普通成员方法一样)
    	4.公有、静态方法【类库中比较多】【JDK8开始】——不能被子类继承,只属于本接口,只能通过本接口名访问。
    

    2.子类和接口的关系_实现

    1).子类“实现”接口,使用关键字:implements
    2).子类的几种实现的方式:
    	1).子类可以直接实现一个/多个接口
    	2).子类可以在继承一个类的同时,实现一个/多个接口
    	一定要先“继承”,后“实现”。
    

    3.接口和接口的关系_继承

    接口可以“继承”自其它接口,而且可以“多继承”。
    

    4.子类实现多个接口时几种冲突情况

    1).两个接口中有相同的:公有、静态、常量:
    	子类可以同时实现,但不会继承
    2).两个接口中都定义了相同的:抽象方法:
    	子类必须只需重写一次
    3).两个接口中都定义了相同的:公有、默认方法:
    	子类必须重写一次
    4).两个接口中都定义相同的:公有、静态、方法
    	"静态方法"不能被继承
    

    5.子类继承的同时实现接口时的冲突

    1).父类和父接口中都包含相同名称的变量:
    	子类不会继承
    2).父类中成员方法,和接口中的抽象方法的定义相同的时候:
    	由于先继承后实现,所以可以将父类中的方法作为接口中抽象方法的实现。
    3).父类中成员方法,和接口中的默认方法的冲突:
    	只继承了父类
    4).父类中的静态方法,和接口中的静态方法的冲突:
    	只继承了父类中的静态方法。接口中的静态方法不会被继承。
    

    6.接口继承接口时的几种冲突情况

    1).两个接口有相同的:公有、静态、常量
    	不会继承,因为冲突
    2).两个接口有相同的:公有、抽象方法:
    	只继承了1个
    3).两个接口有相同的:公有、默认方法:
    	必须重写一次,确定最终版本
    4).两个接口都有相同的:公有、静态方法:
    	没有冲突,因为父接口中的:静态方法不会被继承。
    

    多态

    1.多态的概念

    1).一类事物的不同形式——是指同一行为,具有多个不同表现形式。
    2)”多态”在Java的代码体现上:
    	父类的变量,存储它某个子类对象的引用。
    3).多态的实现前提:
    	1).必须要有继承/实现的关系;
    	2).父类的变量存储它的子类对象的引用;
    	3).子类重写父类的方法:
    

    2.多态时访问成员的特点

    多态时,不能访问子类特有成员。只能访问父类的成员。
    如果子类重写父类方法,访问的是子类重写后的方法。
    

    3.多态的弊端和好处

    1).多态的弊端:多态时,不能访问子类“特有”成员。只能访问父类成员。
    2).多态的好处:尤其是作为“方法形参”时,非常利于程序的扩展。
    

    4.多态的三种常见形式和三种常见应用

    多态的三种常见的使用形式:普通父类多态,父级的抽象类的多态,父级的接口的多态
    多态的三种常见应用:变量的多态,形参的多态,返回值的多态
    

    5.多态的转型

    1).向上转型(自动转)
    2).向下转型(强转):目的:由父类类型转换为子类类型,可以访问子类特有成员。(instanceof 判断,向下转型必须转换为之前存储的那个子类对象类型)
    

    内部类

    1.内部类_概念

    指定义在一个类“内部”的类,叫:内部类
    1).成员内部类:定义在外部类的”成员位置”。
    2).匿名内部类:定义在某个方法内部,在方法中调用其它方法,作为实参时,可以单独定义一个“内部类”,并且直接创建对象,作为实参,传入方法。
    	匿名内部类的写法:
    		new 父类名/父级接口名 (){
    			//子类类体。
    		}
    3).使用匿名内部类的好处和弊端:
    	1).弊端:
    		1).可读性差。
    		2).匿名内部类,没有重用性;
    		3).维护性差。
    	2).好处:
    		1).可以不用单独定义一个子类,在调用方法时,直接定义类,并创建对象。
    

    权限修饰符

    1.四种访问权限修饰符

    1).Java中有四种访问权限修饰符:从宽到窄:public 、protected、默认(什么都不写)、private
    2).作用:控制其他类(其它包的类)是否有权限访问本类,或者本类的成员。
    3).访问权限修饰符可以用在:
    	1).类:但只能用两种:
    		A).public:
    		B).默认(什么都不写):
    	2).成员上(成员属性、成员方法、构造方法、内部类):四种都可以。
    4).明细:
    	1).类:
    		A).public :代表本模块下所有其他包的类都可以访问本类;
    		B).默认(什么都不写):代表:本类只能被同包下的其它类访问。
    	2).成员:可以修饰:成员属性、成员方法、构造方法。(四种访问权限修饰符都可以使用):
    		A).public(公有):公有:可以被本模块中所有的类访问。
    		B).protected(受保护):只能被同包下的其它类访问。如果在包外,可以被子类访问。
    		C).默认(什么都不写):只能被同包下的其它类访问。
    		D).private(私有):只能被本类内部访问。
    

    代码块

    1.三种代码块:

    	1).构造代码块:写在类体中,直接使用一对大括号括起来
    		在每次创建本类对象时,都会被执行一次,而且会在构造方法执行之前被执行。
    		作用:当类中有多个构造方法,而每个构造方法都需要做同样的事,这样可以将这些相同的代码写在一个“构造代码块”中,这个构造代码块,会保证在每个构造方法之前,被执行
    	2).静态代码块:写在类体中,方法外,使用static{}格式
    		静态代码块的执行时机:当程序运行后,第一次使用这个类时,会先被执行,而且只执行一次。
    		作用:初始化“静态成员属性”——有些静态成员属性不能在定义时初始化完毕
    	3).局部代码块:写在方法内,使用一对大括号括
    		执行时机:它不影响此方法的执行顺序,从上到下依次运行。当方法被调用,执行到代码块时,从上到下依次运行。
    		作用:限制变量的生命周期
    

    String类

    1.String类概述

    java.lang.String(类):String类代表字符串。(它们的值在创建后不能被更改)
    

    2.String类的使用

    String是一个类,使用时就要先创建对象,要创建对象,就要先了解它有哪些构造方法。
    	注意:String类内部使用了一个char[]数组
    	1.String()
    	2.String(byte[] bytes):将一个byte[]数组转换为一个String
    	3.String(char[] chars):将一个char[]数组转换为一个String对象
    	4.String(String s):用一个String对象构造一个String对象
    	直接为String对象赋值 String s = “Hello”;(存储在“常量池”)
    

    3.String类常用方法—判断功能

    1).public boolean equals (Object anObject) :将此字符串与指定对象进行比较。
    2).public boolean equalsIgnoreCase (String anotherString) :将此字符串与指定对象进行比较,忽略大小写。
    3).public boolean contains (CharSequence s) :判断参数字符串在当前字符串中是否存在(区分大小写)。存在,返回true,否则,返回false。
    4).public boolean endsWith(String suffix) :测试此字符串是否以指定的后缀结尾(区分大小写)。
    5).public boolean startsWith(String prefix) :测试此字符串是否以指定的前缀开始(区分大小写)
    

    4.String类常用方法—获取功能

    1).public int length () :返回此字符串的长度。
    2).public String concat (String str) :将指定的字符串连接到该字符串的末尾。相当于:+符号,做字符串连接
    3).public char charAt (int index) :返回指定索引处的 char值。
    4).public int indexOf (String str) :返回指定子字符串第一次出现在该字符串内的索引。
    5).public int lastIndexOf(String str) :返回指定子字符串最后一次出现的字符串中的索引。 如果不包含,则返回-1。
    6).public String substring (int beginIndex) :返回一个子字符串,从beginIndex开始截取字符串到字符串结尾。
    7).public String substring (int beginIndex, int endIndex) :返回一个子字符串,从beginIndex到endIndex截取字符串。含beginIndex,不含endIndex。
    

    5.String类常用方法—转换功能

    1).public char[] toCharArray () :将此字符串转换为新的字符数组。
    2).public byte[] getBytes () :使用平台的默认字符集将该 String编码转换为新的字节数组。
    3).public String toLowerCase() :使用默认语言环境的规则将此 String所有字符转换为小写。
    4).public String toUpperCase() :将此 String所有字符转换为大写,使用默认语言环境的规则。
    5).public String replace (CharSequence target, CharSequence replacement) :将与target匹配的字符串使用replacement字符串替换。
    

    6.String类常用方法—分割功能

    1). public String[] split(String regex) :将此字符串按照给定的regex(规则)拆分为字符串数组。
    2). public String trim() :去掉当前字符串的”前后”空格,并返回一个新字符串,原字符串不变。
    

    StringBuilder类

    1.StringBuilder类概述

    1).java.lang.StringBuilder(类):一个可变的字符序列——它内部是“可变的”(跟String类不同)。
    2).String和StringBuilder的区别:
    		1).String类:表示Java中的”字符串”。内部“不可变”。
    		2).StringBuilder类:它是“字符串”的工具类,专门用于“字符串”拼接的。内部“可变的”。
    3).当我们程序中需要做“字符串”拼接时:
    		如果使用String类,String s = “Hello”;
    							s += “World”;
    		效率比较低,这个过程会产生很多对象。所以当做“字符串拼接”时,建议使用:StringBuilder类。
    

    2.StringBuilder的使用

    1).StringBuilder的构造方法:
    		1). StringBuilder() 构造一个没有字符的字符串构建器,初始容量为16个字符
    		2). StringBuilder(String str) 构造一个初始化为指定字符串内容的字符串构建器。
    										 将String转换为StringBuilder。  
    2).StringBuilder的成员方法:
    		1).public StringBuilder append(基本类型/引用类型 c):向StringBuilder的末尾添加新的字符。
    		2).public StringBuilder reverse():将StringBuilder中的字符反序重新排列。
    		3).public String toString():将StringBuilder转换为String类型。
    

    ArrayList集合类

    1.ArrayList概述

    	一种容器:ArrayList——集合类来存储、管理大量的的对象。
    	1).java.util.ArrayList(类):它是一个集合类,内部采用“数组”实现,它的长度是“可变的”。
    	2).ArrayList的构造方法:
    			1). ArrayList():构造一个初始容量为十的空列表。
    	3).ArrayList的成员方法:
    		1).增:
    				1).public boolean add(E e) 将指定的元素追加到此集合的末尾
    				2).public void add(int index,E element) 在此集合中的指定位置插入指定的元素
    					index可以使用的最大索引:当前集合中元素的数量
    		2).删:
    				3).public boolean remove(Object o) 删除指定的元素,返回删除是否成功
    				4).public E remove(int index) 删除指定索引处的元素,返回被删除的元素
    		3).改:
    				5).public E set(int index,E element) 修改指定索引处的元素,返回被修改的元素
    		4).查:
    				6).public E get(int index) 返回指定索引处的元素
    				7).public int size() 返回集合中的元素的个数
    		**注意:ArrayList里面只能存储“引用类型”,不能存储“基本数据类型”。**
    

    2.ArrayList存储基本类型数据

    1).ArrayList是“不能存储基本类型数据”的。
    2).Java针对每种“基本数据类型”都提供了对应的“类”——“包装类”
    		基本数据类型			包装类型
    		byte				Byte
    		short				Short
    		int 				Integer
    		long				Long
    		float				Float
    		double				Double
    		char				Character
    		boolean			Boolean
    	注意:如果想要在集合中存储一些“数值”,泛型,应该指定为:包装类型。
    

    Object类

    1.Object类概述

    java.lang.Object(类):类Object是类层次结构的根。 每个类都有Object作为超类。 所有对象(包括数组)都实现了这个类的方法。——任何的类,如果不继承自其它类,就会隐式的继承自Object。
    

    2.Object类_toString方法

    public String toString():返回对象的字符串表示形式(重写)
    

    3.Object类_equals方法

    public boolean equals(Object obj):比较两个对象中的内容是否完全相同(重写)
    

    Objects类

    1).java.util.Objects(类):它是对”对象”进行操作的一个工具类。里面包含很多的“静态方法”,而且方法中提供安全验证,可以很安全的对“对象”进行操作。
    2).public static boolean equals(Object a, Object b)
    

    日期类Date

    1.日期类_Date

    1).java.util.Date(类):Date类代表了一个特定的时间,以毫秒的精度(1秒 = 1000毫秒)
    		作用:获取系统时间。
    2).Date类的构造方法:
    		1).Date():使用当前系统时间构造一个Date对象。
    		2).Date(long m):使用一个从1970年1月1日0时开始的一个“毫秒值”构造一个Date对象。
    3).Date类的成员方法:
    		1).public long getTime():获取此Date对象所表示的时间到1970年1月1日0之间的“毫秒值”。
    		2).public void setTime(long m):设置一个新毫秒值。
    

    日期格式化类DateFormat

    1).java.text.DateFormat(抽象类):做日期格式化的。它是一个抽象类,不能创建对象。我们可以使用它的子类:
    									java.text. SimpleDateFormat(子类)
    2).SimpleDateFormat的构造方法:
    		SimpleDateFormat(String pattern) 使用给定模式字符串构建一个 SimpleDateFormat 。
    				模式字符串:在SimpleDateFormat说明中有:
    					y:年
    					M:月
    					d:日
    					H:小时
    					m:分钟
    					s:秒
    3).SimpleDateFormat的成员方法:
    		1).将Date转换为String:
    				public final String format(Date date)
    		2).将String转换为Date对象:
    				public Date parse(String source)
    

    日历类_Calendar

    1).java.util.Calendar(抽象类):它表示一个“日历类”内部可以进行日期运算。它是一个抽象类,不能创建对象。我能可以使用它的静态方法:
    		public static Calendar getInstance():此方法会返回它的一个子类:GregorianCalendar对象。
    2).成员方法:
    	1).public int get(int field):获取某个字段的值(年、月、日、小时、分、秒....)
    	2).public void set(int field,int value):设置某个字段的值为value。
    	3).public void add(int field,int value):将field字段的值增加/减少value值。
    

    Math类

    1).java.lang.Math(类):它里面定义了一些做数学运算的一些“静态方法”。它内部的“构造方法”被私有化了,不能创建它的对象,我们也不需要创建对象,直接使用“类名”访问它的静态方法就可以。
    2).常用方法:
    	1).public static int abs(int a) 获取参数a的绝对值:
    	2).public static double ceil(double a) 向上取整
    	3).public static double floor(double a) 向下取整
    	4).public static double pow(double a, double b) 获取a的b次幂
    	5).public static long round(double a) 四舍五入取整
    

    System类

    1).java.util.System(类):System类包含几个有用的类字段和方法。 它不能被实例化。它内部提供的都是“静态方法”。
    2).常用方法:
    	1).public static void exit(int status) 终止当前运行的 Java 虚拟机,非零表示异常终止
    	2).public static long currentTimeMillis() 返回当前时间(以毫秒为单位)
    

    BigInteger类

    1).java.math.BigInteger(类): 不可变的任意精度整数。如果我们需要计算的整数超出了long范围,可以使用BigInteger类来计算。它可以计算任意大小的整数(内存能存下就可以)。
    2).构造方法:
    	1). BigInteger(String val):将参数字符串转换为一个“整数”,存储到BigInteger对象内部。
    3).成员方法:
    	1). public BigInteger add(BigInteger value): 返回其值为 (this + val) 的 BigInteger,超大整数加法运算
    	2). public BigInteger subtract(BigInteger value):返回其值为 (this - val) 的 BigInteger,超大整数减法运算
    	3). public BigInteger multiply(BigInteger value):返回其值为 (this * val) 的 BigInteger,超大整数乘法运算
    	4). public BigInteger divide(BigInteger value) 返回其值为 (this / val) 的 BigInteger,超大整数除法运算,除不尽取整数部分
    

    BigDecima类

    1).java.math.BigDecimal(类):做浮点运算。如果使用“基本数据类型”做浮点运算,可能会产生“丢失精度”的情况,做“浮点运算”,无论数据大小,不使用“基本数据类型”,使用BigDecimal类。
    2).构造方法:
    		1). BigDecimal(String val)【建议】:将参数String的内容转换为浮点数,并且存储到BigDecimal对象内部;
    			注意:不要使用BigDecimal(double d)构造,它内部会将参数d转存,就可能会产生丢失精度的问题。
    3).成员方法:
    		1). public BigDecimal add(BigDecimal value) 加法运算
    		2). public BigDecimal subtract(BigDecimal value) 减法运算
    		3). public BigDecimal multiply(BigDecimal value) 乘法运算
    		4). public BigDecimal divide(BigDecimal value, int scale, RoundingMode rm) 除法运算
    

    Arrays类

    1).java.util.Arrays(类):它是对“数组”操作工具类。它不能创建对象。内部提供了大量的“静态方法”,可以对各种类型数组进行操作。
    2).成员方法:
    	1). public static void sort(int[] a):按照数字顺序排列指定的数组。
    	2). public static String toString(int[] a):将一个int[]转换为字符串。
    

    包装类

    1.包装类的概念

    1).Java中针对四类八种的基本数据类型都提供了对应的包装类,它们都在java.lang包下:
    		基本数据类型			包装类
    		byte				Byte
    		short				Short
    		int					Integer
    		long				Long
    		float				Float
    		double				Double
    		char				Character
    		boolean				Boolean
    		例:Integer的成员方法:
    		1).public static Integer valueOf(int n):将一个int转换为Integer。
    		2).public static Integer valueOf(String s):将一个String转换为Integer。
    		3).public int intValue():取出Integer内部的int值。
    

    2.自动装箱和自动拆箱

    自动装箱-基本类型直接赋给包装类型
    自动拆箱-将包装类型赋给基本类型
    

    引用类型使用

    	1).类、抽象类、接口作为:方法形参——抽象类、接口类型:接收是:它们的子类对象
    	2).类、抽象类、接口作为:方法返回值——抽象类、接口类型:返回时:它们的子类对象
    	3).类、抽象类、接口作为:成员属性——抽象类、接口类型:存储是:它们的子类对象。
    

    Collection集合

    1.集合概述

    1).Java内部提供了很多的“集合类”,这些集合类的作用跟“ArrayList”的作用一样:都是存储、管理大量的对象的。只是它们内部都采用了不同的“数据结构”来存储、管理对象——不同的数据结构会导致集合对象对元素进行“增、删、改、查”的效率不同。
    	ArrayList集合类:内部“数组实现”特点:
    			1).增删:慢;
    			2).查询:快
    2).数据结构:指容器存储、管理大量元素时的“方式”,常见的数据结构:
    	1).数组
    	2).链表
    	3).哈希表
    	4).树
    	5).栈
    	6).队列
    	....
    3).Java的集合体系:
    	Collection(接口)单列集合:定义List和Set集合共有方法
    		List(接口):有序、可存储重复元素、可以通过索引访问
    			ArrayList  【数组】
    			LinkedList  【链表】
    		Set(接口):无序、不可存储重复元素、不可以通过索引访问
    			HashSet  【哈希表】
    			LinkedHashSet  【链表+哈希表】
    	Map(接口)双列集合
    			HashMap  【哈希表】
    			LinkedHashMap  【链表+哈希表】
    

    2.Collection接口中的方法

    1).增:
    	1).public boolean add(E e) : 把给定的对象添加到当前集合中 。
    		关于返回值:
    			a).对于ArrayList永远返回true
    			b).对于HashSet当存储重复元素时会导致存储失败,会返回false。
    2).删:
    	2).public void clear() :清空集合中所有的元素。
    	3).public boolean remove(E e) : 把给定的对象在当前集合中删除。
    3).改【无】:
    4).查:
    	4).public boolean contains(Object obj) : 判断当前集合中是否包含给定的对象。
    	5).public boolean isEmpty() : 判断当前集合是否为空
    	6).public int size() : 返回集合中元素的个数
    	7).public Object[] toArray() : 把集合中的元素,存储到数组中
    	8).public Iterator<E> iterator():获取一个“迭代器”,用于遍历集合元素的。
    

    迭代器

    1.迭代器Iterator接口的使用

    		Iterator<T> it = list.iterator();
            while (it.hasNext()) {//判断集合中是否有元素
                System.out.println(it.next());//打印元素
            }
    
    

    2.迭代器的常见问题

    1).一次hasNext(),多次的next()
    2).并发修改异常:使用“迭代器对象”遍历时,通过“集合对象”删除元素
    	产生的原因:在使用"迭代器"遍历时,通过"集合对象"删除一个元素,而"迭代器"每次遍历,都会核对这个"数量",如果"数量"不正确,就会产生并发修改异常
    

    3.增强for循环

    1).增强for是一个“语法”,对“普通for”的简化写法。
    	格式:for(数据类型  变量名  :   数组/集合对象名){
    				//“变量名”存储的就是“数组/集合对象”中的元素
    		  }
    2).增强for可以遍历:数组、集合
    3).增强for和普通for的区别:
    		增强for:没有循环变量
    		普通for:有循环变量
    

    泛型

    1.泛型概述及作用

    1).在创建“集合对象”时,使用了“泛型”:
    		ArrayList<String> list = new ArrayList<>();
      在使用了泛型后,可以约束这个集合中只能存储“String”类型数据,我们在使用集合是,通常都要求这个集合对象只存储一种数据,目的:提升代码的安全性。
    2).作用:将“避免类型转换的安全隐患”,将类型检查由运行时提前到“编译期”。
    

    2.泛型类、泛型接口、泛型方法

    子类实现/继承具有泛型的接口/父类时子类可以:
    	1.丢弃泛型
    	2.丢弃泛型,但在实现时,可以指定一个"具体类型"
    	3.继续继承泛型
    

    3.泛型通配符

    1).<? extends T>:表示必须是"T或者T的子类"类型;
    2).<? super T>:表示必须是"T或者T的父类"类型;
    3).<?> : 表示可以是任何类型,相当于:<? extends Object>
    

    数据结构

    1.栈

    在这里插入图片描述
    2.队列
    在这里插入图片描述
    3.数组
    在这里插入图片描述

    增删慢、查询快
    

    4.单向链表
    在这里插入图片描述

    增删快、查询慢。
    在前一个节点存储下一个节点的引用。
    

    5.树
    在这里插入图片描述

    树结构->二叉树-->平衡二叉树 --> 红黑树
    

    List接口

    1.List的特点及常用方法

    1).List集合的特点:
    	1).有序的(取出时跟存入的顺序一致的)
    	2).可以存储重复元素;
    	3).可以通过索引访问;
    2).常用方法:
    	1).增【插入】:
    		public void add(int index, E element) : 将指定的元素,添加到该集合中的指定位置上。【插入】
    	2).删:
    		public E remove(int index) : 移除列表中指定位置的元素, 返回的是被移除的元素。
    	3).改:
    		public E set(int index, E element) :用指定元素替换集合中指定位置的元素,返回值的更新前的元素。
    	4).查:
    		public E get(int index) :返回集合中指定位置的元素。
    

    2.List的子类:ArrayList集合

    java.util.ArrayList(List的子类):内部是数组实现,没有新增方法
    

    3.List的子类:LinkedList集合

    1).java.util.LinkedList(List的子类):链表实现。
    2).有新增方法:
    	1).public E pop() :从此列表所表示的堆栈处弹出一个元素。弹栈,相当于: removeFirst():删除并返回第一个元素
    	2).public void push(E e) :将元素推入此列表所表示的堆栈。压栈,相当于:addFirst();
    

    Collections工具类

    1.常用方法

    1).java.util.Collections(工具类):它内部封装了一些对Collection集合操作的方法。
    2).常用方法:
    	1). public static void shuffle(List<?> list):打乱集合内容元素的顺序;
    2). public static <T extends Comparable<? super T>> void sort(List<T> list):对集合元素进行升序排序。
    	3). public static <T> void sort(List<T> list,
                            Comparator<? super T> c):对集合元素进行排序,排序的方式使用第二个参数对象“比较器”。
    

    2.sort方法排序

    sort方法的完整声明:public static <T extends Comparable<? super T>> void sort(List<T> list),此方法可以对参数List集合中的元素进行排序。要求List中的泛型为T类型,而T类型必须实现Comparable接口。
    我们的类必须重写compareTo()方法,用于编写"比较的逻辑"
    
        Collections的sort()方法会调compareTo()方法
        sort()方法只需要compareTo()的"返回值"
            1).返回值如果为"正数":说明当前对象"大于"参数对象,将当前对象挪到参数对象之后
            2).返回值如果为"负数”:说明当前对象"小于"参数对象,将当前对象挪到参数对象之前
            3).返回值如果为"0":说明两个对象相等。
    

    3.sort方法比较器排序

    如果我们要排序的类无法实现Comparable接口,或者我们排序的类实现了Comparable接口,但在排序时,我们想更改排序方式,这时可以使用第二个sort()方法:
    public static <T> void sort(List<T> list, Comparator<? super T> c):对集合元素进行排序,排序的方式使用第二个参数对象“比较器”。
    

    可变参数

    可变参数的使用

    可变参数:指在一个方法中可以定义一个某种类型的,任意数量的形参。
    	格式:public static void f( 数据类型 ... 变量名){
    		  }
    注意:在一个方法的形参中,最多只能有一个“可变参数”,可以是任何类型。而且“可变参数”必须位于形参列表的末尾。
    

    Set集合

    1.Set集合的特点

    1).Set接口没有新增任何方法,使用的都是父接口:Collection的。
    2).Set集合的特点:
    	1).无序的;
    	2).不能存储重复元素;
    	3).不能通过索引访问。
    HashSet
    LinkedHashSet
    	java.util.LinkedHashSet(Set的子类):它内部是:链表 + 哈希表 实现。它是Set的特例:有序的Set
    	链表:保证元素的顺序;
    	哈希表:保证元素唯一。
    	注意:它虽然是有序的,但仍然不能通过索引访问。
    

    Map集合(双列集合)

    1.Map的常用子类

    java.util.Map(接口):双列集合的父接口;
    		|--HashMap(子类):“键”是“哈希表”
    		|--LinkedHashMap(子类):“键”是“链表 + 哈希表”(有序的)
    		|--TreeMap(子类):“键”是“红黑树”(排序的)--元素的compareTo()方法。
    注意:Map的“数据结构”都是应用在“键”上。
    

    2.Map的常用方法

    1).增、改:
    	1).public V put(K key, V value) : 把指定的键与指定的值添加到Map集合中。
    		关于返回值:
    			1).正常put一个的“键值对”:返回null
    			2).如果put一个“已有的键”:会用“新值”替换“原值”,并返回:“原值”——相当于“修改”
    2).删:
    	2).public V remove(Object key) : 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
    3).改(同增)
    4).查:
    	3).public V get(Object key) 根据指定的键,在Map集合中获取对应的值。
    	4).public Set<K> keySet() : 获取Map集合中所有的键,存储到Set集合中。
    	5).public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)。
    	6).public boolean containsKey(Object key) :判断该集合中是否有此键。
    	7).public boolean containsValue(Object value):判断该集合中是否有此值。
    	8).public Collection values():获取所有值的集合。
    

    3.Map集合的遍历方式

    注意:Map不能直接遍历,我们通常使用两种方式,通过Map获取Set集合,然后再遍历Set集合。
    第一种方式:键找值(keySet()方法):获取所有“键”的Set集合。
    第二种方式:键值对(entrySet()方法)
    

    4.HashMap使用自定义对象做键

    Map的“键”和“值”可以是“任何对象”。(需要重写hashCode()和equals()方法)
    关于:HashMap的null键,和null值
    	null可以做键,但一个map对象中,最多只能有一个null键。
    	可以有多个null值
    

    5.LinkedHashMap的基本使用

    java.util.LinkedHashMap:“键”是:链表 + 哈希表,有序的;
    

    6.TreeMap的基本使用

    java.util.TreeMap(子类):“键”是“红黑树”结构——会对“键”进行排序——compreaTo()
    

    任何的“集合”都可以嵌套“任何集合”

    排序算法

    1.冒泡排序
    在这里插入图片描述

    1).对数组排序:Arrays.sort()
    2).对集合排序:Collections.sort();
    原理:
    1).比较轮数 = 数组长度 - 1;
    2).每轮:用第一个数和第二个数比,第二个数和第三个数比,.....,倒数第二个数和倒数第一个数比。
       每轮比较的结果:将“最大数”挪到最后。
    

    2.选择排序
    在这里插入图片描述

    1).第一轮:第一个数和它后面的每个数进行比较;	
    2).第二轮:第二个数和它后面的每个数进行比较;
    .......
    每轮比较的结果:将数组中最小的数挪到左边。
    

    查找算法-二分查找

    二分查找前提条件及原理

    1).二分查找:用于在一个“有序(排序)的数组”中,快速的查找一个元素。
    2).二分查找的使用前提:“数组必须是排序后的”。
    
     		int[] arr = {5, 7, 8, 12, 20};
    
            //开始二分查找
            int tar = 20;
    
            int start = 0;//首索引
            int end = arr.length - 1;//尾索引
            int mid = (start + end) / 2;//中间索引
    
            //开始循环
            while (start <= end) {
                //用findNum 和arr[mid]位置上的元素进行比较
                if (tar > arr[mid]) {//向右走
                    start = mid + 1;
                }else if (tar < arr[mid]){//向左走
                    end = mid - 1;
                }else{
                    System.out.println("找到,位置:" + mid );
                    break;
                }
                //重新计算mid
                mid = (start + end) / 2;
            }
            if (start > end) {
                System.out.println("元素:" + tar + " 没找到!");
            }
    

    异常的概念

    指程序在运行过程中,出现了JVM无法执行的代码,这时JVM会在控制台打印异常信息,并结束程序;
    “异常处理”的重要作用:让JVM在遇到异常代码时,可以跳过异常代码,继续向下运行。
    

    1.异常的产生过程及JVM默认处理异常的方式

    异常产生的过程及JVM默认处理异常的方式:
    	1).JVM执行到有异常的代码。sc.nextInt();
    	2).代码出现异常,JVM要能够识别这种异常
    	3).JVM会到类库中找到描述这个异常的“异常类”,并创建一个此类对象。 
    	4).JVM会看我们的代码中是否希望“捕获(catch)”这个异常:
    			没有:在控制台打印异常信息,然后结束程序
    			有(异常处理):就会执行catch中的语句,程序不会死了。
    

    2.异常的体系结构及分类

    1).Java针对任何的程序所产生的所有异常都进行了定义——针对每种异常,都定义了“异常类”。
        
    2).java.lang.Throwable(类):它是所有异常的父类。
    				|--Error(错误):错误是不希望程序捕获,因为无法处理。
    				|--Exception(异常):希望程序捕获,并处理的。
    						|--RuntimeException(运行时异常):通常属于轻量级异常—程序员可以通过一些判断,避免的异常。
    						|--除RuntimeException外的其它异常类(编译期异常):程序无法判断的异常情况,这些情况出现时必须要处理。
    

    异常的处理

    1.try_catch语句的方式处理异常

    	try{
    			//可能出现异常的代码
    		}catch(异常类名  变量名){
    			//如果try中出现了与catch声明的“异常类名”相同的异常,将会执行这个catch。
    		}
    

    	try{
    		//可能出现异常的代码;
    		//可能出现异常的代码;
    	}catch(异常类名1  变量名){
    		//如果try{}中出现了“异常类名1”的异常,将会执行这里
    	}catch(异常类名2  变量名){
    		//如果try{}中出现了“异常类名2”的异常,将会执行这里
    	}......
    	1).try中某一行代码出现异常,try中异常代码的后续代码全部跳过,不会被执行。
    		所以:在try的代码应该是有“前后的依赖关系”,如果前面的代码执行失败,那么后面的代码也不需要执行。
    	2).多个catch中的“异常类名”通常是“平级关系”。也可以是“子父关系”,如果是“子父关系”父级的异常类型必须声明在多个catch的末尾
    

    	try{
    		//可能出现异常的代码;
    	}catch(异常类名 变量名){
    		//如果try中出现“异常类名”的异常,会执行此catch.
    	}finally{
    		//无论是否出现异常,都会被执行的代码。
    		//做一些资源释放的操作。
    	}
    

    2.操作异常对象

    常用方法:由Throwable定义的:
    	1).toString():获取异常的全类名;
    	2).getMessage():获取异常信息;
    	3).printStackTrace():向控制台打印完整异常信息 + 错误代码的位置
    

    3.throw抛出异常

    throw:它是Java的关键字,作用:用于在一个方法中“抛出一个异常对象”
    throw语句后的任何代码,永远不会被执行——throw会立即结束方法。
    

    4.throws声明抛出异常

    throws:用在“方法的声明”处,表示:声明抛出异常,方法中可能会产生这个这种异常,也可以不会产生这种异常。如果产生这种异常,JVM会自动将这个异常对象抛给调用的代码。
    

    5.throw和throws的区别

    1).throw
    	1).用在方法内部;
    	2).throw后面是:new 异常对象
    	3).throw后面只能是:一个异常对象。
    	4).throw抛出的
    		a).运行时异常:调用处可以不用try...catch..处理,编译可以通过。但是如果出现异常,程序仍然终止。
    		b).编译期异常:方法声明处,必须声明抛出此编译期异常,而且调用处必须用try...catch...或者继续抛出的方式,处理这个异常,否则编译错误。
    2).throws:
    	1).用在方法的声明处;
    	2).throws后面是:异常类名
    	3).throws后面:可以同时声明多个异常对象。
    	4).throws声明抛出的:
    		a).运行时异常:调用处可以不用try...catch..处理,编译可以通过。但是如果出现异常,程序仍然终止。
    		b).编译期异常:调用处必须用try...catch...或者继续抛出的方式,处理这个异常,否则编译错误。
    

    6.子类重写父类方法时的异常声明

    无论父类方法是否抛出异常,子类都可以:
    	1).不抛出任何异常。
    	2).可以抛出任何的“运行时”异常;
    	3).不能抛出跟父类不同的“编译期异常”(可以不抛,但要抛出编译期异常,必须跟父类相同);
    

    自定义异常

    当我们的业务中,根据我们的业务逻辑需要抛出 一个异常对象,但类库中没有表示这种异常的类,这时我们可以自定义一个“异常类”并且可以抛出这个“异常对象”。
    
    public class MyException extends Throwable {//继承任何的异常类都可以。如果继承自RuntimeException,我们的异常就是"运行时"异常。否则,我们的异常就是"编译期"异常。
     	public MyException() {
        }
    
        public MyException(String message) {
            super(message);
        }
    
    }
    

    线程

    1.进程与线程_并行与并发的概念

    1).“进程”:它是“操作系统”的概念,指一个独立运行的程序就是一个“进程”。
    2).“线程”:线程是由“进程”创建——指一个程序中将一段代码剥离出来,独立于“主程序”独立运行,它可以使得我们的程序同时做“多件事情”。
    3).“并发”:一颗CPU,多个线程。
    4).“并行”:两颗CPU,两个线程。
    

    2创建线程的方式一_继承Thread类

    1).在Java中,“线程”是已经实现好的,它就是:java.lang.Thread(类)。我们要制作我们自己的线程,必须要使用这个类。
    2).定义线程的方式一:继承Thread类:
    		1).自定义线程类,继承自Thread类,并重写run()方法;
    2).启动线程:
    		1).创建自定义线程类对象;
    		2).调用自定义线程对象 start()方法;
    

    3.创建线程的方式二_实现Runnable接口

    实现Runnable接口,并重写run()方法
    两种实现线程的方式的对比:
    		1).第一种方式:需要子类“继承”Thread。由于Java是单继承,所以对于子类就形成了限制。
    		2).第二种方式:需要子类“实现”Runnable接口。子类可以继承其它类,同时实现多个接口,对于子类没有限制。
    

    4.匿名内部类的方式实现线程

    1).直接定义Thread的子类,并创建对象——匿名内部类对象:new Thread(){ //子类类体 }.start()
    2).直接定义Runnable的子类,并创建对象——匿名内部类对象:new Thread(//Runnable匿名子类对象).start()
    

    5.Thread类的常用方法

    1).Thread类中定义了一些成员方法、静态方法,用于操作线程的。
    2).普通成员方法:
    	1).public String getName():获取当前的线程的名字。
    		说明:任何的线程创建后,都有一个默认的名字:Thread-[线程的索引]
    	2).public void setName(String name):设置线程的名称;
    3).静态方法:
    	1).public static void sleep(long m):让当前的线程休息指定毫秒。
    	2).public static Thread currentThread():获取当前的线程对象。
    

    高并发及线程安全

    常见的高并发的线程安全性问题,主要有三个表现:
    		1).变量的:可见性;volatile解决可见性
    		2).代码的:有序性;volatile解决有序性
    		3).变量的:原子性;针对变量的整体解决方案:原子类
    

    1.原子类概述

    java.util.concurrent.atomic.AtomicInteger
    java.util.concurrent.atomic.AtomicLong
    java.util.concurrent.atomic.AtomicBoolean
    这些类都是对“某种基本类型”的变量进行“原子”操作的类。它们内部可以封装一个相应类型的数据,它们内部同时提供了一些方法,可以保证对它内部的这个基本类型的数据的操作“原子性”的。所以:当多个线程需要共同访问一个“基本类型变量”时,可以改用“原子类”,能够保证多线程安全。
    	AtomicInteger的常用方法:
    	1).构造方法:
    			1).AtomicInteger():内部使用0初始化。
    			2).AtomicInteger(int v):内部使用参数v初始化。
    	2).常用方法:
    			1).public int getAndIncrement():先获取AtomicInteger内部的值,然后再将AtomicInteger内部的值自增1.
    			2).public int IncrementAndGet():先将AtomicInteger中的值自增1,然后再获取AtomicInteger内部的值;
    			3).public int get():获取AtomicInteger中的值。
    

    2.AtomicInteger的原理_CAS机制(乐观锁)

    CAS机制是一种数据更新的方式,是Compare and Swap的简称。
    CAS 操作包含三个操作数 —— 内存位置V、预期原值A和新值B。 如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值 。否则,处理器不做任何操作。
    

    synchronized关键字

    1.synchronized

    1).使用synchronized关键字,制作一个“同步代码块”,可以将多行代码“加锁”,可以保证一个线程全部执行完所有代码,然后其它线程才可以运行。
    2).synchronized关键字的使用方式有两种:
    	1).同步代码块:
    		synchronized(锁对象){
    			//被同步代码,一个线程执行时,不允许其他线程执行。
    		}
    	2).同步方法:
    		public synchronized void show(){
    			//被同步的方法,一个线程执行此方法时,如其它线程要执行此方法,需要在后面排队。
    		}
    			1.普通的synchronized方法的锁对象:本对象-this
    			2.静态的synchronized方法的锁对象:本类的class对象
    

    2.Lock锁

    1).JDK5开始,提供了一种新的锁:Lock锁:它是一个类:java.util.concurrent.lock.Lock(接口),它本身就是一个“锁”。
    	它提供了比synchronized更加灵活的“锁”的方式。
    2).使用方式(API中建议)
    		Lock l = new 子类对象(); 
    		l.lock(); //加锁
    		try { 
    			// 同步代码 
    		} finally { 
    			l.unlock(); //解锁
    		}
    	说明:
    		1).加锁、解锁都是通过“方法”实现的;
    		2).加锁后,如果代码出现异常,不会解锁的;
    			而synchronized的代码块、方法如果内部出现异常,会自动解锁。
    

    并发包常用类

    并发List集合_CopyOnWriteArrayList
    并发Set集合_CopyOnWriteArraySet
    并发Map集合_ConcurrentHashMap(在JDK1.0时,Java就提供了线程安全的Map集合——Hashtable,它的特点:
    		1).不能使用null做键、值;【不太好用】
    		2).线程安全的,但它内部使用的synchronized实现——效率比ConcurrentHashMap较低。)
    

    1.多线程协作_CountDownLatch

    1).正常情况下,多个线程运行是“无序”的,谁先启动,谁先完成都是不一定的。但如果我们需要多个线程协作完成一项任务,这时就需要对这些线程进行“控制”,让我们按照我们的需要启动、完成。
    2).第一个线程协作类:java.util.concurrent.CountDownLatch(类-倒计数的门闩):允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助。
    3).它内部实现机制:计数器。
    

    2.多线程协作_CyclicBarrier

    1).java.util.concurrent.CyclicBarrier(类-循环的栅栏):允许一组线程全部等待彼此达到共同屏障点的同步辅助。
    2).它内部也是基于“计数器”实现的——可以使用这个对象,实现:控制多个线程到达同一个“屏障点”,然后再执行其他操作。
    

    3.并发数量控制_Semaphore

    1).java.util.concurrent.Semaphore(类-信号量:控制并发数量):它通过“发放许可证”的方式,控制多个线程的并发访问数量。
    2).它是对我们之前学习的synchronized的升级:
    		1).被synchronized修饰的方法,称为:同步方法——特点:只能有一个线程进入执行。
    		2).如果一个方法中的代码没有安全性问题(这时就不需要并发控制),但也不希望有太多的线程同时执行,我们可以通过Semaphore来进行并发数量的控制。
    

    4.线程信息交互_Exchanger

    java.util.concurrent.Exchanger(类):它可以实现两个线程之间的数据交换。
    

    线程池

    1.线程池的概念

    什么是“线程池”:它是一个“容器对象”,里面存储了一些“线程对象”——一个线程对象只能使用一次,如果想再次使用就要再次创建线程对象,创建一个线程对象比较“耗时”,如果程序中需要反复的、大量的使用这个线程,就要反复的、大量创建这个线程对象,这样就会增加服务器的负担。“线程池”可以“缓存”一些线程对象,这些线程对象可以“反复重用”,避免多次创建线程对象,提高程序效率。
    

    2.线程池类:

    java.util.concurrent.Executor(接口):所有线程池的父接口。
    	|--ExecutorService(子类)
    	常用方法:
    		1).Future<?> submit(Runnable task) 提交一个可运行的任务执行,并返回一个表示该任务的未来。  
    		2).<T> Future<T> submit(Runnable task, T result) 提交一个可运行的任务执行,并返回一个表示该任务的未来。  
    		3).<T> Future<T> submit(Callable<T> task) 提交值返回任务以执行,并返回代表任务待处理结果的Future。 
    

    3.线程池工具类:

    java.util.concurrent.Executors(工具类):
    	静态方法:
    		public static ExecutorService newFixedThreadPool(int nThreads):获取具有指定数量的核心线程的线程池对象
    

    4.线程池的作用:

    1).可以反复重用线程对象;对于同一个线程对象,可以反复执行。
    2).线程池内部可以控制“并发数量”;
    

    5.实现线程的第三种方式

    1).继承Thread,重写run()
    2).实现Runnable接口,重写run()
    	这两种实现方式都有两个问题:
    	A).run()方法不能返回值。
    	B).run()方法不能抛出“编译期”异常。
    3).从JDK1.5开始,提供了第三种实现线程的方式:实现Callable接口,重写call()。这种线程,必须要使用“线程池”来启动。
    	Callable接口的call()方法可以:返回值、抛出编译期异常。
    

    死锁

    死锁的现象:两个线程,共同使用两把锁。线程1拿锁A,线程2拿锁B,线程1在去拿锁B,发现锁B被占用,然后等待...线程2去拿锁A,发现锁A被占用,然后等待...
    

    线程状态

    1.“一个线程对象”从创建到最后执行完毕,中间会经历几种“状态”:

    线程状态导致状态发生条件
    NEW(新建)线程刚被创建,但是并未启动。还没调用start方法。MyThread t = new MyThread只有线程对象,没有线程特征。
    Runnable(可运行)线程可以在java虚拟机中运行的状态,可能正在运行自己代码,也可能没有,这取决于操作系统处理器。调用了t.start()方法 :就绪
    Blocked(锁阻塞)当一个线程试图获取一个对象锁,而该对象锁被其他的线程持有,则该线程进入Blocked状态;当该线程持有锁时,该线程将变成Runnable状态。
    Waiting(无限等待)一个线程在等待另一个线程执行一个(唤醒)动作时,该线程进入Waiting状态。进入这个状态后是不能自动唤醒的,必须等待另一个线程调用notify或者notifyAll方法才能够唤醒。
    TimedWaiting(计时等待)同waiting状态,有几个方法有超时参数,调用他们将进入Timed Waiting状态。这一状态将一直保持到超时期满或者接收到唤醒通知。带有超时参数的常用方法Thread.sleep 、Object.wait。
    Teminated(被终止)因为run方法正常退出而死亡,或者因为没有捕获的异常终止了run方法而死亡。

    2.等待和唤醒

    等待和唤醒机制:它是用于两个线程相互协作的。一个线程开始工作,发现问题,会主动“退出(等待)(释放锁)”,另一个线程会拿到锁,解决问题,之后“唤醒(释放锁)”之前等待的线程。这样就达到:两个线程协作完成一项工作。
    	实现前提:两个线程共用同一把锁对象。
    

    定时器

    1.定时器概述

    1).JDK提供了一个“线程的应用”——定时器。它可以设置一个任务在指定的时间被执行一次/反复多次。
    2).要制作定时器需要用到2个类:
    	1).java.util.TimerTask(抽象类):编写任务内容的;我们自己编写定时任务,就需要继承这个类。
    	2).java.util.Timer(类):定时器类,用于设置时间,负责启动任务。
    

    2.定时器Timer的使用

    1).自定义“定时器任务”类,继承自TimerTask——我们使用匿名内部类的方式实现;
    2).创建Timer对象,调用Timer的:
    	1).public void schedule(TimerTask task, long delay) 在指定的延迟之后安排指定的任务执行。只执行一次
    	2).public void schedule(TimerTask task, long delay,long period) 在指定 的延迟之后开始,每间隔period时间执行一次指定任务。
    	3).public void schedule(TimerTask task, Date time) 在指定的时间安排指定的任务执行。
    	4).public void schedule(TimerTask task, Date firstTime, long period) 从指定的时间开始,对指定的任务执行重复的 固定延迟执行 。
    

    Lambda表达式

    1.Lambda表达式

    Lambda表达式:它是JDK8开始的一个“新语法”,它用于代替之前某些情况下的“匿名内部类”的形式。它的语法上更加简洁。
    			new Thread(()-> {
                for (int i = 0; i < 10; i++) {
                    System.out.println(i);
    
               		}
       			 }).start();
    

    2.Lambda的使用前提及函数式接口的概念

    1).Lambda的使用前提:
    	1).面向接口的时候:例如:new Thread(Runnable接口(必须是接口,不能是抽象类)).start();
    	2).接口中“有,且只有一个”必须要子类重写的抽象方法。例如:Runnable接口中的run()方法。
    2).“函数式”接口:
    	当一个接口中“有,且只有一个”必须要子类重写的抽象方法,这种接口被称为:函数式接口,表示,只要类型是函数式接口的地方,就可以使用Lambda表达式。
    	注意:有些时候我们需要定义一些“函数式接口”,使用Lambda表达式。为了保证“函数式接口”定义的正确,我们通常添加一个注解:@FunctionalInterface
    

    3.函数式编程思想

    1).之前的面向对象的编程思想:要定义类、创建对象,调用方法
    2).Lambda表达式,打破了之前Java面向对象的思想:不需要定义类、不需要创建对象,只需要“一个方法体(函数)”就可以。
    	Lambda表达式的优势:语法比较简洁、提高了程序的效率(不需要创建对象)。
    

    4.Lambda的标准格式

    1).Lambda的标准格式:
    	1).一对小括号:形参
    	2).一个右箭头:Lambda特有格式
    	3).一对大括号:方法体。
    

    5.Lambda的省略格式

    1).省略原则:
    	1).形参有关:形参的“数据类型”都可以省略。
    	2).形参有关:如果形参只有一个,可以同时省略:数据类型、一对小括号
    				如果省略一对“小括号”,必须省略“数据类型”。
    				如果省略“数据类型”,可以不省略“小括号”。
    	3).方法体有关:如果方法体中只有一句话,可以同时省略:一对大括号,语句后分号,return关键字(如果有)
    				 要省全省,要用全用。
    

    6.Lambda的几种使用形式

    1).变量的形式:父函数式接口名  变量名 = Lambda表达式;
    2).实参的形式【最常用】:方法名(Lambda表达式)
    3).返回值的形式:return Lambda表达式;
    

    Stream流

    JDK8提出了Lambda表达式,同时也提供了一个应用:Stream流-它可以对大量的数据很方便的进行筛选、过滤、汇总等操作。它里面提供了很多方法,形参都是“函数式接口”,也就意味着可以使用“Lambda表达式”
    

    1.Stream流-获取流的方式

    1).java.util.stream.Stream(接口):它表示一个“流”。有很多方式可以获取它的子类对象;它内部提供很多方法,可以对大量的数据进行筛选、过滤、汇总....
    2).获取Stream流的子类对象的方式:
    		1).通过“集合”对象获取:
    			1).Collection集合:通过Collection接口的“默认方法:stream()”来获取“流对象”
    			2).Map集合:Map集合不能直接获取“Stream流”。只能获取“键的流”、“值的流”、“键值对的流”		
    		2).通过“引用类型数组”获取
    			Stream.<Integer>of(arr);
    		3).通过“基本类型数组”获取:
    			IntStream.of(arr);
    		4).通过“零散的数据”获取:
    			Stream.<String>of(“AA”,”BB”,”CC”);
    

    2.流式思想及惰性求值

    1).流式思想:类似于“流水线”,Stream流从第一次获取开始,每个Stream流只能用一次(做一件事),每个“非终结方法”都会返回一个新流。当我们最终调用流的“终结方法”时,这时才会从第一个流开始执行。
    2).惰性求值:当我们最终调用流的“终结方法”时,这时才会从第一个流开始执行。
    

    3.常用方法

    方法名方法作用方法种类是否支持链式调用
    count统计个数终结
    forEach逐一处理终结
    filter过滤函数拼接
    limit取用前几个函数拼接
    skip跳过前几个函数拼接
    map映射函数拼接
    concat组合函数拼接

    File类

    1.File类概述

    java.io.File(类): 文件和目录路径名的抽象表示——它可以封装一个“文件/目录”的“路径名”,这个路径名可能存在,也可能不存在。通过File的一些方法可以判断路径是否存在。另外它里面还包含一些其他方法:如果文件/目录存在,可以获取文件/目录的一些属性信息:获取文件/目录的名字,文件的大小、是否可读、是否可写....也可以创建文件/目录,删除文件/目录...
    

    2.File类的构造方法

    1.File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例
    2.File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例。
    3.File(File parent, String child) 从父抽象路径名和子路径名字符串创建新的 File实例。 
    

    3.File类的常用方法

    获取:
    	1).public String getAbsolutePath() :返回此File的绝对路径名字符串。	
    	2).public String getPath() :将此File转换为路径名字符串。
    	3).public String getName() :返回由此File表示的文件或目录的名称。
    	4).public long length() :返回由此File表示的文件的长度。 不能获取目录的长度。
    判断:
    	1).public boolean exists() :判断此File表示的文件或目录是否实际存在。
    	2).public boolean isDirectory() :判断此File表示的是否为目录。
    	3).public boolean isFile() :判断此File表示的是否为文件。
    创建和删除:
    	1).public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
    	2).public boolean delete() :删除由此File表示的文件或【空目录】。
    	3).public boolean mkdir() :创建由此File表示的【单级目录】。
    	4).public boolean mkdirs() :创建由此File表示的【多级目录】,包括任何必需但不存在的父目录。
    列表:
    	1). public String[] list():获取此File表示的目录下的所有子文件/子目录的“名称数组”。
    			如果此File对象表示的是一个“文件”,则此方法返回:null
    			如果此File对象表示的是一个“目录”,但目录下面没有任何子文件/子目录,此方法返回:0长度数组(非null)
    	2). public File[] listFiles():获取此File表示的目录下的所有子文件/子目录的“名称的File数组”。
    			如果此File对象表示的是一个“文件”,则此方法返回:null
    			如果此File对象表示的是一个“目录”,但目录下面没有任何子文件/子目录,此方法返回:0长度数组(非null)
    

    递归

    1.递归的概念

    “递归”:全称叫:方法的递归调用,简称:递归。是一种方法调用的形式——方法调用其本身。
    递归的注意事项:
    	1).递归的层次不能太深,否则就是死递归;最终导致:栈溢出
    	2).递归要有出口,否则就是死递归,最终导致:栈溢出
    	3).构造方法不能递归调用
    

    IO流

    1.流概述及分类

    1).IO流:
    		I:Input(输入)
    		O:Output(输出)
    2).IO流的分类:
    	A).字节流:可以读、写任何文件。我们通常用字节流:做文件的复制。
    		1).输出流:|--OutputStream(抽象类)—数据:程序(内存)-->到硬盘。
    						|--FileOutputStream(子类)
    						|--FilterOutputStream
    							|--BufferedOutputStream(高效缓冲流)
    							|--PrintStream(打印流)
    						|--ObjectOutputStream(序列化流)
    		2).输入流:|--InputStream(抽象类)—数据: 到程序(内存) <--硬盘
    						|--FileInputStream(子类)
    						|--FilterInputStream
    							|--BufferedInputStream(高效缓冲流)
    						|--ObjectInputStream(反序列化流)
    	B).字符流:专门用于读、写“纯文本文件”
    		1).输出流:|--OutputStreamWriter(转换流)
    						|--FileWriter(基本字符流)
    					|--BufferedWriter(高效缓冲流)
    					|--PrintWriter(打印流)
    
    		2).输入流:|--InputStreamReader(转换流)
    						|--FileReader(基本字符流)
    					|--BufferedReader(高效缓冲流)
    

    2.字节流

    无论什么文件,最终存储到磁盘上全部是二进制形式。而Java的IO流操作这些文件,最小单位:1字节(8位)。字节流可以操作任何文件。
    	java.io.OutputStream(抽象类):它是所有字节输出流的父类
    		java.io.FileOutputStream(子类):它是OutputStream的子类。
    			方法:
    				FileOutputStream out=FileOutputStream(String/File name,boolean append):如果第二个参数为true则为追加写入,否则就是:覆盖写。
    				out.write(“\r\n”.getBytes());换行
    				out.close();关闭流
    	java.io.InputStream(抽象类):它是所有字节输入流的父类
    		java.io.FileInputStream(子类)
    			方法:
    				FileInputStream in=FileInputStream(String/File name);
    				Java所有的输入流在构造时,文件必须存在,否则运行时抛出异常
    

    2.字符流

    “字符流”底层是基于“字节流”的。由于各国的语言不通,每种语言的“一个字符”在文件中所占用的“字节数”不同,这样,使用“字节流”就不方便了
    	java.io.Writer(抽象类):它是所有字符输出流的父类
    		java.io.FileWriter(子类):
    			方法:
    				Writer out = new FileWriter(String/File name,boolean append);如果第二个参数为true则为追加写入,否则就是:覆盖写。
    	java.io.Reader(抽象类):它是所有字符输入流的父类
    		java.io.FileReader(子类):它是字符输入流的基本流。
    			方法:
    				Reader in = new FileReader(String/File name);
    

    3.缓冲流

    “缓冲流”,这种流内部自带缓存区,它们的读、写都是针对的缓存区的,效率非常高。
    字节缓冲流:
    	BufferedOutputStream和BufferedInputStream:它们没有特有方法,都是继承父类的方法,只是内部的工作机制不同:它的读、写都是针对内部缓存区,而不是针对磁盘的。当它们内部的缓存区满了,才会自动的写入到磁盘,效率比较高。
    字符缓冲流:
    	BufferedWriter和BufferedReader:内部提供了更大的缓存区;它们内部新增了一些方法,可以更加方便的操作文本文件:
    		1).BufferedWriter:新增:newLine():输出一个当前平台的换行符。相当于write(“\r\n”);
    		2).BufferedReader:新增:readLine():读取一行数据。
    

    4.转换流

    转换流:OutputStreamWriter和InputStreamReader,它们是“字符流”,它们的作用
    	1).可以指定“编码”读写文件;(通过构造方法实现)
    	2).可以将“字节流”转换为“字符流”工作;(通过构造方法实现)
    一些常用的码表
    	1).ASCII码表:美国码表,里面存储128个字符,没有中文,只包含英文字符。最早的码表。一个字符占:1个字节
    				任何的其它码表,都兼容ASCII码表。
    	2).IOS-8859-1码表:国际码表,没有中文;
    	3).GBK码表:中文码表。里面定义了:2W多个汉字,每个汉字占:2个字节。
    				 Windows下的文本编辑器(记事本)默认使用的就是:GBK码表。
    	4).UTF-8码表:国际码表,包括中文,也包括国际上大多数国家的常用字符。每个中文占:3个字节
    				IDEA就是使用UTF-8码表的。也是我们以后开发WEB程序常用的码表。
    	5).Unicode码表:国际码表,也包括中文,每种中文占:2个字节。一共是65536个字符。
    				Java语言本身就是使用Unicode码表的。
    

    5.序列化

    序列化及反序列化的概念
    	1).序列化:将“堆”中的对象,连同属性名,属性值整体存储到一个文本文件中,或者通过网络传输。
    		ObjectOutputStream(类):字节流——对象输出流
    		被序列化的类,必须实现Serializable接口——没有任何抽象方法、静态方法、默认方法,它属于:标记接口。当类实现此接口表示,开启了:序列化功能。
    	2).反序列化:将之前“序列化”的对象,再次的读取到“内存堆中”,并创建一个新对象。
    		ObjectInputStream(类):字节流——对象输入流
    版本号
    	当我们序列化一个对象后,如果更改了“类结构”,再反序列化时,会导致“运行时异常:InvalidClassException”,原因:
      在反序列化时,JVM会检查我们之前序列化到文件中的“序列号”和我们当前类的“序列号”是否匹配,如果不匹配,就抛出这个异常。
      当我们的类,被序列化时,编译器会为其添加一个成员属性:这个属性作为“序列号”使用。
      	private static final long serialVersionUID
    某个属性不希望被序列化,可以将其修饰为:transient
    

    6.打印流

    1).字节打印流:PrintStream(其实就是:System.out对象)
    2).字符打印流:PrintWriter(在网络流中常用)
    

    7.IO的异常处理

    try{}catch{}
    

    属性集-Properties类

    1.Properties类概述

    java.util.Properties(类):它是一个Map集合,因为实现了Map接口。它内部提供了两个方法,可以结合“IO流”很方便的操作“配置文件”。
    

    2.Properties类与流相关的方法

    1).store(Writer out,String str):将Properties集合中的键值对写入到文件中;
    2).load(Reader in):将配置文件中的键值对,读取到Properties集合中。
    3).setProperty(String key,String value):相当于:put()
    4).getProperty(Stirng key):相当于:get()
    5).stringPropertyNames():相当于:keySet();
    

    网络编程入门

    1.软件结构

    桌面应用程序:在本机有独立安装程序,安装后独立的启动文件(Windows下xxx.exe)
    	优点:可以充分利用客户端电脑的硬件资源(CPU资源、显卡...)为用户显示非常炫酷的界面效果。
    	缺点:开发困难、后期维护难。
    
    WEB应用程序(B-browser/S-server版):应用程序被部署在互联网上某一台(几台)计算机上,客户端不需要安装程序,只需要一个“WEB浏览器”就可以(WEB浏览器充当了客户端程序)
    优点:开发容易,只需要一套软件,发布到互联网的一台电脑上就可以。后期维护容易。客户端使用方便,不需要安装独立的软件。
    缺点:不能为用户显示非常酷炫的页面效果。
    

    2.网络通信协议

    1).网络程序指:互联网上的两台电脑之间的信息交互。发送端发送信息的格式,必须要跟接收端接收的形式一致,发送端按照某种格式封装数据,接收端按照相同的格式解析数据,这样才可以正常的信息交互,交互信息的格式:被称为“网络通信协议”。因为网络的应用非常多:聊天、文件上传、下载、网页发布.....基于每种应用,都有对应的信息交互的格式——信息交互的“协议”。
    2).常见的协议:http、ftp、UDP、TCP
    	1).UDP协议的特点:
    		1).数据要打包发送;
    		2).数据包大小有限制:64K
    		3).发送时,可以没有接收端——不安全的协议——非面向连接的协议。快——不需要三次握手
    			例如:视频会议系统、共屏软件。
    	2).TCP协议的特点:	
    		1).数据不需要打包发送;使用流
    		2).数据大小没有限制。
    		3).发送时,必须要有接收端——安全的协议——面向连接的协议。慢——连接时需要:三次握手
    			例如:聊天、文件上传、下载.....
    

    3.网络编程三要素

    1).IP地址:是一台电脑在互联网上的唯一地址。
    2).端口:
    	物理端口:网卡口
    	逻辑端口:Windows系统维护的一组数字。范围:0--65535
    3).协议:发送端和接收端必须使用“相同的协议”
    

    TCP通信程序

    1.Socket类和ServerSocket类

    1).客户端:Socket:
    		1).构造:Socket socket = new Socket(“服务器IP”, 服务器端口);//作用:连接服务器
    		2).成员方法:
    			1).public OutputStream getOutputStream():获取输出流;
    			2).public InputStream getInputStream():获取输入流;
    2).服务器:ServerSocket:
    		1).构造:ServerSocket server = new ServerSocket(8888);//作用:监听本机端口
    		2).成员方法:
    			1).public Socket accept():等待客户端连接,此方法会阻塞。
    

    JUnit

    “JUnit”:它是一个第三方的软件包,作用:“单元测试”。
    @Test注解
    	1).需要被测试的方法,使用@Test注解修饰;
    	2).测试方法的要求:
    		1).必须是“无参的”;
    		2).返回值类型必须是“void”;
    		3).必须是“public”;
    		4).不能是“static”
    @Before:在每个@Test测试方法之前执行。
    @After:在每个@Test测试方法执行之后执行。
    @BeforeClass:用于修饰“静态方法”,在所有的@Before之前执行,而且只执行一次。
    @AfterClass:用于修饰“静态方法”,在所有的@After之后执行,而且只执行一次。
    

    BIO、NIO、AIO概述

    1).BIO:block IO——阻塞的IO
    2).NIO:Non block IO——同步、非阻塞IO
    3).AIO:Asynchronous IO——异步、非阻塞IO
    	1).阻塞:指一些IO方法如果没结束,调用方法的代码不能做其它事情的。例如:accept()
    	2).非阻塞:与阻塞相反。IO方法如果没结束,调用方法的代码可以立即返回,做其它事情。例如:NIO的accept()就是非阻塞。
    	3).同步(非阻塞):在“非阻塞”状态下,后期通过一些方法反复去“轮询”,查看方法是否有结果,这种形式:同步
    	4).异步(非阻塞):在“非阻塞”状态下,如果IO方法没有完成,可以在调用方法时“留下”一个“回调函数”,然后调用方法的线程就可以做其它事情,后期如果方法执行完毕,会自动去执行“回调函数”。
    

    Buffer类

    1.Buffer概述

    1).java.nio.Buffer(抽象类):封装了某种“基本数据类型数组”的容器。
    2).它的子类:
    		1).ByteBuffer(抽象类):里面可以封装一个”byte[]数组”的一个缓存区。【重点学习】
    		2).ShortBuffer(抽象类)
    		3).IntBuffer(抽象类)
    		4).LongBuffer(抽象类)
    		5).FloatBuffer(抽象类)
    		6).DoubleBuffer(抽象类)
    		7).CharBuffer(抽象类)
    		(没有boolean类型)
    3).作用:跟byte[]数组一样,存储“数据”的”byte”值。
    

    2.创建ByteBuffer对象

    1).ByteBuffer是一个“抽象类”,不能创建对象。我们可以使用它的一些“静态方法”获取它的子类对象:
    2).常用的静态方法:
    		1).public static ByteBuffer allocate(int capacity):使用参数指定的容量,来创建内部的byte[]数组,并创建一个ByteBuffer的子类对象。叫:间接缓存。内存空间创建在程序的运行时内存中(堆)。
    		2).public static ByteBuffer allocateDirect(int capacity):使用参数指定的容量,来创建内部的byte[]数组,并创建一个ByteBuffer的子类对象。叫:直接缓	存。内存空间创建在“操作系统内存”中。
    		3).public static ByteBuffer wrap(byte[] bytes):使用一个已有的byte[]数组创建一个ByteBuffer对象。
    3).间接缓存:创建、删除快、但操作元素的速度比较慢;
        直接缓存:创建、删除慢,但操作元素的速度比较快;
    

    3.向ByteBuffer中添加数据

    1).常用的添加数据的方法:
    		1).public ByteBuffer put(byte b):向内部的数组中添加一个byte值。
    		2).public ByteBuffer put(int index,byte b):向指定位置添加一个byte值。不更改position位置
    		3).public ByteBuffer put(byte[] bytes):向参数byte[]数组添加到当前byte[]数组的末尾。
    

    4.容量_capacity

    public int capacity():返回此ByteBuffer中byte[]数组的容量(长度)
    

    5.限制_limit

    1).limit的概念:表示“限制”,当前byte[]中可用的最大索引。如果设置“限制”,限制索引位置及之后的索引位置将不可用。“限制”是可以随时调整。作用:限制这个byte[]数组的“可用范围”。
    2).相关方法:
    		1).public int limit():获取当前的限制位置;
    		2).public void limit(int newLimit):设置新的限制位置。
    

    6.位置_position

    1).position的概念:表示“位置”,当前再添加数据时,所添加的索引位置。当我们put()新数据时,它内部的position位置是随时在改变的,我们也可以随时调整这个position位置;
    2).相关方法:
    	1).public int position():获取当前的位置;
    	2).public void position(int p):设置新的位置。
    

    7.标记_mark

    1).mark的概念:表示“标记”,可以临时在数组的某个索引位置设置一个“标记位”,当调用Buffer的reset()方法,会将当前的position位置直接设置到之前的“标记位”。
    2).相关方法:
    	1).public void mark():设置当前的position位置为“标记位”。
    

    8.其它方法

    1).	public Buffer clear():还原缓冲区的状态。
    		将position设置为:0
    		将限制limit设置为容量capacity;
    		丢弃标记mark。
    2).public Buffer flip():缩小limit的范围。
    	1).将limit设置为当前position位置;
    	2).将当前position位置设置为0;
    	3).丢弃标记。
    	作用:标出了有效数据的部分:position(0)到limit的位置
    

    Channel通道

    1.Channel概述

    1).java.nio.channels.Channel(接口):它表示一个“连接通道”,它内部封装了IO流。
    2).常用的子类:
    	1).FileChannel:文件通道;封装了文件的输入输出流。
    	2).DatagramChannel:UTP通道。
    	3).SocketChannel和ServerSocketChannel:TCP通道。它里面封装了Socket和ServerSocket
    

    Selector选择器

    “多路”:指在“服务器”端同时“监听多个端口”,监听每个端口就是一个“通道(一路)”.
    	如果服务器端每监听一个端口,就要开一个线程,这样非常占用系统资源,尤其是此端口的数据量比较少,而它对应的线程会一直占用系统资源。
    	
    1).java.nio.channels.Selector(抽象类):它表示一个“多路复用器”。
    2).获取Selector的子类对象:
    		Selector selector = Selector.open();
    常用方法
    	1). public int select():获取当前“已连接的通道”的数量。
    	2). public abstract Set<SelectionKey> selectedKeys():获取已连接的通道对象的Set集合。
    

    AIO

    AIO(AsynchronousIO-异步、非阻塞的IO),实际上AIO支持:同步非阻塞、异步非阻塞。它的所有的IO方法都是“非阻塞”。
    AIO用的两个通道:
    		1).客户端:AsynchronousSocketChannel
    		2).服务器:AsynchronousServerSocketChannel;
    

    反射

    1.反射的概念

    也叫“反向加载”。通过某种方式我们的程序可以获取一个字符串形式的“类名”,然后通过“反射”技术可以取加载这个类,并且创建这个类的对象,从而去访问它的内部的属性、方法。好处:解开类和类之间的耦合(依赖、关联)。
    

    2.获取Class对象的三种方式

    	1).getClass():Object类定义的方法,任何子类都有的。
    	2).数据类型.class:任何一个数据类型(包括基本类型)都有一个静态属性,可以获取这个数据类型的Class对象;
    	3).Class类的静态方法:forName(String 全类名)
    

    3.获取构造方法并创建对象-Constructor

    1).批量获取:
    	1).public Constructor[] getConstructors():获取所有的“公有”构造方法;
    	2).public Constructor[] getDeclaredConstructors():获取所有的构造方法,包括公有、受保护、默认、私有。
    2).获取单个:
    	1).public Constructor getConstructor(Class ... params):获取某个“公有”构造方法。
    	2).public Constructor getDeclaredConstructor(Class ... params):获取某个构造方法,可以是:公有、受保护、默认、私有。
    	调用构造方法,创建对象:
    	Constructor类的newInstance(Class ... params):
    

    4.获取成员属性并赋值和取值-Field

    1).批量获取:
    	1).public Field[] getFields():获取所有的“公有”成员属性;
    	2).public Field [] getDeclaredFields():获取所有的成员属性,包括公有、受保护、默认、私有。
    2).获取单个:
    	1).public Field getField(String fieldName):获取某个“公有”成员属性。
    	2).public Field getDeclaredField(String fieldName):获取某个成员属性,可以是:公有、受保护、默认、私有。
    	为成员属性赋值:
    	Field类的set(Object targetObj,Object value):为targetObj对象的当前Field表示的属性赋值为:value
    	Field类的get(Object obj):获取obj对象的Field表示的属性的值。
    

    5.获取成员方法并调用-method

    1).批量获取:
    	1).public Method[] getMethods():获取所有的“公有”成员方法;
    	2).public Method[] getDeclaredMethods():获取所有的成员方法,包括公有、受保护、默认、私有。
    2).获取单个:
    	1).public Method getMethod(String methodName,Class ... params):获取某个“公有”成员方法。
    	2).public Method getDeclaredMethod(String methodName,Class ... params):获取某个成员方法,可以是:公有、受保护、默认、私有。
    	调用方法:
    	Method的invoke(Object targetobj,Class ... params)
    

    注意:如果没有访问权限,要设置暴力访问:Method类的setAccessble(true)

    注解

    1.注解的概念_作用

    1).什么是“注解”:从JDK1.5开始提出的。@Override,@FunctionalInteger,@Test等等这些都是注解。
    2).注解的作用:写在源码中,告诉“注解解析器”,怎样编译、运行下面的代码。
    		一些注解(@Override、@FunctionalInteger)是在编译时使用——编译器内部会带“注解解析器”
    		一些注解(@Test)是在运行时使用——不是由JVM启动main()运行的,是启动的“注解解析器”,由“注解解析器”运行的。
    

    2.元注解

    元注解:Java内部定义好的注解,这种元注解只用在“注解的定义上”,它们是用来约束新定义的注解:
    		A).使用位置:@Target,可选的几个属性值:
    				1). ElementType. TYPE,类,接口
      				2). ElementType. FIELD, 成员变量
      				3). ElementType. METHOD, 成员方法
      				4). ElementType. PARAMETER, 方法参数
      				5). ElementType. CONSTRUCTOR, 构造方法
      				6). ElementType. LOCAL_VARIABLE, 局部变量
    		B).生命周期:@Retention,可选的几个属性值:
    				1).RetentionPolicy.SOURCE:注解只存在于源码中,编译后不会生成到class文件;例如:@Override就是源码级的注解,就是给编译器中的“注解解析器”看,告诉注解解析器,怎样编译下面的代码。
    				2).RetentionPolicy.CLASS:注解会存在于:源码、class文件,但运行时,不会加载到内存。
    				3).RetentionPolicy.RUNTIME:注解会存在于:源码、class文件、运行时内存。例如:@Test
    

    3.解析注解

    1).要想注解有作用,必须要有“注解解析器”:可以编写“源码级”的注解解析器,处理类似于:@Override的注解。
    										也可以编写“运行时”的注解解析器,处理类似于:@Test的注解
    2).“运行时”的注解解析器,以“反射”的方式加载使用了注解的类,并以反射的方式调用使用了注解的方法
    

    4.包含属性的注解

    1).类似于:@Target注解,在使用时:
    		@Target(ElementType.METHOD)
    	其中ElementType.METHOD就是注解的“属性”,作用:可以进行更细致的设置。
    
    2).注解中定义属性的格式:
    	public @interface MyTest{
    		数据类型    属性名() [default 值];
    

    设计模式

    单例模式:指在整个程序运行期间,某个类最多只能产生一个对象,被其它类使用。(饿汉式,懒汉式)
    
    多例模式:指在程序的整个运行期间,某个类可以有固定数量的对象,不能多,也不能少
    
    工厂模式:与“创建对象”有关,是指前端不直接创建某个类的对象,而且通过一个“工厂类”里面的“工厂方法”来获取某个类的对象
    	1).解耦合:解开前端类和后端需要创建对象的类的耦合;
    	2).如果创建类的对象比较复杂,前端类就不需要了解创建这个类对象的细节,而是由“工厂方法”创建对象。尤其在多个公司合作开发时。
    代理模式:
    	动态代理:由程序创建目标对象的代理对象,并对目标对象中的方法进行功能性增强的一种技术
    

    枚举

    枚举的底层就是使用“多例模式”实现定义枚举:
    		public enum 枚举名{//语法糖:编译后就是:多例模式
    			//1.枚举项;
    			//2.其他的成员属性、成员方法、构造方法
    		}
    

    JDK8新特性

    Lambda方法引用
    	当我们使用Lambda时,如果“现有方法”的功能跟我们要写的Lambda的功能一样,这时我们就可以使用“现有的方法”来“代替”我们要写的Lambda——方法引用——在使用Lambda的使用,引用其它现有的方法来代替Lambda表达式。
    	格式:对象名::普通成员方法名
    

    正则表达式

    正则表达式:它是一门独立的语言,它也有独立的语法。作用:可以描述一组规则,我们可以在程序中使用这个规则去验证字符串数据是否符合这个规则。
    

    1.字符类

     [abc]:代表a或者b,或者c字符中的一个。
     [^abc]:代表除a,b,c以外的任何字符。
     [a-z]:代表a-z的所有小写字符中的一个。
     [A-Z]:代表A-Z的所有大写字符中的一个。
     [0-9]:代表0-9之间的某一个数字字符。
     [a-zA-Z0-9]:代表a-z或者A-Z或者0-9之间的任意一个字符。
     [a-dm-p]:a 到 d 或 m 到 p之间的任意一个字符。
    

    2.逻辑运算符

    正则表达式有两个逻辑运算符:
    	1).|  :或,表示:或者
    	2).&& : 与,表示:并且
    

    3.预定义字符

    在正则表达式内部“预定义”了一些字符,代替之前的一些某些“范围”的表示方式:
    	1. "." : 匹配任何字符。
    	2. "\d":任何数字[0-9]的简写;
    	3. "\D":任何非数字[^0-9]的简写;
    	4. "\s": 空白字符:[ \t\n\x0B\f\r] 的简写
    	5. "\S": 非空白字符:[^\s] 的简写
    	6. "\w":单词字符:[a-zA-Z_0-9]的简写
    	7. "\W":非单词字符:[^\w]
    

    4.数量词

    常用数量词:
    	1. ? : 0次或1次
    	2. * : 0次到多次
    	3. + : 1次或多次
    	4. {n} : 恰好n次
    	5. {n,} : 至少n次
    	6. {n,m}: n到m次(n和m都是包含的)
    

    5.分组括号

    把一部分正则表达式使用一对小括号括起来,表示“一组”,然后对这一组进行整体设置
    

    6.String的split方法中使用正则表达式

    public String[] split(String regex):参数实际上是一个“正则表达式”。
    

    7.String类的replaceAll方法中使用正则表达式

    public String replaceAll(String regex, String replacement);
    
    展开全文
  • JAVASE重点汇总

    2019-11-12 19:01:57
    javase重点汇总 你是什么,你有什么用,怎么使用 1.名词解释 JVM(Java Virtual Machine):java虚拟机,用于支持java程序的运行。 JRE(Java Runtime Environment):java运行时环境 JVM 和java的核心类库(J2SE ),要...
  • JavaSE 泛型

    2019-09-23 19:28:05
    想要使用String就得用类的全称java.lang.String 泛型的用法 (1)定义泛型类时声明多个类型 类名,T2> (2)定义泛型时声明数组类型 类名<T>{ T[] over; } public class Example < T > { ...
  • javaSE学习 Day1

    2016-08-03 13:36:09
    javaSE学习 Day1
  • JavaSE基础概念

    2018-06-15 14:40:01
    这是我在学习JavaSE中自己的一些笔记和简介变量 变量类型 变量名=值 int age=19(整数) double money=1.2(浮点类型带小数点的)===========================================================================...
  • javaSE入门

    2017-09-05 22:59:59
    计算机(Computer)全称:电子计算机,俗称电脑。计算机由硬件和软件所组成。 应用举例: 科学计算 数据处理 自动控制 计算机辅助设计 人工智能 多媒体应用 计算机网络 1.2计算机...
  • JavaSE知识点总结

    2020-04-15 09:46:17
    JavaSE知识点总结 作者:田超凡 版权所有,转载请注明原作者...
  • JavaSE编程基础试题

    万次阅读 2018-09-10 23:26:15
    JavaSE编程基础 第一章 初识Java Java的三个版本是什么? JavaSE: 定位在客户端,主要用于桌面应用软件的编程 JavaEE:定义在服务器端的企业版,主要用于分布式网络程序的开发 JavaME:主要应用于嵌入式系统开发...
  • Java javase15

    2021-08-25 17:08:25
    C/S结构:全称为Client/Server结构,是指客户端和服务器结构。常见的有QQ、迅雷等。 B/S结构:全称为Browser/Server结构,是指浏览器和服务器结构。常见的有谷歌、火狐等等。 网络编程:就是在一定的协议下实现两台...
  • javaSE知识概括

    2021-02-11 21:07:39
    javaSE知识概括java类中各成员初始化的顺序 java类中各成员初始化的顺序 代码示例: class Father { static{ System. out.println("父类静态代码块初始化" ); } { System. out.println("父类代码块初始化" ); ...
  • JavaSE阶段笔记

    2020-10-20 09:52:44
    JavaSE 一.Java编程基础 ①.数据类型 基本数据类型 数值型(int,long) 字符型(char) 布尔型(boolean) 引用数据类型 类(class) 接口(interface) 数组 枚举(enum) 注解(Annotation) 英文 音标...
  • JavaSE面试题

    2019-09-13 05:52:37
    JavaSE面试题 欢迎到我的Git仓库去提交您觉得优秀的内容! 1.是否可以从一个static方法内部发出对非static方法的调用? 不可以。当一个static方法被调用时,可能还没有创建任何实例对象,如果从一个static...
  • JavaSE基础知识回顾

    2019-06-03 10:44:51
    JavaSE基础知识回顾 1. java的数据类型 (1)基本类型:byte(单字节—8位)、short(双字节—16位)、int(4字节—32位)、long(8字节—64位)、float(四字节—32位)、double(8字节—64位)、char(双字节—16...
  • JavaSE的总结

    2021-08-04 09:40:19
    1).Class.forName("类的全称"); 2).Personperson=newPerson(); 2.类的重载(Overloading): 类名相同,形参列表不同(类型,顺序,个数),system.out.println();也是方法重载。 方法重载出现的原因:在同...
  • JavaSE基础01笔记

    2019-01-24 12:51:27
    计算机(Computer)全称:电子计算机,俗称电脑。是一种能够按照程序运行,自动、高速处理海量数据的现代化智能电子设备。由硬件和软件所组成,没有安装任何软件的计算机称为裸机。常见的形式有台式计算机、笔记本...
  • JavaSE与JavaEE的区别

    2020-07-17 10:10:12
    **JavaSE**,全称“Java Enterprise Edition”, 翻译过来就是“Java企业版”, 自jdk5.0之前也被叫做J2SE, 多用于企业级开发,包括电脑上运行的软件等等, 它允许开发和部署在桌面、服务器、嵌入式环境和实时环境...
  • JavaSE总结篇

    千次阅读 2014-09-10 17:51:21
    一、集合框架和泛型 JAVA集合框架提供了一套性能优良、使用方便的接口和类,它们存放于java.util包中。JAVA的集合类主要由Map接口和Collection接口派生而来。Collection接口有两个常用的子接口:List接口和Set接口...
  • javase学习笔记

    2018-12-16 22:05:02
    计算机(Computer)全称:电子计算机,俗称电脑。是一种能够按照程序运行,自动、高速处理海量数据的现代化智能电子设备。由硬件和软件所组成,没有安装任何软件的计算机称为裸机。常见的形式有台式计算机、笔记本...
  • JavaSE day1

    2019-01-19 20:55:09
    计算机(Computer):全称电子计算机,俗称电脑。是一种能够按照程序运行,自动、高速处理海量数据的现 代化智能电子设备。由硬件和软件组成,没有安装任何软件的计算机称为裸机。常见的形式有台式计算机、笔记本计 ...
  • JavaSE 学习 基础知识

    2020-12-15 16:49:28
    JavaSE基础知识类相关default关键字 基础知识 类相关 default关键字 jdk1.8之后可以在interface中添加default实现方法 如果两个interface的default了一个方法则需要在多实现类中重载方法 类大于接口 package ...
  • JavaSE By狂神

    2021-10-09 19:21:41
    然后接空格 无序列表,- 然后接空格,*然后接空格 也行 表格 代码,三个反引号后面接编程语言 什么是计算机 Computer:全称电子计算机,俗称电脑。 能够按照程序运行,自动、高速处理海量数据的现代化智能电子设备。...
  • 一、JAVASE面试题

    2019-07-11 20:18:00
    一、Java 基础 JDK 和 JRE 有什么区别? (1)JDK 全称Java development kit Java语言开发工具。 把Java程序设计语言、Java虚拟机、JavaAPI库这三部分统称为JDK, ...把JavaAPI类库中的JavaSE ...
  • JavaSE-进阶

    2020-09-06 23:19:21
    课程第1天 ( 1 )分类思想 分类思想概述:分工协作,专人干专事 ( 2 )分包思想 **分包思想概述:**如果将所有的类文件都放在同一个包下,不利于管理和后期维护,所以,对于不同功能的类文件,可以放在不同的包下进行管理 ...
  • Javase_2.6网络net

    2021-02-04 13:15:54
    Javase 2.6 网络基础 protocol–协议 软件结构 C/S结构 :全称为Client/Server结构,是指客户端和服务器结构。常见程序有QQ、迅雷等软件。 B/S结构 :全称为Browser/Server结构,是指浏览器和服务器结构。常见...
  • JavaSE入门学习1:计算机基础知识

    千次阅读 2016-01-18 16:16:18
     计算机(Computer)全称:电子计算机,俗称电脑。是一种能够按照程序运行,自动、高速处理海量数据的现代化 智能电子设备。由硬件和软件所组成,没有安装任何软件的计算机称为裸机。常见的形式有台式计算机、笔记本...
  • javaSE 字符串

    2019-09-11 11:55:13
    一·String类 1.字符串 用双引号表示" " String s="hello"; 2.创建字符串 java语言中将字符串作为对象。创建对象要使用类的构造方法。String类的常用构造方法 1.String(char a[]) 用一个字符数组创建String对象 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,757
精华内容 1,102
关键字:

javase全称

java 订阅