Java基础知识

本文深入浅出地讲解了Linux操作系统的基本概念与常用命令,包括目录结构、安全级别及核心命令如pwd、ls和cd的使用。同时,文章详细介绍了Java开发环境的搭建,涵盖了编译运行流程、JVM、JRE与JDK的区别,以及环境变量的配置方法。适合初学者快速掌握Java与Linux的基础知识。
笔记:
1.Linux:
  1)开源的操作系统、免费
    主要是服务器操作系统,而Java主要是服务器端开发
  2)Linux与Windows目录结构的区别:
    2.1)文件系统不同:
	      Linux:目录     Windows:盘符
	2.2)外部设备映射不同:
	      Linux:挂载点   Windows:盘符
	2.3)安全级别不同:
	      Linux:高       Windows:低
  3)常用命令:
    3.1)pwd:显示当前工作目录
	3.2)ls:查看当前工作目录的内容
	3.3)cd:改变当前工作目录
	     绝对路径:相对于根目录的位置
		 相对路径:相对于当前目录的位置
		   .:当前目录
		   ..:上一级目录
2.Java开发环境:
  1)Java编译运行过程:---------常见面试题
    1.1)编译期:.java源文件,经过编译,生成.class字节码文件
	1.2)运行期:JVM加载.class并运行.class
	特点:跨平台、一次编程到处使用
  2)名词解释:-----------------常见面试题
    2.1)JVM:java虚拟机
	        加载.class并运行.class
	2.2)JRE:java运行环境
	        除了包含JVM以外还包含了运行Java程序所必须的环境
			JRE=JVM+java系统类库
	2.3)JDK:java开发工具包
	        除了包含JRE以外还包含了开发Java程序所必须的命令工具
			JDK=JRE+编译、运行等命令工具
		运行Java程序的最小环境为JRE
		开发Java程序的最小环境为JDK
  3)配置环境变量:-----了解(下周末看一看就懂了)
    3.1)JAVA_HOME:指向jdk的安装目录
	3.2)CLASSPATH:表示类的搜索路径,一般简写为.
	3.3)PATH:指向jdk下的bin目录
3.eclipse:
    IBM、开源的、免费、不需要安装,只需要解压即可

开发步骤:
1)新建一个Java项目/工程-------------小区
2)新建一个Java包--------------------楼+单元
3)新建一个Java类--------------------房子

注释:解释性文本
1)单行注释://
2)多行注释:/* */
3)文档注释:/** */
--------------------------------------------------------------------------------------------------
回顾:
1.Linux:
   开源的操作系统、免费,服务器
   目录、挂载点、安全级别高
   pwd,ls,cd
    绝对:相对于根目录的位置,以/开头
	相对:相对于当前目录的位置
	  .:当前目录
	  ..:上一级目录
2.java开发环境:
  1)编译运行过程:
    1.1)编译期:.java源文件,经过编译,生成.class字节码文件
	1.2)运行期:JVM加载.class并运行.class
	跨平台、一次编程到处使用
  2)JVM:java虚拟机
        加载并运行.class
    JRE:java运行环境
	    除了包含JVM以外还包含运行java程序必须的环境
		JRE=JVM+java系统类库
	JDK:java开发工具包
	    除了包含JRE以外还包含开发java程序必须的命令工具
		JDK=JRE+编译、运行等工具
  3)配置环境变量
3.eclipse
   IBM、开源的、免费的、只需解压即可
   System.out.println("你好");



笔记:
1.变量:存数的,代词,指代的就是它所存的那个数
  1)声明:
      int a; //声明一个整型的变量,名为a
	  int b,c,d; //声明三个整型的变量,名为b,c,d
  2)命名:
    2.1)只能包含字母、数字、_和$符,
	    并且不能以数字开头
	2.2)严格区分大小写
	2.3)不能使用关键字
	2.4)可以中文命名,但不建议
	    建议"英文的见名知意","驼峰命名法"
  3)初始化:第一次赋值
    3.1)声明的同时初始化:
	      int a = 250; //声明整型变量a并赋值为250
	3.2)先声明后初始化:
	      int a;   //声明整型变量a
		  a = 250; //给变量a赋值为250
  4)使用:
    4.1)对变量的使用就是对它所存的那个数的使用
	      int a = 5; //声明整型变量a并赋值为5
		  int b = a+10; //取出a的值5,加10后,再赋值给b
		  System.out.println(b); //输出b的值15
		  System.out.println("b"); //b,双引号中的原样输出
          a = a+10; //取出a的值5,加10后,再赋值给a
          System.out.println(a); //输出a的值15
	4.2)变量的使用必须与数据类型匹配
	      int a = 3.14; //编译错误,数据类型不匹配
	4.3)变量在用之前必须声明并初始化
	      System.out.println(m); //编译错误,m未声明
		  int m;
		  System.out.println(m); //编译错误,m未初始化
2.基本数据类型:
  1)int:整型,4个字节,-21个多亿到21个多亿
    1.1)整数直接量默认为int型,但不能超出范围,超范围则编译错误
	1.2)两个整数相除,结果还是整数,小数位无条件舍弃
	1.3)整数运算时超出范围,则发生溢出,溢出是需要避免的
  2)long:长整型,8个字节,很大很大很大
    2.1)长整型直接量需在数字后加L和l
	2.2)运算时为了避免溢出,需要第1个数字后加L
	2.3)System.currentTimeMillis()用于获取自
	    1970.1.1零时到此时此刻的毫秒数
  3)double:浮点型,8个字节,很大很大很大
    3.1)浮点数直接量默认为double型,表示float需在数字后加f或F
	3.2)double型数据参与运算时,有可能会出现舍入误差
	    精确场合不能用double,可选择BigDecimal(后续章节介绍)
  4)boolean:布尔型,1个字节
    4.1)只能取值为true和false
  5)char:字符型,2个字节
    5.1)采用Unicode编码格式,一个字符对应一个码
	    表现形式是字符char,实质上是码int(0到65535)
		ASCII码('a'--97  'A'--65  '0'--48)
	5.2)字符必须放在单引号中,有且仅有一个
	5.3)特殊字符需要通过\为转义
3.基本数据类型的转换:
    数据类型从小到大依次为:
	  byte,short,int,long,float,double
	        char,
  1)两种方式:
    1.1)自动类型转换:从小类型到大类型
	1.2)强制类型转换:从大类型到小类型
	      语法: (要转换为的类型)变量
		  强转有可能会溢出或丢失精度
  2)两点规则:
    2.1)整数直接量可以直接赋值给byte,short,char,
	    但不能超出范围
	2.2)byte,short,char型数据参与运算时,
	    先一律转为int再运算
4.Scanner的用法:
  1)在package下:
      import java.util.Scanner;
  2)在main方法中:
      Scanner scan = new Scanner(System.in);
  3)在第2步之下:
      System.out.println("请输入年龄:");      
      int age = scan.nextInt();
	  System.out.println("请输入价格:");
	  double price = scan.nextDouble();
--------------------------------------------------------------------------------------------------
回顾:
1.变量:存数的
    int a; int b,c,d;
	int a=5; int b; b=5;
	int c = a+10;
	System.out.println(c);
	int d = 4.6; //错
	System.out.println(m); //错
	int m;
	System.out.println(m); //错
2.基本数据类型:
  1)int:整型,4个字节,5,25,250...
  2)long:长整型,8个字节,5L,250L,10000000000L...
  3)double:浮点型,8个字节,2.5,3.14,5.0...
  4)boolean:布尔型,1个字节,true,false
  5)char:字符型,2个字节,'你','y','6',' ','\\'...
3.基本数据类型的转换:
  1)两种方式:
    1.1)自动类型转换:小到大
	1.2)强制类型转换:大到小
	      (要转的换的数据类型)变量
		  有可能溢出或丢失精度
  2)两点规则:
      short s1 = 5;
	  short s2 = 6;
	  short s3 = (short)(s1+s2);
4.Scanner的用法:
   import java.util.Scanner;
   Scanner scan = new Scanner(System.in);
   System.out.println("请输入年龄:");
   int age = scan.nextInt();
   System.out.println("请输入价格:");
   double price = scan.nextDouble();  


笔记:
1.运算符:
  1)算术运算符:+-*/%,++,--
  2)关系运算符:>,<,>=,<=,==,!= boolean
  3)逻辑运算符:&&,||,! boolean
  4)赋值运算符:=,+=,-=,*=,/=,%=
  5)字符串连接运算符:+
  6)三目运算符:boolean?数1:数2
2.分支结构:
  1)if结构:1条路
  2)if...else结构:2条路
  3)if...else if结构:多条路
  4)switch...case结构:多条路
    优点:效率高、结构清晰
	缺点:整数、相等
	break:跳出switch
************************************************************************************************
回顾:
1.运算符:
  1)算术:+-*/%,++,--
  2)关系:>,<,>=,<=,==,!= boolean
  3)逻辑:&&,||,! boolean
  4)赋值:=,+=,-=,*=,/=,%=
  5)字符串连接:+
  6)三目:boolean?数1:数2
2.分支结构:
  1)if:1
  2)if...else:2
  3)if...else if:多
  4)switch...case:多
    优点:效率高、结构清晰
	缺点:整数、相等
	break:跳出循环



笔记:
1.循环:反复执行一段相同或相似的语句
2.循环三要素:
  1)循环变量的初始化
  2)循环的条件(以循环变量为基础)
  3)循环变量的改变(向着循环的结束变)
  循环变量:在循环过程中所反复改变的那个量
3.循环结构:
  1)while:先判断后执行,有可能一次都不执行
  2)do...while:先执行后判断,至少执行一次
               要素1与要素3相同时,首选do...while
  3)for:应用率最高,固定次数循环
4.break:跳出循环
  continue:跳过循环体中剩余语句而进入下一次循环
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
回顾:
1.循环:反复执行一段相同或相似的语句
2.循环三要素:
  1)循环变量的初始化
  2)循环的条件(以循环变量为基础)
  3)循环变量的改变(向着循环的结束变)
  循环变量:在循环过程中所反复改变的那个量
3.循环结构:
  1)while:先判断后执行,有可能一次都不执行
  2)do...while:先执行后判断,至少执行一次
               要素1与要素3相同时首选
  3)for:应用率最高,固定次数循环
4.break:跳出循环
  continue:跳过循环体中剩余语句而进入下一次循环


笔记:
1.三种循环结构的更佳适用情况:
  1)while:"当..."循环
  2)do...while:"直到..."循环
               要素1与要素3相同时首选do...while
  3)for:固定次数循环,应用率最高
2.嵌套循环:
  1)循环中套循环,一般多行多列时使用,
    外层控制行,内层控制列
  2)执行过程:外层循环走一次,内层循环走所有次
  3)建议:循环层次越少越好,能一层就不用两层,能两层就不用三层
         若业务必须通过三层以上的循环才能解决,说明设计有问题
  4)break只能跳出一层循环
3.程序=算法+数据结构
  1)算法:解决问题的流程/步骤(顺序、分支、循环)
  2)数据结构:将数据按照某种特定的结构来保存
             数怎么存
	设计良好的/合理的数据结构会导致好的算法
4.数组:
  1)相同数据类型元素的集合
  2)数组是一种数据类型(引用类型)
  3)数组的定义:
      int[] arr = new int[10];
  4)数组的初始化:
      int[] arr = new int[3]; //0,0,0
	  int[] arr = {1,4,7}; //1,4,7
	  int[] arr = new int[]{1,4,7}; //1,4,7
	  int[] arr;
	  arr = {1,4,7}; //编译错误
	  arr = new int[]{1,4,7}; //正确
  5)数组的访问:
    5.1)通过(数组名.length)来获取数组的长度
	      int[] arr = new int[3];
          System.out.println(arr.length); //3
	5.2)通过下标/索引来访问数组中的元素
	    下标从0开始,最大到(数组的长度-1)
		  int[] arr = new int[3];
		  arr[0] = 100; //给arr中第1个元素赋值为100
		  arr[1] = 200;
		  arr[2] = 300;
		  arr[3] = 400; //数组下标越界异常
		  System.out.println(arr[arr.length-1]); //输出arr中最后一个元素的值
  6)数组的遍历:
      int[] arr = new int[10];
	  for(int i=0;i<arr.length;i++){
	    arr[i] = 100;
	  }
	  for(int i=0;i<arr.length;i++){
	    System.out.println(arr[i]);
	  }
	  for(int i=arr.length-1;i>=0;i--){
	    System.out.println(arr[i]);
	  }
  7)数组的复制:
    7.1)System.arraycopy(a,1,a1,0,4);
	7.2)int[] a1 = Arrays.copyOf(a,6);
	    a = Arrays.copyOf(a,a.length+1); //扩容
  8)数组的排序:
    8.1)Arrays.sort(arr); //升序排列
    8.2)冒泡排序算法:
	    8.2.1)4个数冒3轮
		8.2.2)每一轮都是从第1个元素开始冒
		      每一次都是和它的下一个元素比
		8.2.3)冒出来的就不带它玩了
************************************************************************************************
回顾:
1.适用情况:
2.嵌套循环:
    循环中套循环,外层走一次,内层走所有次
	层次越少越好,break只能跳出一层循环
3.数组:
    相同数据类型元素的集合,引用类型
	int[] arr = new int[10];
	int[] arr = {1,4,6};
	int[] arr = new int[]{1,4,6};
	arr[0] = 100;
	System.out.println(arr[arr.length-1]);
    for(int i=0;i<arr.length;i++){
	  arr[i] = 100;
	  System.out.println(arr[i]);
	}
	System.arraycopy(a,1,a1,0,4);
	int[] a1 = Arrays.copyOf(a,6);
    a = Arrays.copyOf(a,a.length+1); //扩容
	Arrays.sort(arr); //升序
	冒泡:
	  1)5个数冒4轮
	  2)每一轮都是从第1个元素开始冒
	    每一次都是和它的下一个元素比
	  3)冒出来的就不带它玩了




笔记:
1.方法:
  1)封装一段特定的业务逻辑功能
  2)方法要尽可能的独立,一个方法只干一件事
  3)方法可以被反复的调用多次
  4)减少代码的重复,有利于代码的维护,有利于团队的协作开发
2.方法的定义:
    修饰词 返回值类型 方法名(参数列表){
	  方法体
	}
3.方法的调用:
  3.1)无返回值: 方法名(有参传参);
  3.2)有返回值: 数据类型 变量 = 方法名(有参传参);
4.return的用法:
  1)return;    //1)结束方法的执行
  2)return 值; //1)结束方法的执行  2)返回结果给调用方
*******************************************************************************************
回顾:
1.方法:函数、过程
    封装一段特定的业务逻辑功能
	尽可能的独立,只干一件事
	可以被反复调用多次
    减少代码重复、有利于代码的维护,有利于团队协作
2.方法的定义:
    修饰词 返回值类型 方法名(参数列表){
	  方法体
	}
3.方法的调用:
  1)无返回值: 方法名(有参传参);
  2)有返回值: 数据类型 变量 = 方法名(有参传参);
              方法名(有参传参);--------不建议
4.return:
  1)return;    //1.1)结束方法的执行
  2)return 值; //2.1)结束方法的执行 2.2)返回值给调用方



笔记:
1.什么是类?什么是对象?
  1)现实世界是由很多很多对象组成的
    基于对象抽出了类
  2)对象:真实存在的单个的个体
    类:类别/类型,代表一类个体
  3)类中可以包含:
    3.1)所有对象所共有的属性/特征-------成员变量
	3.2)所有对象所共有的行为------------方法
  4)一个类可以包含多个对象,
    同一个类的多个对象,结构相同,数据不同
  5)类是对象的模板,对象是类的具体的实例
2.如何创建类?如何创建对象?如何访问成员?
3.引用类型之间画等号:
  1)指向同一个对象
  2)对其中一个引用的修改会影响另一个引用
    eg:房子钥匙
  基本类型之间画等号:
  1)赋值
  2)对其中一个变量的修改不会影响另一个变量
    eg:身份证复印件
4.null:空,没有指向任何对象
       若引用的值为null,则该引用不能再进行任何操作了
	   若操作则NullPointerException空指针异常
————————————————————————————————————————————————————————————————————————————————————————————————————
回顾:
1.什么是类?什么是对象?
2.如何创建类?如何创建对象?如何访问成员?
3.引用类型画等号:指向同一个对象 影响
  基本类型画等号:赋值 不会影响
4.null:空,没有指向任何对象
  若引用的值为null,则该引用不能再进行任何操作了
  若操作则发生NullPointerException





笔记:
0.方法的签名:方法名+参数列表
1.方法的重载(Overload):
  1)在同一个类中,方法名称相同,参数列表不同
  2)编译器在编译时自动根据签名来绑定调用的方法
2.构造方法:
  1)常常用于给成员变量赋初值
  2)与类同名,没有返回值类型
  3)在创建对象时被自动调用
  4)若自己不写构造方法,则编译器默认一个无参构造方法
    若自己写了构造方法,则不再默认提供
  5)构造方法可以重载
3.this:指代当前对象,哪个对象调方法指的就是哪个对象
       只能用在方法中,方法中访问成员变量之前默认有个this.
  this的用法:
    1)this.成员变量名-------------访问成员变量
	2)this.方法名()---------------调用方法
	3)this()----------------------调用构造方法
4.引用类型数组:
  1)Cell[] cells = new Cell[4]; //创建Cell数组对象
    cells[0] = new Cell(2,5);   //创建Cell对象
	cells[1] = new Cell(2,6);
	cells[2] = new Cell(2,7);
	cells[3] = new Cell(3,6);
  2)Cell[] cells = new Cell[]{
      new Cell(2,5),
	  new Cell(2,6),
	  new Cell(2,7),
	  new Cell(3,6)
    };
  3)int[][] arr = new int[3][];
    arr[0] = new int[2];
	arr[1] = new int[3];
	arr[2] = new int[2];
	arr[1][0] = 100; //给arr中第2个元素中的第1个元素赋值为100
  4)int[][] arr = new int[3][4]; //3行4列
    for(int i=0;i<arr.length;i++){
	  for(int j=0;j<arr[i].length;j++){
	    arr[i][j] = 100;
	  }
	}
***********************************************************************************
回顾:
1.方法的签名:方法名+参数列表
2.方法的重载:
  1)同一个类中,方法名称相同,参数列表不同
  2)编译器在编译时自动根据方法的签名来绑定调用的方法
3.构造方法:构造函数、构造器、构建器
  1)给成员变量赋初值
  2)与类同名,没有返回值类型
  3)在创建对象时被自动调用
  4)若自己不写,默认无参构造,若自己写了,则不再默认提供
  5)可以重载
4.this:指代当前对象,哪个对象调方法指的哪个对象
       只能用在方法中,方法中访问成员变量之前默认有个this.
	   this.成员变量名-------访问成员变量
	   this.方法名()---------调用方法
	   this()----------------调用构造方法
5.引用类型数组:
   Cell[] cells = new Cell[4]; //创建格子数组对象
   cells[0] = new Cell(0,0); //创建格子对象

   int[][] arr = new int[3][]; //数组的数组
   arr[0] = new int[2];
   
   int[][] arr = new int[3][4]; //3行4列


笔记:
1.内存管理:由JVM来管理---------了解
  1)堆:
    1.1)存储所有new出来的对象(包括成员变量)
	1.2)垃圾:没有任何引用所指向的对象
	    垃圾回收器(GC)不定时到内存中清扫垃圾,
		回收过程是透明的,并不一定一发现垃圾,则立即回收,
		调用System.gc()可以建议JVM尽快调度GC来回收垃圾
	1.3)内存泄漏:不再使用的内存还没有被及时的回收
	             严重的泄漏会导致系统的崩溃
		建议:对象不再使用时及时将引用设置为null
	1.4)成员变量的生命周期:
	      创建对象时被存储在堆中,对象被回收时一并被回收
  2)栈:
    2.1)存储正在调用的方法中的所有局部变量(包括参数)
	2.2)调用方法时在栈中为该方法分配一块对应的栈帧,
	    栈帧中存储方法的局部变量以及参数,
		方法执行结束则栈帧被清除,局部变量一并被清除
	2.3)局部变量的生命周期:
	      调用方法时被存储在栈中,方法结束时与栈帧一并被清除
  3)方法区:
    3.1)用于存储.class字节码文件(包括方法)
	3.2)方法只有一份,通过this来区分具体的对象
2.继承:
  1)作用:实现代码的复用
  2)通过extends来实现继承
  3)父类:所有子类所共有的属性和行为
    子类:子类所特有的属性和行为
  4)子类继承父类后,子类具有:子类的+父类的
  5)一个父类可以有多个子类,
    一个子类只能有一个父类-------单一继承
  6)继承具有传递性
  7)java规定:构造子类之前必须得先构造父类
    子类构造方法中若没有调用父类的构造方法,
	则默认super()调用父类的无参构造方法,
	若子类构造方法中调用父类构造方法了,则不再默认提供
    super()调用父类构造方法必须位于子类构造的第一句
3.super:指代当前对象的父类对象
  super的用法:
    1)super.成员变量名---------访问父类的成员变量
	2)super.方法名()-----------调用父类的方法
	3)super()------------------调用父类的构造方法
4.向上造型:
  1)父类型的引用指向子类对象
  2)能点出来什么,看引用的类型
*********************************************************************************
回顾:
1.内存管理:JVM
  1)堆:所有new出来的对象(包括成员变量)
  2)栈:正在调用的方法中的所有局部变量(包括参数)
  3)方法区:.class字节码文件(包括方法)
2.继承:
    代码的复用,extends,
	父:所有子类共有的属性和行为
	子:子类所特有的的属性和行为
	子继承父,子具有:父+子
	单一继承,传递性
	构造子之前必须先构造父,
	  子构造必须通过super调用父类的构造方法
	  若自己不写则默认super()调父类无参构造,
	  若自己写了,则不再默认提供
3.super:指代当前对象的父类对象
    super.成员变量名
	super.方法名()
	super()
4.向上造型:
  1)父类型的引用指向子类的对象
  2)能点出来什么,看引用的类型





笔记:
1.方法的重写(Override):重新写、覆盖
  1)发生在父子类中,方法名称相同,参数列表相同,方法体不同
  2)重写方法被调用时,看对象的类型
2.重写与重载的区别:----------常见面试题
  1)重写(Override):
    1.1)发生在父子类中,方法名称相同,参数列表相同,方法体不同
	1.2)遵循"运行期绑定",看对象的类型调用方法
  2)重载(Overload):
    2.1)发生在一个类中,方法名称相同,参数列表不同,方法体不同
	2.2)遵循"编译期绑定",看引用/参数的类型绑定方法
3.package:
  1)作用:避免类的命名冲突
  2)包名可以有层次结构
  3)同包中的类不能同名,类的全称:包名.类名
  4)包名建议:所有字母都小写
  import:
  1)同包中的类可以直接访问,
    不同包中的类不能直接访问,想访问:
    1.1)先import声明类,再直接访问类-----建议
	1.2)类的全称-----------------太繁琐,不建议
4.访问控制修饰符:
  1)public:公开的,任何类
  2)private:私有的,本类
  3)protected:受保护的,本类、子类、同包类
  4)默认的:什么也不写,本类、同包类
  类的访问修饰符只能是public和默认的
  类中的成员的访问修饰符如上4种都可以
5.static:静态的
  1)静态变量:
    1.1)由static修饰
	1.2)属于类的,存在方法区中,只有一份
	1.3)常常通过类名点来访问
	1.4)何时用:所有对象所共享的数据(图片、音频、视频等)
  2)静态方法:
    2.1)由static修饰
	2.2)属于类的,存在方法区中,只有一份
	2.3)常常通过类名点来访问
	2.4)没有隐式的this传递,
	    所以在静态方法中不能直接访问实例成员
	2.5)何时用:方法的操作仅与参数相关而与对象无关
  3)静态块:
    3.1)由static修饰
	3.2)在类被加载期间自动执行,因类中被加载一次,
	    所以静态块也只执行一次
	3.3)何时用:加载/初始化静态资源(图片、音频、视频等)
6.final:最终的、不可改变的
  1)修饰变量:变量不能被改变
  2)修饰方法:方法不能被重写
  3)修饰类:类不能被继承
7.static final常量:----------自学(明天讲)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
回顾:
1.方法的重写(override):
  1)发生在父子类中,方法名称相同,参数列表相同,方法体不同
  2)重写方法被调用时,看对象的类型
2.重写与重载的区别:
  1)重写:
    1.1)发生在父子类中,方法名称相同,参数列表相同,方法体不同
	1.2)遵循"运行期绑定",看对象的类型来调用方法
  2)重载:
    2.1)发生在同一类中,方法名称相同,参数列表不同,方法体不同
	2.2)遵循"编译期绑定",看参数/引用的类型来绑定方法
3.package和import:
4.访问控制修饰符:
  1)public:公开的,任何类
  2)private:私有的,本类
  3)protected:受保护的,本类、子类、同包类
  4)默认的:什么也不写,本类、同包类
5.static:静态的
  1)静态变量:
      static,属于类,存在方法区,一份,类名点
	  所有对象所共享的数据(图片、音频、视频等)
  2)静态方法:
      static,属于类,存在方法区,一份,类名点
	  没有隐式this传递,所以静态方法中不能直接访问实例成员
	  方法的操作仅与参数相关而与对象无关
  3)静态块:
      static,属于类,类被加载时自动执行,一次
	  加载/初始化静态资源(图片、音频、视频等)
6.final:不可变的、最终的
  1)修饰变量:变量不能被改变
  2)修饰方法:方法不能被重写
  3)修饰类:类不能被继承




笔记:
1.static final常量:
  1)必须声明同时初始化
  2)通过类名点来访问,不能被改变
  3)建议:常量名所有字母都大写,多个单词用_分隔
  4)编译器在编译时常量被直接替换为具体的值,效率高
2.抽象方法:
  1)由abstract修饰
  2)只有方法的定义,没有方法的具体实现(连{}都没有)
3.抽象类:
  1)由abstract修饰
  2)包含抽象方法的类必须是抽象类
    不包含抽象方法的类也可以声明为抽象类---我乐意
  3)抽象类不能被实例化
  4)抽象类是需要被继承的,子类:
    4.1)重写所有抽象方法-------常用
	4.2)也声明为抽象类---------不常用
  5)抽象类的意义:
    5.1)封装子类所共有的属性和行为-------代码复用
	5.2)为所有子类提供一种统一的类型-----向上造型
	5.3)可以包含抽象方法,为所有子类提供一个统一的入口
	    子类可以有不同的实现,但方法的定义是一致的
4.接口:
  1)是一个标准、规范--------制定方
    遵守了这个标准,就能干某件事---------API之后
  2)接口是一种数据类型(引用类型)
  3)由interface定义
  4)只能包含常量和抽象方法
  5)接口不能被实例化
  6)接口是需要被实现的,实现类:
      必须重写接口中的所有抽象方法
  7)一个类可以实现多个接口,用逗号分隔
    若又继承又实现时,应先继承后实现
  8)接口可以继承接口
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
回顾:
1.static final常量:
    必须声明同时初始化,类名访问,不能改,大写
	编译时被直接替换为具体的数,效率高
2.抽象方法
    abstract,只有方法的定义,没有具体的实现
3.抽象类
    abstract,包含抽象方法的类必须是抽象类
	不能被实例化,是需要被继承的,子类:
	  1)重写所有抽象方法
	  2)也声明为抽象类
	意义:
	  1)封装所有子类所共有的属性和行为-----代码复用
	  2)为所有子类提供统一的类型-----------向上造型
	  3)可以包含抽象方法,为所有子类提供统一的入口
4.接口
    标准、规范,引用数据类型,
	interface定义,只能包含常量和抽象方法
	不能被实例化,是需要被实现的,实现类
	  1)必须重写所有抽象方法
	一个类可以实现多个接口,用逗号分隔,应先继承后实现
	接口继承接口





正课:
1.多态:
  1)多态的意义:
    1.1)同一类型的引用,指向不同的对象时,有不同的实现
	    -----行为的多态:cut(),run(),study(),teach()...
	1.2)同一个对象,被造型为不同的类型时,有不同的功能
	    -----对象的多态:我,水...
  2)向上造型:
    2.1)父类型的引用指向子类的对象
	2.2)能造型成为的类型有: 父类+它所实现的接口
	2.3)能点出来什么,看引用的类型
  3)强制类型转换,成功的条件只有两种:
    3.1)引用所指向的对象,就是该类型
	3.2)引用所指向的对象,实现了该接口
  4)若不符合如上两个条件,则发生ClassCastException类型转换异常
    建议:在强转之前先通过instanceof判断引用指向的对象是否是某种类型
2.成员内部类:
3.匿名内部类:
4.面向对象总结:
————————————————————————————————————————————————————————————————————————
回顾:
1.多态:
  1)意义:
    1.1)行为的多态:cut(),run(),study(),teach()...
	1.2)对象的多态:我,你,水...
  2)向上造型:
    2.1)父类型的引用指向子类的对象
	2.2)能造型成为的类型有:父类+所实现的接口
	2.3)能点出来什么,看引用的类型
  3)强制类型转换,成功的条件有两种:
    3.1)引用所指向的对象,就是该类型
	3.2)引用所指向的对象,实现了该接口
  4)若不满足如上两个条件,则发生ClassCastException
    建议:强转之前先能过instanceof判断引用指向的对象是否是该类型


正课:
1.成员内部类: 应用率低
  1)类中套类,外面的称为Outer外部类,里面的称为Inner内部类
  2)内部类通常只服务于外部类,对外不具备可见性
  3)内部类对象通常需要在外部类中创建
  4)内部类可以直接访问外部类的成员,包括私有的
    内部类中有个隐式的引用指向了创建它的外部类对象
	   外部类名.this
2.匿名内部类:
  1)若想创建一个类(子类)的对象,并且对象只被创建一次,
    此时该类不必命名,称之为匿名内部类
  2)内部类中访问外部的变量,该变量必须是final的





面向对象三大特征:
1.封装:
  1.1)类:封装的是对象的属性和行为
  1.2)方法:封装的是具体的业务逻辑功能实现
  1.3)访问控制修饰符:封装的是访问的权限
2.继承:
  2.1)作用:代码的复用
  2.2)extends,父类:共有的 子类:特有的
  2.3)单一继承,多接口实现,传递性
3.多态:
  3.1)意义:行为多态、对象多态
  3.2)向上造型,强制类型转换,instanceof判断
  3.3)多态的表现形式:
      3.3.1)重写:根据对象来实现多态
	  3.3.2)重载:根据参数来实现多态


面向对象课程安排:
第一天:
  1)什么是类?什么是对象?
  2)如何创建类?如何创建对象?如何访问成员?
  3)引用类型之间画等号
  4)null和NullPointerException
第二天:
  1)方法的重载(Overload)
  2)构造方法
  3)this
  4)引用类型数组
第三天:
  1)内存管理:
  2)继承:
  3)super
  4)向上造型
第四天:
  1)方法的重写、重写与重载的区别
  2)package和import
  3)访问控制修饰符
  4)static:
  5)final:
  6)static final常量:
第五天:
  1)抽象方法
  2)抽象类
  3)接口
  4)抽象类与接口的区别
第六天:
  1)多态:意义、向上造型、强制类型转换、instanceof
  2)成员内部类
  3)匿名内部类

*****************************************************************************************************************
JDK API包含的类库功能强大,经常使用的有:字符串操作 集合操作 文件操作 输入输出操作 网络操作 多线程等

	包					功能
 java.lang			java程序的基础类,如字符串 多线程等,该包中的
					类使用的频率非常高,不需要import,可以直接使用.
 java.util			常用工具类,如集合,随机数生产器,日历,时钟等.
  java.io			文件操作,输入/输出操作
  java.net			网络操作
 java.match			数学运算相关操作
java.security		安全相关操作
 java.sql			数据库访问
 java.text			处理文字,日期,数字,信息的格式.

/**
 * 文档注释
 * 文档注释只修饰三个地方:类,方法,常量
 * 用于说明它们的设计意图和作用.
 * 
 * 写在类和方法的开头,专门用于生成
 * 供API使用者进行参考的文档资料
 * 
 * @author-------------------------->作者
 * @version 1.0 21/6/17------------->版本
 * @see java.lang.String------------>参见
 * @since JDK----------------------->始于JDK版本
 * 
 */

	/**
	 * 
	 * @param name 指定的用户的名字----->参数说明
	 * @return 返回含有问候语的字符串--->返回值说明
	 * @throws 			--------------->异常抛出说明
	 */

/**
 * int length()
 * 返回当前字符串的长度(字符个数)
 */

如何使用:
	String str="你好java";
	str.length()-->字符串str长度

/**
 * int indexOf(String str)
 * 返回给定字符串在当前字符串中的位置,若当前字符串
 * 中不含有给定内容则返回值-1
 */

如何使用:
                  0123456789012345
	String str = "thinking in java";//java编程思想
	int index = str.indexOf("in");//查找in在字符串中的位置 即 i的位置
	index = str.indexOf("in",3);//从指定位置开始查找
	index = str.lastIndexOf("in");//查找最后一次出现的位置

/**
 * String substring(int start,int end)
 * 截取字符串
 * java api中通常用两个数字表示范围时都是"含头不含尾"的
 */

如何使用:
	String str = "www.oracle.com";
	String sub = str.substring(4,10);//截取指定下标4-9的字符串
	sub=str.substring(4);////截取指定下标4之后的字符串

	/**
	 * 截取域名:
	 * http://www.tedu.cn
	 * www.tedu.cn
	 */

	如何使用:
		String host="www.tedu.cn";
		int start = host.indexOf(".")+1;//获取指定字符'.'后一位字符的下标
		int end = host.indexOf(".",start);//从指定位置开始查找
		host.substring(start,end);//截取指定下标4-9的字符串

/**
 * String trim()
 * 去除一个字符串两边的空白字符
 */

如何使用:
	String str = "   hello     ";
	String trim = str.trim();//去字符串str两边的空白字符

/**
 * char charAt(int index)
 * 返回当前字符串中指定下标处对应的字符
 */

如何使用:
                  0123456789012345
	String str = "thinking in java";
	char c=str.charAt(12);//返回指定下标5处对应的字符
	
	//判断回文
	String info = "上海自来水来自海上";
	for(int i=0;i<info.length();i++){
		if(info.charAt(i)!=
			info.charAt(info.length()-1-i)
				){
			System.out.println("不是回文");
		}
	}
	System.out.println("是回文");

/**
 * boolean startsWith(String str)
 * boolean endsWith(String)
 * 判断字符串是否是以给定字符串开始或结尾的
 */

如何使用:
	String str = "thinking in java";
	boolean starts = str.startsWith("thi");//判断字符串是否是以给定字符串开始的
	boolean ends=str.endsWith("java");//判断字符串是否是以给定字符串结尾的

/**
 * String toLowerCase()
 * string toUpperCase()
 * 将当前字符串中的英文部分转换为全小写或全大写
 */

如何使用:
	String str = "我爱Java";
	String upper=str.toUpperCase();//-->将字符串str中的Java转换为大写
	String lower=str.toLowerCase();//-->将字符串str中的Java转换为小写

/**
 * static String valueOf()
 * String提供了若干重载的valueOf方法,作用是将java中
 * 其他类型的数据转换为字符串
 */

如何使用:
	int i=123;
	String istr=String.valueOf(i);//将int类型的数值转换为字符串类型
	double d=123.123;
	String dstr=String.valueOf(d);//将double类型的数值转换为字符串类型

/**
 * 由于java中字符串的设计不利于频繁修改内容,所以
 * java提供了另一种解决办法---java.lang.StringBuilder
 * 该类的设计就是为了解决相关修改字符串内容.其提供了便于
 * 编辑字符串内容的相关方法.
 */

如何使用:
	String str = "努力学习java";
	StringBuilder builder=new StringBuilder(str);//声明一个StringBuilder类型变量,将str传参给它
	
	/*
	 * 努力学习java
	 * 努力学习java,为了找个好工作!
	 * append(String str)
	 * 将给定字符串拼接到当前字符串的末尾
	 */
	builder.append(",为了找个好工作!");
	str=builder.toString();
	System.out.println(str);
	
	/*
	 * 努力学习java,为了找个好工作!
	 * 努力学习java,就是为了改变世界!
	 * 
	 * replace(int s,int e,String str)
	 * 将指定范围内的字符串替换为给定字符串
	 */
	builder.replace(9,16,"就是为了改变世界");
	System.out.println(builder.toString());

	/*
	 * 努力学习java,就是为了改变世界!
	 * ,就是为了改变世界!
	 * 
	 * delete(int s,int e)
	 * 删除指定范围内的字符串
	 */
	builder.delete(0, 8);
	System.out.println(builder.toString());
	
	/*
	 * ,就是为了改变世界!
	 * 活着,就是为了改变世界!
	 * insert(int index,String str)
	 * 在指定位置插入给定字符串
	 */
	builder.insert(0, "活着");
	System.out.println(builder.toString());
	
	builder.reverse();
	System.out.println(builder.toString());

/**
 * 字符串是不变对象,即:
 * 字符串对象一旦创建内容不可改变,若改变必定创建新对象.
 */

如何使用:
	String s1="123abc";
	String s2="123abc";
	/**
	 * JAVA推荐使用直接量(字面量)的形式创建
	 * 字符串对象,因为JVM对字符串做了一个优化
	 * 即:字符串常量池
	 * 当使用直接量创建字符串对象时,JVM首先查看
	 * 常量池中是否缓存过该字符串,没有则创建
	 * 并缓存,有则直接拿来重用,减少重复字符串带来的
	 * 内存开销.
	 */
	System.out.println(s1==s2);//true
	/**
	 * 一旦修改字符串对象内容就会创建新对象
	 */
	s1=s1+"!";//s1不再引用原来的123abc对象 
	System.out.println(s1);//123abc!
	System.out.println(s2);//123abc
	System.out.println(s1==s2);//false
	
	/**
	 * 编译器在编译源代码时 有一个优化措施:
	 * 当一个计算表达式的参数全部为字面量时,
	 * 编译器会直接计算该表达式并将结果编译到
	 * class文件中,所以下面的代码JVM在运行class
	 * 文件时的样子为:
	 * Striing s3="123abc"
	 */
	String s3="123"+"abc";
	System.out.println("s3:"+s3);
	System.out.println(s3==s2);//true
	
	String str="123";
	String s4=str+"abc";
	System.out.println("s4:"+s4);
	System.out.println(s4==s2);//false




/**
 * 正则表达式:
 * 正则表达式是用一组特殊字符描述的一个表达式,表述
 * 一个字符串的格式,然后用这个表达式来验证某个字符串
 * 是否符合该格式要求.
 * 
 * 字符串支持正则表达式的相关方法
 * boolean matches(String regex)
 * 使用给定的正则表达式来匹配当前字符串是否满足格式要求
 */

  正则表达式					说明
    [abc]			a.b.c中任意一个字符
   [^abc]			除了a.b.c的任意字符
    [a-z]			a.b.c.....z中的任意一个字符
  [a-zA-Z0-9]		a-z.A-Z.0-9中任意一个字符
  [a-z&&[^bc]]		a-z中除了b和c以外的任意一个字符,其中
					&&表示"与"的关系

			预定义字符集
  正则表达式				说明
	  .				任意一个字符
	 \d				任意一个数字字符
	 \w				单词字符,相当于[a-zA-Z0-9]
	 \s				空白字符,相当于[\t\n\x0B\f\r]
	 \D				非数字字符
	 \W				非单词字符
	 \S				非空白字符

			  数量词
  正则表达式				说明
	 X?				表示0个或一个X
	 X*				表示0个或任意多个X
	 X+				表示1个到任意多个X(大于等于1个X)
	X{n}			表示n个X
	X{n,}			表示n个到任意多个X(大于等于n个X)
	X{n,m}			表示n个到m个X

	如何使用:
		String email="xiezx@tedu.cn";
	//	String regex="[a-zA-Z0-9_]+@[a-zA-Z0-9_]+(\\.[a-zA-Z]+)+";
		String regex="\\w+@\\w+(\\.[a-zA-Z]+)+";//正则表达式
		boolean match=email.matches(regex);//判断是否符合指定表达式的格式要求

	/**
	 * String[] split(String regex)
	 * 将当前字符串按照正则表达式可以匹配的部分
	 * 拆分,将拆分后的若干字符串存入一个数组并返回
	 */

	如何使用:
		String str="012abc123def456ghi789uio";
		String[] date=str.split("[a-z]+");//将当前字符串按照正则表达式可以匹配的部分拆分
		for(int i=0;i<date.length;i++){			//并将拆分后的若干字符串存入一个数组并返回
			System.out.println(date[i]);//按照循环的方式将数组里的字符串依次输出
		}

	/**
	 * String replaceAll(String regex,String str)
	 * 将当前字符串中满足正则表达式的部分替换为给定字符串
	 */

	如何使用:
		String str="aaa123bbb456ccc789ddd";
		/*
		 * 将数字部分替换为"#NUMBER#"  #CHAR#
		 */
		str=str.replaceAll("\\d+","#NUMBER#");
		System.out.println(str);
		str=str.replaceAll("[a-z]+","#CHAR#");
		//str=str.replaceAll("\\D+","#CHAR#");

	例题:
		/**
		 * 程序启动后,要求用户输入邮箱地址,
		 * 然后检验该邮箱格式是否正确,之后输出一句话:
		 * 你输入的邮箱格式有误,请重新输入.
		 * 当输入正确之后输出一句话:
		 * 你好![user],您使用的邮箱格式域名为[host]
		 * 
		 * 如何使用:xiezx@tedu.cn
		 * 输出:你好!xiezx,你使用的邮箱域名为tedu
		 * @author soft01
		 *
		 */

				public static void main(String[] args) {
		
					Scanner scan=new Scanner(System.in);
					String email=null;
					while(true){
						System.out.println("请输入邮箱地址:");
						email=scan.next();
						if(matches(email)){
							break;
						}else{
							System.out.println("你输入的邮箱格式有误");
						}
					}
					String[] date=email.split("\\.");
					String[] dates=date[0].split("@");
					System.out.println("你好!"+dates[0]+",你使用的邮箱格式域名为"+dates[1]);
				}
	
				/**
				 * 判断用户输入的邮箱格式是否正确
				 * @param email
				 * @return
				 */
				public static boolean matches(String email){
					String regex="\\w+@\\w+(\\.[a-z]+)+";
					System.out.println(regex);
					email.matches(regex);
					System.out.println(email.matches(regex));
					return email.matches(regex);
				}

	/**
	 * java中所有的类都继承自Object
	 * 当我们定义的一个类没有使用extends继承任何类时,编译器
	 * 在编译时会自动让当前类继承Object
	 * 
	 * 使用该类测试重写Object的相关方法
	 */

			/**
			 * 通常需要用到一个类的toString方法时,就应当
			 * 重写该方法.因为Object提供的该方法返回的字符串
			 * 是该对象的句柄(地址信息)
			 * 
			 * toString方法返回的字符串应当包含当前对象的
			 * 属性信息.具体格式结合实际需求而定.
			 */
			public String toString(){
				return "(" + x + "," + y + ")";
			}
	
			/**
			 * equals方法的作用是比较当前对象与参数给定的对象
			 * 内容是否一致.即:两个对象"像不像"
			 * 
			 * 若不重写该方法,则使用Object提供的,但是Object
			 * 提供equals方法内部比较原则就是"==",所以不具备
			 * 实际意义
			 * 
			 * equals方法并不要求两个对象所有属性值必须完全
			 * 一样,结合实际业务逻辑需求定义判断标准.
			 */
			public boolean equals(Object obj){
				if(obj==null){
					return false;			
				}
				if(obj==this){
					return true;			
				}
				if(obj instanceof _7Point){
					_7Point p=(_7Point)obj;
					return this.x==p.x&&this.y==p.y;
				}
				return false;
			}


		//测试Point重写的Object相关方法
				_7Point p=new _7Point();
				p.setX(1);
				p.setY(2);
		
				String str=p.toString();
				/**
				 * System.out.println(Object obj);
				 * 该方法会将给定对象的toString方法返回值
				 * 输出到控制台
				 */
				System.out.println(p);
		
				_7Point p2=new _7Point();
				p2.setX(1);
				p2.setY(2);
				System.out.println(p2);
		
				System.out.println(p==p2);//false
				System.out.println(p.equals(p2));//true


/**
 * 包装类
 * 由于java中有8个基本数据类型,它们不具有面向对象的
 * 特性,因此不能直接参与到面向对象的开发中,为了
 * 解决这个问题,java对着8个基本类型分别提供了对应
 * 的包装类.
 * 
 * 其中数字类型的包装类继承自java.lang.Number
 * Number定义了一些抽象方法,允许在数字的类型之间相互
 * 转换
 */

	如何使用:
	//		int->Interger
			int d=123;
			Integer dd=new Integer(d);
	
	//		long->long
			long l=123123L;
			Long ll=new Long(l);
	
	//		Integer->int
			d=dd.intValue();
	//		Long->long
			l=ll.longValue();
	
	//		Integer->byte
			byte b=dd.byteValue();
			System.out.println(b);

	/**
	 * 基本类型转换为包转类应当使用静态方法valuef
	 */

		如何使用:
			Integer i1=Integer.valueOf(123);
			Integer i2=Integer.valueOf(123);
			//Integer的valueOf会缓存1个字节内的整数
			System.out.println(i1==i2);//true
			System.out.println(i1.equals(i2));//true
		
			Double d1=Double.valueOf(12.12);
			Double d2=Double.valueOf(12.12);
			System.out.println(d1==d2);//false
			System.out.println(d1.equals(d2));//true

	/**
	 * 所有数字基本类型包装类都有两个常量分别表示其对应
	 * 的基本类型的最大值与最小值
	 */

		如何使用:		
			int imax=Integer.MAX_VALUE;
			int imin=Integer.MIN_VALUE;

			long lmax=Long.MAX_VALUE;
			long lmin=Long.MIN_VALUE;

			double dmax=Double.MAX_VALUE;
			double dmin=Double.MIN_VALUE;

	/**
	 * JDK1.5之后推出了一个新特性
	 * 自动拆装箱
	 * 自动拆装箱特性是编译器认可而不是虚拟机认可
	 * 即:编译器在编译源代码时会自动补全代码来完成
	 * 基本类型于引用类型之间的转换.
	 */
	/**
	 * 触发自动装箱特性(基本类型转换为引用类型)
	 * 下面的代码会被编译器改为:
	 * Integer in=Integer.valueOf(1);
	 */
	Integer in=1;
	/**
	 * 触发自动装箱特性(引用类型转换为基本类型)
	 * 下面的代码会被编译器改为:
	 * int i=in.inValue();
	 */
	int i=in;

	/**
	 * 包装类提供了一个静态方法parseXXX(String str)
	 * 可以将字符串解析为对应的基本类型数据.前提是该
	 * 字符串能正确表示基本数据类型的值
	 */

	如何使用:
		String str="123";
		int i=Integer.parseInt(str);//123
		double d=Double.parseDouble(str);//123.0

/**
 * java.util.Date
 * Date的每一个实例用于表示一个具体的时间
 * 内部维护一个long值,该值为UTC时间
 * 即:1970年1月1号00:00:00 到当前Date所表示的时间
 * 之间所经过的毫秒.
 * 由于Date存在设计缺陷(时区,千年虫问题),所以Date的
 * 大部分操作时间的方法全部被标注为过时方法.
 * 
 * 因此使用Date仅用做表示一个时间
 */

		如何使用:
			/*
			 *默认创建出来表示当前系统时间
			 */
			Date date=new Date();
	
			System.out.println(date);
	
			/*
			 *获取Date内部维护的long值 
			 */
			long time = date.getTime();
			System.out.println(time);
	
			time+=1000*60*60*24;
			date.setTime(time);
			System.out.println(date);
			Date ds=new Date();
			ds.setTime(time);
			System.out.println(ds);

/**
 * java.text.SimpleDateFormat_format
 * SimplleDateFormat可以按照指定的日期格式在
 * Date与String之间相互转换.
 */

	如何使用:
		Date now = new Date();
		System.out.println(now);
		/*
		 * 时间格式转换
		 * "yyyy-MM-dd HH:mm:ss E"
		 */
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss E");
		/*
		 * String format(Date date)
		 * 将给定的Date表示的日期按照当前SimpleDateFormat
		 * 指定的格式转换为字符串.
		 * Date-->String
		 */
		String str=sdf.format(now);
		System.out.println(str);

	/**
	 * date parse(String)
	 * 将给定的字符串按照当前SimpleDateFormat指定的
	 * 日期格式解析为Date
	 * String-->Date
	 * @author soft01
	 *
	 */

		如何使用:		
			String str="2008-08-08 20:08:08";
		
			SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
			Date date=sdf.parse(str);
	
			System.out.println(date);

	/**
	 * 要求用户输入自己的生日,格式如1992-08-04
	 * 然后经过程序计算输出到今天为止活了多少天.
	 * @author soft01
	 *
	 */
		如何使用:
			Scanner scan=new Scanner(System.in);
			System.out.println("请输入生日: 格式如1992-09-24");
			String birth=scan.nextLine();
			SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
			Date birthDate=sdf.parse(birth);
			Date now=new Date();
			long birthtime=birthDate.getTime();
			long time=now.getTime()-birthDate.getTime();
			time/=1000*60*60*24;
			System.out.println("你迄今为止已经活了"+time+"天");
			birthtime+=1000*60*60*24*10000L;
			birthDate.setTime(birthtime);
			String st=sdf.format(birthDate);
			System.out.println(st);

/**
 * java.util.Calendar
 * 日历类.该类是一个抽象类,规定了用于操作
 * 时间的相关方法.
 * Date大部分操作时间的方法都是过时的,取而
 * 代之的就是Calendar中的相关方法.
 * 
 * 常用实现类:GregorianCalendar 即:阳历
 * Calendar有一个静态方法:
 * static Calendar getInstance()
 * 该方法可以获取当前系统所在地区适用的
 * 历法实现类,大部分地区返回的都是GreorianCalendar
 * @author soft01
 *
 */
		如何使用:
			/*
			 * 默认创建的Calendar实例也是表示
			 * 当前系统默认时间
			 */
			Calendar calendar=Calendar.getInstance();
		
			/*
			 * GreorianCalendar的toString
			 * 信息很多,但是不能直观反映出
			 * 表示的日期.
			 */
			System.out.println(calendar);
		
			/*
			 * Calendar提供了一个方法:
			 * Date getTime();
			 * 该方法可以将当前Calendar所表示
			 * 的时间以一个Date实例形式返回
			 * 
			 * Calendar-->Date
			 */
			Date date=calendar.getTime();
			System.out.println(date);
		
			/*
			 * void setTime(Date date)
			 * 使当前Calendar表示给定的Date所
			 * 表示的日期
			 * Date-->Calendar
			 */
			calendar.setTime(date);
			System.out.println(calendar);
			System.out.println(date);

	/**
	 * Calendar提供了一个方法:
	 * int get(int field)
	 * 获取指定时间分量所对应的值.
	 * 
	 * 时间分量是一个整数,无需记住每个具体的值
	 * 因为时间分量Calendar已经提供了相应的常量
	 * @author soft01
	 *
	 */
		如何使用:
			Calendar calendar=Calendar.getInstance();
		
			//获取年?
			int year=calendar.get(Calendar.YEAR);
			//获取月?
			int month=calendar.get(Calendar.MONTH)+1;
			/*
			 * 获取日?
			 * 关于天的时间分量有:
			 * DAY_OF_MONTH:月中的天
			 * DAY_OF_WEEK:周中的天
			 * DAY_OF_YEAR:年中的天
			 * DATE:月中的天,与DAY_OF_MONTH一致
			 */
			int day=calendar.get(Calendar.DAY_OF_MONTH);
		
			System.out.println(year+"-"+month+"-"+day);
		
			int h=calendar.get(Calendar.HOUR_OF_DAY);
			int m=calendar.get(Calendar.MINUTE);
			int s=calendar.get(Calendar.SECOND);
			System.out.println(h+":"+m+":"+s);
		
			int days=calendar.get(Calendar.DAY_OF_YEAR);
			System.out.println("今天是今年的第"+days+"天");
		
			String[] data={"日","一","二","三","四","五","六",};
			int week=calendar.get(Calendar.DAY_OF_WEEK)-1;
			System.out.println("周"+data[week]);
		
			int maxyear=calendar.getActualMaximum(Calendar.DAY_OF_YEAR);
			System.out.println("今年一共"+maxyear+"天");
		
			int maxmonth=calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
			System.out.println("这个月一共"+maxmonth+"天");

	/**
	 * void set(int field,int value)
	 * 为指定的时间分量设置指定的值
	 * @author soft01
	 *
	 */
		如何使用:
			Calendar calendar=Calendar.getInstance();
		
			/*
			 * 2008-08-08 20:08:08
			 */
			//设置年!
			calendar.set(Calendar.YEAR,2008);
			calendar.set(Calendar.MONTH,5);
			calendar.set(Calendar.DAY_OF_MONTH,12);
			calendar.set(Calendar.HOUR_OF_DAY,12);
			calendar.set(Calendar.MINUTE,10);
			calendar.set(Calendar.SECOND,00);
			Convert(calendar);

		
			/*
			 * 设置为当周的周二
			 */
			calendar.set(Calendar.DAY_OF_WEEK,3);
			Convert(calendar);
		
			/*
			 * 时间分量的值超过了允许范围时会进位
			 */
			calendar.set(Calendar.DAY_OF_MONTH,32);
			Convert(calendar);
		
		}
	
		public static void Convert(Calendar calendar){
			calendar=calendar;
			Date date=calendar.getTime();
			System.out.println(date);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss E");
			String str=sdf.format(date);
			System.out.println(str);
		}

	/**
	 * void add(int field,int value)
	 * 对指定时间分量累加指定的值,若给定的值
	 * 为负数,则是减去
	 * @author soft01
	 *
	 */
		如何使用:
			/*
			 * 查看3年零两个月25天以后那周的周五是哪天?
			 */
			Calendar calendar=Calendar.getInstance();
			System.out.println(calendar.getTime());
		
			//加上3年
			calendar.add(Calendar.YEAR,-4);
			//再加上两个月
			calendar.add(Calendar.MONTH,-5);
		
			//再加上25天
			calendar.add(Calendar.DAY_OF_YEAR,25);
			System.out.println(calendar.getTime());
			//设置为当周的周六
			calendar.add(Calendar.DAY_OF_WEEK,6);
			System.out.println(calendar.getTim());

	/**
	 * boolean contains(E e)
	 * 判断当前集合是否包含给定元素
	 * @author soft01
	 *
	 */
		如何使用:
			Collection c=new ArrayList();
			c.add(new Point(1,2));
			c.add(new Point(2,3));
			c.add(new Point(3,4));
			System.out.println(c);
		
			Point p=new Point(1,2);
	//		c.add(p);
	//		System.out.println(c);
			boolean contains = c.contains(p);
			System.out.println(contains);

/**
 * java.util.Collection
 * 集合
 * 集合用来存放一组元素,功能与数组类似
 * 集合提供了很多方便操作元素的方法.
 * 
 * Collection是所有集合的顶级父接口,规定了
 * 所有集合都应当具备的功能
 * Collection下面派生了两个子接口:
 * java.util.List:可重复集且有序
 * java.util.Set:不可重复集
 * 元素是否重复是依靠元素equals比较的结果而定
 * 
 * @author soft01
 *
 */
	如何使用:
		Collection c=new ArrayList();
		/*
		 * boolean add(E e)
		 * 向当前集合中添加元素
		 */
		c.add("one");
		c.add("two");
		c.add("three");
		c.add("four");
		System.out.println(c);
		
		
		/*
		 * int size()
		 * 返回当前集合的元素个数
		 */
		int size=c.size();
		System.out.println(size);
		
		
		/*
		 * boolean isEmpty()
		 * 判断集合是否为空集(不含有元素)
		 */
		boolean isEmpty=c.isEmpty();
		System.out.println(isEmpty);
		
		
		/*
		 * void clear()
		 * 清空集合
		 */
		c.clear();
		System.out.println(c);
		System.out.println("size:"+size);
		System.out.println("isEmpty:"+c.isEmpty());

	/**
	 * 集合存放的是元素的引用
	 * @author soft01
	 *
	 */
		如何使用:
			Point p=new Point(1,2);
			Collection c=new ArrayList();
			c.add(p);
		
			System.out.println("p:"+p);
			System.out.println("c:"+c);
		
			p.setX(2);
			System.out.println(p);
			System.out.println(c);

	/**
	 * 集合操作
	 * @author soft01
	 *
	 */
		如何使用:
			Collection c1=new ArrayList();
			c1.add("java");
			c1.add("c++");
			c1.add("php");
			System.out.println(c1);
		
			Collection c2=new HashSet();
			c2.add("android");
			c2.add("ios");
			c2.add("java");
			System.out.println(c2);
			/*
			 * 将c2集合中所有元素添加到c1中
			 * boolean addAll(Collection c)
			 * 将给定集合中的所有元素添加到
			 * 当前集合中,添加后当前集合元素
			 * 发生变化则返回true
			 */
			c1.addAll(c2);
			System.out.println(c1);
		
			Collection c3=new ArrayList();
			c3.add("c++");
			c3.add("ios");
			//c3.add("c#");
		
			/*
			 * boolean containsAll(Collection c)
			 * 判断当前集合是否包含给定集合中的所有元素
			 */
			boolean contains = c1.containsAll(c3);
			System.out.println("全包含:"+contains);
		
			/*
			 * boolean removeAll(Collection c)
			 * 删除当前集合中与给定集合的共有元素
			 */
			c1.removeAll(c3);
			System.out.println(c1);

	/**
	 * 删除集合元素
	 * @author soft01
	 *
	 */
		如何使用:
			Collection c = new ArrayList();
			c.add(new Point(1,2));
			c.add(new Point(2,3));
			c.add(new Point(3,4));
			c.add(new Point(4,5));
			c.add(new Point(1,2));
			System.out.println(c);
		
			Point p = new Point(1,2);
			/*
			 * boolean remove(E e)
			 * 将给定元素从集合中删除,若成功
			 * 删除则返回true
			 * 将给定元素与集合中现有元素顺序
			 * 进行equals比较,然后删除与给定
			 * 元素equals比较为true的.若有多个
			 * 仅删除一个
			 */
			c.remove(p);
			System.out.println(c);

/**
 * iterator迭代器
 * 迭代器是用来遍历集合元素的
 * Collection提供了用于获取遍历集合元素的
 * 迭代器的方法
 * Iterator iterator()
 * 
 * Iterator 是一个接口,规定了遍历集合的相关方法.
 * 不同的集合实现类都提供了一个可以遍历自身的
 * 迭代器实现类
 * 
 * 使用迭代器遍历集合遵循步骤:
 * 问,取,删
 * 其中删元素不是必要操作
 * @author soft01
 *
 */
	如何使用:
		Collection c = new ArrayList();
		c.add("one");
		c.add("#");
		c.add("two");
		c.add("#");
		c.add("three");
		c.add("#");
		c.add("four");
		c.add("#");
		c.add("five");
		
		/*
		 * boolean hasNext()
		 * 判断集合是否还有元素可以取出
		 */
		Iterator it = c.iterator();
		while(it.hasNext()){
			/*
			 * E next()
			 * 通过迭代器获取集合下一个元素
			 */
			String str = (String)it.next();
			System.out.println(str);
			if("#".equals(str)){
//				c.remove(str);
				/*
				 * 迭代器的remove方法会将
				 * 刚通过next方法获取的元素
				 * 从集合中删除
				 * 注意.在迭代器遍历集合的过
				 * 程中不要通过集合的方法增删
				 * 元素,否则可能抛出异常.
				 */
				it.remove();
			}
		}
		System.out.println(c);

/**
 * 增强for循环
 * 又称为:新循环,for each
 * 自java1.5之后推出的一个新的特性,作用是
 * 遍历集合或数组
 * 所以新循环不取代传统for循环的工作
 * @author soft01
 *
 */
	如何使用:
		String[] array = {"one","two","three","four","five"};
		
		for(int i=0;i<array.length;i++){
			String str=array[i];
			System.out.println(str);
		}
		
		for(String str:array){
			System.out.println(str);
		}

	/**
	 * 使用新循环遍历集合
	 * @author soft01
	 *
	 */
		如何使用:
			Collection c = new ArrayList();
			c.add("one");
			c.add("two");
			c.add("three");
			c.add("four");
		
			/*
			 * 新循环并非新的语法,JVM并不认识
			 * 新循环,而是编译器认可.
			 * 编译器在编译源程序时发现,若使用
			 * 新循环遍历集合时会将其改为使用
			 * 迭代器遍历
			 */
			for(Object o:c){
				String str = (String)o;
				System.out.println(str);
			}


/*集合工具类*/
/**
 * 排序集合
 * Collection是集合的工具类,提供了很多便于
 * 操作集合的方法
 * 
 * static void sort(List list)
 * 对给定的List集合进行自然排序(从小到大)
 * @author soft01
 *
 */
	例:
		List<Integer> list = new ArrayList<Integer>();
		Random random = new Random();
		for(int i=0;i<10;i++){
			list.add(random.nextInt(100));
		}
		System.out.println(list);
		Collections.sort(list);
		System.out.println(list);

/**
 * 泛型在集合中的应用是用来约束集合中
 * 的元素类型
 * @author soft01
 *
 */
public class _7CollectionDemo1 {
	public static void main(String[] args) {
		Collection<String> c = new ArrayList<String>();
		c.add("one");
		c.add("two");
		c.add("three");
		c.add("four");
//		c.add(123);
		
		for(String str:c){
			System.out.println(str);
		}
		
		/*
		 * 迭代器也支持泛型,泛型的类型应当
		 * 与其遍历的集合指定的泛型一致
		 */
		Iterator<String> it = c.iterator();
		while(it.hasNext()){
			String str = it.next();
			System.out.println(str);
		}

/**
 * List提供了一对重载的add,remove方法
 * @author soft01
 *
 */
	如何使用:
		List<String> list = new ArrayList<String>();
		list.add("one");
		list.add("two");
		list.add("three");
		list.add("four");
		System.out.println(list);
		
		/*
		 * void add(int index,E e)
		 * 将给定元素插入到指定位置
		 */
		//[one,two,2,three,four]
		list.add(2,"2");
		System.out.println(list);
		
		/*
		 * E remove(int index)
		 * 删除并返回指定位置对应的元素
		 */
		//[one,2,three,four]
		String old = list.remove(1);
		System.out.println(old);

/**
 * java.util.List
 * Collection的一个子接口.
 * List:可重复集,且有序.
 * 提供了一系列的基于下标操作元素的方法.
 * @author soft01
 *
 */
	如何使用:
		List<String> list = new ArrayList<String>();
		list.add("one");
		list.add("two");
		list.add("three");
		list.add("four");
		list.add("five");
		System.out.println(list);
		/*
		 * E get(int index)
		 * 获取指定下标处对应的元素
		 */
		//获取第二个元素
		String str = list.get(1);
		System.out.println(str);
		
		for(int i=0;i<list.size();i++){
			str = list.get(i);
			System.out.println(str);
		}
		
		/*
		 * E set(int index,E e)
		 * 将给定元素设置到指定位置,返回值
		 * 为原位置对应的元素.所以该方法
		 * 是替换元素操作
		 */
		//[one,two,three,four,five]
		String old = list.set(1,"2");
		System.out.println(list);
		System.out.println("old:"+old);

/**
 * List subList(int start,int end)
 * 截取子集
 * @author soft01
 *
 */
	如何使用:
		List<Integer> list = new ArrayList<Integer>();
		for(int i=0;i<10;i++){
			list.add(i);
		}
		System.out.println(list);
		
		/*
		 * 获取子集[3-7]
		 */
		List<Integer> subList = list.subList(3,8);
		System.out.println(subList);
		
		/*
		 * 将子集中每个元素扩大十倍
		 * [30,40,50,60,70]
		 */
		for(int i=0;i<subList.size();i++){
			int num = subList.get(i);
			num = num*10;
			subList.set(i, num);
		}
		/*
		 * 对子集元素的操作就是对原集合中
		 * 对应元素的操作
		 */
		System.out.println(subList);
		System.out.println(list);
		
		/*
		 * 删除2-7
		 */
		list.subList(2,8).clear();
		System.out.println(list);

/**
 * 集合转换为数组
 * Collection提供了相应的方法
 * Object[] toArray()
 * 
 * @author soft01
 *
 */
	如何使用:
		Collection<String> c = new ArrayList<String>();
		c.add("one");
		c.add("two");
		c.add("three");
		c.add("four");
//		Object[] array = c.toArray();
		
		String[] array = c.toArray(new String[c.size()]);
		System.out.println(array.length);
		for(String str:array){
			System.out.println(str);
		}

/**
 * 数组转换为List集
 * 通过数组的工具类:Arrays的静态方法asList
 * @author soft01
 *
 */
	如何使用:
		String[] array = {"one","two","three","four"};
		
		List<String> list = Arrays.asList(array);
		
		System.out.println(list.size());
		System.out.println(list);
		
		list.set(1,"2");
		System.out.println(list);
		for(String str:array){
			System.out.println(str);
		}
		
		/*
		 * 数组转换的集合是不能添加新元素的
		 * 因为这会导致数组扩容,那么就不能
		 * 表示原数组,所以不支持这样的操作
		 */
//		list.add("five");
//		System.out.println(list);
		
		/*
		 * 想添加新元素需要额外创建一个List
		 */
		List<String> list1 = new ArrayList<String>(list);
//		list1.addAll(list);
		list1.add("five");
		System.out.println(list1);

/**
 * 泛型 JDK1.5之后推出的新特性
 * 泛型又称为参数化类型,是将一个类中属性
 * 的类型,方法参数的类型,方法返回值的类型
 * 的定义权交给了使用者.使用者在实例化当前
 * 类实例时传入实际类型.
 * @author soft01
 *
 *@param <E>
 */
	例:
		public class _a3Point<E> {
				private E x;
				private E y;
		
				public _a3Point(E x, E y) {
					super();
					this.x = x;
					this.y = y;
				}
		
				public E getX() {
					return x;
				}
				public void setX(E x) {
					this.x = x;
				}
				public E getY() {
					return y;
				}
				public void setY(E y) {
					this.y = y;
				}
		
				public String toString(){
					return "(" + x + "," + y + ")";
				}
		}
	
	测试:
		_a3Point<Integer> p1 = new _a3Point<Integer>(1,2);
		System.out.println("p1:"+p1);
		p1.setX(2);
		System.out.println("p1:"+p1);
		int x1 = p1.getX();
		System.out.println("x1:"+x1);
		
		_a3Point<Double> p2 = new _a3Point<Double>(1.1,2.2);
		System.out.println("p2:"+p2);
		p2.setX(2.2);
		System.out.println("p2:"+p2);
		double x2 = p2.getX();
		System.out.println("x2:"+x2);
		
		_a3Point<String> p3 = new _a3Point<String>("一","二");
		System.out.println("p3:"+p3);
		p3.setX("二");
		System.out.println("p3:"+p3);
		String x3 = p3.getX();
		System.out.println("x3:"+x3);

/**
 * 泛型的原型就是Object
 * 泛型是编译器认可的,它会检查泛型实参的类型
 * 是否符合泛型指定的类型.
 * 当获取一个泛型数据时,编译器也会自动添加
 * 类型转换.
 * @author soft01
 *
 */
	如何使用:
		/*
		 * 编译器会检测赋值的实际数据是否满足
		 * 泛型类型要求.不满足则编译不通过
		 */
		_a3Point<Integer> p1 = new _a3Point<Integer>(1,2);
		p1.setX(2);
		//编译器会补充造型的代码
		int x1=(Integer)p1.getX();
		System.out.println("x1:"+x1);
		
		/*
		 * 不指定泛型的实际类型则使用
		 * 原型Object
		 */
		_a3Point p2 = p1;
		p2.setX("二");
		System.out.println("p2:"+p2);
		String x2 = (String)p2.getX();
		System.out.println("x2:"+x2);
		
		//类造型异常!
		x1 = (Integer)p1.getX();
		System.out.println("x1:"+x1);
----------------------------------------------------------------------------------------|-
/**																						|
 * 使用该类来测试作为集合的元素进行排序													|
 * @author soft01																		|
 *																						|
 */																						|
public class _0Point implements Comparable<_0Point>{									|
	private int x;																		|
	private int y;																		|
																						|
	public _0Point(int x, int y) {														|
		super();																		|
		this.x = x;																		|
		this.y = y;																		|
	}																					|
	public int getX() {																|
		return x;																		|
	}																					|
	public void setX(int x) {															|
		this.x = x;																		|
	}																					|
	public int getY() {																|
		return y;																		|
	}																					|
	public void setY(int y) {															|
		this.y = y;																		|
	}																					|
																						|
	public String toString(){															|
		return "("+x+","+y+")";															|
	}																					|
																						|
	/*																					|
	 * 当一个类实现了Comparable接口后,接口												|
	 * 要求必须重写方法comparaTo.该方法的													|
	 * 作用是定义当前对象与参数给定对象比较大小的规则										|
	 * 方法要求返回一个整数,该整数不关注具体												|
	 * 值,只关注取值范围,即:																|
	 * 当返回值>0:当前对象大于参数对象(this>0)											|
	 * 当返回值<0:当前对象小于参数对象													|
	 * 当返回值=0:两个对象相等															|
	 */																					|
	public int compareTo(_0Point o) {													|
		//点到原点的距离长的大															|
		int len = this.x*this.x+this.y*this.y;										|
		int olen = o.x*o.x+o.y*o.y;														|
		return len-olen;																|
	}																					|
																						|
																						|
}																						|
----------------------------------------------------------------------------------------|-

/**
 * 排序含有自定义类型元素的集合
 * @author soft01
 *
 */
	如何使用:
		List<_0Point> list = new ArrayList<_0Point>();
		list.add(new _0Point(3,4));		
		list.add(new _0Point(1,7));
		list.add(new _0Point(2,5));
		list.add(new _0Point(2,2));
		list.add(new _0Point(8,6));
		System.out.println(list);
		
		/*
		 * Collections.sort(List list)
		 * 该方法要求集合中的元素必须可以
		 * 比较大小,即:元素必须实现Comparable接口
		 * 
		 * 上述方法实际上排序自定义元素的
		 * 集合时对我们的代码是有"侵入性"的
		 * 所谓侵入性即:
		 * 当我们需要使用某个功能,而该功能要求
		 * 我们为其修改代码,修改的越多侵入性
		 * 就越强.
		 * 侵入性带来的弊端是一旦该功能不再需
		 * 要时,之前修改的代码都不具意义.增加
		 * 后期维护代码成本
		 * 
		 */
		Collections.sort(list);
		System.out.println(list);

/**
 * java提供的数据类型基本都实现了Comparable
 * @author soft01
 *
 */
	如何使用:
		/*
		 * 排序字符串
		 */
		List<String> list = new ArrayList<String>();
		
//		list.add("tom");
//		list.add("jerry");
//		list.add("Tomy");
//		list.add("Top");
//		list.add("King");
//		list.add("smith");
//		list.add("scott");
//		list.add("Black");
//		list.add("Killer");
//		list.add("james");
//		list.add("bill");
		list.add("养殖强");
		list.add("尘雨季");
		list.add("烟味");
		list.add("要是开");
		
		/*
		 * Collections提供了一个重载的sort方法
		 * 该方法要求提供一个额外的比较规则,该
		 * 比较规则是"比较器,Comparator"
		 * 使用这个方法可以解决:
		 * 1:sort方法要求排序元素必须实现Comparable
		 * 	 接口,而该sort方法不要求,所以没有对
		 * 元素的侵入性
		 * 2:java提供的类需要排序时由于已经实现了
		 * Comparable接口并定义了比较规则,但由于
		 * 有不满足排序需求的情况,也可以通过这种
		 * sort方法传入额外比较规则来解决
		 */
		Collections.sort(list,new Comparator<String>(){
			public int compare(String o1,String o2){
				return o1.length()-o2.length();
			}
		});
		System.out.println(list);

/**
 * 队列
 * java.util.Qurur
 * 队列也可以存储一组元素,但是对于存取
 * 元素要求必须从两端进行.
 * 队列存取元素要求:先进先出
 * @author soft01
 *
 */
	如何使用:
		
		/*
		 * java.util.LinkedList也是队列的实现类.
		 * 因为Linkedist可以存一组元素,并且
		 * 由于链表的特性,收尾增删元素效率好
		 * 所以也满足队列的特点.于是java就让
		 * Linkist也实现了队列接口
		 */
		Queue<String> queue = new LinkedList<String>();
		/*
		 * boolean offer(E e)
		 * 入队操作,向队列末尾追加给定元素
		 * 元素入队成功则返回true
		 */
		queue.offer("one");
		queue.offer("two");
		queue.offer("three");
		queue.offer("four");
		queue.offer("five");
		System.out.println(queue);
		
		/*
		 * E poll()
		 * 出队操作,获取并从队列中删除队首元素
		 */
		String str = queue.poll();
		System.out.println(str);
		System.out.println(queue);
		
		/*
		 * E peek()
		 * 引用丢首元素,获取队首元素,但该元素
		 * 不做出队操作
		 */
		str = queue.peek();
		System.out.println(str);
		System.out.println(queue);
		
		for(String s:queue){System.out.println(s);}
		System.out.println(queue);
		
		/*
		 * 自行遍历的形式,那么队列的遍历
		 * 是一次性的
		 */
		while(queue.size()>0){
			str = queue.poll();
			System.out.println(str);
		}
		System.out.println(queue);

/**
 * 双端队列java.util.Deque
 * 两端都可以进出队的队列
 * Deque继承自Queue
 * @author soft01
 *
 */
	如何使用:
		Deque<String> deque = new LinkedList<String>();
		deque.offer("one");
		deque.offer("two");
		
		deque.offerFirst("three");
		deque.offerLast("four");
		System.out.println(deque);
		
		String str = deque.poll();
		System.out.println(str);
		System.out.println(deque);
		
		str = deque.pollFirst();
		System.out.println(str);
		System.out.println(deque);
		
		str = deque.pollLast();
		System.out.println(str);
		System.out.println(deque);

/**
 * 栈
 * 栈结构存取元素遵循先进后出原则
 * 通常使用栈来完成"后退"功能
 * @author soft01
 *
 */
	如何使用:
		Deque<String> stack = new LinkedList<String>();
		/*
		 * 双端队列为栈提供了相应的出入栈方法
		 */
		stack.push("one");
		stack.push("two");
		stack.push("three");
		stack.push("four");
		System.out.println(stack);
		
		String str = stack.pop();
		System.out.println(str);
		System.out.println(stack);

/**
 * java.util.Map
 * 查找表
 * Map体现的样子是一个多行两列的表格
 * 以key-value对的形式存储元素.
 * Map要求key不允许重复(equals判断)
 * 常用实现类:
 * java.util.HashMap 即:散列表(三列算法实现)
 * @author soft01
 *
 */
	如何使用:
		Map<String,Integer> map = new HashMap<String,Integer>();
		/*
		 * V put(K k,V v)
		 * 将给定的key-value对存入Map
		 * 由于Map不允许有重复的key,所以
		 * 若给定的key在Map中已经存在,则是
		 * 替换value操作,那么返回值就是被替换
		 * 的value值.若给定的key在Map中
		 * 不存在,则返回值为null.
		 * 
		 */
		 map.put("语文",99);
		 map.put("数学",98);
		 map.put("英语",97);
		 map.put("物理",99);
		 map.put("化学",98);
		 System.out.println(map);
		 //相同的key是替换value操作
		 Integer num = map.put("数学",99);
		 System.out.println(num);
		 System.out.println(map);
		  
		 /*
		  * V get(K k)
		  * 根据给定的key获取对应的value
		  * 若给定的key不存在则返回值为null
		  */
		 num = map.get("语文");
		 System.out.println("语文:"+num);
		 
		 num = map.get("体育");
		 System.out.println("体育:"+num);

	/**
	 * 删除Map中指定元素
	 * 
	 * @author soft01
	 *
	 */
		如何使用:
			Map<String,Integer> map = new HashMap<String,Integer>();
			map.put("语文",99);
			map.put("数学",98);
			map.put("英语",97);
			map.put("物理",99);
			map.put("化学",98);
		
			/*
			 * V remove(K k)
			 * 将给定的key所对应的key-value对
			 * 从Map中删除,返回值为该key所对应
			 * 的value
			 */
			Integer old = map.remove("英语");
			System.out.println(map);
			System.out.println(old);

	/**
	 * Map的遍历
	 * 遍历Map有三种模式:
	 * 1:遍历所有的key
	 * 2:遍历所有的value
	 * 3:遍历每一组key-value
	 * @author soft01
	 *
	 */
		如何使用:
			Map<String,Integer> map = new HashMap<String,Integer>();
			map.put("语文",99);
			map.put("数学",98);
			map.put("英语",97);
			map.put("物理",99);
			map.put("化学",98);
		
			/*
			 *  遍历所有的key
			 *  Set<K> keySet()
			 *  将当前Map中所有的key存入一个Set
			 *  集合后将其返回,那么遍历该集合就
			 *  等同于遍历了所有的key
			 */
			Set<String> keySet = map.keySet();
			for(String key:keySet){
				System.out.println("key:"+key);
			}
		
			/*
			 * 遍历每一组键值对
			 * Set<Entry> entrySet()
			 * 将当前Map中每一组键值对(Etry实例)
			 * 存入一个Set集合后返回
			 * java.util.Map.Entry
			 * 该类的每一个实例用于表示Map中的
			 * 一组键值对
			 */
			Set<Entry<String,Integer>> entrySet = map.entrySet();
			for(Entry<String,Integer> e:entrySet){
				String key = e.getKey();
				Integer value = e.getValue();
				System.out.println(key+":"+value);
			}
		
			/*
			 * 遍历所有的value
			 * Collection values()
			 * 将当前Map中所有的value存入到
			 * 一个集合后返回
			 */
			Collection<Integer> values = map.values();
			for(Integer value:values){
				System.out.println("value:"+value);

----------------------------------------------------------------------------------------|-
/**																						|
 * 在HashMap的应用中,Key元素的equls方法													|
 * 与hashcode方法直接影响着散列表的查询性能												|
 * 而这两个方法是Object定义的方法,在手册上												|
 * 也明确说明,当我们需要重写时,两个方法应当												|
 * 遵循:																					|
 * 1:成对重写,即:当重写一个类的equals方法时												|
 *   就应当连同重写hashcode																|
 * 2:equals与hashcode应当具有一致性,即:													|
 *   两个对象equals比较为true时,hashcode方法												|
 *   返回的数字应当相同.反过来也是如此.虽然不是											|
 *   必须的,但尽量保持当两个对象hashcode方法												|
 *   返回值相等时equals也应当为true,否则会在												|
 *   HashMap中产生链表影响查询性能.														|
 * 3:hashcode方法的值应当是稳定的,即:在当前												|
 *   对象参与equals比较的属性值没有发生改变												|
 *   的前提下,多次调用hashcode方法返回的数字应当相同										|
 * @author soft01																		|
 *																						|
 */																						|
	例:																					|
		private int x;																	|
		private int y;																	|
		@Override																		|
		public int hashCode() {														|
			final int prime = 31;														|
			int result = 1;																|
			result = prime * result + x;												|
			result = prime * result + y;												|
			return result;																|
		}																				|
		@Override																		|
		public boolean equals(Object obj) {											|
			if (this == obj)															|
				return true;															|
			if (obj == null)															|
				return false;															|
			if (getClass() != obj.getClass())											|
				return false;															|
			_9Key other = (_9Key) obj;													|
			if (x != other.x)															|
				return false;															|
			if (y != other.y)															|
				return false;															|
			return true;																|
		}																				|
	}																					|
----------------------------------------------------------------------------------------|-
/**
 * java.io.File
 * File类的每一个实例是用于表示操作系统中
 * 文件系统里的一个文件或目录
 * 使用File可以:
 * 1:访问文件或目录的属性信息
 * 2:操作文件或目录(创建,删除)
 * 3:访问一个目录中的子项
 * 但是不能访问文件数据.
 * @author soft01
 *
 */
	如何使用:
		/*
		 * 创建File时需要指定该文件或目录的
		 * 路径.
		 * 路径通常使用相对路径(跨平台)
		 * ".":当前目录,当前目录由运行程序
		 *     的环境决定,在eclipse中当前
		 *     目录的定义是:当前类所在项目
		 *     的根目录(这里是JSD1705_SE)
		 * 目录的层级分隔符:"\","/",由于不同
		 * 的操作系统不一样,java在File中提供
		 * 了常量separator来屏蔽差异.
		 */
		File file = new File("."+File.separator+"demo.txt");
		//获取文件名
		String name = file.getName();
		System.out.println("文件名:"+name);
		//返回文件的大小(字节量)
		long length = file.length();
		System.out.println("大小:"+length+"字节");
		
		boolean canRean = file.canRead();
		boolean canWrite = file.canWrite();
		System.out.println("可读:"+canRean);
		System.out.println("可写:"+canWrite);
		
		boolean isHidden = file.isHidden();
		System.out.println("是否隐藏:"+isHidden);
		
		/*
		 * 最后修改日期
		 * 2017年06月28日 星期三 05时24分33秒
		 */
		long time = file.lastModified();
		System.out.println(time);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日,E,H:m:s");
		String str = sdf.format(time);
		System.out.println(str);

	/**
	 * 使用File创建文件
	 * @author soft01
	 *
	 */
		如何使用:
			/*
			 * 在当前目录下创建文件:test.txt
			 */
			File file = new File("."+File.separator+"test.txt");
		
			/*
			 * boolean exests()
			 * 判断当前File表示的文件或目录是否
			 * 已经存在
			 */
			if(!file.exists()){
				file.createNewFile();
				System.out.println("创建完毕");
			}else{
				System.out.println("该文件已存在!");
			}

	/**
	 * 删除一个文件
	 * @author soft01
	 *
	 */
		如何使用:
			/*
			 * 将当前目录下的test.txt文件删除
			 * "./"不写默认也是当前目录
			 */
			File file = new File("test.txt");
		
			if(file.exists()){
				file.delete();
				System.out.println("文件以删除!");
			}else{
				System.out.println("文件不存在!");
			}

	/**
	 * 删除一个目录
	 * @author soft01
	 *
	 */
		如何使用:
			/*
			 * 将当前目录下的demo目录删掉
			 */
			File dir = new File("a");
			if(dir.exists()){
				dir.delete();
				System.out.println("目录已删除!");
			}else{
				System.out.println("该目录不存在!");
			}

	/**
	 * 使用File创建一个目录
	 * @author soft01
	 *
	 */
		如何使用:
			/*
			 * 在当前目录下创建目录:demo
			 */
			File dir = new File("demo");
			if(!dir.exists()){
				dir.mkdir();
				System.out.println("创建目录完毕!");
			}else{
				System.out.println("目录已存在!");
			}

	/**
	 * 创建一个多级目录
	 * @author soft01
	 *
	 */
		如何使用:
			/*
			 * 在当前目录下创建:a/b/c/d/e/f
			 */
			File file = new File(
					"a"+File.separator+
					"b"+File.separator+
					"c"+File.separator+
					"d"+File.separator+
					"e"+File.separator+
					"f");
			if(!file.exists()){
				/*
				 * mkdir方法要求创建的目录所在的
				 * 父目录必须存在
				 * mkdirs则会将所有不存在的父目录
				 * 一并创建出来
				 */
				file.mkdirs();
				System.out.println("创建完毕!");
			}else{
				System.out.println("该目录已存在");
			}

	/**
	 * 获取一个目录中的子项
	 * @author soft01
	 *
	 */
		如何使用:
			/*
			 * 获取当前目录中的子项
			 */
			File dir = new File(".");
		
			/*
			 * boolean isFile()  文件
			 * boolean isDirectory()  目录
			 * 判断当前File表示的是文件还是目录
			 */
			if(dir.exists()&&dir.isDirectory()){
				File[] subs = dir.listFiles();
				for(File sub:subs){
					if(sub.isFile()){
						System.out.print("文件:");
					}
					if(sub.isDirectory()){
						System.out.print("目录:");
					}
					System.out.println(sub.getName());
				}
			}

	/**
	 * 编写程序完成删除指定的文件或目录
	 * @author soft01
	 *
	 */
		如何使用:
		public static void main(String[] args) {
			File dir = new File("a");
			delete(dir);
		}
	
		/**
		 * 将给定的File所表示的文件或目录删除
		 * @param file
		 */
		public static void delete(File file) {
			if(file.isDirectory()){
				//先将该目录中所有子项删除
				File[] subs = file.listFiles();
				for(File sub:subs){
					//递归调用
					delete(sub);
				}
			}
			file.delete();
		}
/* 递归练习题 */ 
	/**
	 * 1.一块钱可以买一瓶汽水,
	 *   两个瓶子可以换一瓶汽水,
	 *   三个瓶盖可以换一瓶汽水.
	 *   20块钱可以买多少瓶汽水!
	 *   
	 * 2.1+2+3+4+5+......+99+100
	 *   不能使用for while 
	 *   
	 * @author soft01
	 *
	 */
		做如下:
			private static Object bottle;
			public static void main(String[] args) {
				matchs(1,0);
		
				while(true){
				Scanner scan = new Scanner(System.in);
				int money=scan.nextInt();
				int bottlesoda,bottle,cap;
				bottlesoda=bottle=cap=money;
				Bottles(bottlesoda,bottle,cap);
				}
		
			}
			public static void matchs(int x,int num){
				num+=x;
				if(x==100){System.out.println(num);}
				x++;
				if(x<=100){matchs(x,num);}
			}
			public static void Bottles(int bottlesoda,int bottle,int cap){
				if(bottle>=2||cap>=3){
					if(bottle>=2){
						while(bottle>=2){
							bottle-=1;
							bottlesoda+=1;
							cap+=1;
						}
						if(bottle>=2||cap>=3){Bottles(bottlesoda,bottle,cap);}
					}else{
						while(cap>=3){
							cap-=2;
							bottlesoda+=1;
							bottle+=1;
						}
						if(bottle>=2||cap>=3){Bottles(bottlesoda,bottle,cap);}
					}
					if(bottle<2&&cap<3){
						System.out.println("汽水数量:"+bottlesoda);
						System.out.println("瓶子数量:"+bottle);
						System.out.println("瓶盖数量:"+cap);
					}
				}
			}

	/**
	 * File提供了一个重载的listFiles方法
	 * 可以额外指定一个文件过滤器(FileFilter)
	 * 然后将File表示的目录中满足该过滤器要求
	 * 的子项返回
	 * @author soft01
	 *
	 */
		如何使用:
			/*
			 * 获取当前目录中所有以"."开头
			 * 的子项
			 */
			File dir = new File(".");
			File[] subs =  dir.listFiles(new FileFilter(){
				public boolean accept(File file) {
					String name = file.getName();
					return name.startsWith(".");
				}
			});
			for(File sub:subs){
				System.out.println(sub.getName());
			}

	/**
	 * java.io.RandomAccessFile
	 * 用来读写文件数据的类
	 * RAF是基于指针进行文件数据的读写的,即:
	 * 总是在指针当前位置读写字节.
	 * 创建RAF有两种常用模式:
	 * 1.只读模式
	 * 2.读写模式
	 * @author soft01
	 *
	 */
		如何使用:
			/*
			 * 创建RandomAccessFile时常用的构造方法:
			 * RandomAccessFile(String path,String mode)
			 * RandomAccessFile(File file,String mode)
			 * 其中第一个参数为要进行读写操作的文件.
			 * 第二个参数为模式:
			 * "r":只读模式
			 * "rw":读写模式
			 */
			 RandomAccessFile raf = new RandomAccessFile("raf.dat","rw");
			 
			 /*
			  * void write(int d)
			  * 向文件中写入一个字节,写入的内容是
			  * 指定int值对应二进制的"低八位"
			  * 
			  * 00000000 00000000 00000000 00000001
			  */
			 raf.write(1);
			 System.out.println("写出完毕!");
			 
			 raf.close();

	/**
	 * 读取字节
	 * @author soft01
	 *
	 */
		如何使用:
			RandomAccessFile raf = new RandomAccessFile("raf.dat","r");
			/*
			 * 读取1个字节,并以int形式返回.
			 * 若返回值为-1,则表示读取到了文件末尾.
			 */
			int d = raf.read();
			System.out.println(d);
		
			raf.close();

	/**
	 * 复制文件
	 * @author soft01
	 *
	 */
		如何使用:
			RandomAccessFile src = new RandomAccessFile("tts9.zip","r");
			RandomAccessFile desc = new RandomAccessFile("tts9.zip_pg","rw");
			int d=-1;//保存每次读取到的字节
			long start = System.currentTimeMillis();
			while((d = src.read())!=-1){
				desc.write(d);
			}
			long end = System.currentTimeMillis();
		
			System.out.println("复制完毕!耗时:"+(end-start));
		
			src.close();
			desc.close();

	/**
	 * 由于磁盘单字节读写速度差,所以
	 * 可以通过提高每次读写的数据量,减少读写
	 * 次数来提高读写效率
	 * @author soft01
	 *
	 */
		如何使用:
			RandomAccessFile src = new RandomAccessFile("tts9.zip","r");
			RandomAccessFile desc = new RandomAccessFile("tts9.zip_pg","rw");
			/*
			 * RAF提供了单词读取多字节的方法
			 * int read(byte[] data)
			 * 一次性尝试读取给定的字节数组总
			 * 长度的字节量,并将读到的字节存入
			 * 到该数组中,返回值为实际读取到的
			 * 字节量
			 */
			//10k
			byte[] data = new byte[1024*10];
			int len = -1;
		
			long start = System.currentTimeMillis();
			while((len = src.read(data))!=-1){
				/*
				 * RAF提供了写出一组字节的方法
				 * void write(byte[] data)
				 * 一次性将给定的字节数组中所有字节
				 * 写出.
				 * void write(byte[] data,int start,int len)
				 * 将给定的字节数组中从start开始的
				 * 连续len个字节一次性写出
				 */
				desc.write(data,0,len);
			}
			long end = System.currentTimeMillis();
			System.out.println("复制完毕!耗时:"+(end-start)+"ms");
		
			src.close();
			desc.close();

	/**
	 * 写字符串
	 * @author soft01
	 *
	 */
		如何使用:
			RandomAccessFile raf = new  RandomAccessFile("raf.txt","rw");
			String str = "让我再看你一遍,从南到北.";
			/*
			 * String---->byte
			 * String提供了将字符串转换为字节的方法:
			 * byte[] getBytes()
			 * 将当前字符串按照系统默认字符集转换为一组字节
			 * 
			 * byte[] getBytes(String csn)
			 * 按照指定的字符集将字符串转换为
			 * 一组字节
			 */
			byte[] data = str.getBytes("GBK");
			raf.write(data);
			raf.write("像是北五环路,蒙住的双眼.".getBytes("GBK"));
			System.out.println("写出完毕!");
			raf.close();

	/**
	 * 读取字符串
	 * @author soft01
	 *
	 */
		如何使用:
			RandomAccessFile raf = new RandomAccessFile("raf.txt","r");
		
			byte[] data = new byte[200];
			int len = raf.read(data);
			System.out.println(len);
			/*
			 * byte-->String
			 * String 提供构造方法:
			 * String(byte[] data)
			 * 将给定字节数组中所有字节
			 * 按照系统默认的字符集还原为字符串
			 * 
			 * String(byte[] data,int start,int len)
			 * 
			 * 下面的构造方法可以按照指定的字符集转换
			 * String(byte[] data,String csn)
			 * String(byte[] data,int start,int len,String csn)
			 * 
			 */
			String str = new String(data,0,len,"GBK");
			System.out.println(str);
		
			raf.close();

/**
 * RandomAccessFile提供了便捷的读写
 * 基本类型数据的方法.
 * 由于RAF是基于指针进行读写的,所以RAF
 * 也提供了操作指针的方法
 * @author soft01
 *
 */
	如何使用:
		RandomAccessFile raf = new RandomAccessFile("raf.dat","rw");
		
		/*
		 * long getFilePointer();
		 * 返回RAF当前指针位置
		 */
		long pos = raf.getFilePointer();
		System.out.println("pos:"+pos);
		
		/*
		 * 向文件中写入一个int最大值
		 *                            vvvvvvvv
		 * 01111111 11111111 11111111 11111111
		 * imax>>>
		 */
		int imax = Integer.MAX_VALUE;
		raf.write(imax>>>24);
		System.out.println("pos:"+raf.getFilePointer());
		raf.write(imax>>>16);                          
		System.out.println("pos:"+raf.getFilePointer());
		raf.write(imax>>>8);
		System.out.println("pos:"+raf.getFilePointer());
		raf.write(imax);
		System.out.println("pos:"+raf.getFilePointer());
		
		/*
		 * 连续写4个字节将给定的int值写出
		 */
		raf.writeInt(imax);
		System.out.println("pos:"+raf.getFilePointer());
		raf.writeLong(123456L);
		System.out.println("pos:"+raf.getFilePointer());
		raf.writeDouble(159.753);
		System.out.println("pos:"+raf.getFilePointer());
		
		System.out.println("写出完毕!");
		
		/*
		 * void seek(long pos)
		 * 将指针移动到指定位置
		 */
		raf.seek(0);
		/*
		 * RAF提供了相应读取基本类型数据的方法
		 * int readInt()
		 * 连续读取4个字节并返回该int值
		 * 若读取过程中发现读取到了文件末尾
		 * 回抛出EOFException(文件末尾异常)
		 * 不以-1表示文件末尾的原因在于这里
		 * 是真实读取了4个字节的int值,那么就
		 * 有可能真读取到一个-1,所以不能再用
		 * -1表示文件末尾.
		 */
		int i = raf.readInt();
		System.out.println(i);
		System.out.println("pos:"+raf.getFilePointer());
		
		raf.seek(8);
		long l = raf.readLong();
		System.out.println(l);
		System.out.println("pos:"+raf.getFilePointer());
		
		double d = raf.readDouble();
		System.out.println(d);
		System.out.println("pos:"+raf.getFilePointer());
		
		raf.close();

/**
 * java标准的IO操作
 * IO操作的目的是允许程序与外界数据集交互
 * 既可以从外界获取数据,也可以将数据发送
 * 到外界.
 * java中的IO操作是流式操作,根据方向分为:
 * 输入流:用于将外界输入数据到程序(读操作)
 * 输出流:用于将数据发送至外界(写操作)
 * 
 * java将流分为两类:
 * 字节流,处理流
 * 字节流又称为低级流.是真实在程序与数据源
 * 之间的"管道",负责在两端搬运数据.读写一定
 * 基于节点流.
 * 
 * 处理流:处理流不能独立存在(没意义),它的作用
 * 是基于其处理的流工作,简化读写操作
 * 
 * java提供了两个父类,规定了所有字节输入流与
 * 字节输出流的功能定义.
 * 
 * java.io.InputStream:所有字节输入流都继承
 * 自该流.其规定了使用输入流读取字节的相关
 * 方法.
 * 
 * java.io.OutputStream:所有字节输出流都继承
 * 自该流,规定了所有输出流写出字节的相关方法.
 * 
 * 文件流
 * java.ioFileOutPutStream
 * java.ioFileInPutStream
 * 文件流是一对低级流,作用是读写文件中的数据
 * 
 * 
 * @author soft01
 *
 */
	其一:
		/*
		 * 向fos.txt文件中写入字符串
		 * FileOutPutStream提供了相应的构造方法
		 * FileOutPutStream(String path)
		 * FileOutPutStream(File file)
		 * 数据都删除,然后将本次通过该流写出的数据
		 * 作为该文件中的数据.
		 * FileOutPutStream(String path,bollean append)
		 * FileOutPutStream(File filie,boolean append)
		 * 这两种构造方法要求在额外传入一个boolean值
		 * 参数,若该值为true,则文件输出流为追加写操作
		 * 即:若文件存在,会将本次通过该流写出的数据
		 * 追加到文件末尾.
		 */
		FileOutputStream fos = new  FileOutputStream("fos.txt",true);
		                                            
		fos.write("简单点,说话的方式简单点.".getBytes());
		fos.write("递进的情绪请省略,你又不是个演员,别设计那些情节".getBytes());
		fos.write("该配合你演出的我演视而不见.".getBytes());
		
		System.out.println("写出完毕!");
		fos.close();

	/**
	 * 文件输入流,用于从文件中将数据读取到
	 * 程序中
	 * @author soft01
	 *
	 */
		如何使用:
			FileInputStream fis = new FileInputStream("fos.txt");
			byte[] data = new byte[200];
			int len = fis.read(data);
		
			String str = new String(data,0,len);
			System.out.println(str);
			fis.close();

	/**
	 * 使用文件流复制文件
	 * @author soft01
	 *
	 */
		如何使用:
			FileInputStream src = new FileInputStream("fos.txt");
			FileOutputStream desc = new FileOutputStream("fis.txt");
			byte[] data = new byte[1024*10];
			int len = -1;
			long start = System.currentTimeMillis();
			while((len = src.read(data))!=-1){
				desc.write(data,0,len);
			}
			long end = System.currentTimeMillis();
			System.out.println("复制完毕!耗时:"+(end-start));
			src.close();
			desc.close();

	/**
	 * 缓冲输出流写出数据时的缓冲区操作
	 * 
	 * @author soft01
	 *
	 */
		如何使用:
			FileOutputStream fos = new FileOutputStream("bos.txt");
			BufferedOutputStream bos = new BufferedOutputStream(fos);
			String str = "你还要我怎样,要怎样,你突然来的短信就够我悲伤了!";
			byte[] data = str.getBytes();
			bos.write(data);
			/*
			 * void flush()
			 * 缓冲流的flush方法的作用是强制
			 * 将缓冲流内部缓冲区已经缓存的数据
			 * 一次性写出.
			 * 这样做可以提高写出数据的即时性,
			 * 但是频繁调用会导致写次数的提高
			 * 从而减低写效率.结合实际业务需求
			 * 灵活运用.
			 */
			bos.flush();
			System.out.println();
		
			bos.close();

/**
 * 缓冲流
 * java.io.BufferedInputStream
 * java.io.BufferedOutputStream
 * 缓冲流是一对高级流,使用它们可以提高读写
 * 效率
 * @author soft01
 *
 */
	如何使用:
		FileInputStream src = new FileInputStream("tts9.zip");
		BufferedInputStream bis = new BufferedInputStream(src);
		FileOutputStream desc = new FileOutputStream("tts9_2.zip");
		BufferedOutputStream bos = new BufferedOutputStream(desc);
		byte[] data = new byte[1024*10];
		int d = -1;
		long start = System.currentTimeMillis();
		/*
		 * 缓冲流内部维护一个字节数组,实际上
		 * 也是通过提高每次实际读写的字节量
		 * 减少读写次数来提高的读写效率.
		 * 如何使用:
		 * 当调用bis.read()方法读取一个字节时
		 * 实际上bis会通过文件流一次性读取若干
		 * 字节并存入内部的字节数组,然后只将
		 * 第一份额自己返回.当后面再次调用read
		 * 方法读取一个字节时,bis则直接将数组中
		 * 下一个字节返回,直到所有字节都已经
		 * 返回后才会再次读取一组字节回来.
		 */
		while((d=bis.read())!=-1){
			bos.write(d);
		}
		long end = System.currentTimeMillis();
		
		System.out.println("复制完毕:"+(end-start));
		bis.close();
		bos.close();

-------------------------------------------------------------------------------------------------|-
/**																								 |
 * 使用该类的实例测试对象流的对吸纳个读写操作														 |
 * @author soft01																				 |
 *																								 |
 */																								 |
public class _0Person implements Serializable{												 |
	/**																							 |
	 * 当一个类实现了Seerializable接口后															 |
	 * 应当定义一个常量:序列化版本号																 |
	 * serialVersionUID																			 |
	 * 如果我们没有指定,编译器会根据当前类														 |
	 * 的结构生成一个版本号,但是只要当前类														 |
	 * 发生了改变,那么版本号会随之改变.															 |
	 * 																							 |
	 * 版本号影响ObjectInputStream在进行															 |
	 * 对象反序列化时的结果																		 |
	 * 当OIS发现要进行反序列化的对象与当前														 |
	 * 类版本已经不一致,那么反序列化直接失败														 |
	 * 若一致,则反序列化成功,如果该对象与															 |
	 * 当前类结构不完全一致时,则启用兼容模式,														 |
	 * 即:能还原的属性依然还原,没有的则忽略														 |
	 */																							 |
	private static final long serialVersionUID = 1L;											 |
	private String name;																		 |
	private int age;																			 |
	private String gender;																		 |
	/*																							 |
	 * 当一个属性被transient修饰后,那么															 |
	 * 该属性在进行对象序列化时值会被忽略															 |
	 * 将不必要的属性忽略可以达到对象"瘦身"														 |
	 * 的目的																					 |
	 */																							 |
	private transient List<String> otherInfo;													 |
																								 |
	public _0Person(){																			 |
																								 |
	}																							 |
																								 |
	public _0Person(String name, int age, String gender, List<String> otherInfo) {				 |
		super();																				 |
		this.name = name;																		 |
		this.age = age;																			 |
		this.gender = gender;																	 |
		this.otherInfo = otherInfo;																 |
	}																							 |
																								 |
	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;																			 |
	}																							 |
	public String getGender() {																	 |
		return gender;																			 |
	}																							 |
	public void setGender(String gender) {														 |
		this.gender = gender;																	 |
	}																							 |
	public List<String> getOtherInfo() {														 |
		return otherInfo;																		 |
	}																							 |
	public void setOtherInfo(List<String> otherInfo) {											 |
		this.otherInfo = otherInfo;																 |
	}																							 |
																								 |
	public String toString(){																	 |
		return name+","+age+","+gender+","+otherInfo;											 |
	}																							 |
}																								 |
-------------------------------------------------------------------------------------------------|-

/**
 * 对象流
 * 对象流是一对高级流,作用是方便我们读写java
 * 中的任意对象.
 * 
 * 对象输出流
 * java.io.ObjectOutputStream
 * 对象输出流可以将给定的对象按照结构转换
 * 为一组字节.然后在通过其处理的流将这组
 * 字节写出.
 * @author soft01
 *
 */
	如何使用:
		_0Person p = new _0Person();
		p.setName("苍老师");
		p.setAge(18);
		p.setGender("女");
		
		List<String> otherInfo = new ArrayList<String>();
		otherInfo.add("是一名演员");
		otherInfo.add("爱好写毛笔字");
		otherInfo.add("促进中日文化交流");
		otherInfo.add("是广大男性同胞的启蒙老师");
		p.setOtherInfo(otherInfo);
		
		FileOutputStream fos = new FileOutputStream("person.obj");
		
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		
		/*
		 * void writeObject(Object O)
		 * 对象输出流的该方法是将给定对象
		 * 转换为一组字节后输出.
		 * 若希望被oos写出,就要求该对象所属类
		 * 必须实现可序列化接口
		 * 
		 * 下面的代码将p对象写出时,经历了
		 * 两个步骤:
		 * 1:通过OOS将给定对象转换为一组字节
		 *   这个过程称为:对象序列化
		 * 2:在将这组字节通过FOS写入到硬盘
		 *   中的这个过程称为:数据持久化
		 */
		oos.writeObject(p);
		System.out.println("写出完毕!");
		
		oos.close();

	/**
	 * 对象输入流
	 * 可以将这一组字节读取后还原为其表示的对象
	 * 前提是这组字节应当是对象输出流将一个对象
	 * 转换的字节.否则会抛出异常.
	 * @author soft01
	 *
	 */
		如何使用:
			FileInputStream fis = new FileInputStream("person.obj");
			ObjectInputStream ois = new ObjectInputStream(fis);
			_0Person p = (_0Person)ois.readObject();
			System.out.println(p);
			ois.close();

/**
 * 字符流
 * Reader,Writer
 * Reader是所有字符输入流的父类,Writer是所有
 * 字符输出流的父类
 * 
 * 字符流是以字符为最小单位读写数据的,然实际
 * 本质底层还是读写字节,只是字符与字节的转换
 * 工作有字符流来完成了.
 * 
 * 由于字符流被设计用来读写字符数据,所以字符流
 * 不通用于读写任何种类的数据,只用来读写文本数据.
 * 
 * 转换流,转换流是字符流的一套实现类
 * OutputStreamWriter,InputStreamReader
 * 特点:可以按照指定的字符集将字符与字节之间
 * 转换然后读写
 * 
 * 转换流之所以称为转换流是因为在实际的开发
 * 中,在进行流连接操作时,其他的字符高级流都
 * 只能处理其他字符流,然后低级流大部分都是
 * 字节流,这就导致了字符流不能连接到字节流
 * 上,但是转换流是可以处理字节流的,而他们自身
 * 又是字符流,所以在流连接中一般起到衔接其他
 * 字符高级流与字节流的作用
 * @author soft01
 *
 */
	如何使用:
		FileOutputStream fos = new FileOutputStream("osw.txt");
		/*
		 * OSW常用构造方法:
		 * OutputStreamWriter(OutputStream out)
		 * 
		 * OutputStreamWriter(
		 *  OutputStream out,
		 *  String charSetName
		 * )
		 * 当传入第二个参数时,可以按照指定的字符
		 * 集将字符串转换为字节后写出.
		 */
		OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK");
		
		osw.write("董小姐,你从没忘记你的微笑.");
		osw.write("就算你和我一样,渴望着衰老.");
		
		System.out.println("写出完毕!");
		
		osw.close();

	/**
	 * 使用转换流读取数据
	 * @author soft01
	 *
	 */
		如何使用:
			FileInputStream fis = new FileInputStream("osw,txt");
		
			InputStreamReader isr = new InputStreamReader(fis,"GBK");
		
			int d=-1;
			while((d=isr.read())!=-1){
				System.out.println((char)d);
			}
		
			isr.close();

	/**
	 * 缓冲数据流
	 * BufferWiter,BufferedReader
	 * 缓冲字符流的特点是可以按行读写字符串,内部
	 * 维护缓冲区,所以对效率也高.
	 * 
	 * PrintWriter也是缓冲字符流,并且还支持自动
	 * 行刷新功能,内部包含BufferWiter作为其缓冲功能.
	 * 
	 * @author soft01
	 *
	 */
		如何使用:
			/*
			 * PW提供了直接针对文件进行操作的构造方法
			 * 
			 * PrintWriter(File file)
			 * PrintWriter(String path)
			 * 
			 * 也可以按照指定的字符集写出字符串
			 * PrintWriter(File file,String csn)
			 * PrintWriter(String path,String csn)
			 */
			PrintWriter pw = new PrintWriter("pw.txt","GBK");
			pw.println("夜空中最亮的星,");
			pw.println("能都听请,");
			pw.println("那仰望的人,心底的孤独和叹息.");
			System.out.println("写出完毕!");
			pw.close();

/**
 * PrintWriter在流连接中的应用
 * @author soft01
 *
 */
	如何使用:
		/*
		 * PrintWriter(OutputStream out)
		 * PrintWriter(Writer writer)
		 * 
		 */
		FileOutputStream fos = new FileOutputStream("pw2.txt");
		/*
		 * 在流连接线中若希望按照指定字符集写出,需要自行连接转换流OSW并指定字符集
		 */
		OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK");
		PrintWriter pw = new PrintWriter(osw);
		pw.println("摩擦摩擦,似魔鬼的步伐.");
		pw.println("在光滑的马路牙子上打出溜滑.");
		System.out.println("写出完毕!");
		pw.close();

/**
 * 编写一个简易记事本功能
 * 程序启动后,要求用户输入一个文件名,然后针对该文件写信息.
 * 用户在控制台输入的每行字符串都按照行写入到该文件中.
 * 当用户输入"exit"时程序退出.
 * @author soft01
 *
 */
	如何使用:
		Scanner scan = new Scanner(System.in);
		System.out.println("请输入文件名称:");
		while(true){
			String stxt = scan.nextLine()+".txt";
			File file = new File(stxt);
			if(!file.exists()){
				file.createNewFile();
				System.out.println("创建完毕");			
			}else{
				System.out.println("该文件已存在!请重新输入");
				continue;
			}
			FileOutputStream fos = new FileOutputStream(file);
			OutputStreamWriter osw = new OutputStreamWriter(fos);
			/*
			 * 当创建PW时第一个参数为流时,就支持第二个
			 * 参数为boolean值的构造方法,该构造方法
			 * 如果传入true,则当前PW具有自动行刷新功能
			 * 即:使用pw.println方法写出一行字符串后
			 * 会自动flush
			 */
			PrintWriter pw = new PrintWriter(osw);
			System.out.println("");
			String str;
			do{str = scan.nextLine();
			pw.println(str);
			}while(!"exit".equals(str));
			System.out.println("写出完毕!");
			pw.close();
			break;
		}

/**
 * java.io.BufferedLine
 * 缓冲字符输入流,可以按行读取字符串
 * @author soft01
 *
 */
	如何使用:
		FileInputStream fis = new FileInputStream(
						"src"+File.separator+"day08"+File.separator+"BufferedReader_readLine.java");
		InputStreamReader isr = new InputStreamReader(fis);
		BufferedReader br = new BufferedReader(isr);
		/*
		 * String readLine()
		 * 连续读取若干字符,直到读取到换行
		 * 符为止,然后将所有字符以一个字符串
		 * 的形式返回.注意:返回的这个字符串
		 * 中是不包含最后的换行符的.
		 * 
		 * 若该方法返回值为null,则表示读取到了
		 * 文件末尾.将来用BR读取其他设备时若
		 * 返回值为null意味着通过该流不可能再
		 * 读取到任何数据
		 */
		String line = null;
		while((line=br.readLine())!=null){
			System.out.println(line);
		}
		br.close();

------------------------------------------------------------------------|-
  /* System.in */														|
		InputStreamReader isr = new InputStreamReader(System.in);		|
		BufferedReader br = new BufferedReader(isr);					|
		String line;													|
		while(true){													|
			line = br.readLine();										|
			System.out.println(line);									|
		}																|
------------------------------------------------------------------------|-

/**
 * java异常捕获机制
 * try{}块,用来将可能出现异常的代码片段括起来
 * catch块用来捕获并解决try块中代码抛出的异常
 * 
 * try块是不能单独定义的,后面通常会定义catch
 * 块.也可以直接跟finally块.
 * @author soft01
 *
 */
	如何使用:
		System.out.println("程序开始了");
		try{
			String str = "a";
			System.out.println(str.length());
			System.out.println(str.charAt(0));
			System.out.println(Integer.parseInt(str));
			//try虫出现错误的代码下面的内容不会执行
			System.out.println("!!!!");
		}catch(NullPointerException e){
			System.out.println("出现了空指针!");
		}catch(StringIndexOutOfBoundsException e){
			System.out.println("字符串下标越界");
			/*
			 * catch可以定义多个,针对不同异常有
			 * 不同处理手段时,应当分别捕获并定义
			 * 解决手段.
			 * 但是应当养成一个好习惯,在最下面捕获
			 * Exception,以防代码中出现一个未知异常
			 * 而导致程序中断.
			 * 当捕获的异常之间存在继承关系时,应当
			 * 先捕获子类型异常后捕获父类型异常
			 */
		}catch(Exception e){
			System.out.println("发生未知错误!");
		}
		
		System.out.println("程序结束了");

/**
 * finally块
 * finally块只能出现在异常处理机制的最后
 * 即:try后面或者最后一个catch之后.
 * finally块可以保证无论try块中的代码是否
 * 抛出异常该块里的代码都一定会执行.
 * 所以通常会将无论程序是否出错都要运行的
 * 代码放在finally中确保执行,比如流操作
 * 中的关闭流以及其他释放资源等操作.
 * @author soft01
 *
 */
public class _1Exception_finally {
	public static void main(String[] args) {
		
		System.out.println("程序开始了!");
		try{
			String str = null;
			System.out.println(str.length());
		}catch(Exception e){
			System.out.println("程序出错了!");
		}finally{
			System.out.println("finally中的代码执行了!");
		}
		System.out.println("程序结束了!");

/**
 * 异常处理机制在IO中的操作
 * @author soft01
 *
 */
	如何使用:
		BufferedReader br = null;
		try {
			br = new BufferedReader(new InputStreamReader(
						new FileInputStream("src/day08/Exception_finally2")));
			String line = null;
			while((line=br.readLine())!=null){
				System.out.println(line);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(br!=null){
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

/**
 * 使用该类测试throw,throws的用法
 * @author soft01
 *
 */
  用来测试:
	private int age;

	public int getAge() {
		return age;
	}
	
	/**
	 * throw用于向方法的调用者抛出一个异常
	 * 通常两种情况下会主动抛出异常:
	 * 1:当前方法在调用时遇到了一个满足语法
	 *   要求(程序可以正常运行),但是不满足该
	 *   方法设计的业务逻辑需求时,可以当作一
	 *   个异常抛出给调用者.
	 * 2:当前方法确实运行中出现了异常,但是该异常
	 *   不应该在当前方法中给解决时时,可以抛出给调用者解决
	 *   
	 * throws的作用是在声明方法的同时声明该方法
	 * 可能抛出的异常以通知调用者在调用该方法时
	 * 去处理该异常.
	 * 除了RuntimeException的其他类型异常在方法
	 * 中被抛出时,该方法必须用throws声明这类异常
	 * 的抛出,否则编译不通过.
	 *   
	 * @param age
	 */
	public void setAge(int age) throws _7IllegalAgeException{
		if(age<=0||age>=100){
			throw new _7IllegalAgeException("年龄不合法!");
		}
		this.age = age;
	}

/**
 * 测试异常的抛出
 * @author soft01
 *
 */
	如何使用:
		_3Person p = new _3Person();
		/*
		 * 当调用一个含有throws声明异常抛出的
		 * 方法时,编译器会要求必须有处理该异常
		 * 的手段,处理异常有两种方式:
		 * 1:使用try-catch捕获并处理
		 * 2:在当前方法继续使用throws声明该
		 *   异常的抛出
		 */
		try {
			p.setAge(100);
		} catch (_7IllegalAgeException e) {
			e.printStackTrace();
		}
		System.out.println(p.getAge());

/**
 * 子类重写父类一个含有throws异常声明的方法
 * 时对throws的重写准则
 * @author soft01
 *
 */
	public class _5Exception_throws {
		public void dosome()throws IOException,AWTException{
				
		}
	
	}

	class Son extends _5Exception_throws{
	
		//允许不抛出任何异常
	//	public void dosome(){
	//		
	//	}
	
		//可以抛出父类方法抛出异常的子类型异常
	//	public void dosome()
	//		throws FileNotFoundException{
	//		
	//	}
	
		//不允许抛出额外异常
	//	public void dosome()
	//		throws SQLException{
	//		
	//	}
	
		//不允许抛出父类方法抛出异常的父类型异常
	//	public void dosome()
	//		throws Exception{
	//		
	//	}

	
	}

/**
 * 异常的常用方法
 * @author soft01
 *
 */
	如何使用:
		System.out.println("程序开始了.");
		try{
			String str = "abc";
			System.out.println(Integer.parseInt(str));			
		}catch(NumberFormatException e){
			//输出错误堆栈信息
			e.printStackTrace();
			
			String message = e.getMessage();
			System.out.println(message);
		}
		
		System.out.println("程序结束了.");
	}

/**
 * 自定义异常
 * 自定义异常通常用来说明我们项目中某个
 * 业务逻辑异常.
 * 
 * 年龄不合法异常
 * 当设置年龄给定的值超出人类年龄范畴时会抛出异常
 * @author soft01
 *
 */
	如何使用:
	public class _7IllegalAgeException 
								extends Exception{
		private static final long serialVersionUID = 1L;

		public _7IllegalAgeException() {
			super();
			// TODO Auto-generated constructor stub
		}

		public _7IllegalAgeException(String message, Throwable cause, 
						boolean enableSuppression, boolean writableStackTrace) {
			super(message, cause, enableSuppression, writableStackTrace);
			// TODO Auto-generated constructor stub
		}

		public _7IllegalAgeException(String message, Throwable cause) {
			super(message, cause);
			// TODO Auto-generated constructor stub
		}

		public _7IllegalAgeException(String message) {
			super(message);
			// TODO Auto-generated constructor stub
		}

		public _7IllegalAgeException(Throwable cause) {
			super(cause);
			// TODO Auto-generated constructor stub
		}

/**
 * 线程有两种创建方式:
 * 方式一:继承Thread并重写run方法
 * @author soft01
 *
 */
	如何使用:
	public class _8ThreadDemo1 {
		public static void main(String[] args) {
			Thread t1 = new MyThread1();
			Thread t2 = new MyThread2();
			/*
			 * 启动线程要注意,不要直接调用线程
			 * 的run方法,因为run方法是线程要执行
			 * 的任务.而启动线程是调用start方法.
			 * 当start方法执行完毕后,线程会纳入到
			 * 线程调度中.一旦线程调度分配cpu时间
			 * 片后,该线程会自动执行它的run方法.
			 */
			t1.start();
			t2.start();
		}
	}

	/**
	 * 第一种创建线层的方式有两个不足:
	 * 1:由于java是单继承的,这就导致如果继承了
	 *   Thread就不能继承其他类,在实际开发中经常
	 *   会继承某个类来复用方法,这就导致若需要
	 *   同时具备线程能力时出现继承冲突.
	 * 2:由于继承Thread后需要重写run方法来定义
	 *   线程要执行的任务,这就导致线程与任务有
	 *   一个必然的耦合关系,会导致线程重用性差.
	 * @author soft01
	 *
	 */
	class MyThread1 extends Thread{
		public void run(){
			for(int i=0;i<1000;i++){
				System.out.println("你是谁啊?");
			}
		}
	}

	class MyThread2 extends Thread{
		public void run(){
			for(int i=0;i<1000;i++){
				System.out.println("我是查水表的!");
			}
		}
	}
	
----------------------------------------------------------------

	/**
	 * 第二种创建线程的方式
	 * 实现Runnable接口单独定义线程任务.
	 * @author soft01
	 *
	 */
	public class _9ThreadDemo2 {
		public static void main(String[] args) {
			Runnable r1 = new MyRunnable1();
			Runnable r2 = new MyRunnable2();
		
			Thread t1 = new Thread(r1);
			Thread t2 = new Thread(r2);
		
			t1.start();
			t2.start();
		}
	}

	class MyRunnable1 implements Runnable{
		public void run(){
			for(int i=0;i<1000;i++){
				System.out.println("xxThankYou");
			}
		}
	}

	class MyRunnable2 implements Runnable{
		public void run(){
			for(int i=0;i<1000;i++){
				System.out.println("You to mechyc");
			}
		}
	}

----------------------------------------------------------------

	/**
	 * 使用匿名内部类完成两种方式线程的创建
	 * @author soft01
	 *
	 */
		如何使用:
			Thread t1 = new Thread(){
				public void run(){
					for(int i=0;i<1000;i++){
						System.out.println("xxThankYou");
					}
				}
			};
		
			Thread t2 = new Thread(new Runnable(){
				public void run(){
					for(int i=0;i<1000;i++){
						System.out.println("YOu to me chyc");
					}
				}
			});
		
			t1.start();
			t2.start();
		
		}

/**
 * 线程提供了一个静态方法:
 * static Thread currentThread()
 * 该方法可以获取运行这个方法的线程
 * @author soft01
 *
 */
	如何使用:
		Thread main = Thread.currentThread();
		System.out.println("运行main方法的线程是:"+main);
		dosome();
		Thread t = new Thread(){
			public void run(){
				Thread t = Thread.currentThread();
				System.out.println("自定义线程:"+t);
				dosome();
			}
		};
		t.start();
	}
	
	public static void dosome(){
		Thread t = Thread.currentThread();
		System.out.println("运行dosome方法的线程是:"+t);
	}

/**
 * 获取线程信息的相关方法
 * @author soft01
 *
 */
	如何使用:
		Thread main = new Thread();
		
		String name = main.getName();
		System.out.println("name:"+name);
		
		long id = main.getId();
		System.out.println("ID:"+id);
		
		int priority = main.getPriority();
		System.out.println("priority:"+priority);
		
		boolean isAlive = main.isAlive();
		System.out.println("isAlive:"+isAlive);
		//是否为守护线程
		boolean isDaemon = main.isDaemon();
		System.out.println("isDaemon:"+isDaemon);
		//是否是被中断的
		boolean isInterrupted = main.isInterrupted();
		System.out.println("isInterrupted:"+isInterrupted);

/**
 * 线程优先级
 * 线程的优先级有10个,分别用数字1-10表示
 * 其中1最低,10最高,5为默认优先级.
 * 
 * 理论上,优先级越高的线程获取CPU时间片的
 * 次数就越多.
 * @author soft01
 *
 */
	如何使用:
		Thread max = new Thread(){
			public void run(){
				for(int i=0;i<10000;i++){
					System.out.println("max");
				}
			}
		};
		Thread min = new Thread(){
			public void run(){
				for(int i=0;i<10000;i++){
					System.out.println("min");
				}
			}
		};
		Thread nor = new Thread(){
			public void run(){
				for(int i=0;i<10000;i++){
					System.out.println("nor");
				}
			}
		};
		max.setPriority(Thread.MAX_PRIORITY);
		min.setPriority(Thread.MIN_PRIORITY);
		max.start();
		min.start();
		nor.start();

/**
 * 线程提供了一个静态方法:
 * static void sleep(long ms)
 * 该方法会将运行这个方法的线程阻塞指定毫秒
 * 当超时后该线程会重新回到RUNNABLE状态等待
 * 再次分配CPU时间并发运行.
 * @author soft01
 *
 */
	如何使用:
		/*
		 * 实现电子表功能
		 * 每秒钟输出当前系统时间,格式:
		 * 16:57:25
		 */
		
		while(true){
			Calendar calender = Calendar.getInstance();
			calender.add(calender.HOUR_OF_DAY,4);
			calender.add(calender.MINUTE,5);
			calender.add(calender.SECOND,18);
			Date date = calender.getTime();
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			System.out.println(sdf.format(date));
//			for(int i=0;i<21;i++){
//				System.out.println();
//			}
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

/**
 * 守护线程,又称为后台线程
 * 守护线程在是使用和创建是都与前台线程一致(
 * 线程默认创建出来时都是前台线程)
 * 但是结束时机有一点不同,即:进程结束时,所有
 * 守护线程都会被强制中断.
 * 当一个进程中的所有前台线程都结束时,进程
 * 就会结束.
 * @author soft01
 *
 */
	如何使用:
		//rose:前台线程
		Thread rose = new Thread(){
			public void run(){
				for(int i=0;i<5;i++){
					System.out.println("rose:let me go");
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
					}
				}
				System.out.println("rose:啊啊啊啊啊啊啊AAAAAAaaaa");
				System.out.println("音效:噗通");
			}
		};
		Thread jack = new Thread(){
			public void run(){
				while(true){
					System.out.println("jack:you jamp i jamp!");
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
					}
				}
			}
		};
		rose.start();
		/*
		 * 设置为后台线程,需要注意,该方法
		 * 必须在线程启动前调用
		 */
		jack.setDaemon(true);
		jack.start();

/**
 * 线程执行代码是异步的
 * 异步:各执行各的,互相没有影响.
 * 同步:有先后顺序的执行代码.
 * 
 * 线程提供了一个join方法,可以让线程之间
 * 同步执行代码.
 * @author soft01
 *
 */
  如何使用:
	public class _1Thread_join {
		//标识图片是否下载完毕
		public static boolean isFinish = false;
		public static void main(String[] args) {
			final Thread download = new Thread(){
				public void run(){
					System.out.println("down:开始下载图片");
					for(int i=1;i<=100;i++){
						System.out.println("down:"+i+"%");
						try {
							Thread.sleep(50);
						} catch (InterruptedException e) {
						}
					}
					System.out.println("down:图片下载完毕!");
					isFinish = true;
				}
			};
			Thread show = new Thread(){
				public void run(){
					System.out.println("show:准备显示图片");
					//应当等待下载线程将图片下载完
					/*
					 * show线程调用download.join后就
					 * 进入了阻塞状态,直到download线程
					 * 结束才会解除阻塞.
					 */
					try {
						/*
						 * java8以前的版本要求,在一个方法
						 * 的局部内部类中若想引用这个方法的
						 * 其他局部变量,那么这个变量必须是final的
						 */
						download.join();
					} catch (InterruptedException e) {
					}
				
				
					if(!isFinish){
						throw new RuntimeException("图片没下载完成");
					}
					System.out.println("show:显示图片完毕");
				}
			};
			show.start();
			download.start();
		}
	}

/**
 * 多线程并发安全问题
 * 当多个线程访问同一个资源时,由于线程切换时机
 * 不确定,导致代码执行顺序出现混乱,直接影响代码
 * 执行结果(为按照代码设计的执行顺序有序执行代码)
 * 严重时可能导致系统瘫痪.
 * @author soft01
 *
 */
	如何使用:
		public class _2SyncDemo {
			public static void main(String[] args) {
				final Table table = new Table();
				Thread t1 = new Thread(){
					public void run(){
						while(true){
							int bean = table.getBean();
							Thread.yield();
							System.out.println(getName()+":"+bean);
						}
					}
				};
				Thread t2 = new Thread(){
					public void run(){
						while(true){
							int bean = table.getBean();
							Thread.yield();
							System.out.println(getName()+":"+bean);
						}
					}
				};
				t1.start();
				t2.start();
			}
		}
		class Table{
			private int beans = 20;
			/**
			 * 当一个方法使用synchronized修饰后,那么
			 * 该方法称为"同步方法",即:多个线程不能
			 * 同时访问方法内部(只能排队,有先后顺序
			 * 的执行方法内部代码).
			 * 这样就不会因为多个线程同时在方法内部
			 * 执行由于出现线程切换导致代码执行顺序
			 * 出现混乱的情况.
			 * 
			 * 在方法上使用synchronized,那么同步
			 * 监视器对象为当前方法所属对象,即:
			 * 方法中看到的"this"
			 * @return
			 */
			public synchronized int getBean(){
				if(beans==0){
					throw new RuntimeException("没有豆子了");
				}
				Thread.yield();//模拟线程切换
				return beans--;
			}
		}

/**
 * 有效缩小同步范围可以在保证并发安全的
 * 前提下尽可能的提高并发效率.
 * @author soft01
 *
 */
	如何使用:
		public class _3SyncDemo2 {
			public static void main(String[] args) {
				final Shop shop = new Shop();
				Thread t1 = new Thread(){
					public void run(){
						shop.buy();
					}
				};
				Thread t2 = new Thread(){
					public void run(){
						shop.buy();
					}
				};
				t1.start();
				t2.start();
			}
		}
		class Shop{
			public void buy(){
				Thread t = Thread.currentThread();
				try{
					System.out.println(t.getName()+":正在挑衣服...");
					Thread.sleep(5000);
					/*
					 * 同步块
					 * 同步块可以精确的括上需要多个线程
					 * 同步执行的代码.有效的缩小同步范围
					 * 可以提高并发效率
					 * 需要注意的是,同步块需要指定"同步监视器"
					 * 即:上锁的对象.
					 * 若希望多个线程可以同步执行代码,那么
					 * 上锁的这个对象必须多个线程看到的是
					 * [同一个]才行
					 */
					synchronized (this){
						System.out.println(t.getName()+":正在试衣服...");
						Thread.sleep(5000);				
					}
			
					System.out.println(t.getName()+":结帐离开...");
			
				}catch(Exception e){
			
				}
			}
		}

/**
 * 互斥锁
 * 
 * 互斥锁可以让多段代码间执行是互斥的,即
 * 当其中一段代码被一个线程执行时,其他线程
 * 除了这段代码不能执行外,其他代码也不可以执行.
 * 
 * 只要使用同步块将需要互斥的代码括起来,然后保证
 * 这些同步块指定的同步监视器对象是同一个即可.
 * @author soft01
 *
 */
	如何使用:
		public class _4SyncDemo3 {
			public static void main(String[] args) {
				final Foo foo = new Foo();
				Thread t1 = new Thread(){
					public void run(){
						foo.methodA();
					}
				};
				Thread t2 = new Thread(){
					public void run(){
						foo.methodB();
					}
				};
				t1.start();
				t2.start();
			}
		}

		class Foo{
			public synchronized void methodA(){
				Thread t = Thread.currentThread();
				System.out.println(t.getName()+":正在执行A方法");
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
				}
				System.out.println(t.getName()+":执行A方法完毕");
			}
			public synchronized void methodB(){
				Thread t = Thread.currentThread();
				System.out.println(t.getName()+":正在执行B方法");
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(t.getName()+":执行B方法完毕");
			}
		}

/**
 * 静态方法如果使用Synchronized后,该方法
 * 一定具有同步效果
 * @author soft01
 *
 */
	如何使用:
		public class _5SyncDemo4 {
			public static void main(String[] args) {
				Thread t1 = new Thread(){
					public void run(){
						Boo.dosome();
					}
				};
				Thread t2 = new Thread(){
					public void run(){
						Boo.dosome();
					}
				};
				t1.start();
				t2.start();
			}
		}

		class Boo{
			public static synchronized void dosome(){
				Thread t = new Thread();
				System.out.println(t.getName()+":正在运行dosome方法...");
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
				}
				System.out.println(t.getName()+":运行完毕!");
			}
		}
-------------------------------------------------------------------------------------------------|-
	public class _6SyncDemo5 {																	 |
		public static void main(String[] args) {												 |
			final Coo coo = new Coo();															 |
			Thread t1 = new Thread(){															 |
				public void run(){																 |
					coo.methodA();																 |
				}																				 |
			};																					 |
			Thread t2 = new Thread(){															 |
				public void run(){																 |
					coo.methodB();																 |
				}																				 |
			};																					 |
			t1.start();																			 |
			t2.start();																			 |
		}																						 |
	}																							 |
																								 |																 
	class Coo{																					 |
		private Object o1 = new Object();														 |
		private Object o2 = new Object();														 |
		public void methodA(){																	 |
			try{																				 |
				synchronized(o1){																 |
					Thread t = Thread.currentThread();											 |
					System.out.println(t.getName()+"正在运行A方法...");							 |
					Thread.sleep(5000);															 |
					methodB();																	 |
					System.out.println(t.getName()+"运行A完毕");									 |
				}																				 |
			}catch(Exception e){																 |
			}																					 |
		}																						 |
		public void methodB(){																	 |
			try{																				 |
				synchronized(o2){																 |
					Thread t = Thread.currentThread();											 |
					System.out.println(t.getName()+"正在运行B方法...");							 |
					Thread.sleep(5000);															 |
					methodA();																	 |
					System.out.println(t.getName()+"运行B完毕");									 |
				}																				 |
			}catch(Exception e){																 |
			}																					 |
		}																						 |
-------------------------------------------------------------------------------------------------|-

/**
 * 将集合或Map转换为线程安全的
 * 
 * @author soft01
 *
 */
	如何使用:
		/*
		 * ArrayList,LinkedList都不是
		 * 线程安全的
		 */
		List<String> list = new ArrayList<String>();
		list.add("one");
		list.add("two");
		list.add("three");
		System.out.println(list);
		/*
		 * 将给定的List转换为线程安全的
		 */
		list = Collections.synchronizedList(list);
		System.out.println(list);
		
		//HashSet也不是线程安全的
		Set<String> set = new HashSet<String>(list);
		System.out.println(set);
		//将给定的Set集合转换为线程安全的
		Collections.synchronizedSet(set);
		System.out.println(set);
		
		/*
		 * HashMap也不是线程安全的
		 */
		Map<String,Integer> map = new HashMap<String,Integer>();
		map.put("语文",88);
		map.put("数学",98);
		map.put("英语",89);
//		map.put("语文",88);
		System.out.println(map);
		//将给定的Map转换为线程安全的
		map = Collections.synchronizedMap(map);
		System.out.println(map);
		
		
		/*
		 * API文档也有说明:
		 * 线程安全的集合也不与迭代器操作互斥.
		 * 所以在使用迭代器遍历集合时要自行维护
		 * 与集合增删元素等操作的互斥关系.否则
		 * 迭代器遍历过程中其他线程对集合元素
		 * 进行变动,迭代器遍历会抛出异常.
		 * 
		 */

/**
 * 线程池
 * 线程池是用来管理和调度线程的.
 * 主要有两个作用:
 * 1:控制线程数量
 * 2:重用线程
 * 
 * 当项目中需要创建大量线程,或者发现线程有
 * 频繁创建销毁等情况时,就应当那个考虑使用线程池
 * 来管理线程
 * @author soft01
 *
 */
	如何使用:
		ExecutorService threadPool = Executors.newFixedThreadPool(3);
		for(int i=0;i<5;i++){
			Runnable runn = new Runnable(){
				public void run(){
					Thread t = Thread.currentThread();
					System.out.println(t.getName()+"正在执行任务");
					try {
						Thread.sleep(5000);
						System.out.println(t.getName()+"运行任务完毕");
					} catch (InterruptedException e) {
						System.out.println("线程被中断了!");
					}
				}
			};
			threadPool.execute(runn);
			System.out.println("指派了一个任务给线程池");
		}
		
		/*
		 * shutdown()
		 * 线程池不再接收新的任务,并且会将当前
		 * 线程池中所有任务都执行完毕后停止.
		 * 
		 * shutdownNow()
		 * 会强制将线程池中所有线程中断并立即
		 * 停止线程池.
		 */
		threadPool.shutdownNow();
		System.out.println("线程池停止了!");

---------------------------------------------------------------------------------------------------

/**
 * 聊天室服务端
 * @author soft01
 *
 */
public class Server {
	
	/**
	 * java.net.ServerSocket
	 * 运行在服务端的Socket,主要有两个作用:
	 * 1:向操作系统申请服务端口,客户端就是
	 *   通过这个端口找到服务端应用程序的.
	 * 2:监听服务端口,当客户端实例化Socket并
	 *   通过ServerSocket服务端口发起连接时,
	 *   ServerSocket就能感知到并实例化一个
	 *   Socket与客户端通讯.
	 *   
	 */
	private ServerSocket server;
	/*
	 * 保存所有客户端的输出流,用来广播消息使用.
	 */
	private List<PrintWriter> allOut;
	
	public Server(){
		try {
			/*
			 * 实例化ServerSocket的同时指定
			 * 服务端口
			 * 该端口不能与操作系统上其他应用
			 * 程序已经申请的端口冲突,否则实例
			 * 化失败,抛出地址被占用的异常.
			 */
			server = new ServerSocket(8088);
			
			allOut=new ArrayList<PrintWriter>();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void start(){
		try {
			/*
			 * ServerSocket提供方法
			 * Socket accept()
			 * 该方法是一个阻塞方法,作用是
			 * 监听服务端口,直到一个客户端
			 * 连接过来为止,然后返回一个Socket
			 * 实例,通过该Socket就可以与刚
			 * 连接的客户端交互数据了.
			 */
			while(true){
				System.out.println("等待客户端连接...");
				Socket socket = server.accept();
				System.out.println("一个客户端已连接!");
				
				//启动一个线程来处理该客户端的交互
				ClientHandler handler = new ClientHandler(socket);
				Thread t = new Thread(handler);
				t.start();
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		try{
			Server server = new Server();
			server.start();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	/**
	 * 该线程任务是负责与给定的Socket对应
	 * 的客户端进行交互.
	 * @author soft01
	 *
	 */
	class ClientHandler implements Runnable{
		//该线程通过这个Socket与客户端进行交互
		private Socket socket;
		//远端计算机(客户端)地址信息
		private String host;
		
		public ClientHandler(Socket socket){
			this.socket=socket;
			//获取远端计算机地址信息
			InetAddress address = socket.getInetAddress();
			host=address.getHostAddress();
		}
		
		public void run(){
			PrintWriter pw = null;
			try {
				/*
				 * Socket提供了方法:
				 * InputStream getInputStream()
				 * 通过该输入流可以读取远端计算机
				 * 发送过来的消息.
				 */
//				InputStream in = socket.getInputStream();
//				InputStreamReader isr = new InputStreamReader(in,"UTF-8");
//				BufferedReader br = new BufferedReader(isr);
				
				BufferedReader br = new BufferedReader(
						new InputStreamReader(socket.getInputStream(),"UTF-8"));
				
				//创建输出流
//				OutputStream out = socket.getOutputStream();
//				OutputStreamWriter osw = new OutputStreamWriter(out,"UTF-8");
//				pw = new PrintWriter(osw,true);
				
				pw = new PrintWriter(new OutputStreamWriter(
						socket.getOutputStream(),"UTF-8"),true);
				
				//将该输出流存入共享集合
				synchronized(allOut){
					allOut.add(pw);
				}
				
				String message=null;
				/*
				 * 使用readLine方法读取客户端发送过来的
				 * 每一行字符串时,客户端断开连接后,这里
				 * 根据客户端系统不同有两种情况:
				 * 1:windows的客户端断开后:readLine方法
				 *   会直接抛出异常
				 * 
				 * 2:linux的客户端断开连接后:readLine方法
				 * 会返回null
				 * 
				 */
				while((message = br.readLine())!=null){
					System.out.println("客户端说:"+message);
//					pw.println(message);
					//转发给所有客户端
					synchronized(allOut){
						for(PrintWriter p:allOut){
							p.println(host+"说:"+message);
						}
					}
				}
				
			} catch (Exception e) {
				e.printStackTrace();
			}finally{
				//处理客户端断开连接的操作
				
				//将该客户端的输出流从共享集合删除
				synchronized(allOut){
					allOut.remove(pw);					
				}
				
				//将Socket关闭释放资源
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
}

---------------------------------------------------------------------------------------------------

/**
 * 聊天室客户端
 * @author soft01
 *
 */
public class Client {
	/*
	 * java.net.Socket
	 * Socket封装了TCP协议,使用它可以进行
	 * TCP通讯.
	 */
	private Socket socket;
	
	/**
	 * 构造方法,用来初始化客户端.
	 */
	public Client(){
		try {
			/*
			 * 实例化Socket时需要传入两个
			 * 参数:
			 * 1:服务端计算机的IP地址,通过
			 *   它可以找到网络上的服务端
			 *   计算机.
			 * 2:服务端口,该端口是服务端程序
			 *   启动后向它的计算机申请的,我们通过
			 *   这个端口就可以找到运行服务端
			 *   计算机上的这个服务端应用程序了.
			 *   
			 * 3:而且实例化Socket过的过程就是连接
			 *   服务端的过程在实例化时就会按照
			 *   给定的地址与端口进行网络连接,若
			 *   服务端没有响应,这里会抛出异常.
			 * 
			 * localhost:表示本机地址
			 *   
			 */
			System.out.println("正在连接服务端...");
			socket = new Socket("172.231.9.130",8088);
			System.out.println("已连接!");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 开始客户端工作的方法.
	 */
	public void start(){
		try {
			//启动接受服务端消息的线程
			ServerHandler handler = new ServerHandler();
			Thread t = new Thread(handler);
			t.start();
			
			Scanner scanner = new Scanner(System.in);
			/*
			 * Socket提供方法:
			 * OutputStream getOutputStream()
			 * 该方法会获取一个输出流,通过该
			 * 流写出的数据会发送给远端计算机
			 * 对于客户端这边而言,远端就是服务端
			 */
//			OutputStream out = socket.getOutputStream();
//			OutputStreamWriter osw = new OutputStreamWriter(out,"UTF-8");
//			PrintWriter pw = new PrintWriter(osw,true);
			PrintWriter pw = new PrintWriter(
				new OutputStreamWriter(socket.getOutputStream(),"UTF-8"),true);
			String message = null;
			long lastSend=System.currentTimeMillis()-500;
			while(true){
				message = scanner.nextLine();
				if(System.currentTimeMillis()-500<lastSend){
					System.out.println("你的说话速度太快了!");
					continue;
				}
				lastSend=System.currentTimeMillis();
				pw.println(message);
			}
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		try{
			Client client = new Client();
			client.start();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	/**
	 * 该线程负责接受服务端发送过来的消息
	 * @author soft01
	 *
	 */
	class ServerHandler implements Runnable{
		public void run(){
			try {
				BufferedReader br = new BufferedReader(
						new InputStreamReader(socket.getInputStream(),"UTF-8"));
				String message = null;
				while((message=br.readLine())!=null){
					System.out.println(message);
				}
				
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

---------------------------------------------------------------------------------------------------
package day12;

public class Emp {
	private int id;
	private String name;
	private int age;
	private String gender;
	private int salary;
	
	public Emp(){
		
	}

	public Emp(int id, String name, int age, String gender, int salary) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
		this.gender = gender;
		this.salary = salary;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	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;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public int getSalary() {
		return salary;
	}

	public void setSalary(int salary) {
		this.salary = salary;
	}
	
	public String toString(){
		return id+","+name+","+age+","+gender+","+salary;
	}
}
---------------------------------------------------------------------------------------------------
package day12;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * 使用DOM解析XML文档
 * @author adminitartor
 *
 */
public class ParseXMLDemo {
	public static void main(String[] args) {
		/*
		 * 使用dom4j解析xml文档的大致流程
		 * 1:创建SAXReader
		 * 2:使用SAXReader读取XML文档并生成
		 *   Document对象.
		 *   这一步就是DOM解析XML耗时耗资源
		 *   的地方,因为要先将XML文档所有内容
		 *   读取完毕以生成Document,所以耗时
		 *   并且由于Document对象是存入内存
		 *   的所以耗资源.这都取决于XML文档的
		 *   大小.
		 * 3:通过Document对象获取根元素
		 * 4:按照xml文档结构从根元素开始逐级
		 *   获取子元素,以达到遍历XML文档的
		 *   目的.
		 * 
		 */
		try {
			//1
			SAXReader reader = new SAXReader();
			
			//2
			Document document = reader.read(new File("emplist.xml"));		
//			reader.read(new FileInputStream("emplist.xml"));
			
			/*
			 * 3
			 * Document提供了获取根元素的方法:
			 * Element getRootElement()
			 * 
			 * Element的每一个实例用于表示XML文档
			 * 中的一个元素(一对标签)
			 */
			Element root = document.getRootElement();
			/*
			 * Element提供了获取元素内容的相关方法:
			 * 
			 * Element element(String name)
			 * 获取当前元素下指定名字的子元素
			 * 
			 * List elements()
			 * 获取当前元素下的所有子元素
			 * 
			 * List elements(String name)
			 * 获取当前元素下所有同名子元素
			 * 
			 * String getName()
			 * 获取当前元素的名字
			 * 
			 * String getText()
			 * 获取当前元素中间的文本
			 * 
			 * Attribute attribute(String name)
			 * 获取当前元素中指定名字的属性
			 * 
			 */
			//用于保存所有解析出来的员工信息
			List<Emp> empList = new ArrayList<Emp>();
			
			//获取根元素<list>中的所有子元素<emp>
			List<Element> list = root.elements();
			
			for(Element empEle : list){
				//获取name
				Element nameEle = empEle.element("name");
				String name = nameEle.getText();
				
				//获取age
				int age = Integer.parseInt(
					empEle.elementText("age")
				);
		
				//获取gender
				String gender = empEle.elementText("gender");
			
				//获取salary
				int salary = Integer.parseInt(
					empEle.elementText("salary")	
				);
				//获取id属性
				Attribute attr = empEle.attribute("id");
				int id = Integer.parseInt(
					attr.getValue()
				);
				
				Emp emp = new Emp(id, name, age, gender, salary);
				empList.add(emp);
			}
			
			System.out.println("解析完毕!");
			for(Emp emp : empList){
				System.out.println(emp);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
---------------------------------------------------------------------------------------------------
package day12;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

/**
 * 使用DOM生成XML文档
 * @author adminitartor
 *
 */
public class WriteXMLDemo {
	public static void main(String[] args) {
		
		List<Emp> empList = new ArrayList<Emp>();
		empList.add(new Emp(1,"张三",22,"男",3000));
		empList.add(new Emp(2,"李四",23,"女",4000));
		empList.add(new Emp(3,"王五",24,"男",5000));
		empList.add(new Emp(4,"赵六",25,"女",6000));
		empList.add(new Emp(5,"钱七",26,"男",7000));
		
		/*
		 * 生成XML文档的大致步骤:
		 * 1:创建Document对象
		 * 2:向Document中添加根元素
		 * 3:向根元素中按照XML文档需要的结构
		 *   逐级添加子元素.
		 * 4:创建XmlWriter
		 * 5:使用XmlWriter将Document写出  
		 */
		XMLWriter writer = null;
		try {
			//1
			Document document
				= DocumentHelper.createDocument();
			
			/*
			 * 2  Document提供了方法:
			 * Element addElement(String name)
			 * 向当前文档中添加给定名字的根元素
			 * 并将其返回,以便针对这个根元素继续
			 * 操作.
			 * 需要注意,该方法只能调用一次,因为
			 * 一个文档中只能有一个根元素
			 */
			Element root 
				= document.addElement("list");
			
			/*
			 * 将集合中的每个员工信息以一个<emp>
			 * 标签形式存入<list>中
			 */
			for(Emp emp:empList){
				/*
				 * 添加<emp>标签
				 * 
				 * Element提供了操作元素的相关方法:
				 * 
				 * Element addElement(String name)
				 * 向当前元素中添加给定名字的子元素
				 * 并将其返回.
				 * 
				 * Element addText(String text)
				 * 向当前元素中添加指定文本
				 * 
				 * Element addAttribute(String name,String value)
				 * 向当前元素中添加指定名字及对应值的属性
				 */
				Element empEle = root.addElement("emp");
				
				//添加<name>
				Element nameEle = empEle.addElement("name");
				nameEle.addText(emp.getName());
				
				//添加<age>
				Element ageEle = empEle.addElement("age");
				ageEle.addText(String.valueOf(emp.getAge()));
				
				//添加<gender>
				empEle.addElement("gender").addText(
					emp.getGender()
				);
				
				//添加<salary>
				empEle.addElement("salary").addText(
					String.valueOf(emp.getSalary())	
				);
				
				//添加id属性
				empEle.addAttribute(
					"id", String.valueOf(emp.getId())
				);
			}
			
			
			FileOutputStream fos
				= new FileOutputStream("myemp.xml");
			 
			writer = new XMLWriter(
				fos,OutputFormat.createPrettyPrint()
			);
			
			writer.write(document);
			System.out.println("生成完毕!");
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			if(writer != null){
				try {
					writer.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
	}
}
---------------------------------------------------------------------------------------------------
package day12;

import java.io.File;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * 使用XPath检索XML文档数据
 * 需要注意,在DOM4J中如果需要使用这个功能
 * 需要引入一个额外的jar包:jaxen-xx-xx.jar
 * @author adminitartor
 *
 */
public class XPathDemo {
	public static void main(String[] args) {
		try {
			
			SAXReader reader = new SAXReader();
			Document doc = reader.read(
				new File("myemp.xml")
			);
			/*
			 * Document提供了方法:
			 * List selectNodes(String path)
			 * 根据给定的XPATH检索数据并返回
			 * 返回的集合中是Element还是Attribute
			 * 取决于XPATH检索内容.
			 */
			String xpath = "/list/emp[salary>4000 and gender='男']/name";
			List<Element> list 
				= doc.selectNodes(xpath);
			for(Element e : list){
				System.out.println(e.getText());
			}
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
---------------------------------------------------------------------------------------------------
生成随机数的两种方法:
 1.   Random r = new Random();
	  int index = r.nextInt(100);
 2.	  int index = (int)(Math.random()*100);

  

转载于:https://www.cnblogs.com/diviner0359/p/10114197.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值