• JAVA学习笔记


    1,取模:%:取余数. 结果的符号取决于被模数
    int i3 = 12 % (-5); //2
    int i4 = -12 % (-5); //-2
    System.out.println(i3);
    System.out.println(i4);
    2,short s = 10; *******************
    //s += 3;编译不通过
    s = (short)(s + 1);//不建议如此实现
    s += 1;//既可以实现运算,又不会更改s的数据类型
    3,
    System.out.println('*' + ' ' + '*'); //输出ASCII码的具体数值
    System.out.println("*" + " " + "*"); //输出字符
    4,//方法一:提供一个临时变量。
    //int temp = m;
    // m = n;
    // n = temp;
    //System.out.println("m:" + m + " n:" + n);

    //方法二:当m和n较大时,有可能出现精度损失
    //m = m + n;//m = 12 + 5;
    //n = m - n;//n = 17 - 5;
    //m = m - n;//m = 17- 12
    //System.out.println("m:" + m + " n:" + n);

    //方法三:优点:没有上面两种方法的缺点。 缺点:难!
    m = m ^ n;
    n = m ^ n;//(m ^ n) ^ n == m
    m = m ^ n;//(m ^ n) ^ m == n
    System.out.println("m:" + m + " n:" + n);
    5, String binary = Integer.toBinaryString(i);
    String hex = Integer.toHexString(i);
    6, 条件判断之间可以嵌套
    ①如果多个条件之间是“互斥”关系,多个条件语句上下顺序是自由的。
    ②如果多个条件之间存在“包含”关系,要求范围小的写在范围大的上面。
    7, import java.util.Scanner;
    Scanner s = new Scanner(System.in);
    int score = s.nextInt();
    Scanner 使用分隔符模式将其输入分解为标记,默认情况下该分隔符模式与空白匹配。
    然后可以使用不同的 next 方法将得到的标记转换为不同类型的值。
    8, //& 与 && 的区别:&:不管左边是true还是false,右端都会进行运算。
    // &&:当左端为false时,右端不再进行运算
    //| 与 || 的区别:|:当左端为true时,右端照样做运算。
    // ||:当左端为true时,右端不再进行运算。
    7,三元运算符
    //练习:如何使用三元运算符,输出三个数中的较大值。
    int m = 12;
    int n = 23;
    int k = -9;
    int max1 = (m > n)? m : n;
    int max2 = (max1 > k)? max1 : k;
    System.out.println(max2);
    8,//1.如何定义一个数组
    //1.1数组的声明
    String[] names;
    int scores[];
    //1.2初始化
    //第一种:静态初始化:初始化数组与给数组元素赋值同时进行。
    names = new String[]{"周爽","郭强强","俞乾龙"};

    //第二种:动态初始化:初始化数组与给数组元素赋值分开进行。
    scores = new int[4];
    //2.如何调用相应的数组元素:通过数组元素的下角标的方式来调用。
    //下角标从0开始,到n -1 结束。其中n表示的数组的长度。
    scores[0] = 87;
    scores[1] = 89;
    scores[3] = 98;
    //3.数组的长度:通过数组的length属性。
    System.out.println(names.length);//3
    System.out.println(scores.length);//4
    //4.如何遍历数组元素
    // System.out.println(names[0]);
    // System.out.println(names[1]);
    // System.out.println(names[2]);
    for(int i = 0;i < names.length;i++){
    System.out.println(names[i]);
    }
    9,//在break和continue语句之后不能添加其他语句,应为永远也不可能被执行!
    10,label:for(int i = 1;i < 5;i++){
    for(int j = 1;j <= 10;j++){
    if(j % 4 == 0){
    //break;
    //continue;
    //break label;
    continue label;
    }
    System.out.print(j);
    }
    System.out.println();
    }
    11,无限循环:
    for(;;){}
    或者
    while(true){
    }
    说明:一般情况下,在无限循环内部要有程序终止的语句,使用break实现。若没有,那就是死循环!
    12,class Test{
    public static void main(String[] args){
    boolean flag = false;
    long start = System.currentTimeMillis();//获取系统当前的毫秒数
    /*1:*/for(int i = 2;i <= 100000;i++){//实现100000以内的自然数的遍历
    //如何判断i是否为一个质数
    for(int j = 2;j <= Math.sqrt(i);j++){
    if(i % j == 0){
    flag = true;
    break;
    //continue l;
    }
    }
    if(!flag){//if(flag == false){
    System.out.println(i);
    }
    flag = false;
    }
    long end = System.currentTimeMillis();
    System.out.println("所花费的时间为:" + (end - start));
    //35535--加上break:10059--使用Math.sqrt():
    }
    }
    13,int[] array1, array2;
    array1 = new int[] { 2, 3, 5, 7, 11, 13, 17, 19 };
    System.out.println(array1);
    array2 = array1;
    System.out.println(array2);//array1和array2代表的栈的地址一样,指向的堆也相同
    14,杨辉三角
    /*
    * 使用二维数组打印一个 10 行杨辉三角.
    1
    1 1
    1 2 1
    1 3 3 1
    1 4 6 4 1
    1 5 10 10 5 1
    ....

    【提示】
    1. 第一行有 1 个元素, 第 n 行有 n 个元素
    2. 每一行的第一个元素和最后一个元素都是 1
    3. 从第三行开始, 对于非第一个元素和最后一个元素的元素.
    yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];

    */
    public class Test {
    public static void main(String[] args) {
    int[][] yangHui = new int[10][];
    //1.初始化二维数组
    for(int i = 0;i < yangHui.length;i++){
    yangHui[i] = new int[i + 1];
    }
    //2.显式的为二维数组的每个元素赋值
    for(int i = 0;i < yangHui.length;i++){
    for(int j = 0;j < yangHui[i].length;j++){
    yangHui[i][0] = yangHui[i][i] = 1;

    if(i > 1 && j > 0 && j < i){
    yangHui[i][j] = yangHui[i-1][j] + yangHui[i-1][j-1];
    }
    }
    }

    //遍历二维数组
    for(int i = 0;i < yangHui.length;i++){
    for(int j = 0;j < yangHui[i].length;j++){
    System.out.print(yangHui[i][j] + " ");
    }
    System.out.println();
    }
    }
    }
    15,//1.二维数组的初始化
    scores2 = new int[][]{{1,2,3},{3,4,5},{6}};//静态初始化

    //names = new String[6][5];//动态初始化的方式一
    names = new String[6][];//动态初始化的方式二
    names[0] = new String[5];
    names[1] = new String[4];
    names[2] = new String[7];
    names[3] = new String[5];
    names[4] = new String[8];
    names[5] = new String[5];

    //错误的初始化方式
    //names = new String[][];
    //names = new String[][5];

    //2.如何来引用具体的某一个元素
    int[][] i = new int[3][2];//int[] i[] = new int[3][2];
    i[1][0] = 90;
    i[2][1] = 100;
    //3.数组的长度
    //二维数组的长度:length属性
    System.out.println(i.length);//3
    //二维数组中元素的长度
    System.out.println(i[0].length);//2
    System.out.println(names.length);//6
    System.out.println(names[4].length);//8
    System.out.println();
    //4.如何遍历二维数组
    for(int m = 0;m < scores2.length;m++){//控制行数
    for(int n = 0;n < scores2[m].length;n++){
    System.out.print(scores2[m][n] + " ");
    }
    System.out.println();
    }
    //5.内存结构

    int[] x,y[];
    //int[] x;//一维
    //int[] y[];//二维
    y = new int[3][2];
    x = y[0];
    //x[0] = y[1][2];
    System.out.print(y);
    System.out.print(x);
    16,// 数组元素的反转
    for (int x = 0, y = arr.length - 1; x < y; x++, y--) {
    int temp = arr[x];
    arr[x] = arr[y];
    arr[y] = temp;
    }
    17,// // 使用冒泡排序使数组元素从小到大排列
    // for (int i = 0; i < arr.length - 1; i++) {
    // for (int j = 0; j < arr.length - 1 - i; j++) {
    // if (arr[j] > arr[j + 1]) {
    // int temp = arr[j];
    // arr[j] = arr[j + 1];
    // arr[j + 1] = temp;
    // }
    // }
    // }
    // //使用直接选择排序使数组元素从小到大排列
    // for(int i = 0; i < arr.length - 1; i++){
    // int t = i;//默认i处是最小的
    // for(int j = i;j < arr.length;j++){
    // //一旦在i后发现存在比其小的元素,就记录那个元素的下角标
    // if(arr[t] > arr[j]){
    // t = j;
    // }
    // }
    // if(t != i){
    // int temp = arr[t];
    // arr[t] = arr[i];
    // arr[i] = temp;
    // }
    // }
    import java.util.Arrays
    Arrays.sort(arr);
    18,异常
    //1.数组下标越界的异常:java.lang.ArrayIndexOutOfBoundsException
    int[] i = new int[10];
    // i[0] = 90;
    // i[10] = 99;

    // for(int m = 0;m <= i.length;m++){
    // System.out.println(i[m]);
    // }
    //2.空指针的异常:NullPointerException
    //第一种:
    // boolean[] b = new boolean[3];
    // b = null;
    // System.out.println(b[0]);

    //第二种:
    // String[] str = new String[4];
    // //str[3] = new String("AA");//str[3] = "AA";
    // System.out.println(str[3].toString());

    //第三种:
    int[][] j = new int[3][];
    j[2][0] = 12;

    //对于基于基本数据类型的变量创建的数组:byte short int long float double char boolean
    //1.对于byte short int long 而言:创建数组以后,默认值为0
    //2.对于float double而言:默认值是0.0
    //3.对于char而言:默认为空格
    //4.对于boolean而言:默认为false
    //5.对于引用类型的变量构成的数组而言:默认初始化值为null。以String为例

    19,//关于数组在内存中的结构(看ppt) ??????????

    int[] myInt = {12,13,14};

    int[] myInt1;
    myInt1 = new int[]{12,1,3,14};
    20,排序集合:
    21,/*
    * 方法的重载(overload)
    * 要求:1.同一个类中 2.方法名必须相同 3.方法的参数列表不同(①参数的个数不同②参数类型不同)
    * 补充:方法的重载与方法的返回值类型没有关系!
    */
    22,三、类的属性(成员变量)
    * 成员变量 vs 局部变量
    * 相同点:1.遵循变量声明的格式: 数据类型 变量名 = 初始化值
    * 2.都有作用域
    * 不同点:1.声明的位置的不同 :成员变量:声明在类里,方法外
    * 局部变量:声明在方法内,方法的形参部分,代码块内
    * 2.成员变量的修饰符有四个:public private protected 缺省
    * 局部变量没有修饰符,与所在的方法修饰符相同。
    * 3.初始化值:一定会有初始化值。
    * 成员变量:如果在声明的时候,不显式的赋值,那么不同数据类型会有不同的默认初始化值。
    * byte short int long ==>0
    * float double ==>0.0
    * char ==>空格
    * boolean ==>false
    * 引用类型变量==>null
    * 局部变量:一定要显式的赋值。(局部变量没有默认初始化值)
    * 4.二者在内存中存放的位置不同:成员变量存在于堆空间中;局部变量:栈空间中
    *
    * 总结:关于变量的分类:1)按照数据类型的不同:基本数据类型(8种) & 引用数据类型
    * 2)按照声明的位置的不同:成员变量 & 局部变量
    23,四、类的方法:提供某种功能的实现
    * 1)实例:public void eat(){//方法体}
    * public String getName(){}
    * public void setName(String n){}
    * 格式:权限修饰符 返回值类型(void:无返回值/具体的返回值) 方法名(形参){}
    *
    * 2)关于返回值类型:void:表明此方法不需要返回值
    * 有返回值的方法:在方法的最后一定有return + 返回值类型对应的变量
    * 记忆:void 与return不可以同时出现一个方法内。像一对“冤家”。
    *
    * 3)方法内可以调用本类的其他方法或属性,但是不能在方法内再定义方法!
    24,一、类的第三个成员:构造器(constructor 构造方法) construction CCB ICBC oop
    * constructor:建造者
    * 构造器的作用:①创建对象 ②给创建的对象的属性赋值
    *
    * 1.设计类时,若不显式声明类的构造器的话,程序会默认提供一个空参的构造器
    * 2.一旦显式的定义类的构造器,那么默认的构造器就不再提供。
    * 3.如何声明类的构造器。格式:权限修饰符 类名(形参){ }
    * 4.类的多个构造器之间构成重载
    *
    *
    * 二、类对象的属性赋值的先后顺序:①属性的默认初始化 ②属性的显式初始化③通过构造器给属性初始化
    * ④通过"对象.方法"的方式给属性赋值
    25,/*
    * 方法的参数传递(重点、难点)
    * 1.形参:方法声明时,方法小括号内的参数
    * 实参:调用方法时,实际传入的参数的值
    *
    * 2.规则:java中的参数传递机制:值传递机制
    * 1)形参是基本数据类型的:将实参的值传递给形参的基本数据类型的变量
    * 2)形参是引用数据类型的:将实参的引用类型变量的值(对应的堆空间的对象实体的首地址值)传递给形参的引用类型变量。
    *
    */
    26,/*
    * 可变个数的形参的方法:
    * 1.格式:对于方法的形参: 数据类型 ... 形参名
    * 2.可变个数的形参的方法与同名的方法之间构成重载
    * 3.可变个数的形参在调用时,个数从0开始,到无穷多个都可以。
    * 4.使用可变多个形参的方法与方法的形参使用数组是一致的。
    * 5.若方法中存在可变个数的形参,那么一定要声明在方法形参的最后。
    * 6.在一个方法中,最多声明一个可变个数的形参。
    */
    27.public void sayHello(String ... args){
    for(int i = 0;i < args.length;i++){
    System.out.println(args[i] + "$");
    }
    System.out.println("=====");
    }
    结果:hello China$
    hello BeiJing$
    =====
    28, 3.子类继承父类以后,父类中声明的属性、方法,子类就可以获取到。
    * 明确:当父类中有私有的属性或方法时,子类同样可以获取得到,只是由于封装性的设计,使得子类不可以直接
    * 调用罢了。
    * 子类除了通过继承,获取父类的结构之外,还可以定义自己的特有的成分。
    *
    * extends:子类是对父类功能的“扩展”,明确子类不是父类的子集。
    29,/*
    * this:
    * 1.可以用来修饰属性、方法、构造器
    * 2.this理解为当前对象或当前正在创建的对象.比如:this.name,this.show();
    *
    * 3.可以在构造器中通过“this(形参)”的方式显示的调用本类中其它重载的指定的构造器。
    * 要求:1.在构造器内部必须声明在首行!
    * 2.若一个类中有n个构造器,那么最多有n-1个构造器中使用了this(形参);
    *
    */
    30,* import:
    * 1)显式导入指定包下的类或接口
    * 2)写在包的声明和源文件之间
    * 3)如果需要引入多个类或接口,那么就并列写出
    * 4)如果导入的类是java.lang包下的,如:System String Math等,就不需要显式的声明。
    * 5)理解.*的概念。比如java.util.*;
    * 6)如何处理同名类的导入。如:在util包和sql包下同时存在Date类。
    * 7)import static 表示导入指定类的static的属性或方法
    * 8)导入java.lang.*只能导入lang包下的所有类或接口,不能导入lang的子包下的类或接口
    */
    //import java.util.Scanner;
    //import java.util.Date;
    //import java.util.List;
    //import java.util.ArrayList;
    31,if (p instanceof Graduate) {
    System.out.println("a graduate");
    }
    判断是否包含
    32,* super:可以用来修饰属性、方法、构造器
    *
    * 1)当子类与父类中有同名的属性时,可以通过"super.此属性"显式的调用父类中声明的属性.
    * 若想调用子类的同名的属性“this.此属性”
    *
    * 2)当子类重写父类的方法以后,在子类中若想再显式的调用父类的被重写的方法,就需要使用“super.方法”
    *
    * 3)super修饰构造器:通过在子类中使用“super(形参列表)”来显式的调用父类中指定的构造器。
    * >在构造器内部,“super(形参列表)”必须要声明在首行!
    * >在构造器内部,“this(形参列表)”或“super(形参列表)”只能出现一个!
    * >当构造器中,不显式的调用“this(形参列表)”或“super(形参列表)”其中任何一个,默认调用的是
    * 父类空参的构造器!
    * 建议:设计一个类时,尽量要提供一个空参的构造器! *****************************
    33,/*
    * 面向对象的特征三:多态性
    * 1.多态性指的是什么?多态性,可以理解为一个事物的多种表型形态。
    * 1)方法的重载与重写 2)子类对象的多态性
    *
    * 2.子类对象的多态性使用的前提:①要有类的继承②要有子类对父类方法的重写
    *
    * 3.程序运行分为编译状态和运行状态。
    * 对于多态性来说,编译时,"看左边",将此引用变量理解为父类的类型
    * 运行时,"看右边",关注于真正对象的实体:子类的对象。那么执行的方法就是子类重写的。
    *
    * 4.子类对象的多态性,并不使用于属性。
    */
    34,Person p1 = new Man();// 向上转型
    //子类对象的多态性:父类的引用指向子类对象Person p1 = new Man();// 向上转型
    Woman w = (Woman) p2;// 向下转型,使用强转符:()
    w.shopping();
    35,if (p1 instanceof Woman) {
    System.out.println("hello!");
    Woman w1 = (Woman) p1;
    w1.shopping();
    }

    if (p1 instanceof Man) {
    Man m1 = (Man) p1;
    m1.entertainment();
    }

    if (p1 instanceof Person) {
    System.out.println("你好!");
    }
    36,// 1.基本数据类型:根据基本数据类型的值判断是否相等。相等返回true,反之返回false
    // 注:两端数据类型可以不同,在不同的情况下,也可以返回true。
    // 2.引用数据类型:比较引用类型变量的地址值是否相等。
    37,int i = 12;
    int j = 12;
    System.out.println(i == j);// true
    char c = 12;
    System.out.println(i == c);// true
    float f = 12.0F;
    System.out.println(i == f);// true

    int k = 65;
    char a = 'A';
    System.out.println(k == a);// true

    Object obj1 = new Object();
    Object obj2 = new Object();
    System.out.println(obj1);
    System.out.println(obj2);
    System.out.println(obj1 == obj2);// false

    Person p1 = new Person();
    Person p2 = new Person();
    Person p3 = p1;
    System.out.println(p1 == p2);// false
    System.out.println(p1 == p3);// true
    38,//equals():
    //①只能处理引用类型变量②在Object类,发现equals()仍然比较的两个引用变量的地址值是否相等

    ********//①像String 包装类 File类 Date类这些重写Object类的equals()方法,比较是两个对象的"实体内容"是否完全相同。
    39,import java.util.Vector;

    /*
    * 利用Vector代替数组处理:从键盘读入学生成绩(以负数代表输入结束),找出最高分,并输出学生成绩等级。
    提示:数组一旦创建,长度就固定不变,所以在创建数组前就需要知道它的长度。
    而向量类java.util.Vector可以根据需要动态伸缩。
    创建Vector对象:Vector v=new Vector();
    给向量添加元素:v.addElement(obj); //obj必须是对象
    取出向量中的元素:Object obj=v.elementAt(0);
    注意第一个元素的下标是0,返回值是Object类型的。
    计算向量的长度:v.size();
    若与最高分相差10分内:A等;20分内:B等;
    30分内:C等;其它:D等
    */
    40,//依次将学生成绩村放入v中
    Integer score1 = new Integer(score);
    v.addElement(score1);
    41,//4.通过v.elementAt(i)依次获取填入v中的元素,同时判断一下各个分数的等级并输出。
    for(int i = 0;i < v.size();i++){
    Integer score = (Integer)v.elementAt(i);
    42,* static,静态的,可以用来属性、方法、*代码块(或初始化块)、*内部类
    *
    * static修饰属性(类变量):
    * 1.由类创建的所有的对象,都共用这一个属性
    * 2.当其中一个对象对此属性进行修改,会导致其他对象对此属性的一个调用。vs 实例变量(非static修饰的属性,各个对象各自拥有一套副本)
    * 3.类变量随着类的加载而加载的,而且独一份
    * 4.静态的变量可以直接通过“类.类变量”的形式来调用
    * 5.类变量的加载是要早于对象。所以当有对象以后,可以“对象.类变量”使用。但是"类.实例变量"是不行的。
    * 6.类变量存在于静态域中。
    *
    * static修饰方法(类方法):
    * 1.随着类的加载而加载,在内存中也是独一份
    * 2.可以直接通过“类.类方法”的方式调用
    * 3.内部可以调用静态的属性或静态的方法,而不能调用非静态的属性或方法。反之,非静态的方法是可以调用静态的属性或静态的方法
    * >静态的方法内是不可以有this或super关键字的!
    * 注:静态的结构(static的属性、方法、代码块、内部类)的生命周期要早于非静态的结构,同时被回收也要晚于非静态的结构
    */
    43,重写equals方法
    public boolean equals(Object obj) {
    if (this == obj)
    return true;
    if (obj == null)
    return false;
    if (getClass() != obj.getClass())
    return false;
    Person other = (Person) obj;
    if (age != other.age)
    return false;
    if (name == null) {
    if (other.name != null)
    return false;
    } else if (!name.equals(other.name))
    return false;
    return true;
    }
    44,import org.junit.Test;
    /*
    * Junit单元测试类
    * 1.当前工程下-右键build path-add libraries-Junit4
    * 2.在主类中,创建一个空参的无返回值的方法,(如:public void test1())用于代码的测试,方法上声明:@Test
    * 3.导入import org.junit.Test;
    * 4.在test1()方法中,进行代码的编写。
    * 5.测试:双击方法名,右键run as-junit Test即可。
    */
    45,/*
    * toString()方法:
    * java.lang.Object类的toString()方法的定义如下:
    * public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
    1.当我们打印一个对象的引用时,实际上默认调用的就是这个对象的toString()方法
    2. 当我们打印的对象所在的类没有重写Object中的toString()方法时,那么调用的就是Object中定义的toString()方法,
    返回此对象所在的类及对应的堆空间对象实体的首地址值
    3.当我们打印的对象所在的类重写了toString()方法时,调用的就是我们自己重写的toString()方法。
    常常这样重写:将对象的属性信息返回。
    */
    46,//包装类:8种基本数据类型对应着一个类,此类即为包装类。
    //基本数据类型 包装类 及String之间的相互转换
    //基本数据类型、包装类 --->String类:调用String类的重载的valueOf(Xxx x)方法
    Integer i2 = i1;
    String str2 = String.valueOf(i2);
    String str3 = String.valueOf(true);//"true"
    //String类--->基本数据类型、包装类:调用包装类的parseXxx(String str)方法
    int i3 = Integer.parseInt(str2);
    System.out.println(i3);
    boolean b1 = Boolean.parseBoolean(str3);
    System.out.println(b1);
    //基本数据类型与包装类之间的转化
    int i = 10;
    //基本数据类型--->对应的包装类:调用包装类的构造器
    Integer i1 = new Integer(i);//对于Boolean来讲,当形参是"true"返回true,除此之外返回false。
    Boolean b1 = new Boolean("false");
    //包装类--->基本数据类型:调用包装类Xxx的XxxValue()方法。
    int i2 = i1.intValue();
    System.out.println(i2);
    //JDK5.0以后,自动装箱和拆箱
    int i4 = 12;
    Integer i3 = i4;//自动装箱
    Boolean bb = false;

    int i5 = i3;//自动拆箱
    47,/*
    * 类的第四个成员:初始化块(或代码块)
    * 1.代码块如果有修饰的话,那么只能使用static。
    * 2.分类:
    * 静态代码块:
    * 1.里面可以有输出语句
    * 2.随着类的加载而加载,而且只被加载一次
    * 3.多个静态代码块之间按照顺序结构执行
    * 4.静态代码块的执行要早于非静态代码块的执行。
    * 5.静态的代码块中只能执行静态的结构(类属性,类方法)
    *
    * 非静态代码块:
    * 1.可以对类的属性(静态的 & 非静态的)进行初始化操作,同时也可以调用本类声明的方法(静态的 & 非静态的)
    * 2.里面可以有输出语句
    * 3.一个类中可以有多个非静态的代码块,多个代码块之间按照顺序结构执行
    * 4.每创建一个类的对象,非静态代码块就加载一次。
    * 5.非静态代码块的执行要早于构造器
    *
    * 关于属性赋值的操作:①默认的初始化②显式的初始化或代码块初始化(此处两个结构按照顺序执行) ③构造器中;④通过方法对对象的相应属性进行修改
    */
    48,//只能创建Singleton的单个实例
    class Singleton{
    恶汉方式
    //1.私有化构造器,使得在类的外部不能够调用此构造器
    private Singleton(){

    }
    //2.在类的内部创建一个类的实例
    private static Singleton instance = new Singleton();
    //3.私有化此对象,通过公共的方法来调用
    //4.此公共的方法,只能通过类来调用,因为设置为static的,同时类的实例也必须为static声明的
    public static Singleton getInstance(){
    return instance;
    }

    }
    懒汉方式
    class Singleton1{
    //1.
    private Singleton1(){

    }
    //2.
    private static Singleton1 instance = null;
    //3.
    public static Singleton1 getInstance(){

    if(instance == null){

    instance = new Singleton1();
    }
    return instance;
    }
    }
    49,/*
    * abstract:抽象的,可以用来修饰类、方法
    *
    * 1.abstract修饰类:抽象类
    * 1)不可被实例化
    * 2)抽象类有构造器 (凡是类都有构造器)
    * 3)抽象方法所在的类,一定是抽象类。
    * 4)抽象类中可以没有抽象方法。
    *
    * 2.abstract修饰方法:抽象方法
    * 1)格式:没有方法体,包括{}.如:public abstract void eat();
    * 2)抽象方法只保留方法的功能,而具体的执行,交给继承抽象类的子类,由子类重写此抽象方法。
    * 3)若子类继承抽象类,并重写了所有的抽象方法,则此类是一个"实体类",即可以实例化
    * 4)若子类继承抽象类,没有重写所有的抽象方法,意味着此类中仍有抽象方法,则此类必须声明为抽象的!
    *
    */
    //abstract 不能用来修饰属性、构造器、private、final、static
    50,/*
    * final:最终的 ,可以用来修饰类、属性、方法
    *
    * 1.final修饰类:这个类就不能被继承。如:String类、StringBuffer类、System类
    *
    * 2.final修饰方法:不能被重写。如:Object类的getClass()
    *
    * 3.final修饰属性:此属性就是一个常量,一旦初始化后,不可再被赋值。习惯上,常量用大写字符表示。
    * 此常量在哪里赋值:①此常量不能使用默认初始化 ②可以显式的赋值、代码块、构造器。
    *
    * 变量用static final修饰:全局常量
    *
    * >与finally finalize()区分开
    *
    */
    51,/*
    * 接口(interface) 是与类并行的一个概念
    * 1.接口可以看做是一个特殊的抽象类。是常量与抽象方法的一个集合,不能包含变量、一般的方法。
    * 2.接口是没有构造器的。
    * 3.接口定义的就是一种功能。此功能可以被类所实现(implements)。
    * 比如:class CC extends DD implements AA
    * 4.实现接口的类,必须要重写其中的所有的抽象方法,方可实例化。若没有重写所有的抽象方法,则此类仍为一个抽象类
    * 5.类可以实现多个接口。----java 中的类的继承是单继承的
    * 6.接口与接口之间也是继承的关系,而且可以实现多继承
    * >5,6描述的是java中的继承的特点。
    *
    */
    52,interface AA{
    //常量:所有的常量都用public static final修饰
    int I = 12;
    boolean FLAG = false;
    // int i;
    //抽象方法:所有的都用public abstract修饰
    void method1();
    void method2();
    }
    53,模板设计模式
    //模板方法设计模式
    public class TestTemplate {
    public static void main(String[] args) {
    new SubTemplate().spendTime();
    }
    }

    abstract class Template {

    public abstract void code();

    public void spendTime() {
    long start = System.currentTimeMillis();

    this.code();

    long end = System.currentTimeMillis();
    System.out.println("花费的时间为:" + (end - start));
    }
    }

    class SubTemplate extends Template {

    public void code() {
    boolean flag = false;
    for(int i = 2;i <= 10000;i++){
    for(int j = 2;j <= Math.sqrt(i);j++){
    if(i % j == 0){
    flag = true;
    break;
    }
    }
    if(!flag){
    System.out.println(i);
    }
    flag = false;
    }
    }
    }
    54,/*一、异常的体系结构
    * java.lang.Throwable
    * |-----Error:错误,程序中不进行处理
    * |-----Exception:异常,要求在编写程序时,就要考虑到对这些异常的处理
    * |-----编译时异常:在编译期间会出现的异常(执行javac.exe命令时,出现异常)
    * |-----运行时异常:在运行期间出现的异常(执行java.exe命令时,出现异常)
    *
    * 当执行一个程序时,如果出现异常,那么异常之后的代码就不再执行!
    */
    //1.数组下标越界的异常:ArrayIndexOutOfBoundsException
    //2.算术异常:ArithmeticException
    //3.类型转换异常:ClassCastException
    //4.空指针异常:NullPointerExcetion
    /*
    * 二、如何处理Exception的异常
    * Java提供的是异常处理的抓抛模型
    * 1."抛":当我们执行代码时,一旦出现异常,就会在异常的代码处生成一个对应的异常类型的对象,并
    * 将此对象抛出。(自动抛出 / 手动抛出)
    * >一旦抛出此异常类的对象,那么程序就终止执行
    * >此异常类的对象抛给方法的调用者。
    * 2."抓":抓住上一步抛出来的异常类的对象。如何抓?即为异常处理的方式
    * java 提供了两种方式用来处理一个异常类的对象。
    * 处理的方式一:
    * try{
    * //可能出现异常的代码
    * }catch(Exception1 e1){
    * //处理的方式1
    * }catch(Exception2 e2){
    * //处理的方式2
    * }finally{
    * //一定要执行的代码
    * }
    * 注:1.try内声明的变量,类似于局部变量,出了try{}语句,就不能被调用
    * 2.finally是可选的。
    * 3.catch语句内部是对异常对象的处理:
    * >getMessage(); printStackTrace();
    * 4.可以有多个catch语句,try中抛出的异常类对象从上往下去匹配catch中的异常类的类型,一旦满足
    * 就执行catch中的代码。执行完,就跳出其后的多条catch语句
    * 5.如果异常处理了,那么其后的代码继续执行。
    * 6.若catch中多个异常类型是"并列"关系,孰上孰下都可以。
    * 若catch中多个异常类型是"包含"关系,须将子类放在父类的上面,进行处理。否则报错!
    * 7.finally中存放的是一定会被执行的代码,不管try中、catch中是否仍有异常未被处理,以及是否有return语句。
    * 8.try-catch是可以嵌套的。
    *
    * 三、对于运行时异常来说,可以不显式的进行处理。
    * 对于编译时异常来说,必须要显式的进行处理。
    55, * 类的第5个成员:内部类
    * 1.相当于说,我们可以在类的内部再定义类。外面的类:外部类。里面定义的类:内部类
    * 2.内部类的分类:成员内部类(声明在类内部且方法外的) vs 局部内部类(声明在类的方法里)
    * 3.成员内部类:
    * 3.1是外部类的一个成员:①可以有修饰符(4个)②static final ③可以调用外部类的属性、方法
    *
    * 3.2具体类的特点:①abstract ②还可以在其内部定义属性、方法、构造器
    *
    * 4.局部内部类:
    *
    * 5.关于内部类,大家掌握三点:
    * ①如何创建成员内部类的对象(如:创建Bird类和Dog类的对象)
    * ②如何区分调用外部类、内部类的变量(尤其是变量重名时)
    * ③局部内部类的使用 (见TestInnerClass1.java)
    *
    */
    56,class Person{
    String name = "韩梅梅";
    int age;
    //成员内部类(非static的)
    class Bird{
    String name = "黄鹂";
    int id;

    public Bird(){

    }
    public void setName(String name){
    System.out.println(name);//杜鹃
    System.out.println(this.name);//黄鹂
    System.out.println(Person.this.name);//韩梅梅
    }
    public void info(){
    show();
    }
    }
    //成员内部类(静态内部类)
    static class Dog{

    }

    public void show(){
    System.out.println("我是show()方法");
    }

    public void method1(){
    class A{

    }
    }
    }

    public class TestInnerClass {
    public static void main(String[] args) {
    //创建静态内部类的对象:可以直接通过外部类调用静态内部类的构造器
    Person.Dog d = new Person.Dog();//Person.new Dog();
    //Person.Bird b = new Person.Bird();
    //创建非静态的内部类的对象:必须先创建外部类的对象,通过外部类的对象调用内部类的构造器
    Person p = new Person();
    Person.Bird b = p.new Bird();//new p.Bird();
    b.info();
    b.setName("杜鹃");
    }
    }

    57,/*
    * 关于局部内部类的使用
    */
    public class TestInnerClass1 {

    }

    class OuterClass{
    //局部内部类
    //如下的使用方式较少
    public void method1(){

    class InnnerClass{

    }
    }
    //常常使用一个方法,使其返回值为某个类或接口的对象。而这个类或接口在方法内部创建
    //使用方式一
    public Comparable getComparable(){
    //1.创建一个实现Comparable接口的类:局部内部类
    class MyComparable implements Comparable{

    @Override
    public int compareTo(java.lang.Object o) {
    return 0;
    }

    }
    //2.返回一个实现类的对象
    return new MyComparable();
    }
    //使用方式二
    public Comparable getComparable1(){
    //返回一个实现Comparable接口的匿名内部类的对象
    return new Comparable(){

    @Override
    public int compareTo(java.lang.Object o) {
    // TODO Auto-generated method stub
    return 0;
    }

    };
    }
    }
    58,//ArrayList:List的主要实现类
    /*
    * List中相对于Collection,新增加的方法
    * void add(int index, Object ele):在指定的索引位置index添加元素ele
    boolean addAll(int index, Collection eles)
    Object get(int index):获取指定索引的元素
    Object remove(int index):删除指定索引位置的元素
    Object set(int index, Object ele):设置指定索引位置的元素为ele
    int indexOf(Object obj):返回obj在集合中首次出现的位置。没有的话,返回-1
    int lastIndexOf(Object obj):返回obj在集合中最后一次出现的位置.没有的话,返回-1
    List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex结束的左闭右开一个子list

    List常用的方法:增(add(Object obj)) 删(remove) 改(set(int index,Object obj))
    查(get(int index)) 插(add(int index, Object ele)) 长度(size())
    */
    /*
    * 1.存储对象可以考虑:①数组 ②集合
    * 2.数组存储对象的特点:Student[] stu = new Student[20]; stu[0] = new Student();....
    * >弊端:①一旦创建,其长度不可变。②真实的数组存放的对象的个数是不可知。
    * 3.集合
    * /*
    * Collection接口 :
    * |------List接口:
    * |------ArrayList(主要的实现类)、
    * |------LinkedList(对于频繁的插入、删除操作)、
    * |------Vector(古老的实现类、线程安全的,但效率要低于ArrayList)
    * |------Set接口:存储无序的,不可重复的元素.Set中常用的方法都是Collection下定义的。
    * |------HashSet(主要实现类)
    |------LinkedHashSet
    |------TreeSet
    * Map接口
    * |-----HashMap:Map的主要实现类
    * |-----LinkedHashMap:使用链表维护添加进Map中的顺序。故遍历Map时,是按添加的顺序遍历的。
    * |-----TreeMap:按照添加进Map中的元素的key的指定属性进行排序。要求:key必须是同一个类的对象!
    * 针对key:自然排序 vs 定制排序
    * |-----Hashtable:古老的实现类,线程安全,不建议使用。
    * |----Properties:常用来处理属性文件。键和值都为String类型的
    */
    59,package com.atguigu.exer;
    /*
    * 编写应用程序EcmDef.java,接收命令行的两个参数,要求不能输入负数,计算两数相除。
    对数据类型不一致(NumberFormatException)、缺少命令行参数(ArrayIndexOutOfBoundsException、
    除0(ArithmeticException)及输入负数(EcDef 自定义的异常)进行异常处理。
    提示:

    (1)在主类(EcmDef)中定义异常方法(ecm)完成两数相除功能。
    (2)在main()方法中使用异常处理语句进行异常处理。
    (3)在程序中,自定义对应输入负数的异常类(EcDef)。
    (4)运行时接受参数 java EcmDef 20 10
    //args[0]=“20” args[1]=“10”
    (5)Interger类的static方法parseInt(String s)将s转换成对应的int值。如int a=Interger.parseInt(“314”); //a=314;

    */
    public class EcmDef {
    public static void main(String[] args) {
    try{
    int i = Integer.parseInt(args[0]);//被除数
    int j = Integer.parseInt(args[1]);//除数
    ecm(i,j);
    }catch(NumberFormatException e){
    System.out.println("输入的数据类型不一致");
    }catch(ArrayIndexOutOfBoundsException e){
    System.out.println("缺少命令行参数");
    }catch(ArithmeticException e){
    System.out.println("分母为零了");
    }catch(EcDef e){
    System.out.println(e.getMessage());
    }
    }
    public static void ecm(int i,int j) throws EcDef{
    if(i < 0 || j < 0){
    throw new EcDef("您输入的数值存在负数!");
    }
    System.out.println(i / j);
    }
    }
    //自定义异常类
    class EcDef extends Exception{
    static final long serialVersionUID = -3387524229948L;

    public EcDef(){

    }
    public EcDef(String msg){
    super(msg);
    }
    }
    60,/如何自定义一个异常类
    //1.自定义的异常类继承现有的异常类
    //2.提供一个序列号,提供几个重载的构造器
    public class MyException extends Exception{

    static final long serialVersionUID = -70348975766939L;

    public MyException(){

    }
    public MyException(String msg){
    super(msg);
    }
    }
    61,/*
    * 异常处理的方式二:在方法的声明处,显式的抛出该异常对象的类型
    * 格式:如:public static void method2() throws FileNotFoundException,IOException{}
    * 当在此方法内部出现异常的时候,会抛出一个异常类的对象,抛给方法的调用者。
    * 异常的对象可以逐层向上抛,直至main中。当然在向上抛的过程中,可以再通过try-catch-finally进行处理。
    *
    * java的异常处理:抓抛模型
    * 1.抓:异常的处理,有两种方式(①try-catch-finally② throws + 异常的类型)
    * 2.抛:一旦执行过程中,出现异常,会抛出一个异常类的对象。(自动的抛出 vs 手动的抛出(throw + 异常类的对象))
    * >异常类,既可以是现成的异常类,也可以是自己创建的异常类
    */
    62,/*
    * 定义个泛型类 DAO<T>,在其中定义一个Map 成员变量,Map 的键为 String 类型,值为 T 类型。

    分别创建以下方法:
    public void save(String id,T entity): 保存 T 类型的对象到 Map 成员变量中
    T get(String id):从 map 中获取 id 对应的对象
    void update(String id,T entity):替换 map 中key为id的内容,改为 entity 对象
    List<T> list():返回 map 中存放的所有 T 对象
    void delete(String id):删除指定 id 对象

    */
    63,//自定义的注解
    @Target({TYPE,FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
    @Retention(RetentionPolicy.RUNTIME)
    /*
    * 注解
    * 1.JDK提供的常用的注解
    * @Override: 限定重写父类方法, 该注释只能用于方法
    @Deprecated: 用于表示某个程序元素(类, 方法等)已过时
    @SuppressWarnings: 抑制编译器警告
    2.如何自定义一个注解
    3.元注解

    */
    64,/*
    * 一、枚举类
    * 1.如何自定义枚举类
    * 2.如何使用enum关键字定义枚举类
    * >常用的方法:values() valueOf(String name)
    * >如何让枚举类实现接口:可以让不同的枚举类的对象调用被重写的抽象方法,执行的效果不同。(相当于让每个对象重写抽象方法)
    */
    //枚举类
    enum Season1 implements Info{
    SPRING("spring", "春暖花开"){
    public void show(){
    System.out.println("春天在哪里?");
    }
    },
    SUMMER("summer", "夏日炎炎"){
    public void show(){
    System.out.println("生如夏花");
    }
    },
    AUTUMN("autumn", "秋高气爽"){
    public void show(){
    System.out.println("秋天是用来分手的季节");
    }
    },
    WINTER("winter", "白雪皑皑"){
    public void show(){
    System.out.println("冬天里的一把火");
    }
    };

    private final String seasonName; //1.提供类的属性,声明为private final
    private final String seasonDesc;

    private Season1(String seasonName,String seasonDesc){//2.声明为final的属性,在构造器中初始化。
    this.seasonName = seasonName;
    this.seasonDesc = seasonDesc;
    }
    public String getSeasonName() {//3.通过公共的方法来调用属性
    return seasonName;
    }
    public String getSeasonDesc() {
    return seasonDesc;
    }

    @Override
    public String toString() {
    return "Season [seasonName=" + seasonName + ", seasonDesc="
    + seasonDesc + "]";
    }





    //4.创建枚举类的对象:将类的对象声明public static final
    public static final Season SPRING = new Season("spring", "春暖花开");
    public static final Season SUMMER = new Season("summer", "夏日炎炎");
    public static final Season AUTUMN = new Season("autumn", "秋高气爽");
    public static final Season WINTER = new Season("winter", "白雪皑皑");
    //1.values()
    Season1[] seasons = Season1.values();
    for(int i = 0;i < seasons.length;i++){
    System.out.println(seasons[i]);
    }
    //2.valueOf(String name):要求传入的形参name是枚举类对象的名字。
    //否则,报java.lang.IllegalArgumentException异常
    String str = "WINTER";
    Season1 sea = Season1.valueOf(str);
    System.out.println(sea);
    65,/*
    * java.io.File类
    * 1.凡是与输入、输出相关的类、接口等都定义在java.io包下
    * 2.File是一个类,可以有构造器创建其对象。此对象对应着一个文件(.txt .avi .doc .ppt .mp3 .jpg)或文件目录
    * 3.File类对象是与平台无关的。
    * 4.File中的方法,仅涉及到如何创建、删除、重命名等等。只要涉及文件内容的,File是无能为力的,必须由io流来完成。
    * 5.File类的对象常作为io流的具体类的构造器的形参。
    */
    /*
    * createNewFile()
    delete()
    mkDir():创建一个文件目录。只有在上层文件目录存在的情况下,才能返回true
    mkDirs():创建一个文件目录。若上层文件目录不存在,一并创建
    list()
    listFiles()
    */
    /*
    * exists()
    canWrite()
    canRead()
    isFile()
    isDirectory()
    lastModified()
    length()

    */
    /*
    * 路径:
    * 绝对路径:包括盘符在内的完整的文件路径
    * 相对路径:在当前文件目录下的文件的路径
    *
    * getName()
    getPath()
    getAbsoluteFile()
    getAbsolutePath()
    getParent()
    renameTo(File newName)

    */
    //renameTo(File newName):重命名
    //file1.renameTo(file2):file1重命名为file2.要求:file1文件一定存在,file2一定不存在
    66,/*
    * 使用FileReader、FileWriter 可以实现文本文件的复制。
    * 对于非文本文件(视频文件、音频文件、图片),只能使用字节流!
    */
    //1.输入流对应的文件src一定要存在,否则抛异常。
    //输出流对应的文件dest可以不存在,执行过程中会自动创建
    FileReader fr = null;
    FileWriter fw = null;
    File src = new File("dbcp.txt");
    File dest = new File("dbcp1.txt");
    //2.
    fr = new FileReader(src);
    fw = new FileWriter(dest);
    //3.
    char[] c = new char[24];
    int len;
    while((len = fr.read(c)) != -1){
    fw.write(c, 0, len);
    }
    fr.close();
    67,/*
    * 1.流的分类:
    * 按照数据流向的不同:输入流 输出流
    * 按照处理数据的单位的不同:字节流 字符流(处理的文本文件)
    * 按照角色的不同:节点流(直接作用于文件的) 处理流
    *
    * 2.IO的体系
    * 抽象基类 节点流(文件流) 缓冲流(处理流的一种)
    * InputStream FileInputStream BufferedInputStream
    * OutputStream FileOutputStream BufferedOutputStream
    * Reader FileReader BufferedReader
    * Writer FileWriter BufferedWriter
    */
    // 1.提供读入、写出的文件
    File file1 = new File("C:\Users\shkstart\Desktop\1.jpg");
    File file2 = new File("C:\Users\shkstart\Desktop\2.jpg");
    // 2.提供相应的流
    FileInputStream fis = null;
    FileOutputStream fos = null;
    try {
    fis = new FileInputStream(file1);
    fos = new FileOutputStream(file2);
    // 3.实现文件的复制
    byte[] b = new byte[20];
    int len;
    while ((len = fis.read(b)) != -1) {
    // fos.write(b);//错误的写法两种: fos.write(b,0,b.length);
    fos.write(b, 0, len);
    }
    67,//使用缓冲流实现文件的复制的方法
    public void copyFile(String src,String dest){
    BufferedInputStream bis = null;
    BufferedOutputStream bos = null;
    try {
    //1.提供读入、写出的文件
    File file1 = new File(src);
    File file2 = new File(dest);
    //2.想创建相应的节点流:FileInputStream、FileOutputStream
    FileInputStream fis = new FileInputStream(file1);
    FileOutputStream fos = new FileOutputStream(file2);
    //3.将创建的节点流的对象作为形参传递给缓冲流的构造器中
    bis = new BufferedInputStream(fis);
    bos = new BufferedOutputStream(fos);
    //4.具体的实现文件复制的操作
    byte[] b = new byte[1024];
    int len;
    while((len = bis.read(b)) != -1){
    bos.write(b, 0, len);
    bos.flush();
    }
    }catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }finally{
    //5.关闭相应的流
    if(bos != null){
    try {
    bos.close();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }
    if(bis != null){
    try {
    bis.close();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }

    }
    }


    //使用BufferedInputStream和BufferedOutputStream实现非文本文件的复制
    @Test
    public void testBufferedInputOutputStream(){
    BufferedInputStream bis = null;
    BufferedOutputStream bos = null;
    try {
    //1.提供读入、写出的文件
    File file1 = new File("1.jpg");
    File file2 = new File("2.jpg");
    //2.想创建相应的节点流:FileInputStream、FileOutputStream
    FileInputStream fis = new FileInputStream(file1);
    FileOutputStream fos = new FileOutputStream(file2);
    //3.将创建的节点流的对象作为形参传递给缓冲流的构造器中
    bis = new BufferedInputStream(fis);
    bos = new BufferedOutputStream(fos);
    //4.具体的实现文件复制的操作
    byte[] b = new byte[1024];
    int len;
    while((len = bis.read(b)) != -1){
    bos.write(b, 0, len);
    bos.flush();
    }
    }catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }finally{
    //5.关闭相应的流
    if(bos != null){
    try {
    bos.close();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }
    if(bis != null){
    try {
    bis.close();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }

    }
    }

    }
    68,/*
    * 标准的输入输出流:
    * 标准的输出流:System.out
    * 标准的输入流:System.in
    *
    * 题目:
    * 从键盘输入字符串,要求将读取到的整行字符串转成大写输出。然后继续进行输入操作,
    * 直至当输入“e”或者“exit”时,退出程序。

    */
    /*
    * 如何实现字节流与字符流之间的转换:
    * 转换流:InputStreamReader OutputStreamWriter
    * 编码:字符串 --->字节数组
    * 解码:字节数组--->字符串
    */
    //解码
    File file = new File("dbcp.txt");
    FileInputStream fis = new FileInputStream(file);
    InputStreamReader isr = new InputStreamReader(fis, "GBK");
    br = new BufferedReader(isr);
    //编码
    File file1 = new File("dbcp4.txt");
    FileOutputStream fos = new FileOutputStream(file1);
    OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");
    bw = new BufferedWriter(osw);
    String str;
    while((str = br.readLine()) != null){
    bw.write(str);
    bw.newLine();
    bw.flush();
    }
    69,
    /*
    * RandomAccessFile:支持随机访问
    * 1.既可以充当一个输入流,有可以充当一个输出流
    * 2.支持从文件的开头读取、写入
    * 3.支持从任意位置的读取、写入(插入)
    */
    public void test4(){
    RandomAccessFile raf = null;
    try {
    raf = new RandomAccessFile(new File("hello1.txt"),"rw");

    raf.seek(4);
    byte[] b = new byte[10];
    int len;
    StringBuffer sb = new StringBuffer();
    while((len = raf.read(b)) != -1){
    sb.append(new String(b,0,len));
    }
    raf.seek(4);
    raf.write("xy".getBytes());
    raf.write(sb.toString().getBytes());
    }catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }finally{
    if(raf != null){
    try {
    raf.close();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }}}
    70,/*
    * Thread的常用方法:
    * 1.start():启动线程并执行相应的run()方法
    * 2.run():子线程要执行的代码放入run()方法中
    * 3.currentThread():静态的,调取当前的线程
    * 4.getName():获取此线程的名字
    * 5.setName():设置此线程的名字
    * 6.yield():调用此方法的线程释放当前CPU的执行权
    * 7.join():在A线程中调用B线程的join()方法,表示:当执行到此方法,A线程停止执行,直至B线程执行完毕,
    * A线程再接着join()之后的代码执行
    * 8.isAlive():判断当前线程是否还存活
    * 9.sleep(long l):显式的让当前线程睡眠l毫秒
    * 10.线程通信:wait() notify() notifyAll()
    *
    * 设置线程的优先级
    * getPriority() :返回线程优先值
    setPriority(int newPriority) :改变线程的优先级

    */
    /*
    * 创建一个子线程,完成1-100之间自然数的输出。同样地,主线程执行同样的操作
    * 创建多线程的第一种方式:继承java.lang.Thread类
    */
    //1.创建一个继承于Thread的子类
    class SubThread extends Thread{
    //2.重写Thread类的run()方法.方法内实现此子线程要完成的功能
    public void run(){
    for(int i = 1;i <= 100;i++){
    System.out.println(Thread.currentThread().getName() +":" + i);
    }
    }
    }

    public class TestThread {
    public static void main(String[] args) {
    //3.创建子类的对象
    SubThread st1 = new SubThread();
    SubThread st2 = new SubThread();

    //4.调用线程的start():启动此线程;调用相应的run()方法
    //一个线程只能够执行一次start()
    //不能通过Thread实现类对象的run()去启动一个线程
    st1.start();

    //st.start();
    //st.run();
    st2.start();

    for(int i = 1;i <= 100;i++){
    System.out.println(Thread.currentThread().getName() +":" + i);
    }
    }
    }
    71,class PrintNum extends Thread{
    public void run(){
    //子线程执行的代码
    for(int i = 1;i <= 100;i++){
    if(i % 2 == 0){
    System.out.println(Thread.currentThread().getName() + ":" + i);
    }
    }
    }
    public PrintNum(String name){
    super(name);
    }
    }
    /*
    * 创建多线程的方式二:通过实现的方式
    *
    * 对比一下继承的方式 vs 实现的方式
    * 1.联系:public class Thread implements Runnable
    * 2.哪个方式好?实现的方式优于继承的方式
    * why? ① 避免了java单继承的局限性
    * ② 如果多个线程要操作同一份资源(或数据),更适合使用实现的方式
    */
    72,//线程通信。如下的三个关键字使用的话,都得在同步代码块或同步方法中。
    //wait():一旦一个线程执行到wait(),就释放当前的锁。
    //notify()/notifyAll():唤醒wait的一个或所有的线程
    //使用两个线程打印 1-100. 线程1, 线程2 交替打印
    //死锁的问题:处理线程同步时容易出现。
    //不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁
    //写代码时,要避免死锁!
    //关于懒汉式的线程安全问题:使用同步机制
    //对于一般的方法内,使用同步代码块,可以考虑使用this。
    //对于静态方法而言,使用当前类本身充当锁。
    73,常用类
    /*
    * 与时间相关的类:
    * 1.System 类下的currentTimeMillis();
    * 2.Date类:java.util.Date
    * 如何创建其实例;其下的方法:toString()、getTime()
    * (以及其子类java.sql.Date)
    * 3.SimpleDateFormat类
    * 4.Calendar类
    */
    /*
    * 1.字符串 与基本数据类型、包装类之间转换
    * ①字符串 --->基本数据类型、包装类:调用相应的包装类的parseXxx(String str);
    * ①基本数据类型、包装类--->字符串:调用字符串的重载的valueOf()方法
    *
    * 2.字符串与字节数组间的转换
    * ①字符串---->字节数组:调用字符串的getBytes()
    * ②字节数组---->字符串:调用字符串的构造器
    *
    * 3.字符串与字符数组间的转换
    * ①字符串---->字符数组:调用字符串的toCharArray();
    * ②字符数组---->字符串:调用字符串的构造器
    */
    /*
    * java.lang.StringBuffer:可变的字符序列
    * java.lang.StringBuilder:可变的字符序列,是jdk5.0新加入的,线程不安全,效率要高于StringBuffer.

    * 对比String,StringBuffer,StringBuilder三者在添加上的效率:
    * 效率从高到底: StringBuilde > StringBuffer > String
    */
    public class TestBigDecimal {
    @Test
    public void testBigInteger() {
    BigInteger bi = new BigInteger("12433241123");
    BigDecimal bd = new BigDecimal("12435.351");
    BigDecimal bd2 = new BigDecimal("11");
    System.out.println(bi);
    // System.out.println(bd.divide(bd2));
    System.out.println(bd.divide(bd2, BigDecimal.ROUND_HALF_UP));
    System.out.println(bd.divide(bd2, 15, BigDecimal.ROUND_HALF_UP));
    }

    }
    74,package com.atguigu.exer;

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;

    /*
    * 1.模拟一个trim方法,去除字符串两端的空格。

    2.将一个字符串进行反转。将字符串中指定部分进行反转。比如将“abcdefg”反转为”abfedcg”

    3.获取一个字符串在另一个字符串中出现的次数。
    比如:获取“ab”在 “abkkcadkabkebfkabkskab”
    中出现的次数

    4.获取两个字符串中最大相同子串。比如:
    str1 = "abcwerthelloyuiodef";str2 = "cvhellobnm"

    5.对字符串中字符进行自然顺序排序。

    练习:I am a student! 写一个方法:实现输出 !student a am I

    */
    public class StringDemo {
    public static void main(String[] args) {
    String str = " abc de ";
    //str = " ";
    String str1 = myTrim(str);
    System.out.println(str1);

    String str2 = "abcdefg";
    String str3 = reverseString(str2,2,5);
    String str4 = reverseString1(str2,2,5);
    System.out.println(str3);//abfedcg
    System.out.println(str4);

    int i = getTime("abkkcadkabkebfkabkskab","abk");
    System.out.println(i);

    List<String> strs5 = getMaxSubString("abcwerthelloyuiodef","abcwecvhellobnm");
    System.out.println(strs5);

    String str6 = "aediewfn";
    String str7 = sort(str6);
    System.out.println(str7);
    }

    //5.对字符串中字符进行自然顺序排序。
    public static String sort(String str){
    char[] c = str.toCharArray();
    Arrays.sort(c);
    return new String(c);
    }

    //4.获取两个字符串中最大相同子串。
    public static List<String> getMaxSubString(String str1,String str2){
    String maxStr = (str1.length() > str2.length())? str1 : str2;
    String minStr = (str1.length() < str2.length())? str1 : str2;
    int len = minStr.length();
    List<String> list = new ArrayList<>();
    for(int i = 0;i < len;i++){
    for(int x = 0,y = len - i;y <= len;x++,y++){
    String str = minStr.substring(x, y);
    if(maxStr.contains(str)){
    list.add(str);
    }
    }
    if(list.size() != 0){
    return list;
    }
    }
    return null;
    }

    //3.获取一个字符串在另一个字符串中出现的次数。判断str2在str1中出现的次数
    public static int getTime(String str1,String str2){
    int count = 0;
    int len;
    while((len = str1.indexOf(str2)) != -1){
    count++;
    str1 = str1.substring(len + str2.length());
    }

    return count;
    }


    //将一个字符串进行反转。将字符串中指定部分进行反转。(法二) 在考虑使用StringBuffer将此算法优化!
    public static String reverseString1(String str,int start,int end){
    String str1 = str.substring(0, start);
    for(int i = end;i >= start;i--){
    char c = str.charAt(i);
    str1 += c;
    }

    str1 += str.substring(end + 1);
    return str1;
    }


    //2.将一个字符串进行反转。将字符串中指定部分进行反转。比如将“abcdefg”反转为”abfedcg”
    public static String reverseString(String str,int start,int end){
    char[] c = str.toCharArray();//字符串--->字符数组
    return reverseArray(c,start,end);

    }
    public static String reverseArray(char[] c,int start,int end){
    for(int i = start,j = end;i < j;i++,j--){
    char temp = c[i];
    c[i] = c[j];
    c[j] = temp;
    }
    //字符数组--->字符串
    return new String(c);
    }


    //1.模拟一个trim方法,去除字符串两端的空格。
    public static String myTrim(String str){
    int start = 0;
    int end = str.length() - 1;
    while(start < end && str.charAt(start) == ' '){
    start++;
    }
    while(start < end && str.charAt(end) == ' '){
    end--;
    }

    return str.substring(start, end + 1);
    }
    }
    75,反射机制
    //调用指定的方法
    @Test
    public void test4() throws Exception{
    Class clazz = Class.forName("com.atguigu.review.Animal");
    Object obj = clazz.newInstance();
    Animal a = (Animal)obj;

    //调用非public的方法
    Method m1 = clazz.getDeclaredMethod("getAge");
    m1.setAccessible(true);
    int age = (Integer)m1.invoke(a);
    System.out.println(age);
    //调用public的方法
    Method m2 = clazz.getMethod("show", String.class);
    Object returnVal = m2.invoke(a,"金毛");
    System.out.println(returnVal);
    //调用static的方法
    Method m3 = clazz.getDeclaredMethod("info");
    m3.setAccessible(true);
    // m3.invoke(Animal.class);
    m3.invoke(null);

    }

    //调用指定属性
    @Test
    public void test3() throws Exception{
    Class clazz = Class.forName("com.atguigu.review.Animal");
    Object obj = clazz.newInstance();
    Animal a = (Animal)obj;
    //调用非public的属性
    Field f1 = clazz.getDeclaredField("name");
    f1.setAccessible(true);
    f1.set(a, "Jerry");
    //调用public的属性
    Field f2 = clazz.getField("age");
    f2.set(a, 9);
    System.out.println(f2.get(a));
    System.out.println(a);
    //调用static的属性
    Field f3 = clazz.getDeclaredField("desc");
    System.out.println(f3.get(null));
    }

    //调用指定的构造器创建运行时类的对象
    @Test
    public void test2() throws Exception{
    Class clazz = Animal.class;
    Constructor cons = clazz.getDeclaredConstructor(String.class,int.class);
    cons.setAccessible(true);
    Animal a = (Animal)cons.newInstance("Tom",10);
    System.out.println(a);
    }

    //获取运行时类的对象:方法一
    @Test
    public void test1() throws Exception{
    Class clazz = Class.forName("com.atguigu.review.Animal");
    Object obj = clazz.newInstance();
    Animal a = (Animal)obj;
    System.out.println(a);
    }
    76,网络编程
    /*
    * 网络通信的第一个要素:IP地址。通过IP地址,唯一的定位互联网上一台主机
    * InetAddress:位于java.net包下
    * 1.InetAddress用来代表IP地址。一个InetAdress的对象就代表着一个IP地址
    * 2.如何创建InetAddress的对象:getByName(String host)
    * 3.getHostName(): 获取IP地址对应的域名
    * getHostAddress():获取IP地址
    */
    public class TestInetAddress {
    public static void main(String[] args) throws Exception {
    //创建一个InetAddress对象:getByName()
    InetAddress inet = InetAddress.getByName("www.atguigu.com");
    //inet = InetAddress.getByName("42.121.6.2");
    System.out.println(inet);
    //两个方法
    System.out.println(inet.getHostName());
    System.out.println(inet.getHostAddress());
    //获取本机的IP:getLocalHost()
    InetAddress inet1 = InetAddress.getLocalHost();
    System.out.println(inet1);
    System.out.println(inet1.getHostName());
    System.out.println(inet1.getHostAddress());
    }
    }


    //TCP

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.InetAddress;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.util.Scanner;

    import org.junit.Test;
    //客户端给服务端发送文本,服务端会将文本转成大写在返回给客户端。
    //如下程序为了保证相应的流及socket的关闭(即使在关闭之前出现异常,也一定要保证相应的资源的关闭),要求是用
    //try-catch-finally进行操作。要求将关闭的信息写在finally里!

    public void client() {
    // 1.
    Socket socket = null;
    // 2.
    OutputStream os = null;
    Scanner scanner = null;
    // 4.接收来自于服务端的数据
    InputStream is = null;
    try {
    socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
    os = socket.getOutputStream();
    // 3.向服务端发送数据
    // os.write("abc".getBytes());
    System.out.println("请输入多个字符:");
    scanner = new Scanner(System.in);
    String str = scanner.next();
    os.write(str.getBytes());
    socket.shutdownOutput();
    is = socket.getInputStream();
    byte[] b = new byte[10];
    int len;
    while ((len = is.read(b)) != -1) {
    String str1 = new String(b, 0, len);
    System.out.print(str1);
    }
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } finally {
    // 5.
    if(is != null){
    try {
    is.close();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }
    if(scanner != null){
    scanner.close();

    }
    if(os != null){
    try {
    os.close();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }
    if(socket != null){
    try {
    socket.close();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }
    }

    }

    @Test
    public void server() {
    // 1.
    ServerSocket ss = null;
    // 2.
    Socket s = null;
    // 3.接收来自于客户端的信息
    InputStream is = null;
    // 4.返回给客户端
    OutputStream os = null;
    try {
    ss = new ServerSocket(9090);
    s = ss.accept();
    is = s.getInputStream();
    byte[] b = new byte[10];
    int len;
    String str = new String();
    while ((len = is.read(b)) != -1) {
    String str1 = new String(b, 0, len);
    str += str1;
    }
    String strUpperCase = str.toUpperCase();
    os = s.getOutputStream();
    os.write(strUpperCase.getBytes());
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }finally{
    if(os != null){
    try {
    os.close();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }
    if(is != null){
    try {
    is.close();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }
    if(s != null){
    try {
    s.close();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }
    if(ss != null){
    try {
    ss.close();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }
    }
    // 5.
    }
    }

    //UDP编程的实现
    public class TestUDP {

    // 发送端
    @Test
    public void send() {
    DatagramSocket ds = null;
    try {
    ds = new DatagramSocket();
    byte[] b = "你好,我是要发送的数据".getBytes();
    //创建一个数据报:每一个数据报不能大于64k,都记录着数据信息,发送端的IP、端口号,以及要发送到
    //的接收端的IP、端口号。
    DatagramPacket pack = new DatagramPacket(b, 0, b.length,
    InetAddress.getByName("127.0.0.1"), 9090);

    ds.send(pack);
    }catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }finally{
    if(ds != null){
    ds.close();

    }
    }

    }

    // 接收端
    @Test
    public void rceive() {
    DatagramSocket ds = null;
    try {
    ds = new DatagramSocket(9090);
    byte[] b = new byte[1024];
    DatagramPacket pack = new DatagramPacket(b, 0, b.length);
    ds.receive(pack);

    String str = new String(pack.getData(), 0, pack.getLength());
    System.out.println(str);
    }catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }finally{
    if(ds != null){
    ds.close();

    }
    }




    }
    }

    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.net.URL;
    import java.net.URLConnection;

    //URL:统一资源定位符,一个URL的对象,对应着互联网上一个资源。
    //我们可以通过URL的对象调用其相应的方法,将此资源读取(“下载”)
    public class TestURL {
    public static void main(String[] args) throws Exception {
    //1.创建一个URL的对象
    URL url = new URL("http://127.0.0.1:8080/examples/HelloWorld.txt?a=b");//File file = new File("文件的路径");
    /*
    * public String getProtocol( ) 获取该URL的协议名
    public String getHost( ) 获取该URL的主机名
    public String getPort( ) 获取该URL的端口号
    public String getPath( ) 获取该URL的文件路径
    public String getFile( ) 获取该URL的文件名
    public String getRef( ) 获取该URL在文件中的相对位置
    public String getQuery( ) 获取该URL的查询名
    */
    // System.out.println(url.getProtocol());
    // System.out.println(url.getHost());
    // System.out.println(url.getPort());
    // System.out.println(url.getFile());
    // System.out.println(url.getRef());
    // System.out.println(url.getQuery());
    //如何将服务端的资源读取进来:openStream()
    InputStream is = url.openStream();
    byte[] b = new byte[20];
    int len;
    while((len = is.read(b)) != -1){
    String str = new String(b,0,len);
    System.out.print(str);
    }
    is.close();
    //如果既有数据的输入,又有数据的输出,则考虑使用URLConnection
    URLConnection urlConn = url.openConnection();
    InputStream is1 = urlConn.getInputStream();
    FileOutputStream fos = new FileOutputStream(new File("abc.txt"));
    byte[] b1 = new byte[20];
    int len1;
    while((len1 = is1.read(b1)) != -1){
    fos.write(b1, 0, len1);
    }
    fos.close();
    is1.close();
    }
    }

    77,
    String为引用类型,如果对象为null,也就是说这个对象都不存在了,
    再去调用对象的相关方法,肯定会报空指针异常。这里调用了String类的length()方法
    &&和||具有短路的效果,在进行&&时,如果&&前的是false,
    那么&&后的不再执行,直接返回false,同理||也一样。





  • 相关阅读:
    [转]JavaScript和html5 canvas生成圆形印章
    [转]微信小程序开发:http请求
    [转]Clean up after Visual Studio
    [转]How to Clean the Global Assembly Cache
    [转].NET Core dotnet 命令大全
    [转].NET 4.5+项目迁移.NET Core的问题记录 HTTP Error 502.5
    [转]How do I run msbuild from the command line using Windows SDK 7.1?
    [转]glyphicons-halflings-regular字体 图标
    [转]程序集之GAC---Global Assembly Cache
    [转]How can I install the VS2017 version of msbuild on a build server without installing the IDE?
  • 原文地址:https://www.cnblogs.com/nku-wangfeng/p/7636675.html
Copyright © 2020-2023  润新知