JAVA基础知识总结

2018-06-23  本文已影响0人  鹅鹅鹅曲项向天歌呀

JAVA概述

一、java之父

詹姆斯·高斯林

二、java体系

1、javaSE,标准版,各应用平台的基础,桌面开发和低端商务应用的解决方案。

2、javaEE,企业版,以企业为环境而开发应用程序的解决方案。

3、javaME,微型版,致力于消费产品和嵌入式设备的最佳方案。

三、java可以做什么

1、开发桌面应用程序。

2、开发面向Internet的web应用程序。

3、提供各行业的解决方案。

4、开发android手机应用程序。

四、java的特性

1、一种面向对象的编程语言。

2、一种与平台无关的语言(根据JVM实现的)。

3、一种健壮性语言。

4、具有较高的安全性。

五、java应用程序的运行机制

先编译(.class),在解释运行。

六、java程序开发的三个步骤

1、编写源程序,java源代码文件。

2、编译源程序,编译器编译编译成java字节码文件。

3、运行,java虚拟机(JVM)。

七、垃圾回收器(GC)

在java运行过程中自动启动,程序员无法干预。

八、JDK和JRE

JDK:java开发工具包

    先编译(编译器javec),后运行(解释器java)

JRE:java运行环境

    加载代码(加载器),校验代码(校验器),执行代码(解释器)

九、java虚拟机

  java虚拟机实际上只是一层接口,一层Java程序和操作系统通讯的接口。java文件编译生成class文件,

而java虚拟机就是这些class文件能够在上面运行的一个平台,你把class文件看成一个软件,java虚拟机就是这个软件可以运行的操作系统。

十、开发java应用的要点

1、一个源文件中只能有一个public修饰的类,其他类个数不限。

2、一个源文件有n个类时,编译结果的class文件就有n个。

3、源文件的名字必须和public修饰的类名相同

4、java语言中单词拼写大小写严格区分。

5、main方法入口

6、每一句以分号(;)结束

十一、注释

1、单行注释//

2、多行注释/* */

3、java文档注释/**  */

Java编程基础

一、标识符

1、命名规则:由字母、下划线、数字和美元符号组成,不能以数字开头,区分大小写,不能是关键字和保留字(goto、const),长度一般不超过15个字符。

2、驼峰式命名:

    类名:单个单词,首字母大写,多个单词,首字母都大写。

    方法名、参数名、变量名:单个单词,首字母小写,多个单词,第一单词首字母小写,其他单词首字母大写。

    包名:全部小写。

二、java数据类型划分

1、基本数据类型:

    数值型:byte     1字节   8位   -128~127

        short    2字节   16位  -32768~32767

        int      4字节   32位  -2^31~2^31-1

        long     8字节   64位  2^63~2^63-1

    浮点类型:

        float    4字节   32位  

        double   8字节   64位

    字符型:char     2字节   16位   0~65535

    布尔型:boolean  true    false

2、引用类型:

    字符串 String、 类 class 、枚举 enum、接口interface

三、普及二进制

1、计算机中的数据都以二进制数据保存。

2、计算机信息的存储单位:

    位(bit):是计算机存储处理信息的最基本的单位

    字节(byte):一个字节有8个位组成。

四、转义字符

\n 换行  \r 回车  \t 水平制表  ' 单引号  " 双引号  \斜杠

五、基本数据类型之间的转换

1、自动类型转换:范围小→范围大

    byte→short→int→long→float→double;

    char→int→long→float→double          

2、强制类型转换:范围大→范围小

    需要加强制转换符

六、变量

1、数据类型划分:

    基本类型变量:数据的值

    引用类型变量:数据的地址

2、声明的位置划分:

    局部变量

    全局变量

        区别:

        1、默认值

            局部没有默认值,使用前必须初始化。

            全局有默认值,默认为0,不必须初始化。

        2、声明位置

            局部在方法内。

            全局在方法外类内。

        3、作用位置

            局部只能在自己声明的方法里。

            全局在整个类中

七、java中的运算符

算术运算符:+ 、 - 、 * 、 / 、 % 、 ++ 、 --

赋值运算符:= 、 += 、 -= 、 *= 、 /= 、 %=

关系运算符:> 、 < 、 >= 、 <= 、 == 、 !=

逻辑运算符:! 、 & (只要有一个false  最终结果就是false) 、

         | (但凡有一个true   最终结果就是true) 、

         ^ (如果两边一样     最终结果为false   如果两边不同   最终结果为true)、

         &&(如果第一个是false 那第二个不执行  最终结果是false)、

         ||(如果第一个表达式的结果是true 那第二个表达式 就不去计算了 ,最终结果是true)

位运算符: ~ 、 >> 、 << 、 >>>

字符串连接运算符:+

三目运算符:X ? Y : Z

            X为boolean类型表达式,先计算x的值,若为true,整个三目运算的结果为表达式Y的值,否则整个运算结果为表达式Z的值。

八、程序流程控制

结构化程序的三种结构:

    顺序、选择(分支)、循环

九、if语句

1、if(){}

2、if(){}else{}

3、if(){}else if(){}

4、if(){if(){}else()}    

5、if()执行语句 esle   执行语句 注意:执行语句只有一条语句的时候.可以将if esle 的大括号省略

注意:()内是boolean类型表达式,{}是语句块

    比较字符串用equals,比较内容。比较数值用==,比较地址。

    基本数据类型:变量名、变量值在栈中。

    引用数据类型:变量名在栈中,变量值在常量池中。

十、switch语句

switch(表达式expr){

    case const1:

        statement1;

        break;

    … …

    case constN:

        statementN;

        break;

    [default:

        statement_dafault;

        break;]

}

注意:1、表达式必须是int、byte、char、short、enmu、String类型

      2、constN必须是常量或者finall变量,不能是范围

      3、所有的case语句的值不能相同,否则编译会报错

      4、default可要可不要

      5、break用来执行完一个分支后使程序跳出switch语句块,否则会一直会执行下去。

十一、if和switch的区别

1、if可以判断范围,也可以判断一个值

    switch只能判断指定的值

2、若只判断指定的值,则使用switch语句,效率快

   if判断范围,对数据判断灵活,自身的格式也比较灵活

十二、for循环

for ([循环变量初始值设定]; [循环条件判断]; [改变循环变量的值]){

        循环体

}

注意:1、表达式2一般不可以省略,否则死循环

      2、表达式3可以省略,但是在循环体中必须有语句修改变量,以使表达式2在某一时刻为false结束循环。

      3、若同时省略表达式1,表表达式3,则相当于while(表达式2)语句

      4、三个表达式均省略 即for(;;)语句,此时相当于while(true)语句

      5、表达式1、表达式3可以是逗号表达式,以使循环变量值在修改时可以对其它变量赋值

十三、while

while( 条件表达式语句){

     循环体语句;

     }

  [初始条件]


  do{

    循环体;

[迭代]

}while( 循环条件判断); 

  注意:1、当第一次执行时,若表达式=false时,则while语句不执行,而do/while语句执行一次后面的语句
  2、一定要切记在switch循环中,如果没有break跳出语句,每一个case都要执行一遍,在计算最终结果。

十四、break和continue

break跳出某个循环

continue跳过某个循环

注意:if外有循环可以用break、continue,单纯if不可以用。

十五、方法

1、为什么使用方法?

    减少重复代码,提供代码复用性

    使用方法将功能提炼出来

    写在类内

2、声明格式

    [修饰符] 返回值类型 方法名([形式参数列表]){

              程序代码;

              [return 返回值;]

            }

   注意:1、方法是给外界提供内容的位置,形式参数是外界提供的

     2、方法调用的时候写的是实际参数

     3、实际参数的类型、顺序和形参要对应上

     4、支持自动转换类型,不支持强制类型转换

十六、return

1、将数据返回给调用者,除了void外,return后必须跟着返回值,只能返回一个。

2、终止方法的执行,返回数据类型必须是void,return后不能添加数据。

注意:1、当return结束方法的时候,要让其后面的代码有可能被执行到。

      2、一个方法里可以有多个return,在void里不能有返回值,其他的必须有返回值。        

十七、重载overload

1、在一个类中,方法名字相同,参数类型不同。

   参数类型不同:个数、数据类型、顺序。

注意:

    1、重载和返回值类型,修饰符没有任何关系。

    2、参数变量名修改也不能够重载

十九、递归

1、有返回值

2、有参数

3、能够有跳出循环的控制语句

4、自己调用自己

面向对象编程

一、面向对象和面向过程

1、面向对象:是以具体的事物为单位,考虑的是它的特征(属性)和行为(方法)。

2、面向过程:是以具体的流程为单位,考虑功能的实现。

二、类和对象

1、对象:看得见摸得着的具体事物。

     类:抽象化的概念

2、类和对象的关系:

     类是对象的模板/抽象化的概念,对象是类的实例。

3、创建类和对象

     类:

    特征:全局变量/属性/成员变量

    动作:方法

    对象:

    类名 对象名=new 类名()

    注意:一个类可以创建多个对象,,每个对象之间没有关系。

三、内存图

1、栈:先进后出,存放基本数据类型变量名和变量值,引用数据类型的变量名,方法执行的时候进入栈中。

2、堆:先进先出,new出来的对象的实例,包括类的属性个方法。

四、构造方法

1、构造方法是new关键字调用的,用来帮助构建对象

2、显示构造对象

3、隐示构造对象(没有显示的情况下存在)

4、构造对象可以重载,参数类型不一致。

五、关键字

1、static调用格式:

    1、同一个类中:

        静态的:

            方法名     属性名

            类名.方法名  类名.属性名

            对象名.方法名 对象名.属性名

        非静态的:

            对象名.属性名 对象名.方法名

    2、不同类中:

        静态的:

            对象名.方法名 对象名.属性名

            类名.方法名  类名.属性名

        非静态的:

            对象名.属性名 类名.方法名

    注意:1、static可以修饰属性、方法、代码块,不可以修饰类和构造方法。

          2、静态方法随着类的加载而加载。

          3、在静态方法区内的东西只有一份,所有的对象共享这一份空间,只要有一个对象对属性进行修改,所有的对象调用都是修改后的数据。

          4、代码块的执行顺序:静态代码块(只被调用一次)>构造代码块{}>构造方法>普通方法(需调用)

2、this关键字

    1、可以调用属性和方法。

        this.属性名(全局变量)

        this.方法名();

    2、在构造方法中:

        1、this();括号内的参数个数、顺序、类型根据调用的方法来决定。

        2、必须放在第一行,只能调用一次。

        3、调用构造方法时只能在构造方法中调用,调用属性和方法时可以在构造方法中可以在普通方法中。

        4、当全局变量和局部变量有重名字的时候,用this来区分。

3、super关键字

    1、super指代父类对象。

    2、super可以调用属性、方法、构造方法。

    3、super调用父类的构造方法。

    4、super调用构造方法时候必须放在第一行。

4、final最终的

    1、可以修饰全局变量,声明的时候必须赋值,只能赋值一次。

    2、可以修饰局部变量,声明时候可以不赋值,但也只能赋值一次。

    3、可以修饰方法,可以正常使用,不能被重写。

    4、可以修饰类,可以正常使用,不能被继承。

    5、用final修饰的属性通常叫常量。

    6、static final 全局变量。每个字母都要大写。

5、this和super的区别

    1、this指的是本类创建的对象。                           super指代的是父类的对象

    2、this可以调用属性、方法、构造方法。                   super也可以调用属性、方法、构造方法。

    3、this调用属性和方法的时候,调用自己本类的属性和方法。 如果本类没有,那就用super去父类中找

    4、this调用构造方法调用,调用本类的其他构造方法。       super调用父类的构造方法。

    5、this和super在调用构造方法的时候必须放在第一行。

    6、this和super不能同时存在

6、最小作用域最强原则:

    局域变量在此方法中,比全局变量在此方法中的作用强。

六、面向对象的三大特征
1、封装

        作用:提高代码的安全性

        1、将属性私有化,并提供对外界的接口(get/set方法)。

        2、用private修饰的属性和方法,只能在本类中使用。

2、继承

   作用:提高代码的复用性,减少重复代码

    1、子类可以继承父类非私有的属性和方法,不能继承构造方法和私有的属性和方法。

    2、可以综合子类的共同特征来去提炼父亲的类。

    3、子类在继承父类的各种属性和方法时,也可以有自己的属性和方法。

    4、一个子类只能有一个父类,java只能单继承,不能多继承,因为多个类中的方法名相同,方法体不同,不知使用哪个。

    5、一个类继承最顶端叫做基类或者超类,所有的超类叫做object 。

    6、在继承关系中,如果父类没有无参数的构造方法,如何解决?

           1>子类中添加一个和父类构造方法参数列表相同的构造方法,通过super参数传递给父类的构造方法

           2>如果父类允许修改的时候,可以在父类中创建一个无参的构造方法

    7、在继承关系中,代码块的执行顺序:父静>子静>父构造代码块>父构造方法>子构造代码块>子构造方法

3、多态

    1、分类

        编译时多态:在编译过程中察觉的多态,重载,向上转型。

        运行时多态:在运行过程中察觉的多态,向下转型。

    2、向上转型、向下转型是在继承关系中,向下转型必须在向上转型的基之上。

    3、在继承关系中,父类的对象可以指向子类的实例,父类引用实体方法的时候,是调用子类重写以后的方法。

    4、向上转型

        父类的引用指向子类的实体

        父类类名 对象名=new 子类类();

        优点:减少重复代码,提高代码的复用性

        缺点:父类的引用无法调用子类特有的属性和方法

        解决方案:向下转型

    5、向下转型:

        子类对象的父类引用赋给子类

        子类类名 对象名=(子类类名)父类对象;

    6、 instanceof 判断左边的对象是否属于右边的类  对象名 instanceof 类名(子类类名)

    7、匿名对象

        new 类名()  只有堆空间,没有栈空间,只能属于一次,为了节省代码。

七、抽象abstract

作用:节省代码,提高代码的复用性

1、抽象类格式:访问权限修饰符   abstract class 类名{}

2、抽象方法格式:访问权限修饰符  abstract 返回值类型  方法名(形式参数列表);

注意:

    1、如果一个类里有抽象方法,那么这个类必须声明成抽象类。

    2、一个类里面可以没有抽象方法,可以有非抽象方法,

    3、类继承抽象类:

        把子类也用abstract修饰,变成抽象类。

        子类重写父类的抽象的方法

    4、抽象类不能创建对象。

    5、抽象类可以有构造方法,在创建子类的时候,super隐式调用父类的构造方法,将父类的属性和方法放到子类的对象空间里。

    6、在继承你关系中,子类能够继承抽象类的各种属性和方法,除了私有的和构造方法。

    7、只有公开的才可以和abstract连用,static final private 都不可以。

        static属于类方法,不允许覆盖,abstract必须被覆盖。final不能被重写。

八、接口interface

作用:规范了代码,提高代码的拓展性

1、格式:访问权限修饰符  interface 接口名称{}

2、实现类的格式:访问权限修饰符  class 实现类名  implements 接口名{必须重写接口中的所有的抽象方法}

3、接口中只有全局常量和抽象方法。

4、书写的时候可以省略部分修饰符,系统会默认给添上。

5、接口在实现的同时去继承,extends在implement前面。

6、接口可以多实现,实现的也必须是接口,方法名可以重复,实现类实现一个就行了,因为没有方法体,不会发生冲突。

九、抽象和接口的区别

1、关键字:抽象类 abstract      接口interface

2、抽象类继承 extends         接口实现 implements

3、子类继承抽象类和          实现类实现接口的格式不同

4、接口中只有全局变量和抽象方法        抽象类中有各种属性和方法

5、抽象类只能单继承              接口可以多实现

6、抽象类的子类只能继承一个父类    实现类可以实现多个接口,并且还可以继承父类

7、抽象类的作用:提高代码的复用性   接口的作用:1、规范代码2、提高代码的拓展新

十、方法重写override 覆盖(多态)

1.在子类中。

2、返回值相同、方法名相同、参数列表相同。

3、访问权限修饰符不能比父类更严格。

4、父类的方法不能够满足子类需求的时候,子类需要重写父类的方法。

十一、重写和重载的区别:

1、重写是在继承关系中             重载是在同一个类中

2、重写是方法名、参数列表和父类相同      重载,方法名相同,参数列表不相同(个数、类型、顺序)

3、重写返回值类型和父类相同          重载和返回值无关

4、重写访问权限修饰符不能比父类更加严格 重载没有要求

十二、访问权限修饰符

              本类中       本包中        其他包子类       其他包非子类

  public         √        √       √        √

  protected      √        √       √        ×

  default        √        √       ×        ×

  private        √        ×           ×        ×

十三、equals

object中的equals比较的是地址,底层封装的是==

==比较的是基本数据类型,比较的是内容

    引用数据类型比较的是地址

String中也有equals,String中的equals被重写过了,比较的是内容。

十四、空指针异常

1、声明了对象名,但没有给对象初始化,然后使用这个对象

2、遇到了类类型作为属性的时候,就必须初始化,否则就会报错

十五、内部类

   分类:成员内部类、静态内部类、局部内部类、匿名内部类

1、成员内部类:

    1、可以用四种访问权限修饰符修饰

    2、可以有自己的属性和方法,除了静态的。

    3、可以使用外部类的所有属性和方法,包括私有的。

    4、创建对象

        1、通过创建外部类对象的方式创建对象

        外部类 外部类对象=new 外部类();

        内部类 对象名=外部类对象.new 内部类();

        2、内部类 对象名=new 外部类.new 内部类();

2、静态内部类

    1、格式:static class 类名{}

    2、可以声明静态的属性和方法

    3、可以使用外部的静态的属性和方法

    4、创建对象

        内类名 对象名=new 内类名();(可以直接创建)

        外部类名.内部类 对象名=new  外部类.内部类();

        包名.外部类名.内部类 对象名=new  包名.外部类.内部类();

    5、外部类与内部类同名时,默认是使用内部类对象调用外部类属性

        this代表内部类对象

    6、要想使用外部类属性,需要使用外部类对象调用

3、局部内部类

    1、在方法中声明

    2、只能用default修饰

    3、可以声明属性和方法,但不能是静态的

    4、创建对象,必须在声明内部类的方法内创建

    5、调用方法的时候,局部内部类才会被执行

4、匿名内部类

    1、匿名内部类只是用一次

    2、格式:

    父类或接口名 对象名=new  父类或接口名(参数列表){

       重写抽象方法

            }

    调用抽象方法:对象名.方法名

十六、模式

1、单例模式

    分类:懒汉式、饿汉式

    1、构造方法私有化

    2、在本类中创建本类对象

    3、保证对象的唯一性final

    4、给外界提供得到对象的方法 static

    5、在多线程中,饿汉式安全,懒汉式不安全

2、简单工厂模式

    批量创建对象

    1 创建工厂类 : 创建对象的方法

    2 果汁类 是所有种类果汁的父类

    3 在工厂类的方法中返回果汁类

    4 根据测试类中传递的字符串判断到底返回哪种果汁

    5 测试类通过工厂类返回果汁对象

3、建造者模式 

    内部类使用场景

    目的:静态内部类创建外部类对象

    1、 创建外部类,在其中创建一个静态内部类

    2、静态内部类中写属性,构造方法和set get方法

    3、静态内部类中写一个方法,必须返回外部类对象

    4、 给外部类创建对象,传递参数。

4、装饰者模式

    1、在处理流中使用

    2、子类重写父类的方法,提高父类方法的功能及效率

    3、为了尽可能减少重复代码,在重写的方法中用父类的对象调用父类原来的方法

    4、得到父类对象可以通过将父类对象作为子类属性,通过子类构造方法传递父类对象

数组及常用算法

一、一维数组

1、声明:

  int a[];  int []b;

2、初始化:

    动态初始化:1、a=new int[2]; int[0]=1;...

    动态初始化:2、b=new b[]{3,4};

    静态初始化:int [] c={5,6};

3、数组常用的方法:

    排序:Array.sort();

    查找:Array.binarySearch();

    打印:Array.toString();

    复制:Array.copyof();

4、常用操作

    1、冒泡排序

    for(int i=0;i<a.length-1;i++){//控制外循环的次数

        for(int j=0;j<a.length-1-i;j++){//控制内循环次数,比外循环少一次,与下一个比较

            if(a[j]>a[j+1]){

                int temp=a[j];

                a[j]=a[j+1];

                a[j+1]=temp;

            }

        }

    }

    2、选择排序

    for (int i = 0; i < a.length-1; i++) {

        int k=i;

        for (int j = i; j < a.length-1; j++) {

            if (a[k]>a[j+1]) {

                k=j+1;

            }

        }

        if(i!=k){

            int temp=a[i];

            a[i]=a[k];

            a[k]=temp;

        }

    }

    3、顺序查找

    public static int find(int []b,int a){

    for (int i = 0; i < b.length; i++) {

        if (a==b[i]) {

            return i;

        }

    }

    return -1;

    }

    4、二分查找

    public static int find(int b[],int a){

    int max=b.length-1;

    int min=0;

    for (int i = 0; i < b.length; i++) {

        int midle=(max+min)/2;

        if(a==b[midle]){

            return midle;

        }else if(a>b[midle]){

           min=midle+1;

        }else if(a<b[midle]){

            max=midle-1;

        }

    }

    

return -1;

}

Java常用类

一、装箱拆箱

1、装箱:把基本数据类型转成包装类类型。

2、拆箱:把包装类类型转成基本数据类型。

3、为什么要包装类?

    八种基本数据类型不满足面向对象的思想,不包括属性和方法。如果给基本数据类型添加功能,只能创建其包装类,将方法和属性封装进去。

    jdk5.0以后出现了自动拆箱,装箱。

4、Integer支持字符串,但字符串必须是数字。Integer integer3=new Integer("2");

   compareTo();     比较大小,大返回整数,小于返回负数,相等返回0

   toBinaryString();    将十进制数转成二进制,返回String字符串的表现形式

   toHexString();   将十进制转成十六进制

   toOctalString(); 将十进制转成八进制

   toString();      将int类型数据转成String字符串

   Integer.valueOf();   将int转成integer类型对象

   new Integer();   将int转成integer类型对象

   parseInt();      将Integer转成int

   intValue();      将Integer转成int

二、String字符串

==                  比较地址

.equals()               比较内容

.equalsIgnoreCase()         忽略大小写比较是否相同

.charAt();              字符串截取出指定的下标开始

.compareTo()                比较大小

.compareToIgnore()          忽略大小比较

.concat()               将参数字符串连接到指定字符串后面

.contains()             是否包含参数字符串

.startsWith()               以指定前缀开头

.endsWith()             以指定后缀结尾

.indexOf("/")               第一次出现

.indexOf("/", 3)            指定位置开始索引

.lastIndexOf("/")           最后一次出现

.substring(string11.lastIndexOf("/")+1);截取指定位置

.substring(string11.lastIndexOf("/")+1, string11.lastIndexOf("."));//截取字符串,指定开始位置和结束位置

.replace('a', 'b')          替换指定字符串,替换所有的

.toUpperCase()              全部转为大写

.toLowerCase()              全部转成小写

.trim()                 去掉字符串前后的空格,中间的去不掉

三、StringBuffer

.append("abckjc");          追加

.insert(2, "mmm");          插入

.delete(2, 4);              删除,参数1是起始下标,参数2是结束下标,左闭右开

.reverse();             逆顺反转



    String         长度不可变

  StringBuffer   长度可变   线程安全        速度慢

  StringBuilder  长度可变   线程不安全   速度快

四、Charcter

.isLetter('a');     判断是否为字母

.isLetter('a');     判断是否为小写字母

isUpperCase('A');   判断是否为大写字母

toLowerCase('D');   将大写字母转成小写字母  如果本身是小写字母 则转换完还是小写字母

toUpperCase('f');   将字母专程为大写字母

五、Boolean

  Boolean boolean1=new Boolean("false");

  System.out.println(boolean1);// true boolean中就是true,写的不是true boolean全都是false  

六、正则表达式

字符类

[abc]       a、b、c其中任意一个

[^abc]      除了a、b、c中的任意一个

[a-zA-Z]     a-z或A-Z范围中的任意一个

[a-zA-Z0-9]  a-z A-Z 0-9 其中任意一个

[……]         可以自己定义范围

预定字符类

\d   数字0-9

\D   非数字0-9

\s   空白字符:[ \t\n\x0B\f\r]

\S   非空白字符:\s

\w   单词字符:[a-zA-Z_0-9]

\W   非单词字符\w

数量词

?     一次或者一次也没有

*      0次到多次

+      一次或者多次

{n}    恰好n次

{n,}   至少n次

{n,m}  至少n次但不超过m次

 .matches();    匹配是否适合

 .spil();   拆分

七、时间相关的类

1、Date类

    .getTime();计算毫秒

2、SimpleDateFormat类  格式化时间

    .format();返回的是String字符串

3、Calendar接口  日历字段之间的转换提供了一些方法

    .get(Calendar.YEAR);

    .get(Calendar.MONTH);// 默认是当前月份减一    从0开始的  

    .get(Calendar.DAY_OF_MONTH);

    .get(Calendar.DAY_OF_WEEK);

        Calendar calendar = Calendar.getInstance();

    Date date = calendar.getTime();

4、Runtime运行时时间

    .freeMemory(); 当前的系统剩余空间

5、System.exit(0);退出程序,参数是0 是正常退出

   System.gc();调用垃圾回收器 ,不一定能够起来 ,只是起到一个促进的作用

Java异常处理机制

一、异常

1、在运行时期出现的不正常的事件,从继承的角度看,throwable是错误和异常的超类

2、错误Error:程序员无法处理的严重性问题,资源耗尽,jvm系统内部的错误

   异常Exception:程序员可以处理的一般性问题,偶然的外界因素,编程的逻辑性错误

3、处理的必要性角度:

       受检异常:编译时期就能发现的异常,必须要去处理的异常,继承自Exception

       非受检异常:运行时期发现的异常,不是必须要去处理的,继承自RuntimeException

4、异常的处理机制:

       当运行代码的时候首先先碰到异常,首先产生异常对象,抛出给jvm,jvm会携带异常对象,去找代码能够处理或者捕获异常代码,

       如果找到了,则交给这个代码去处理,没有找打,则程序停止运行。

5、异常处理的两种方式

    1、捕获异常

       try{可能会产生异常的代码}catch(异常类  异常对象){处理异常的代码}

       try{}catch(){}catch(){}...        catch中子类异常放在父类异常的上面

       try{]catch(){}finally{}           finally中的代码一定会被执行到

       try{}finally{}

       1> 如果不去捕获异常,发生异常,异常后面的代码都不会被执行到

       2> 如果捕获异常 try/catch后面的代码会被执行到

       3> 捕获异常,try块中异常后面的代码不会被执行到

    2、抛出异常

       产生异常的位置不去处理异常,由调用此方法的调用者去处理异

         throws  方法的声明后面     后面跟的是异常的类名    可以跟多个类名之间用逗号隔开      可以抛出受检异常和非受检异常

             throw   方法的内部      异常的对象名         一个对象                抛出非受检异常

6、自定义异常

       自定义   受检异常继承Exception

                非受检异常  RuntimeException

二、final finally finalize区别

final 最终的,可修饰类,方法,属性

      类:不能被继承

      方法:不能被重写,可以被继承

      属性:全局变量:声明是必须初始化。局部变量:声明的时候可以不初始化。但都只能赋值一次

finally 跟try/catch后面,无论是否发生异常都会被执行。关闭数据库,关闭数据流。

finalize 由系统调用,垃圾回收器回收之前做一些清理的工作。

集合

数组:长度固定,数据类型相同

集合:长度不固定,数据类型可以不同,只能存对象

collection  

List           Set          Vector

ArrayList      HashSet

LinkedList     TreeSet

Map

HashMap

TreeMap

一、Collection

1、添加元素

    add(Objectobj); //add方法的参数类型是Object。以便于接收任意类型对象。

   2、删除元素

    remove(Objectobj);

    removeAll(另一集合);//调用者只保留另一集合中没有的元素。

    clear();//清空集合

   3、判断元素

    contains(Objectobj);//判断是否存在obj这个元素

    isEmpty();//是否为空

   null  没有初始化  只有栈空间没有堆空间

       empty 已经初始化了对象   这个容器中没有数据 

   4、获取个数,集合长度

    size();

   5、取交集

    retainAll(另一集合);//调用者只保留两集合的共性元素。 

二、List

List:元素是有序的,元素可以重复。因为该集合体系有索引。

        |--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步。

        |--LinkedList:底层使用的是链表数据结构。特点:增删速度很快,查询稍慢。

        |--Vector:底层是数组数据结构。线程同步。被ArrayList替代了。

ArrayList:

    增:add();addAll(0,list2);

    获取:get(1);

    修改:set();

    截取:subList(0, 2);左闭右开

LinkedList:

    增:addFirst(); addLast();      jdk1.6后  offFirst(); offLast();

    获取:getFirst(); getLast();              peekFirst(); peekLast();

    删除:removeFirst(); removeLast();        pollFirst(); pollLast();

    压栈:push();

    弹栈:pop();

    逆序输出:linkedList.descendingIterator()

三、Set

Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复。     

       |--HashSet:底层数据结构是哈希表。线程不同步。 保证元素唯一性的原理:判断元素的hashCode值是否相同。如果相同,还会继续判断元素的equals方法,是否为true。

       |--TreeSet:可以对Set集合中的元素进行排序。默认按照字母的自然排序。底层数据结构是二叉树。保证元素唯一性的依据:compareTo方法return 0。

       Set集合的功能和Collection是一致的

1、HashSet: 哈希表

    1、可以通过元素的两个方法,hashCode和equals来完成保证元素唯一性。如果元素的HashCode值相同,才会判断equals是否为true。

    如果元素的hashCode值不同,不会调用equals。

    2、hashcode是内存地址通过一定运算的到的int类型的数值。返回值是int类型的数据,各个属性的hash值。 相加

    3、hashcode值相同,也不一定是同一个对象 

    4、调用hashcode方法可以帮助去过滤调用完全不可能相同的 对象,提高执行效率

    5、equals最终确定两个对象是否相同的

    @Override

    public int hashCode() {

        // TODO Auto-generated method stub

        int code=name==null?0:name.hashCode();

        return code;

    }

    @Override

    public boolean equals(Object obj) {

        // TODO Auto-generated method stub

        if(obj==this){

            return true;

        }

        if (obj==null) {

            return false;

        }

        if (obj instanceof Person) {

            Person person=(Person)obj;

            if (this.name.equals(person.name)) {

                return true;

            }

                

    }

    return false;

}

2、LinkedHashSet:

1、有序不重复

3、TreeSet:红黑树

1、自然排序,实现Comparable接口,重写compareTo方法 ,系统自动调用

    public int compareTo(Student o) {

    // TODO Auto-generated method stub

    if (this.score<o.score) {

        return 1;

    }else if(this.score>o.score){

        return -1;

    }else {

        if(this.age<o.age){

            return 1;

        }else if(this.age>o.age){

            return -1;

        }else{

            CollationKey collator=Collator.getInstance().getCollationKey(this.name);

            CollationKey collator2=Collator.getInstance().getCollationKey(o.name);

            return collator.compareTo(collator2);

            }

        }

    }

2、定制排序,单独一个类实现Comparator接口,重写compare方法(也可用内部类的方法写)

         o1 相当于 自然排序中this

         o2  相当于自然排序中的参数对象

        public class ComparatorDemo implements Comparator<Person>{

        public int compare(Person o1, Person o2) {

        //o1本来对象 o2参数对象

        //本类比参数大返回1 升序

        //本类比参数小返回-1降序

        if (o1.getAge()>o2.getAge()) {

            return -1;

        }else if(o1.getAge()<o2.getAge()){

            return 1;

        }else {

            CollationKey collationKey=Collator.getInstance().getCollationKey(o1.getName());

            CollationKey collationKey2=Collator.getInstance().getCollationKey(o2.getName());

            return collationKey.compareTo(collationKey2);

            }

        }

        }

        调用格式:TreeSet<Person> treeSet=new TreeSet<Person>(new ComparatorDemo());

        

    内部类的写法:

    TreeSet<Person> treeSet2=new TreeSet<Person>(new Comparator<Person >() {

    public int compare(Person o1, Person o2) {

        // TODO Auto-generated method stub

        if (o1.getAge()>o2.getAge()) {

            return -1;

        }else if(o1.getAge()<o2.getAge()){

            return 1;

        }else {

            CollationKey collationKey=Collator.getInstance().getCollationKey(o1.getName());

            CollationKey collationKey2=Collator.getInstance().getCollationKey(o2.getName());

            return collationKey.compareTo(collationKey2);

            }

        }

    });

    

3、主要:

             自然排序 测试的TreeSet集合 用无参数的构造方法

             定制排序的时候  new TreeSet(Comparator接口对象的)

四、Map

  1)该集合存储键值对,一对一对往里存

      2)要保证键的唯一性

 Map

        |--Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。JDK1.0,效率低。

        |--HashMap:底层是哈希表数据结构。允许使用null键null值,该集合是不同步的。JDK1.2,效率高。

        |--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给Map集合中的键进行排序。

    初始容量16,加载因子0.75

        Map和Set很像。其实Set底层就是使用了Map集合。

    1、添加

        Vput(K key,V value);//添加元素,如果出现添加时,相同的键,那么后添加的值会覆盖原有键对应值,并put方法会返回被覆盖的值。

        voidputAll(Map <? extends K,? extends V> m);//添加一个集合

    2、删除

        clear();//清空

        Vremove(Object key);//删除指定键值对

    3、判断

        containsKey(Objectkey);//判断键是否存在

        containsValue(Objectvalue)//判断值是否存在

        isEmpty();//判断是否为空

    4、获取

         Vget(Object key);//通过键获取对应的值

         size();//获取集合的长度

1、HashMap

    HashSet底层封装HashMap,所以HashSet中的规律都是用于HashMap的键。值允许重复,允许多个null,键只允许一个null

    如果自定义类作为键,需要重写hashcode的和equals方法,保证事物唯一性。如果作为值,则不重写

        @Override

    public int hashCode() {

        // TODO Auto-generated method stub

        int code=name==null?0:name.hashCode();

        int code2=age;

        int code3=sex.hashCode();

        return code+code2+code3;

    }

    @Override

    public boolean equals(Object obj) {

        // TODO Auto-generated method stub

        if (this==obj) {

            return true;        

        }

        if (obj==null) {

            return false;

        }

        if (obj instanceof Person) {

            Person person=(Person) obj;

            if (this.name.equals(person.name)) {

                if(this.age==person.age){

                    if (this.sex.equals(person.sex)) {

                        return true;

                    }

                }   

            }

        }

        return false;

    }

2、TreeMap

    1、自然排序

        public int compareTo(Person o) {

        // TODO Auto-generated method stub

        if (this.age<o.age) {

            return 1;

        }else if (this.age>o.age) {

            return -1;

        }else {

            CollationKey collationKey=Collator.getInstance().getCollationKey(this.name);

            CollationKey collationKey2=Collator.getInstance().getCollationKey(o.name);

            return collationKey.compareTo(collationKey2);

        }

    }

    2、定制排序

    单独写一个类

        public class GirlCom implements Comparator<Girl> {

        @Override

        public int compare(Girl o1, Girl o2) {

        // TODO Auto-generated method stub

        if(o1.age>o2.age){

            return 1;

        }else if(o1.age<o2.age){

            return -1;

        }else {

            if(o1.weight>o2.weight){

                return 1;

            }else if(o1.weight<o2.weight){

                return -1;

            }else {

                CollationKey collationKey=Collator.getInstance().getCollationKey(o1.name);

                CollationKey collationKey2=Collator.getInstance().getCollationKey(o2.name);

                return collationKey.compareTo(collationKey2);   

                    }

                }

            }

        }



    调用格式:TreeMap< Girl,String > treeMap=new TreeMap< Girl,String>(new GirlCom());   

3、Hashtable

如果自定义类作为键,则重写compato方法,如果作为值,则不重写

4、遍历集合的方式:

1、keySet();只得出来值

    Set<String> set = map.keySet();//键的集合

    //1、迭代

    Iterator<String> iterator = set.iterator();

    while (iterator.hasNext()) {

        String key = iterator.next();

        System.out.println(map.get(key));

    }

    //2、fore

    for (String string2 : set) {

        System.out.println(map.get(string2));// String2是键

    }

2、entrySet();键-值对方式

    Set<Entry<String, String>>  set2=map.entrySet();

    //迭代

    Iterator<Entry<String, String>> iterator3=set2.iterator();

    while (iterator3.hasNext()) {

        Entry<String, String> kEntry=iterator3.next();

         System.out.println(kEntry);

    }

    //fore

    for (Entry<String, String> entry : set2) {

        System.out.println(entry);

    }

Java I/O

1、File类

    创建:File file = new File(路径字符串);

    .exists();文件是否存在

    .delete();删除文件

    .getPath();路径

    .isFile());是文件吗

    .isDirectory();是目录吗

    .getName();名称

    .getAbsolutePath();绝对路径

    .lastModified();最后修改时间

    .length();文件大小,不能判断目录/文件夹

    .getParent();父路径,得到指定目录的前一级目录

    .getAbsoluteFile();得到文件绝对路径文件

    创建:

    .createNewFile();创建文件

    .mkdir();创建一层文件夹

    .mkdirs();创建多层文件夹

    File(String path)              通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例

    File(String path,String child) 根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。

    File(File file,String child)

list()                    返回一个字符串数组,这些字符串目录中的文件和目录。

list(FileNameFilter)      返回一个字符串数组,这些字符串指满足指定过滤器的文件和目录。

listFiles                 返回一个抽象路径名数组,这些路径名目录中的文件。

listFiles(FileNameFilter) 返回抽象路径名数组,这些路径名满足指定过滤器的文件和目录。

2、遍历文件夹是用递归。

3、流的分类

按流分向:

    输入流:从数据源到程序中的流   

    输出流:从程序到数据源的流

按数据传输的单位:

    字节流:以字节为单位传输数据的流

    字符流:以字符为单位传输数据的流

按功能分:

    节点流:直接与数据源打交道的流

    处理流:不直接与数据源打交道,与其他流打交道

4、流类

            字节流                       字符流

输入流      InputStream  超类,抽象类       Reader 超类,抽象类

输出流       OutputStream 超类,抽象类       Write  超类,抽象类

5、流

read() 一个字节一个字节的读  返回值是读取到得数据的int表现形式   

read(byte[])  把字节读取到数组中   返回 的是读取到的个数 返回:读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回 -1。

read(byte[],int offset,int length)

       指定的数组中偏移的个数  指定的数组的下标  存储数据的长度

字符流

       FileInputStream   字节流 输入流 节点流 直接操作文件的

                read();

                read(byte[]);

                read(byte[],off,,len);   (byte[]接受数据,返回值!=-1)

       FileOutputStream  字节流 输出流 节点流

                write(int);

                write(byte[]);

                write(bute[],off,len);

        

            File file = new File("E:\ceshi.wmv");// 源文件

            File file2 = new File("E:\aaa\ceshi.wmv");// 目标文件

            // 1、创建流对象

            FileInputStream fis = new FileInputStream(file);

            FileOutputStream fos = new FileOutputStream(file2);

            // 2、读取文件

                byte[] bs = new byte[1024];

            int num = 0;

            while ((num = fis.read(bs)) != -1) {

                fos.write(bs);

            }

            // 3、刷新

            fos.flush();

            // 4、关闭流        

字符流

       FileReader        字符流 输入流 节点流

                read(char[]);            (char[]接收数据,返回值!=-1)

       FileWriter        字符流 输出流 节点流

                write(char,offset,length);

                循环读取判断 !=-1

                

           File file=new File("E:\22.txt");

            File file2=new File("E:\aa\22.txt");

            FileReader fileReader=new FileReader(file);

            FileWriter fileWriter=new FileWriter(file2);

            char [] ch=new char[4];

            int num=0;

            while((num=fileReader.read(ch))!=-1){

            fileWriter.write(ch,0,num);

            }

            fileWriter.flush();

            关闭流

复制文件的流程

   1、创建流对象

   2、读取文件的文件(循环读取)FileInputStream、FileReader

   3、写入目标文件 FileOutputStream、FileWriter

   4、刷新关闭

缓冲流

   BufferedInoutStream   字节流 输入流 处理流    (byte[]接受数据,返回值!=-1) 

   BufferedOutputStream  字节流 输出流

   BufferedReader        字符流 输入流           (String接受数据,返回值!=null)resdLine();

   BufferedWriter        字符流 输出流

            readLine();读取一行,返回值String 循环读取判断 !=null

            newLine();换行

            \r\n换行

    BufferedInputStream bis=new BufferedInputStream(new FileInputStream(new File("E:\ceshi.wmv")));

    BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(new File("E:\aa\ceshi.wmv")));

    byte []bs=new byte[1024];

    int num=0;

    long time=System.currentTimeMillis();

    while((num=bis.read(bs))!=-1){

        bos.write(bs,0,num);

    }

    bos.flush();

    关闭流

转换流

  字节转字符   InputStreamReader   继承自Reader (String接收数据,返回值!=null)

  字符转字节   OutputStreamWriter  继承自Wriiter

    BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(new FileInputStream( new File("E:\ceshi.wmv"))));

    BufferedWriter bufferedWriter=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File("E:\aa\demo\ceshi.wmv"))));

    String string=null;

    while((string=bufferedReader.readLine())!=null){

        bufferedWriter.write(string);

    }

    bufferedWriter.flush();

    关闭流

对象流

   ObjectInputStream    readObject();

   ObjectOutputStream   writeObject(Object obj);

   1、用对象流去存储对象的前提是 将对象序列化 实现接口Serializable

   2、序列化和反序列化(将对象持久化储存)

    将对象转成字节叫序列化

    将字节转成对象叫反序列化

   3、序列化ID,帮助区分版本,可写可不写。

   4、transient修饰不想被序列化的属性,存储默认值

    Person person =new Person("秋秋", 22);

    Person person2=new Person("菜菜", 21);

    ObjectOutputStream objectOutputStream=new ObjectOutputStream(new FileOutputStream(new File("a.txt")));

    objectOutputStream.writeObject(person);

    objectOutputStream.writeObject(person2);

    objectOutputStream.flush();

    if (objectOutputStream!=null) {

        objectOutputStream.close();

    }

    ObjectInputStream objectInputStream=new ObjectInputStream(new FileInputStream(new File("a.txt")));

        Person person3=(Person) objectInputStream.readObject();

        System.out.println(person3);

        Person person4=(Person) objectInputStream.readObject();

        System.out.println(person4);

        if (objectInputStream!=null) {

            objectInputStream.close();          

        }

  数据包装流(了解)字节流,读取字节

       DataInputStream

       DataOutputStream

       1、新增了很多读取和写入基本数据类型的方法

       2、读取的顺序和写入的顺序一样,否则数据内容会和存入时的不同

        DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream(new File("b.txt")));

        dataOutputStream.writeInt(22);

        dataOutputStream.writeLong(34567);

        dataOutputStream.writeBoolean(true);

        dataOutputStream.flush();

        if (dataOutputStream != null) {

            dataOutputStream.close();

        }

    DataInputStream dataInputStream = new DataInputStream(new FileInputStream(new File("b.txt")));

    System.out.println(dataInputStream.readInt());

    System.out.println(dataInputStream.readLong());

    System.out.println(dataInputStream.readByte());

    if (dataInputStream != null) {

        dataInputStream.close();

    }

标准输入/输出/错误流

   System.in  会阻塞程序的运行等待用户输入

   System.out 将内容打印到控制台上

   System.err 将内容打印到控制台上,颜色是红色

标准输入/输出/错误流的重定向

   System.setIn()

   System.setOut()

   System.setErr()

   1、重定向的方法一定要放在标准输入输出错误流的前面

打印流

   PrintStream 字节打印流  可以new可以通过System.out得到

   PrintWriter 字符打印流   new

内存流

   ByteArrayInputStream  输入流  (byte[]接受数据,返回值!=-1)

   ByteArrayOutputStream 输出流

   1、toByteArray() 返回值是byte,内存输出流调用的,byte[] bs=byteArrayOutputStream.toByteArray();

            //将内存中的数据转化成byte数组  

   2、writeTo(OutputStream)  将内存流中的数据直接写入参数流中    

    // 1、创建文件输入流,读取文件内容

    BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(new File("E:\11.txt")));

    // 2、创建内存输入流,将读取后的文件存到内存中

    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

    byte[] bs = new byte[1024];

    int num = 0;

    // 3、循环读取文件内容

    while ((num = bufferedInputStream.read(bs)) != -1) {

        // 4、将文件写入内存中

        byteArrayOutputStream.write(bs,0,num);

        byteArrayOutputStream.flush();

        ////将内存中的数据转化成byte数组

        byte[] bs2 = byteArrayOutputStream.toByteArray();////因为读取的时候需要数组,所以在这儿写

        System.out.println("---" + new String(bs2));

        // 5、创建内存输入流。读取内存中的数据

        ByteArrayInputStream byteArrayInputStreamnew = new ByteArrayInputStream(bs2);

        // 7、创建文件输出流,将内存中的文件 读取到我文件中

        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(

            new FileOutputStream(new File("E:\aaa\11.txt")));

        byte[] bs3 = new byte[1024];

        int num2=0;

        // 8、循环读取内存中的数据

        while ((num = byteArrayInputStreamnew.read(bs3)) != -1) {

            System.out.println("~~~" + new String(bs3));

            // 9、写入到文件中

            bufferedOutputStream.write(bs3,0,num2);

            bufferedOutputStream.flush();

        }

        //10、关闭各种流

随机读写流:在线程中使用较多

    RandomAccessFile  字节流,即可以读又可以写

        // 1、文件的长度

    File file = new File("E:\ceshi.wmv");

    System.out.println(file.length());

    int tlen = 0;

    if (file.exists()) {

        tlen = (int) file.length();    //判断文件并计算文件总长度

    }

    int len = tlen % 4 == 0 ? tlen / 4 : tlen / 4 + 1;  //计算每一段长度

    int last = tlen - len * 3;                          //最后一段长度=总长度-前三段长度      

    Copy copy = new Copy(0, len); copy.start();                      //第一段长度从0到len

    Copy copy2 = new Copy(len, len);    copy2.start();

    Copy copy3 = new Copy(len * 2, len);    copy3.start();

    Copy copy4 = new Copy(len * 3, len);copy4.start();                                                                                                                                                                                                                                                                                                                                                                                                      

        }

    }

    class Copy extends Thread {

        int star = 0; 

        int leng = 0;

        public Copy(int star, int leng) {

            super();

            this.star = star;

            this.leng = leng;

        }

        public void run() {

            RandomAccessFile read = null;

            RandomAccessFile write = null;

                    read = new RandomAccessFile(new File("E:\ceshi.wmv"), "rw");

                    System.out.println(Thread.currentThread().getName() + "开始!!!");

                    write = new RandomAccessFile(new File("E:\aaa\bb\ceshi.wmv"), "rw");

                        read.seek(star);

                        write.seek(star);

                        byte[] bs = new byte[1024];

                        int num = 0;

                        int readlength = 0;

                        while (true) {

                            if (leng - readlength < 1024) {

                                read.read(bs, 0, leng - readlength);

                                write.write(bs, 0, leng - readlength);

                                break;

                            } else   {

                                num = read.read(bs);

                                write.write(bs, 0, num);

                                readlength += num;

                        }

                    }

                    System.out.println(Thread.currentThread().getName() + "完成~~~");

Java多线程

一、线程和进程

1、线程

  注意:多线程。从宏观角度同时执行了多个线程。

             从微观角度同一时间只能执行一个线程

          多个线程是竞争关系,抢占cpu资源,否则只能等待。

2、进程和线程的区别:

    进程是应用程序,线程是一条执行路径

    进程有独立的内存空间,崩溃不会影响其他程序,

    线程没有独立的空间,多个线程在同一个进程的空间,可能会影响其他线程

    一个进程中,至少有一个线程

3、主线程子线程

    主线程:main方法产生的线程,也叫作UI线程。

    子线程:除了主线程以外的,也叫工作线程。

4、创建线程的两种方式

    1、创建一个类继承Thread

    2、重写run方法

    3、创建线程对象

    4、启动线程

    5、Thread.currentThread().getName(),哪个线程调用,名字就是哪个现成的名字

      getName();super调用父类的getName(),被赋值谁的名字,就打印谁的名字

        

    main方法:

    Test2 test=new Test2("一号窗口");test.start();

        Test2 test2=new Test2("二号窗口");test2.start();

    

    class Test2 extends Thread{

        String name;

        int ticket=10;

         public Test2(String name) {

            super(name);

            this.name = name;

        }

        public void run() {

            while (true) {

                if (ticket>0) {

                    ticket--;

                    System.out.println(Thread.currentThread().getName()+"还剩下"+ticket);

                }else {

                    break;}

            }

        }

共享资源操作相同

1、共享资源类实现Runable接口

2、重写run方法

3、创建共享资源对象

4、创建线程对象,将共享资源对象添加到线程中

5、启动线程

    

    main方法:

    Test3 test3=new Test3();

    Thread thread=new Thread(test3);

    Thread thread2=new Thread(test3);

    thread.start();

    thread2.start();

    

    class Test3 extends Thread{

        String name;

        int ticket=10;

         public Test2(String name) {

            super(name);

            this.name = name;

        }

        public void run() {

            while (true) {

                if (ticket>0) {

                    ticket--;

                    System.out.println(Thread.currentThread().getName()+"还剩下"+ticket);

                }else {

                    break;}

            }

        }

贡献资源操作不相同

1、贡献资源作为一个单独的类

2、由多个操作去实现Runable接口

3、把共享资源作为多个操作类的属性

4、创建线程对象,将共享资源对象添加到线程中

5、启动线程

    

    main方法:

    Card card=new Card();

    Boyfriend boyfriend=new Boyfriend(card);

    Girlfriend girlfriend=new Girlfriend(card);

    Thread thread=new Thread(boyfriend);

    Thread thread2=new Thread(girlfriend);

    thread.start();

    thread2.start();

    class Card{

        double money;

    }

    class Boyfriend implements Runnable{

        Card card;

        public Boyfriend(Card card){

            this.card=card;

        }

        @Override

        public void run() {

        // TODO Auto-generated method stub

            for (int i = 0; i < 5; i++) {

                card.money+=500;

                System.out.println(Thread.currentThread().getName()+"存500-剩余金额"+card.money);

            }

        }

    }

    class Girlfriend implements Runnable{

        Card card;

        public Girlfriend(Card card){

            this.card=card;

        }

        @Override

        public void run() {

        // TODO Auto-generated method stub

            for (int i = 0; i < 5; i++) {

                card.money-=500;

                System.out.println(Thread.currentThread().getName()+"取500,剩余金额"+card.money);

            }

        }

    }

5、run和start的区别

run没有开辟新的栈空间,没有新线程,都是主线程在执行

start开辟了新的栈空间,在新的栈空间启动run()方法

6、线程的调度

setPriority();分配优先级,默认5,最低1,最高10

.join();插队,阻塞指定的线程等到另一个线程完成以后再继续执行

    .sleep();需要设置睡眠时间

    .yield();礼让,当执行到这个方法时,会让出cpu时间,立马变成可执行状态

sleep和pield的区别:

         sleep                 yeild

        线程进入被阻塞的状态   线程转入暂停执行的状态

(没有其他线程运行)等待指定的时间再运行 马上恢复执行的状态

        其他线程的执行机会是均等的   将优先级或更高的线程运行

7、打断线程的终止方式

1、用标记,当终止线程时,会执行完run方法

2、stop()方法,不建议使用,会执行不到特定的代码

3、interrupt(),只能中断正在休眠的线程,通过抛异常的方法中断线程的终止。

    InputStream inputStream=System.in;

    int m=inputStream.read();

    myThread2.interrupt();//通过外界输入打断    

8、线程是五种状态

新建    就绪   执行   死亡  阻塞

二、同步

发生在两个以两个以上的线程中

解决代码的重复问题

优点:提高了线程中数据的安全性

缺点:降低了执行效率

 1、同步代码块

synchronized(锁){同步代码块}

注意:锁分任意锁和互斥锁,锁是对象,琐是唯一的。        

 2、同步方法

public synchroinzed 返回值类型 方法名(){同步代码}

 3、在共享资源中:

    线程操作相同,琐是this

        synchronized (this) {// 同步代码块,包含同步代码块。任意锁,互斥锁。

            if (ticket > 0) {

                System.out.println(Thread.currentThread().getName() + "---" + ticket--);

            } else {

                break;

            }

        }

    线程操作不相同,琐是共享资源对象

        synchronized (card) {

            card.setMoney(card.getMoney() + 1000);

            System.out.println("Boy+1000---" + card.getMoney());

        }

 4、在同步方法中:

    共享资源,线程操作相同,资源类中的锁是this

    共享资源,线程操作不相同,资源类中的锁也是this

        public synchronized void input(){

            money+=100;

            System.out.println("input+100----"+money);

    

    }

5、在静态方法中同步:懒汉式

同步代码块,琐是类.class

同步方法,锁也是类.class

    public  static LazyInstance getInstance(){

        if (instance==null) {

            synchronized (LazyInstance.class) {

                if (instance==null) {

                    try {

                        Thread.sleep(1000);

                    } catch (InterruptedException e) {

                        // TODO Auto-generated catch block

                        e.printStackTrace();

                    }

                    instance=new LazyInstance();

                }

            System.err.println(instance.hashCode());

            }

    

            }       

        return instance;

    }

三、经典例子:生产者消费者

面包类:class Bread{属性和构造方法}

超市类:class Market{

        Bread[] breads=new Bread[];//超市里有面包数组

        int index=-1;//一开始没有面包,下标为-1;

        public synchronized void sale(){

            if(index<=-1){////如果没有没有面包,就等待添加

                this.wait();

                }

            ////如果有面包,就打印面包信息

            System.out.println("消费面包"+breads[index].id+breads[index].name+breads[index].price);

            index--;//面包减少一个

            this.notify();唤醒添加线程

            }

        public synchronized vide add(Bread bread){

            if(index>=4){

                this.wait();

                }

            indenx++;//面包下标+1,存入下一面包位置中

            breads[index]=bread;//给数组中的面包赋值

            System.out.println("添加面包"+breads[index].id+breads[index].name+breads[index].price); 

            this.notify();//唤醒销售线程

            }

工厂类:实现Runnable接口:

        将超市类作为属性

        添加构造方法

        重写run方法,调用超市类add方法

顾客类:实现Runnable接口:

        将超市类作为属性

        添加构造方法

        重写run方法,调用超市类sale方法

Java网络编程

1、计算机网络:

  将多态计算机,通过网络通信连接到一起,实现了资源的共享和信息的传递

2、计算机网络的分类:

广域网,城域网,局域网。

3、参考模型

4、tcp/ip协议

  :tcp、udp、ip

5、tcp特点:

    面向连接,数据安全可靠,效率偏低,传输数据大小无限制

6、 udp特点:

    面向无连接,数据安全不可靠,执行效率高,数据大小不超过64kb

 注意:tcp和udp只是传输协议,只是设定了规范,真正传输的数据ip协议。

    ip协议:将数据从源传递到目的地

    ipv4:32位

    ipv6:128位

    ipconfig 查看ip相关信息

    ping 查看指定ip或者地址能不能连通

7、IP编程:

    1、InetAddress,  没有构造方法,只能通过自己的静态方法创建对象

    2、getLocalHost(),   返回值是InetAddress,得到本机的主机名和地址

    3、getByName(ip),    返回值是InetAddress,有参数,可以写ip,网址,得到指定的主机

    4、getHostAddress(), 得到主机的地址

    5、getHostName(),    得到指定的主机名

8、TCP编程

    客户端:

        1、创建socket对象,指定ip地址和端口号

        2、需要从socket中得到OutputStream

            聊天配合字符流输入流使用,直接转换输入输出即可

            文件配合字节流使用,字节流读,socket输出。

        3、将想要发送的数据写入到OutputStream中。flush    

        4、关闭流关闭socket  

    服务器:

        1、创建ServerSocket对象,指定端口号

        2、serversocket.accep(),返回一个Socket对象(客户端发过来的socket)

         接收客户端发送的数据,如果没有接收到,阻塞程序的运行

        3、从Socket中得到InputStream流,将数据从流中读取出来

            聊天配合字符输出流使用。

            文件配合字节输出流使用,socket读,字节流输出。

        4、展示/写入到另外的地方

        5、关闭流,关闭Socket  

    聊天:

    聊天客户端:

        Socket socket=new Socket("127.0.0.1", 65499);

        OutputStream outputStream=socket.getOutputStream();

        BufferedWriter bufferedWriter=new BufferedWriter(new OutputStreamWriter(outputStream));

        InputStream inputStream=socket.getInputStream();

        BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));

        Scanner scanner=new Scanner(System.in);

        while (true) {

            System.out.println("客户端:");

            String string=scanner.next();

            bufferedWriter.write(string);

            bufferedWriter.newLine();

            bufferedWriter.flush();

            if (string.equals("拜拜")) {

                break;

            }

            //接收数据

            String string2=null;

                string2=bufferedReader.readLine() ;

                System.out.println("服务器回复:"+string2);

                }  

        //关闭流和socket

    聊天服务器:

        ServerSocket serverSocket=new ServerSocket(65499);

        System.out.println("服务器等待中。。。");

        Socket socket=serverSocket.accept();

        InputStream inputStream=socket.getInputStream();

        Scanner scanner=new Scanner(System.in);

        BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));

        OutputStream outputStream=socket.getOutputStream();

        BufferedWriter bufferedWriter=new BufferedWriter(new OutputStreamWriter(outputStream));

        String string=null;

        while (true) {

         string=bufferedReader.readLine();

         System.out.println("客户端说"+string);

         if (string.equals("拜拜")) {

                break;

            }

         System.out.println("服务器回复:");

         String string2=scanner.next();

         bufferedWriter.write(string2);

         bufferedWriter.newLine();

         bufferedWriter.flush();

        }

        //关闭各种流和socket等

9、UDP编程

    客户端:

        1、创建套接字对象,DatagramSocket,不需要指定端口号和地址

            (聊天配合字符输入流),文件配合字节输入流

        2、创建数据报包对象DatagramPacket,使用四个参数,指定数据,数据长度,地址,端口号。

        3、send发放发送数据

        4、关闭socket

    服务器:

        1、创建套接字对象DatagramSocket,指定端口号

        2、创建数据报包对象DatagramPacket,用两个参数的。指定数据和数据长度。

        3、receice()接收数据,如果接受不到,阻塞程序。

        4、根据数据报包进行一系列需要的操作

    聊天:

    客户端:

        DatagramSocket datagramSocket=new DatagramSocket();

        BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in));

        while (true) {

            System.out.println("客户端--:");

            String string2=bufferedReader.readLine();

            DatagramPacket datagramPacket=new DatagramPacket(string2.getBytes(), string2.getBytes().length, InetAddress.getLocalHost(),65496);

            datagramSocket.send(datagramPacket);

            if (string2.equals("拜拜")) {

                break;

            }

        byte []buf=new byte[1024];

        DatagramPacket datagramPacket2=new DatagramPacket(buf, buf.length);

        datagramSocket.receive(datagramPacket2);

        String string=new String(datagramPacket2.getData(), 0, datagramPacket2.getLength());

        System.out.println("服务器--"+string);

        }

    服务器:

        DatagramSocket datagramSocket = new DatagramSocket(65496);

        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));

        System.out.println("客户端已准备");

        byte[] buf = new byte[1024];

        while (true) {

            DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length);

            datagramSocket.receive(datagramPacket);

            String string = new String(datagramPacket.getData(), 0, datagramPacket.getLength());

            if (string.equals("拜拜")) {

                break;

            }

        System.out.println("我说~~"+string);

        //回复数据

        System.out.println("你说~~:");

        String string3 = bufferedReader.readLine();

        DatagramPacket datagramPacket2 = new DatagramPacket(string3.getBytes(), string3.getBytes().length,

                InetAddress.getLocalHost(), datagramPacket.getPort());

        if (string3.equals("拜拜")) {

            break;

        }

        datagramSocket.send(datagramPacket2);

        }

反射机制

1、反射:

    反射是将类中的属性,方法,构造方法等解剖成一个个小的对象,并且能够调用

2、为什么使用反射:

    在一个类中,可以创建另外一个类的对象,调用其的属性和方法,无论那个类是否被创建了。

3、如何使用反射:

    类

    Class class=Class.forName(包名.类名),每一个类都有唯一的一个类对象,这个类对象可以的得到类中的所有信息。

    构造方法

    class.getConstructor(null);     得到无参构造方法,返回Constructor

    class.getConstructor(String.clss,int.class);得到有参构造方法,返回Constructor

    constructor2.newInstance("曹菜菜",21); 返回Object类型的对象

    class.getConstructors();        得到所有构造方法,返回Constructor[]数组

    方法

    getMethod();                得到普通的方法,返回Method,指定方法名

    class1.getMethod("eat", null);      无参、无返回值、非私有的方法。

    class1.getMethod("play", String.class); 有参、无返回值。非私有方法。参数一,方法名。参数二,参数类型.class

    method(n).invoke(object,null);      方法的执行,参数一是对象,参数二是传的参数值。

    getMethods();               得到子类和父类所有普通的方法,返回Method[]数组

    class1.getDeclaredMethod("sleep", null);得到私有的方法

    method6.setAccessible(true);

    class1.getDeclaredMethods();        得到自己类的所有方法,包括私有的,返回Method[]

    属性

    getFields();                得到public所有属性,返回Field[]

    getFileld("name");          得到public属性,返回Field,指定属性名

    field3.set(object5, "菜菜");

    Object object6 = field3.get(object5);

    getDeclareFields();         得到所有属性,包括私有的,返回Field[]

    getDeclareField();          得到属性,包括私有的,指定属性名,返回Field

4、反射的优点

    1、提高了java程序的灵活性和扩展性,降低了耦合性,提高了自适应的能力

    2、允许程序创建和控制任何类的对象,无需提前编码目标类

5、反射的缺点

    1、性能问题

    2、代码维护问题    

HTML& SQLite

一、HTML

标签:

    换行<br>、段落<p>、超链接<a href="网址">、图片

    删除线<del>、下划线<u>、加粗<b>、倾斜<i>、标题<h1-h6>、文字样式<font size color>

    横线<hr size width color>、空格&nbsp、

    有序列表<ol> <li> </li></ol>

    无序列表<ul> <li> </li></ul>

    多个列表嵌套<ol><li>  <ol><li></li></ol> </li></ol>

锚点:

    <a name="a"><img src=""/></a>

    <a href="#a">超链接</a>

form表单:

    文本按钮多选等:<input type="" name=""/>

    下拉列表:<select><option>内容</option></select>

    多行文本:<textarea conslpan="" rowspan=""></textarea>

表格: 

    <table><tr><td></td></tr></table>可设置跨列跨行

CSS层叠样式:

    <style>

    标签选择器:标签名{}

    id选择器:#选择器的名字 id="#名"

     类选择器:.选择器的名字 class=".名字"   

    </style>

JS:

    在head标签中写,页面上想要动态的去展示或操作页面的时候

二、SQLite

  固定语句:

    Class.forName("org.sqlite.JDBC");加载驱动

            Connection connection=DriverManager.getConnection("jdbc:sqlite:/e:/SQLite/day0919-1.db");创建连接       

    Statement statement=connection.createStatement();创建执行sql语句的对象

     1、创建表 create table [if not exists] tablename(_id integer primary key autoincrement,name vachar(15)....);

     2、追加列 alter table tablename add 字段名 integer

     3、插入数据 insert into tablename(id,name...)values(1,'aa');

     4、查询数据 select * from tablename where name='aa';    

     5、修改数据 update tablename set name='aa' where name='aa';

     6、删除数据 delete from tablename where name='aa'

     7、模糊查询 select * from tablename where name like '%aa%';

     8、升序     select * from employees order by id ;

     9、降序     select * from employees order by id desc;

     10、多字段  select * from employees order by department_id desc,salary asc;

     11、and or   

     执行语句: statement        用于查询(executequery)删除(executeupdate)修改(executeupdate)

                preparastatement 用于插入(executeupdate)

    注意:insert into tablename(id,name...)values(?,?,?...);

          preparedStatement.setString(1, id);//用占位符的时候需要prepareStatement设置

Servlet

1、浏览器和服务器的交互  请求/响应式交互

    1>浏览器先发送请求给服务器

    2>指定的servlet去接收 (根据method属性值如果是post则调用doPost,如果不是则 调用doGet)

    3>在servlet中动态的执行逻辑代码,也可以动态给浏览器发送数据

    4>服务器响应浏览器的请求

2、C/S结构:客户端/服务器

    优势:充分利用两端硬件的优势,提高了执行效率

    劣势:必须安装客户端软件,维护客户端的更新

3、B/S结构:浏览器/服务器 

    优势:操作简单,不需要下载软件。只需要网络

    劣势:将所有的操作全部交给服务器处理,增加了服务器的压力。

4、页面跳转:

    request.getRequestDispatcher("new.jsp").forward(request, response);

    地址栏显示servelet的名字?属性名=属性值&...,可以将前一个网页的值传递过去。

5、重定向:

    response.sendRedirect("new.jsp");

    地址栏中显示指定页面的值。不能传递数据。

6、request

    request.getParameter("useName");括号内写的是输入框的名字。

    request.getParameterValues("hobby");复选框,返回数组。   

    requst.setAttribute(属性的名字,属性值)

    requst.getAttribute(属性名字),在另一个页面中写。

    doGet()

        name = new String(name.getBytes("iso-8859-1"),"utf-8")

    doPost()

        给requst设置统一的编码格式   (要在得到表单中内容之前调用)

        request.setCharacterEncoding("utf-8");

 7、response

    response.sendRedirect("new.jsp");地址栏中显示的是 指定页面的地址。

8、请求方式:

    get:

        1、可以缓存

        2、请求保留在浏览器的历史中

        3、可以收藏为书签

        4、处理敏感数据时不能用

        5、数据的长度有限制

        6、数据在URL中对所有人可见

        7、数据类型必须使用ASCII编码。

        8、安全性差

    post:

        1、不可以缓存

        2、请求不保留在浏览器的历史中

        3、不可以收藏为书签

        4、数据的长度无限制

        5、数据在URL中不可见

        6、数据类型无限制

        7、安全在好

 9、生命周期:

    http请求→解析请求→创建servlet实例→调用init()方法→调用service方法→输出响应信息→响应

 10、错误提示

    404没有找到页面

    500服务器发生错误,一般代码有误

    200正确连接

HttpClient& HttpURLConnection&OkHttpClient

一、HttpClient

1、get方法

    1、创建对象                  HttpClient client = new DefaultHttpClient();

    2、创建请求方式对象,参数是地址            HttpGet get = new HttpGet("path");

    3、客户端发出请求,服务器进行响应       HttpResponse response = client.execute(get);

    4、判断是否成功,得到状态信息         if(response.getStatusLine().getStatusCode()==200){

    5、获取数据,entity 得到返回数据的"实体"   HttpEntity entity = response.getEntity();

                            InputStream inputStream = entity.getContent();

                            

                        // 通过entityUtils工具类可以将 返回数据直接 格式化成  String字符串

                        String result = EntityUtils.toString(httpEntity);

                        // 可以将entity转化成byte数组  (下载图片)

                        byte[] bs = EntityUtils.toByteArray(entity);

2、post方法

1、创建httpclient对象            HttpClient  client = new DefaultHttpClient();

2、创建请求方式对象,参数是地址        HttpPost post = new HttpPost(path);

3、创建BasicNameValuePair对象        BasicNameValuePair pair = new BasicNameValuePair("useName", "李四");

4、创建可以盛放参数的对象       List<BasicNameValuePair> list = new ArrayList<BasicNameValuePair>();

5、将参数封装到  httpEntity中       HttpEntity entity = new UrlEncodedFormEntity(list);

6、将带有参数的实体放入进httpPost中  post.setEntity(entity);

7、客户端请求数据 ,服务器端作出相应 HttpResponse response = client.execute(post);

8、 判断是否成功           if(response.getStatusLine().getStatusCode()==200){

                    HttpEntity entity2 = response.getEntity();

                    String result = EntityUtils.toString(entity2);

二、HttpURLConnection

1、get方法

    1、统一资源定位符           URL url=new URL(path);

    2、打开连接,向下转型         HttpURLConnection httpURLConnection=(HttpURLConnection) url.openConnection();

    3、设置请求方式                httpURLConnection.setRequestMethod("GET");

    4、连接服务器,可写可不写       httpURLConnection.connect();

    5、接收数据,先判断是否正确连接        if (httpURLConnection.getResponseCode()==200) {

    6、从从httpURLConnection取得数据   InputStream inputStream=httpURLConnection.getInputStream();

    7、读取数据等其他操作         BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream, "utf-8"));

2、post

    1、统一资源定位符           URL url=new URL(path);

    2、打开连接,向下转型         HttpURLConnection httpURLConnection=(HttpURLConnection) url.openConnection();

    3、设置请求方式                httpURLConnection.setRequestMethod("GET");

    4、设置post属性              httpURLConnection.setDoOutput(true);

                        httpURLConnection.setDoInput(true);、

    5、设置传递的数据(输出流)      OutputStream outputStream=httpURLConnection.getOutputStream();

                        outputStream.write(string.getBytes());

                        outputStream.flush();

    6、判断服务器响应码          if(httpURLConnection.getResponseCode()==200){

    7、从httpURLConnection取得数据        InputStream inputStream=httpURLConnection.getInputStream();

    8、读取数据等其他操作         BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream, "utf-8"));

三、OkHttpClient

1、get方法

    1、创建客户端对象                       OkHttpClient okHttpClient=new OkHttpClient();

    2、创建请求,使用构建起模式,通过自己的静态内部类创建对象并赋值    Request request=new Request.Builder().url(path).build();

    3、通过客户端发送请求,获取响应                    Response reponse=okHttpClient.newCall(request).execute();

    4、判断是否成功                            if(reponse.isSuccessful()){

                                    //通过响应得到响应的内容

                                    String result=response.body().string();//字符串

                                    byte[] bs=response.body().bytes();//byte数组(图片,文件等)}

2、post方法

    1、创建OkHttpCilent对象                      OkHttpClient okHttpClient=new OkHttpClient();

    2、将post请求需要传递的参数放置到自己的对象中           RequestBody body=new FormBody.Builder().add("","").add("","").build();

    3、如果想要实现post请求,必须创建requst对象时,调用post方法 传递RequstBodyRequest request = new Request.Builder().url(path).post(body).build();调用post方法 证明是post请求

    4、客户端请求,服务端响应                   Response response = client.newCall(request).execute();

    5、判断是否成功                            if(reponse.isSuccessful()){

                                    //通过响应得到响应的内容

                                    String result=response.body().string();//字符串    }

XML解析&JSON解析

一、XML解析

xml和html的区别:

                HTML            XML

    可扩展性            不具有扩展性  是元标记语言,可定义新的标签

    侧重点         如何显示信息  如何结构化的描述信息

    语法要求   不要求标记的嵌套配对顺序等    严格要求标记的嵌套配对顺序等

    可读性可维护性      难阅读维护      结构清晰便于阅读维护

    数据和显示  内容描述和显示方式融合一起    内容描述和显示方式相分离

    保值性     不具有保值性      具有保值性

1、xml:可拓展的标记语言。

xml的命名规范:   允许英文字母,数字,

        只允许字母和下划线开头,

        不能使用空格,区分大小写,

        属性值必须用""引起来,不能交叉使用。

2、解析:

    Dom:先将整个文档全部加载在内存中,然后以树的结构去解析

        优点:解析速度快

        缺点:浪费内存

    Sax:

根据结点去解析,不会将这个文档全部加载内存中

        区分文档开始、标签开始、数据、标签结束、文档结束

        缺点:不会记录读取到哪一个标签,需要自己标记

        SAXParserFactory factory=SAXParserFactory.newInstance();

        SAXParser parser=factory.newSAXParser();

        MyHandler myHandler=new MyHandler();

        parser.parse("student2.xml",myHandler);

        List<Student> list=myHandler.result();

    MyHandle

            List<Student> students=null;

            Student student=null;

            String tag="";

            public  List<Student> result(){

            return students;

            }

            @Override

            public void startDocument() throws SAXException {

            students=new ArrayList<>();

            }

            @Override

            public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

            //qName当前解析的标签

            //开始标签

            tag=qName;

            if ("student".equals(qName)) {

            student=new Student();

            //标签内有多个属性时

            //int count=attributes.getLength();

            //for (int i = 0; i < count; i++) {

            //String name=attributes.getQName(i);

            //String value=attributes.getValue(i);

            //if ("id".equals(name)) {

            //student.setId(Integer.parseInt(value));

            //}

            //}

            //标签内只要一个属性时

            student.setId(Integer.parseInt(attributes.getValue(0)));

    

            }

            }

            @Override

            public void endElement(String uri, String localName, String qName) throws SAXException {

            // TODO Auto-generated method stub

            //遇到结束标签进入

            if ("student".equals(qName)) {

            students.add(student);

                }

            tag="";

            }

            @Override

            public void endDocument() throws SAXException {

            // TODO Auto-generated method stub

            super.endDocument();

            }

            @Override

            public void characters(char[] ch, int start, int length) throws SAXException {

            // TODO Auto-generated method stub

            String count=new String(ch, start, length).trim();

            if ("id".equals(tag)) {

                student.setId(Integer.parseInt(count));

            }else if ("name".equals(tag)) {

                student.setName(tag);

            }else if ("age".equals(tag)) {

                student.setAge(Integer.parseInt(count));

            }else if ("sex".equals(tag)) {

                student.setSex(count);

            }

            }

Pull:

android中的解析方式

            解析数据的时候可以记录标签

        1、得到pull解析对象的工厂对象

           XmlPullParseFactory factory=XmlPullParseFactory.newInatance();

        2、通过工厂对象得到解析对象

           XmlPullParse parse=factory.newPullParse();

        3、设置解析数据源

           parse.setInput(new FileReader(".xml"));

        4、设置解析文件中事件的状态

           int type=parse.getEventType();

        5、存放解析结果的集合

           Lst<Student> student=null;

        6、声明解析对象

           Student student=null;

        7、判断状态,根据状态取得数据。

           if(type!=XmlPullParse.END_DOCUMENT){

            switch(type){

            case XmlPullParse.START_DOCUMENT:

                student=new ArrayList<>();

                break;

            case XmlPullParse.START_TAG:

                if("student".queals(parser.getName())){

                    student=new Student();

                    }else if("id".equals(parse.getName()))

                        String id=parse.nextInt();

                        student.setId(Integer.parseInt(id));    

                        ......              

                }   }

        8、事件的状态进行下一个

            type=parse.next();

            }

        9、若标签中有很多属性

            int count=parser.getAttributeCount();

                for (int i = 0; i <count; i++) {

                    String arrName=parser.getAttributeName(i);

                    String arrValue=parser.getAttributeValue(i);

                    if ("id".equals(arrName)) {

                        student.setId(Integer.parseInt(arrValue));

                    }

3、用途:结构化的保存信息,通过服务端和服务器交互使用的,设置配置信息。

二、JSON解析

1、JSON

1、对象    JSONObject jsonObject=new JSONObject(string);

2、数组    JSONArray jsonArray=new JSONArray(string);

3、对象里对象 JSONObject jsonObject2=jsonObject.getJSONObject("dept");

4、对象里数组 JSONArray jsonArray=jsonObject.getJSONArray("persons"); 

例子:

    String string="{persons:[{name:'zhangsan',age:20},{name:'lisi',age:21},{name:'wangwu',age:22}]}";

    JSONObject jsonObject=new JSONObject(string);

    JSONArray jsonArray=jsonObject.getJSONArray("persons");

    List<Person3> list=new ArrayList<>();

    for (int i = 0; i < jsonArray.length(); i++) {

        JSONObject jsonObject2=jsonArray.getJSONObject(i);

        String name=jsonObject2.getString("name");

        int age=jsonObject2.getInt("age");

        Person3 person3=new Person3(name, age);

        list.add(person3);      

    }

    for (Person3 person3 : list) {

        System.out.println(person3);

            }

        }

        }

    class Person3{

        String name;

        int age;

        public Person3(String name, int age) {

            super();

            this.name = name;

            this.age = age;

        }

        @Override

        public String toString() {

            return "person2 [name=" + name + ", age=" + age + "]";

        }

        

    }

2、Gson

    Gson gson=new Gson();

    Person6 person6=gson.fromJson(string, Person6.class);

例子:

    String string = "{no:1,name:'android',employees:[{name:'zhangsan',age:20},{name:'lisi',age:21},{name:'wangwu',age:22}]}";

    Gson gson=new Gson();

    Person6 person6=gson.fromJson(string, Person6.class);

    System.out.println(person6);、

        }

    }

    class Person5{

        @Override

        public String toString() {

        return "Person5 [name=" + name + ", age=" + age + "]";

        }

        String name;

        int age;

    }

    class Person6

    {

        int no;

        String name;

        ArrayList<Person5> employees;

        @Override

        public String toString() {

            return "Person6 [no=" + no + ", name=" + name + ", employees=" + employees + "]";

        }

3、FastJson

Person4 person4=JSON.parseObject(string, Person4.class);

例子:

    String string = "{no:1,name:'android',employees:[{name:'zhangsan',age:20},{name:'lisi',age:21},{name:'wangwu',age:22}]}";

    Person4 person4=JSON.parseObject(string, Person4.class);

    System.out.println(person4);

        }

    }

class Person3{

    String name;

    int age;

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public int getAge() {

        return age;

    }

    public void setAge(int age) {

        this.age = age;

    }

    @Override

    public String toString() {

        return "Person3 [name=" + name + ", age=" + age + "]";

        }



}

class Person4{

int no;

String name;

ArrayList<Person3> employees;

public int getNo() {

    return no;

}

public void setNo(int no) {

    this.no = no;

}

public String getName() {

    return name;

}

public void setName(String name) {

    this.name = name;

}

public ArrayList<Person3> getEmployees() {

    return employees;

}

public void setEmployees(ArrayList<Person3> employees) {

    this.employees = employees;

}

@Override

public String toString() {

    return "Person4 [no=" + no + ", name=" + name + ", employees=" + employees + "]";

}



}
上一篇下一篇

猜你喜欢

热点阅读