java

day1

软件(Software)是一系列按照特定顺序组织的计算机数据和指令的集合
人机交互两种方式:图形交互,命令交互。
java的特点:安全可靠,面向对象,跨平台(与平台无关,可以运行在任何操作系统之上)
java的三个版本:javaME(过时了),javaSE(standard editon 即标准版本),javaEE(enterprise edition 即企业版本)
java如何实现跨平台的:因为有JVM(java虚拟机),java程序是由JVM来运行的,JVM是跨平台的,所以java程序是跨平台的。安装jdk时就包含了JVM
       下载JDK时,选择相应操作系统的JDK。
jre:java runtime environment(java运行时环境),运行java程序时需要的资源在jre中,
jdk和jre的关系:jdk包括了jre
jre和jvm的关系:jre包括了jvm 
 jdk>jre>jvm
jdk:java development kit(java开发工具包):编写java程序时需要的资源在jdk中,
安装软件下的目录:
 bin:(binary)二进制,存放可执行文件,其文件夹下的java.exe和javac.exe是经常使用的程序:
  使用方式:1.切换到c盘;2.切换到jdk下的bin所在的路径;3.执行javac
配置环境变量:为了让java,javac这些可执行程序在任何路径下都可以被执行。
        1.添加一个变量:JAVA_HOME :jdk的安装地址
        2.在path中:添加%JAVA_HOME%\bin(可执行程序的路径),%在win中代表取其地址    
           当执行java或javac这些可执行程序时,系统会去path中配置的路径下去找相应的程序。
编写java程序:d.java
编译程序:由于电脑只认识0,1  所以执行前要先进行编译,把java源代码转成电脑认识的 ---javac
 1.吧路径切换到源文件的位置;
 2.javac d.java 编译,编译完会生成和类名相同的.class文件(字节码文件),有多少个类就生成多少个.class文件
执行程序 :执行字节码文件,JVM负责 
    执行含有入口的类(字节码)。java Demo1
第二章:基本语法
2.1关键字
关键字:被java赋予了特殊含义的单词
2.2标识符
标识符:程序中需要自己起名字的   如:类名   由字母,0-9,_,$组成,不能以数字开头,不能和关键字同名,
类名:每个类名首字母必须大写
注释:// 单行注释 /*    */多行注释
缩进
常量:程序中用到的固定不变的数
机制转换:十进制,二进制,八进制,十六进制
 

最小单位是byte(字节),如写4,写成00000100。

八进制:3位数的二进制转换为一位数,最大的数为7,说明3位数取值在0-7中,就是8进制。
 

System.out.println(14);
System.out.println(014); //八进制
System.out.println(0x14); //十六进制

原码,反码,补码:
        正数都是本身
        负数原码首位为1,反码是符号位不变,其余相反,补码就是反码加1。
 6                               -6
原码    00000110             10000110
反码    00000110        11111001
补码    00000110             11111010

一个字节表示的十进制数的范围(包括负数 ):1000 0000   在机器里和数学不一样,这里面都是0是最小的。首位仅代表符号位,与数学中无关。
故答案为  -128,127      
  理解为:1111 1111 是负数,所以0111 1111 是最大的数,为127
      1111 1111 是-127,因为第一个1是符号位,故可以再进位到首位,所以是-128
数据类型:决定变量占据多大的内存
       分为两大类:基本数据类型和引用数据类型
            基本数据类型有8种:整数类型:byte 字节类型  内存大小,一个字节   -128---127
                                                                 short 短整型,2个字节      -32768----32767
                                                            int   整形,4个字节   
                                                            long  长整形,8个字节
                                        浮点型: float  单精度浮点型,4个字节,精确到7位
                                                      double 双精度浮点型,8个字节,精确到16位
                                       布尔类型:boolean  只有两个数值  true和false  一个字节。
                                       字符类型:char         两个字节  使用的是unicode编码表,单引号里面只能放一个字符
           引用数据类型:字符串类型 String
 数据类型转换:数据类型是有级别高低的,从低到高:byte,sort,char>int>long>float>double
       自动类型转换(低级别到高级别)
       强制类型转换(高级别到低级别)
转义字符(就是改变它的意思):通过反斜杠改变后面所跟字符的含义
 1 class Demo2
 2 {
 3     public static void main(String args[]){
 4         /*    
 5             数据类型:决定变量占据多大的内存
 6             分为两大类:基本数据类型和引用数据类型
 7             基本数据类型有8种:整数类型:字节类型:byte  内存大小,一个字节   -128---127
 8                                                    short 短整型,2个字节      -32768----32767
 9                                                    int   整形,4个字节          
10                                                    long     长整形,8个字节
11                                 浮点型:float  单精度浮点型,4个字节,精确到7位
12                                         double 双精度浮点型,8个字节,精确到16位
13                                 布尔类型:boolean  只有两个数值  true和false  一个字节。
14                                 字符类型:char    两个字节  使用的是unicode编码表,单引号里面只能放一个字符
15             字符串类型   String     
16                                         
17         */
18         float f=66.6f;    //一个小数默认是double类型,所以在后面加f可表示float类型
19         boolean b=false;
20         char c='m';
21         System.out.println(c);
22         char c1=97;
23         System.out.println(c1);
24         
25     //    char c2='97';
26     //    System.out.println(c2);
27         char c3='你';
28         System.out.println(c3);    
29     }
30 
31 }
32 class A
33 {
34     public static void main(String args[]){
35         byte b=45;
36         short s=56;
37         int a=88;
38         double d=8900;
39         //自动类型转换
40         double sum=b+s+a+d;//从低级别到高级别会自动转换
41         System.out.println(sum);
42         //自动类型转换
43         byte m=127;//java中一个整数默认看成double类型
44         System.out.println(m);
45 
46         //强制类型转换:从高级别到低级别
47         m=(byte)(m+10);  //赋值                                
48         System.out.println(m);    //答案为-119
49         
50         int g='A';//自动类型转换
51         char ch=97; //砍掉前两个字节
52 
53     }
54 }
55 class B
56 {
57     public static void main(String args[]){
58         //转移字符:通过反斜杠改变后面所跟字符的含义
59         System.out.println("h\'ello\" wor\\ld! 呵呵 \n 哈哈哈");
60         System.out.println("-----\t -----");
61 
62     }
63 }

classA的m输出过程

class B的运行结果为:

day2

   ·java中的运算符:

          算术运算符: + - * / % ++ --
          赋值运算符:=  +=  -=  *=  /=  %=(复合赋值运算符)
 例如:short s=5;
           s=(short)(s+5); //进行强制类型转换
           s+=5; //使用复合赋值运算符
           //s=s+5   由于左边的s是short 类型,右边的5是int类型,自动类型转换会使数据丢失。
          关系运算符:>  >=  <=  ==  !=
          逻辑运算符:&&(与)    ||(或)   内部执行效率更快
  &   | 
    !(非)
  &&:短路与:math>90 && eng>90:左边的表达式值为false,右边的表达式就不计算了,因为结果肯定为false
  ||:短路或:math>90 || eng>90:左边的表达式值为true,右边的表达式就不计算了,因为结果肯定为true。
  &:逻辑与:左边的表达式值为false,右边的表达式仍然计算
  |: 逻辑或:左边的表达式值为true,右边的表达式仍然计算
           位运算符:二进制位    &(按位与,对应位上全是1,才是1)  |(按位或,对应位上只要有1,就是1) 
              ^(按位异或,异即对应位上不同为1,相同为0,一个数异或另一个数两次,还是原数,可以用来实现加密) 
              ~(按位取反,原数取反的话,得到的数就是-(原数-1)可以很快取到反码)
              <<左移(低位补0)        >>右移(高位是0就补0,高位是1就补1)       >>>(无符号右移,高位只补0)
                左移就是 原数*2的几次方     右移要是正数,就是原数/2的几次方要是负数,就要先看补码,再回到源码
               <<< (当不想改变数本身的二进制位时,使用无符号右移,用于进制转换移位时防止符号位出错)。
表达式:由运算符和数据组合在一起叫表达式
表达式是有值的,
 1 class  ZQF
 2 {
 3  public static void main(String[] args) 
 4  {
 5   //+:连接符号
 6   int a=5,b=6;
 7   //字符串和任何类型的数据相连接,最后都是字符串
 8   System.out.println("hehe"+a+b); //hehe56
 9   System.out.println("a="+a+",b="+b);
10   System.out.println(a+","+b);
11   System.out.println(5/2.0); //结果为2.5
12   System.out.println(5%2.0);  //结果为1.0
13   System.out.println(-5%2); //-1 ,结果的正负由被除数决定,和除数无关
14   System.out.println(-5%-2); //-1
15   int num=3456; //求这个整数每一位上的数的和
16   int ge =num%10;
17   int shi=num/10%10;
18   int bai=num/100%10;
19   int qian=num/1000;
20   int m=5,n;
21   n=m++; //先取m的值,取到的值赋给左边的N,然后m再自身加1
22   n=++m; //m先自身加1,然后再赋给左边的变量n,++在后边,先取值,再赋值给左边
23   System.out.pritntln("m="+m+",n="+n);
24   
25   int a=9;//声明变量
26   short s=5;
27   //s=(short)(s+5);
28   s+=5; //s=s+5
29   //关系运算符
30   int x=55,y=66;
31   //x>y :关系表达式 表达式:运算符和数据组合在一起组成了表达式
32   System.out.println(x<y);  //结果只有两种可能,关系成立--true,关系不成立--false
33   System.out.println(x=99);  //赋值表达式
34   System.out.println(x!=y);
35   
36   //逻辑运算符: &&   || !
37   int math=90,eng=60;
38   math>90 && eng>90; //表达式
39   System.out.println(math>90 && eng>90); //表达式
40   //true && false=false
41   //true && true=true
42   System.out.println(math>90 || eng>90); 
43   System.out.println(!true);
44   System.out.println(!(math==67));
  /*
   &&:短路与:math>90 && eng>90:左边的表达式值为false,右边的表达式就不计算了,因为结果肯定为false
   ||:短路或:math>90 || eng>90:左边的表达式值为true,右边的表达式就不计算了,因为结果肯定为true。
   &:逻辑与:左边的表达式值为false,右边的表达式仍然计算
   |: 逻辑或:左边的表达式值为true,右边的表达式仍然计算
  */
  System.out.println(~8);//-9

 } 
}

public class Test{
 public static void main(String args[]){
  System.out.println(~6);
  题目:将一个十进制数转成十六进制数(使用位运算符)
  int num=60;
  int n1=num&15;
  int n2=num>>>4;
  System.out.println(""+n2+(char)(n1-10+'a')); //把高级别的转成低级别的,n1-10为Int类型,比char类型大,2加‘a'为99,转成char类型为'c'


  //对两个整数变量的值进行交换
   //第一种使用加减
  int a=5,b=6;
  a=a+b;  //a+b的值可能溢出
  b=a-b;
  a=a-b;
  System.out.println("a="+a+",b="+b);
   //第二种使用异或
  a=a^b;
  b=a^b; //a^b^b   即a
  a=a^b; //a^a^b   即b
  System.out.println("a="+a+",b="+b);
   //第三种使用第三个变量
   int c=0;
   c=a;
   a=b;
   b=c;
  System.out.println("a="+a+",b="+b);


  //三元运算符
  int x=3,y=6;
  int m;
  x>y?x:y  //先计算?号前面的表达式,如果表达式的值为true,取:号前边的值,否则取:后边的值
  m=a>b?a:b; //赋值是最后进行的
  System.out.println(m);

  //使用三元运算符,获取最大的整数
  int x=56,y=23,z=125;
  int a,max;
  a=x>y?x:y;
  max=a>z?a:z;
 }

   ·选择结构:if....else if...elseif...else...switch()   case


class D{
 public static void main(String args[]){
  int a=4;

  //取值,比case
  //直到遇到break或者右大括号
  //当所有都不匹配时,就会执行default。执行后还是要按照第二步走。

  switch(a) //switch:开关    //支持byte char int short ,枚举,String
  {
   default:
    System.out.println("ok");
   case 1:
    System.out.println("1");//break
   case 2:
    System.out.println("2");//break
   case 3:
    System.out.println("3");break; //break可以拦截
  }
  int month=4;
  switch(month)
  {
   case 3:
   case 4:
   case 5:System.out.println("春季");break;
   case 6:
   case 7:
   case 8:System.out.println("夏季");break;
   case 9:
   case 10:
   case 11:System.out.println("秋季");break;
   case 12:
   case 1:
   case 2:System.out.println("冬季");break;
   default:
    System.out.println("无效月份");

 }  
 } 
}

   ·循环结构:

  while(条件)     与   do....while...     (区别:do...while...至少能执行一次)        for循环

 1 class D{
 2  public static void main(String args[]){
 3   //while...    //先判断再执行11
 4   int i=9;
 5   while(i>=0){
 6    System.out.println("hello ");
 7    i--;
 8   }
 9   //do ...  while...//先执行再判断
10   int j=1;
11   do{
12    System.out.println("hello world");
13    j++;
14   }while(j<=5);
15  
16   //for循环  //先执行表达式1,再执行表达式2,如果表达式2成立,再执行表达式中的代码4
17      //然后执行表达式3,再执行表达式2,成立执行表达式2,反复直到表达式2不成立,则退出循环。
18   for(int j=1;j<=5;j++ )
19   {
20    System.out.println("--"); 
21   }
22   System.out.println(j); //找不到符号
23   //变量的作用域:从其定义的位置开始,到其所在的大括号结束。
24   //for循环结束,变量j同时释放内存,所以当循环中使用的变量在循环结束后不再使用适合使用for循环,否则适合使用while()或do{}while循环。
25  }
26 }

 

变量的作用域:从其定义的位置开始,到其所在的大括号结束。
 

 day3

   ·嵌套循环

  1 class  A
  2 {
  3     public static void main(String[] args) 
  4     {    
  5         /*
  6             嵌套循环: 外层循环控制行数,内层训话控制列数
  7             *****
  8             *****
  9             *****
 10             *****
 11             *****
 12         */
 13         for(int j=1;j<=5;j++){
 14         for(int i=1;i<=5;i++)
 15         System.out.println("*");
 16         }
 17         System.out.println();
 18 
 19 
 20 
 21 
 22         for(int i=1;i<=5;i++){
 23             for(int j=1;j<=1;j++){
 24                 System.out.print("*");
 25             }
 26             System.out.println();
 27         }
 28 
 29         for(int i=1;i<5;i++){
 30             for(int j=1;j<=i;j++){
 31                 System.out.print(j);
 32             }
 33             System.out.println();
 34         }
 35 
 36 /*打印九九乘法表
 37 1*1=1
 38 1*2=2 2*2=4
 39 1*3=3 2*3=6 3*3=9
 40 1*4=4 2*4=8 3*4=12 4*4=16
 41 */
 42         for(int i=1;i<=9;i++){
 43             for(j=1;j<=i;j++){
 44                 System.out.println(j+"*"+i+"="+j*i+" ");
 45             }
 46             System.out.println();
 47 
 48         }
 49 
 50 /*打印一个实心菱形图案
 51         *
 52        *** 
 53       *****
 54      *******
 55       *****
 56        ***
 57         *
 58 */
 59         for(int i=1;i<=4;i++){
 60             //要先输出空格
 61             for(int j=1;j<=4-i;j++){
 62                 System.out.print(" ");
 63             }
 64             //再输出*
 65             for(int j=1;j<=2*i-1;j++){
 66                 System.out.println("*");
 67             }
 68             System.out.println();
 69         }
 70         for(int i=1;i<=3;i++){
 71             //要先输出空格 1 2 3
 72             for(int j=1;j<=i;j++){
 73                 System.out.print(" ");
 74             }
 75             //再输出*
 76             for(int j=1;j<=7-2*i;j++){
 77                 System.out.println("*");
 78             }
 79             System.out.println();
 80         }
 81 
 82 
 83 /*
 84         *
 85        * *
 86       *   *
 87      *     *
 88       *   *
 89        * *
 90         *
 91 */
 92         for(int i=1;i<=4;i++){
 93             //要先输出空格
 94             for(int j=1;j<=4-i;j++){
 95                 System.out.print(" ");
 96             }
 97             //再输出*
 98             for(int j=1;j<=2*i-1;j++){
 99                 if(j==1||j==2*i-1)
100                 System.out.println("*");
101                 else
102                     System.out.println(" ");
103             }
104             System.out.println();
105         }
106         for(int i=1;i<=3;i++){
107             //要先输出空格 1 2 3
108             for(int j=1;j<=i;j++){
109                 System.out.print(" ");
110             }
111             //再输出*
112             for(int j=1;j<=7-2*i;j++){
113                 if(j==1||j==7-2*i)
114                 System.out.println("*");
115                 else 
116                     System.out.print(" ");
117             }
118             System.out.println();
119         }
120 
121     }
122 }

 

   ·break和continue

 1 class B
 2 {
 3     public static void main(String args[]){
 4         //循环中可以使用的语句: break:结束整个循环   continue:结束某一次循环
 5         for(int i=1;i<5;i++){
 6             if(i==3)
 7                 break;        //默认第一条语句属于if的,
 8             System.out.println(i);    //这个是if下的第二条语句不属于if 结果为1,2
 9         }
10         for(int i=1;i<5;i++){
11             if(i==3){
12                 break;        //break后不能加任何代码
13                 System.out.println(i);    //程序报错,由于break已经结束,故不能有此行
14             }
15         }
16 
17 
18         for(int i=1;i<5;i++){    
19             for(int j=1;j<=5;j++){
20                 if(j==3){
21                     break;    //结束的是内部的for,不会结束外面的for
22                 }
23             }
24             System.out.println(i);    //故输出1,2,3,4,5
25         }
26 
27 
28         m:for(int i=1;i<5;i++){
29             n:for(int j=1;j<=5;j++){
30                 if(j==3){
31                     break m;    //结束的是外循环
32                 }
33             }
34             System.out.println(i); //故无输出结果
35         }
36 
37 
38 
39         for(int i=1;i<=5;i++){
40             if(i==3){
41                 continue;//结束的是第三次的循环,也就是直接进入第四次循环,也就是去执行i++
42             }
43             System.out.print(i);    //1 2 4 5
44         }
45 
46         for(int i=1;i<5;i++){    
47             for(int j=1;j<=5;j++){
48                 if(j==3){
49                     continue;    //结束的是内部的for,不会结束外面的for
50                 }
51             }
52             System.out.println(i);    //故输出1,2,3,4,5
53         }
54 
55         for(int i=1;i<5;i++){
56             for(int j=1;j<=5;j++){
57                 if(j==3){
58                     System.out.println(i); System.out.println(j);//分别是i为1,2,3,4,5 ;j为3,3,3,3,3;  
59                     continue ;    
60                 }
61             }
62         }
63 
64         for(int i=1;i<5;i++){
65             if(i==3){
66                 continue;        //continue后不能加任何代码
67                 System.out.println(i);    //程序报错,由于break已经结束,故不能有此行
68             }
69         }
70         
71 
72     }
73 }

 

 1 import java.util*;
 2 class  C
 3 {
 4     public static void main(String[] args) 
 5     {
 6         //编写一个程序,最多接收10个数,求这些数的和
 7         //用户可以通过输入999来终止程序,并显示输入数的和
 8         int sum=0,num;
 9         Scanner sc=new Scanner(System.in);
10         
11         for(int i=1;i<=10;i++){
12             System.out.println("输入一个数");
13             num=sx.nextInt();
14             if(num==999)
15                 break;
16             sum=sum+num;
17         }
18         System.out.println("sum="+sum);//如果注释了14,15行,for一直循环,则此行不会执行,会在编译时报错
19     }
20 }

    ·函数:

为什么用函数:避免代码重复出现,当一个相同功能被多次使用时,如果没有函数,每次都要写重复性的代码。
函数:具备特定功能的一段独立的代码段。什么时候用到这个功能,什么时候就调用
函数关键是实现功能,实现功能用到的数据以参数的形式来接收,如果功能最终得到的是一个数值,需要返回值。
函数的返回值类型就是使用return返回的数值的类型。

  返回值类型  函数名(参数类型 参数1,参数类型 参数2....){
   执行语句
   return 返回结果
  }
  注:void 代表无返回值,否则函数名前需加返回值类型
 
 1 import java.util.Scanner;
 2 class  D
 3 {    
 4     //定义函数:具备特定动能的一段独立的代码段,什么时候用到这个功能,什么是时候去调用
 5     //对于函数来说,关键是实现功能,功能中用到的数据不是函数考虑的重点,重点是功能。
 6     public static int add(int a,int b){//形式参数:用参数来接收数据,被调用的
 7         int sum=a+b;
 8         return sum;    //把值返回到函数调用的位置
 9         System.out.println("sum="+sum);        //由于上面已经return了所以这行会报错,运行不到此行
10     }
11     
12     public static int add(int a,int b){//形式参数:用参数来接收数据,被调用的
13         int sum=a+b;
14         return sum;    //把值返回到函数调用的位置
15         System.out.println("sum="+sum);
16     }
17 
18     public static void main(String[] args) //主函数
19     {    
20         int n=add(6,8);//实参,函数调用,实参和形参要在类型,顺序,个数上保持一致      n=sum,
21         if(n>20)
22             System.out.println("n="+n);
23         System.out.println("okok");
24     }
25 }
26 //每次用到相同的动能都要写重复的代码,冗余。
27 //函数是用来解决一个功能被重复使用的功能的。
 1 class E 
 2 {
 3     public static void main(String[] args) 
 4     {
 5         boolean b= isEqual(4,5);
 6         System.out.println(b);
 7         int max=getMax(34,56);
 8         System.out.println(max);
 9 
10         juXing(5,5);
11         jiuJiu();e
12     }
13 
14     //自己定义函数:确定有没有参数,确定有没有返回值
15     
16     //判断两个整数是否相等
17     //参数:两个整数
18     //返回值:boolean
19 
20     public static boolean isEqual(int a,int b){
21         return a==b;    //返回到函数调用的位置
22 
23     }
24     //求两个整数中的最大值
25     //参数:两个整数
26     //返回值:int
27     public static int getMax(int a,int b){
28         return a>b?a:b;
29     }
30 
31     //用*号打印一个矩形
32     //参数:行数,列数
33     //返回值:无返回值
34     public static void juXing(int rows,int col){
35         for(int i=1;i<=rows;i++){
36             for(int j=1;j<=col;j++){
37                 System.out.print("*");
38             }
39             System.out.println();
40         }
41     }
42     
43     //打印99乘法表
44     //参数:无
45     //返回值:无
46     public static void jiuJiu(){
47         for(int i=1;i<=9;i++){
48             for(int j=1;j<=i;j++){
49                 System.out.print(j+"*"+i+"="+"j*i"+\t);
50             }
51                 System.out.println();
52         }
53     }
54 }

   ·函数内存的分配

 

    ·函数的重载

 1 class E 
 2 {
 3     public static void main(String[] args) 
 4     {
 5         boolean b= isEqual(4,5);
 6         System.out.println(b);
 7         int max=getMax(34,56);
 8         System.out.println(max);
 9 
10         juXing(5,5);
11         jiuJiu();e
12     }
13 
14     //自己定义函数:确定有没有参数,确定有没有返回值
15     
16     //判断两个整数是否相等
17     //参数:两个整数
18     //返回值:boolean
19 
20     public static boolean isEqual(int a,int b){
21         return a==b;    //返回到函数调用的位置
22 
23     }
24     //求两个整数中的最大值
25     //参数:两个整数
26     //返回值:int
27     public static int getMax(int a,int b){
28         return a>b?a:b;
29     }
30 
31     //用*号打印一个矩形
32     //参数:行数,列数
33     //返回值:无返回值
34     public static void juXing(int rows,int col){
35         for(int i=1;i<=rows;i++){
36             for(int j=1;j<=col;j++){
37                 System.out.print("*");
38             }
39             System.out.println();
40         }
41     }
42     
43     //打印99乘法表
44     //参数:无
45     //返回值:无
46     public static void jiuJiu(){
47         for(int i=1;i<=9;i++){
48             for(int j=1;j<=i;j++){
49                 System.out.print(j+"*"+i+"="+"j*i"+\t);
50             }
51                 System.out.println();
52         }
53     }
54 }

    ·数组,局部变量,栈,堆

局部变量:在函数或语句中(如:for语句,for(int i=1;i<5;i++)定义的变量
局部变量的特点:作用域结束后,立刻释放内存。
当函数被调用时,函数入栈,函数内定义的变量在栈中开辟内存,当函数内的代码全部执行完,函数出栈,也就是释放内存

数组:数组的作用:解决存储多个数据的问题
int [] arr=new int[5]是一个局部变量,存的是一个地址值,引用类型的变量, 是数组的一个引用,
int a ; //a存的是一个整数,基本数据类型的变量

 1 class  G
 2 {
 3     public static void main(String[] args) 
 4     {
 5         //数组的作用:解决的是存储多个数据的问题,数组属于引用数据类型
 6         //定义一个可以存储5个整数的数组
 7         //new int[5];    //开辟了5个int类型的内存空间   
 8         //为了方便使用数组,需要定义一个名字
 9         //arr=new int[500];
10 
11         //指定arr代表的数组的类型 
12         int[] arr=new int[500];    //int a;数组占据的内存是连续的
13         arr[0]=12;
14         System.out.println(arr[0]);
15 
16         /*
17             jvm把内存分为5块:栈,堆,方法区,本地方法区,寄存器
18             栈:局部变量进栈,在函数或语句中定义的变量属于局部变量,如for语句,for(int i=1;i<5;I++)
19                 特点:作用域结束立刻释放内存
20             堆:引用数据类型属于堆
21                 特点:有默认值为0;
22         */
23     }
24 }

    ·数组内存的分配:

 
 

 

 

 

 day4

   ·堆和栈对比

1.堆中有默认值,栈中没有默认值
2.堆中的垃圾需要垃圾回收线程回收,也就是说当出现垃圾时,不一定会立刻被回收
3.栈是使用完立刻释放内存
4.局部变量进栈,在方法,语句中定义的变量
5.对象,数组进堆(特点:都是可以存储多个数据的)
栈和堆的对比:
栈:局部变量进栈,在函数,语句定义的变量
      局部变量的作用域结束,立刻释放内存
      进栈的局部变量没有默认值
堆:对象,数组在堆中开辟内存,堆中有默认值,堆中的一旦成为垃圾,需要等待垃圾回收线程回收,不会立刻释放内存。
 

   ·引用类型的内存的特点

int[] arr=new int[5];
arr 是一个引用类型的变量
new int[5]:在堆中开辟内存
arr存的是数组在堆中的首地址,因为arr存储了数组的地址,所以可以通过arr来操作数组
arr[0]=66;先从arr中取出地址值,去堆中找到数组,然后给数组下标为0的赋值为66。
arr=new int[3]; arr又创建了一个新的数组,把该数组的地址存储在arr中,arr不在指向之前的数组,因为arr是一个变量,它的值可以改变

   ·数组:

    解决了存储多个数据的问题,属于引用数据类型。
         数组的内存是连续的,通过下标的方式来区分,下标固定从0开始。
         int[] arr=new int[5];
         for(int i=0;i<arr.length;i++){
 System.out.println(arr[i]); 
         }
 

   ·数组的初始化及异常

 1 import java.util.*;
 2 class C 
 3 {
 4     public static void main(String[] args) 
 5     {
 6         int[] arr=new int[5];//0-4
 7         //System.out.println(arr[5]);//ArrayIndexOutOfBoundsException: 5 数组下标越界
 8         //arr =null;    //arr不指向任何数组
 9         //System.out.println(arr[0]);//NullPointerException    空指针
10         arr[0]=12;
11         arr[1]=12;
12         arr[2]=12;
13         arr[3]=12;
14         arr[4]=12;
15         for(int i=0;i<5;i++){
16             System.out.println("请输入第"+(i+1)+"个数");
17             arr[i]=sc.nextInt();
18 
19             arr[i]=12;
20         }
21     //    for(int i=0;i<5;i++){
22     //        System.out.println(arr[i]);
23     //    }
24         //arr.length得到的是数组的长度
25         for(int i=0;i<arr.length;i++){
26             System.out.println(arr[i]);
27         }
28     }
29 }
30  
31  class Demo1
32  {
33      public static void main(String arg[]){
34         //数组的初始化
35         int[] arr=new int[] {12,34,56,6};    //数组的长度是数值的个数
36         for(int i=0;i<arr.length;i++){
37             System.out.println(arr[i]);
38 
39         int[] b={1,2,3,4,5,6}    
40         for(int i=0;i<b.length;i++){
41             System.out.println(b[i]);
42         }
43      }
44  }

 

 1 //功能:求数组中的最大值
 2     //参数:数组
 3     //返回值:最大值
 4     public static int getMax(int[] arr){
 5         int max=arr[0];
 6         for(int i=1;i<arr.length;i++){
 7             if(arr[i]>max){
 8                 max=arr[i];
 9             }
10         }
11         return max;
12     }

   ·数组的选择排序与冒泡排序

 

 

 

 
 

  

 1 //选择排序与冒泡排序
 2 class E 
 3 {
 4     public static void main(String[] args) 
 5     {
 6         int [] arr={23,45,12,6,78,4};
 7 
 8         selectSort(arr);
 9         for(int i=0;i<arr.length;i++)
10         System.out.print(arr[i]+" ");
11     
12         System.out.println("------------------");
13     
14         bubbleSort(arr);
15         for(int i=0;i<arr.length;i++)
16         System.out.print(arr[i]+" ");
17         
18     }
19     //选择排序
20     //参数:数组
21     //返回值:无
22     public static void selectSort(int [] arr){
23         for(int i=0;i<arr.length-1;i++){
24             for(int j=i+1;j<arr.length;j++){
25                 if(arr[j]<arr[i]){
26                     huan(arr,j,i);
27                 }
28             }
29         }
30     }
31     public static void huan(int[] arr,int m,int n)
32     {
33         int c;
34         c=arr[m];
35         arr[m]=arr[n];
36         arr[n]=c;
37     }
38     
39     //冒泡排序
40     public static void bubbleSort(int [] arr){
41         for(int i=0;i<arr.length-1;i++){
42             for(int j=0;j<arr.length-i-1;j++){
43             if(arr[j+1]<arr[j]){
44                 huan (arr,j+1,j);
45                 }
46             }
47         }    
48     }
49 }

 

 

   ·数组的查找和二分查找

 1 //查找:一个数在数组中第一次出现的下标,没有返回-1
 2 class F 
 3 {
 4     public static void main(String[] args) 
 5     {
 6         int[] arr={23,12,5,44,77,66,99};
 7         int key=44;
 8         int index=find(arr,key);
 9         System.out.println("index="+index);
10 
11 
12     /*    int i=0;
13         for(;i<arr.length;i++){
14             if(arr[i]==44){
15                 System.out.println(i);//找到第一个相同的就结束循环,
16                 break;
17             }
18         }
19         if(i==arr.length){
20             System.out.println(-1);
21         }
22 
23     */
24     }
25 
26     public static int find(int[] arr,int key){
27         for(int i=0;i<arr.length;i++){
28             if(arr[i]==key){
29                 return i;    //返回函数调用的位置
30             }
31             return -1;        //返回函数调用的位置
32         }
33     }
34 }
35 
36 //二分法查找:前提条件数组必须是有序的
37 class G
38 {
39     public static void main(String args[]){
40         int[] arr={12,34,45,56,67,78,89};
41         int index=halfSearch(arr,89);
42         System.out.println("index="+index);
43     }
44         
45     public static int halfSearch(int [] arr,int key){
46         int min=0,max=arr.length-1,mid;
47         while(min<=max){
48             mid=(min+max)/2;
49             if(key>arr[mid]){
50                 min=mid+1;
51             }else if(key<arr[mid]){
52                 max=mid-1;
53             }else
54                 return mid;
55         }
56         return -1;
57     }
58 }

 day5

   ·判断回文数和质数

 1 class Demo1 
 2 {
 3     public static void main(String[] args) 
 4     {
 5         int  a;  //基本类型的变量
 6         int[] arr=null;//引用类型的变量
 7         arr=new int[5];
 8         arr[0]=77;
 9         int a;
10         int[] arr=null;//  int[] 是一种引用数据类型
11         Scanner sc = new Scanner();
12     }
13 
14     //判断一个数是不是质数  (只能被1和它自己整除的数)
15     //参数:一个数
16     //返回值:boolean
17 
18     public static boolean isZhiShu(int num)
19     {
20          for(int i=2;i<num/2;i++)
21          {
22              if(num%i==0)
23                 return false;
24          }
25 
26          return true;
27     }
28 
29     //判断一个数是不是回文  121
30     //参数:一个数
31     //返回值:boolean
32     public static boolean isHuiWen(int num)  //121
33     {
34          int sum=0,n;
35          n=num;
36          while(num!=0){
37              sum=sum*10+num%10;//121
38              num=num/10;
39          }
40 
41          if(sum==n)
42              return true;
43          else
44              return false;
45     }
46 }

   ·十进制转为二,八,十六进制

  1 class Demo3 
  2 {
  3     public static void main(String[] args) 
  4     {
  5         toHex(60);
  6         toOctal(60);
  7         toBinary(60);
  8     }
  9 
 10     //十进制转十六进制
 11     //参数:十进制数
 12     //返回值:无
 13 
 14     public static void toShiLiu(int num)
 15     {
 16         int[] arr=new int[8];
 17         int index=arr.length;//8
 18 
 19         while(num!=0)
 20         {
 21             arr[--index]=num&15;
 22             num=num>>>4;
 23         }
 24 
 25         //System.out.println("index="+index);
 26 
 27         for(;index<arr.length;index++)
 28         {
 29             if(arr[index]>9)
 30                 System.out.print((char)(arr[index]-10+'a'));
 31             else
 32                 System.out.print(arr[index]);
 33         }
 34     }
 35 
 36     //十进制转十六进制:查表法
 37     public static void toShiLiu2(int num)
 38     {
 39         char[] ch={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
 40         char[] arr=new char[8];
 41         int index=arr.length;
 42 
 43         while(num!=0)
 44         {
 45             int x=num&15;  // 13
 46             arr[--index]=ch[x];
 47             num=num>>>4;
 48         }
 49 
 50          for(;index<arr.length;index++)
 51         {
 52             System.out.print(arr[index]);
 53         }
 54     
 55     }
 56 
 57     //十进制转八进制
 58     public static void toBa(int num)
 59     {
 60         char[] ch={'0','1','2','3','4','5','6','7'};
 61         char[] arr=new char[11];
 62         int index=arr.length;
 63 
 64         while(num!=0)
 65         {
 66             int x=num&7;  // 13
 67             arr[--index]=ch[x];
 68             num=num>>>3;
 69         }
 70 
 71          for(;index<arr.length;index++)
 72         {
 73             System.out.print(arr[index]);
 74         }
 75     }
 76     //十进制转2进制
 77     public static void toEr(int num)
 78     {
 79         char[] ch={'0','1'};
 80         char[] arr=new char[32];
 81         int index=arr.length;
 82 
 83         while(num!=0)
 84         {
 85             int x=num&1; 
 86             arr[--index]=ch[x];
 87             num=num>>>1;
 88         }
 89 
 90          for(;index<arr.length;index++)
 91         {
 92             System.out.print(arr[index]);
 93         }
 94     }
 95 
 96     public static void toAny(int num,int base,int offset)
 97     {
 98         char[] ch={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
 99         char[] arr=new char[32];
100         int index=arr.length;
101 
102         while(num!=0)
103         {
104             int x=num&base;
105             arr[--index]=ch[x];
106             num=num>>>offset;
107         }
108 
109         for(;index<arr.length;index++)
110         {
111             System.out.print(arr[index]);
112         }
113     }
114     public static void toHex(int num)
115     {
116         toAny(num,15,4);
117     }
118     public static void toOctal(int num)
119     {
120         toAny(num,7,3);
121     }
122     public static void toBinary(int num)
123     {
124         toAny(num,1,1);
125     }
126 
127 }
一维数组:
 int[ ] arr=new int[5];  
 求最值
 排序:Arrays.sort();
 查找:二分法查找 int key;   Arrays.binarySearch(arr,key);
 进制转换:Integer.toHexString()    Integer.toOctalString()   Integer.toBinaryString()
 

   ·数组去重

 1 1:创建两个一维数组,对两个有序的数组进行合并,并将重复的数字去掉
 2 class T1 
 3 {
 4     public static void main(String[] args) {
 5         int [] num1=new int[]{1,4,5,6,7};
 6         int [] num2=new int[]{3,5,6,8};
 7         hebing(num1, num2);
 8     }
 9     private static void hebing(int [] num1,int [] num2){
10         int[] result=new int[num1.length+num2.length];
11 
12         int i=0,j=0,k=0;//定义三个变量。i  j  k分别控制num1 num2  result三个数组的下标
13 
14         while(i<num1.length && j< num2.length){//两个数组都不为空的时候
15             if(num1[i]<num2[j]){//若num1的元素小,加入result
16                 result[k]=num1[i];
17                 i++;//num1的下标后移
18                 k++;//result的下标后移
19             }else if(num1[i]==num2[j]){//若二者相等 这一步就是去重复。
20                 result[k]=num1[i];//这里两个数组的元素把哪个加入result都行
21                 k++;//result下标后移
22                 i++;//这里要注意的是  两个重复了,去重之后,两个数组的下标都要后移
23                 j++;
24             }else {
25                 result[k]=num2[j];//若num2的元素小,加入result
26                 k++;
27                 j++;
28             }    
29         }
30  
31         //下面是当其中一个数组元素全部添加到result了,另一个还没添加完  继续添加。
32         while(i<num1.length){//
33             result[k]=num1[i];
34             i++;
35             k++;
36         }
37         while(j<num2.length){
38             result[k]=num2[j];
39             j++;
40             k++;
41         }
42         for (int i=0;i<result.length;i++) 
43         {
44             System.out.println(result[i]);
45         }
46     }
47 
48 }

   ·生成范围内的验证码

 1 5.生成4位网站验证码(要求用数组)
 2   1 不能重复
 3   2 只能是数字和大小写字符, 但是不能包含1,0,o,O,l,L,Z,2,9,g
 4 
 5  import java.util.Random;
 6 class T2 
 7 {
 8     public static void main(String[] args) 
 9     {
10        char[] arr={'3','4','5','6','7','8','a','b','c','d','e','f','h','i','j','k','m','n','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F',
11               'G','H','I','J','K','M','N','P','Q','R','S','T','U','V','W','X','Y'};
12 
13                 char[] r=new char[4];//存放验证码的数组
14         int count=0,num,index=0;
15         Random random = new Random();
16         boolean flag=true;
17         while(count!=4)
18         {
19             num=random.nextInt(arr.length);//生成随机的下标
20             System.out.println(num);
21             flag=true;
22             for(int i=0;i<4;i++)
23             {
24                if(r[i]==arr[num])
25                 {
26                    flag=false;
27                    break;
28                 }
29                 
30             }
31             if(flag)
32             {
33                 r[index++]=arr[num];
34                 count++;
35             }
36         }
37         System.out.println();
38         for(int i=0;i<4;i++)
39            System.out.print(r[i]);
40     }
41 }

 

   ·二维数组:    内存

 int[ ][ ] arr=new int[5][ ];
 

 

   

   ·类和对象

把对象装进冰箱
面向过程:打开冰箱,装大象,关闭冰箱
面向对象:冰箱.打开()
类是对对象的描述,属于概念性的东西,
对象:使用new创建的对象才是实实在在存在的实体。
描述对象的类-------》使用类(字节码)创建的对象--------》对象具备了类中定义的属性和方法
 1 class Person
 2 {
 3     String name;//属性用变量表示
 4     int num;
 5     int age;
 6     public void eat(){    //行为用函数表示
 7         System.out.println("吃");
 8     }
 9 }
10 
11 class Demo5
12 {
13     public static void main(String[] args){
14         Car che=new Car();    //创建对象
15         Person ren=new Person();//对象具备Person类中定义的属性和行为
16         ren.name="李四";
17         ren.age=20;
18         System.out.println(ren.name+"   "+ren.age);
19         ren.eat();
20 
21     }
22 }
23 /*jvm先执行main方法,main方法属于Demo5.class字节码,所以先加载Demo5.class到方法区
24     (原则:用到谁加载谁)
25     
26   创建Person的对象使用的是Person.class,所以先加载Person.class到方法区
27   当常见对象时,在堆中为属性开辟内存
28   eat()方法,使用时直接进栈
29   类加载器把字节码加载到方法区
30     */

 

 

   ·成员变量和局部变量的对比:

1.成员变量 有默认值
   局部变量没有默认值
2.成员变量是随着对象的创建在堆中开辟内存
   局部变量是随着其所在函数被调用在栈中开辟内存
3.成员变量是随着对象被垃圾回收才释放内存
   局部变量作用域结束立刻释放内存。
4.成员变量的作用范围是整个类
   局部变量的作用域是其所在的大括号

   ·面向对象的三大特征-封装

 

 1 //封装:只对外界提供有用的属性和行为
 2 class Person{
 3      String name;  
 4      private int age;
 5      
 6      public void setAge(int nianling){
 7         if(nianling<0 || nianling>120)
 8             System.out.println("年龄不合法");
 9         else
10             age=nianling;
11      }
12      public int getAge(){
13         return age;
14      }
15     public void eat(){
16        System.out.println(age+"吃");
17     }
18 }
19 class Demo9 {
20     public static void main(String[] args) {
21         Person ren = new Person();
22         ren.setAge(20);
23         int age = ren.getAge();
24         System.out.println(age);
25        
26         //ren.age=-200; 报错        
27     }
28 }

    ·构造方法

 1 /*
 2 构造方法: 只能用来创建对象的,系统会自动在类中加入一个默认的构造方法 类名(){}
 3             也可以自己定义构造方法,自己一旦写了构造方法,系统就不会再加入默认的构造方法
 4             构造方法是必须存在的
 5             构造方法可以有多个
 6 
 7 特点:
 8    方法名和类名相同
 9    没有返回值类型
10 
11 */
12 class Person{
13      String name;  
14      private int age;
15 
16      Person(){}//创建对象时使用的方法
17 
18      Person(String mingzi,int nianling)//创建对象时使用的方法
19      {
20         name=mingzi;
21         age=nianling;
22      }
23 
24      public void setAge(int nianling){
25          age=nianling;
26      }
27      public int getAge(){
28          return age;
29      }
30 }
31 class Demo10 
32 {
33     public static void main(String[] args) {
34         Person ren = new Person();//  Person():构造函数,
35         Person ren2 = new Person("赵四",20);//创建对象的同时给属性赋值
36         ren2.setAge(21);
37         int a = ren2.getAge();
38         System.out.println(a);  
39     }
40 }

day6

   ·用数组打印杨辉三角

 杨辉三角

1
1  1
1  2  1
1  3  3  1
1  4  6  4   1
1  5  10 10  5  1
。。。。。。。。。。。
 1 class Demo1 
 2 {
 3     public static void main(String[] args) 
 4     {
 5         int[][] arr=new int[10][];
 6         arr[0]=new int[]{1};
 7         for(int i=1;i<10;i++){
 8             arr[i]=new int[i+1];
 9             for(int j=0;j<i+1;j++){
10                 if(j==0||j==i)
11                     arr[i][j]=1;
12                 else
13                     arr[i][j]=arr[i-1][j]+arr[i-1][j-1];
14             }
15         }
16         for(int i=0;i<arr.length;i++){
17           for(int j=0;j<arr[i].length;j++)
18               System.out.print(arr[i][j]+"\t");
19            System.out.println();
20         }
21     }
22 }

把一个数插入到数组, 第一个参数是被拷贝的数组,第二个参数是新数组的长度:

 

 1 class Demo2 
 2 {
 3     public static void main(String[] args) {
 4         //向一个有序的整型数组中插入一个数,插入后该数组还是有序的(二分法)
 5         int[] arr={12,34,56,67,78,89,99};
 6         int key=600;
 7 
 8         int index = halfSearch(arr,key);
 9         System.out.println("index="+index);
10         index=-(index+1);
11         //把这个数插入到数组, 第一个参数是被拷贝的数组,第二个参数是新数组的长度
12         //返回一个新的数组
13         
14         int[] b=new int[arr.length+1];
15         for(int i=0;i<arr.length;i++){
16            b[i]=arr[i];
17         }
18         
19         for(int i=arr.length-1;i>=index;i--){
20             b[i+1]=b[i];
21         }
22         b[index]=key;
23 
24         for(int i=0;i<b.length;i++){
25            System.out.print(b[i]+" ");
26         }
27 
28     }
29         //查找一个数在数组中的位置,并返回下标,
30      public static int halfSearch(int[] arr,int key){
31          int min=0,max=arr.length-1,mid;
32          while(min<=max){
33              mid=(min+max)>>1;
34              if(key>arr[mid])
35                  min=mid+1;
36              else if(key<arr[mid])
37                  max=mid-1;
38              else
39                 return mid;//如果数存在,返回mid即下标
40          }
41          return -min-1;//不存在返回-min-1;
42      }
43 }

 

   ·this

this:是一个引用,总是指向当前被使用的对象
构造函数之间的调用: this();必须写在构造函数代码块的第一行 
this 在函数中,函数栈内存里,指向堆中的对象里的属性,所以this.变量 后面指的是成员变量,可以表示当前的;
Person(String name,int get)   //局部变量和成员变量同名时,使用的是局部变量,可以使用this来用成员变量
 
 1 //this是一个引用,总是指向当前被使用的对象
 2 class Person
 3 {
 4      String name;  //成员变量的作用域是整个类
 5      int age;
 6 
 7      Person(){}
 8 
 9      Person(String name,int age){//局部变量和成员变量同名时,使用的是局部变量
10      
11         this.name=name;
12         this.age=age;
13      }
14 
15      //判断两个人是不是同龄人
16      //参数:Person
17      //返回值:boolean
18      public boolean isAgeEqual(Person person){
19           return age==person.age;
20      }
21 
22 
23      public void show(){
24         System.out.println(this);
25      }
26 }
27 class Demo4 
28 {
29     public static void main(String[] args) {
30         Person  ren = new Person("张三",25);//this指向这个对象
31 
32         Person  ren2= new Person("李四",25);//this指向这个对象
33 
34         boolean boo=ren.isAgeEqual(ren2);//this 指向 张三
35 
36         System.out.println(boo);
37 
38         //System.out.println(ren);
39         //ren.show();
40         //System.out.println(ren.name+","+ren.age);
41 
42         
43 
44     }
45 }

 

 

 

   ·static:静态:

     只能修饰类中的成员
         被static修饰的成员变量的特点:
         1.随着所属类(字节码)加载到方法区的同时,就在方法区内静态区中开辟内存
         2.被static修饰的成员变量(局部变量不能被static修饰)是类所有的对象共享的。
         3.可以直接通过类名访问
什么情况下可以把成员变量修饰为static:当成员变量是类的所有对象共享的变量。
静态的优先于非静态的开辟内存
非静态的成员变量是在创建对象是才开辟内存的,所有非静态的只能使用对象来访问
        

   ·静态成员变量与非静态成员变量对比:

   1.访问方式   静态成员变量既可以通过对象访问,也可以通过类名直接访问
      非静态成员变量只能使用对象访问
   2.存储数据   静态成员变量 存储的是所属类的所有对象共享的数据
      非静态成员变量  存储的是每个对象特有的数据
   3.存储位置   静态成员变量 随着类的加载在方法区的静态区开辟内存
      非静态成员变量 创建对象时在堆中开辟内存
   4.生命周期(从在内存中出现到从内存中消失)
      静态成员变量   随着类的加载在方法区的静态区开辟内存,程序退出时才释放内存   
      非静态成员变量   是创建对象时在堆中开辟内存,当所属对象成为垃圾时等待垃圾回收线程回收
静态的缺点:占用内存时间长
静态的方法只能使用静态的方法或变量
非静态的方法什么都可以用
 
 1 class Student 
 2 {
 3     String name;  //实例变量
 4     static String country="CN"; //类变量
 5 
 6     public void show()  //实例方法:只能使用对象访问
 7     {
 8        System.out.println(country+","+name);
 9     }
10 
11     public static void fun()//类方法 Student.fun()  
12     {
13        System.out.println(country);//无法从静态上下文中引用非静态 变量 name
14     }
15 }
16 class Demo6 
17 {
18     public static void main(String[] args) 
19     {
20         Student stu = new Student();
21         stu.show();
22 
23         Student.fun();
24 
25         //System.out.println(Student.country);//随着所属类的加载在方法区的静态区中开辟内存
26         //System.out.println(Student.name);
27         //System.out.println(stu.country);
28 
29         //stu.country="USA";
30         //Student stu2 = new Student();
31         //System.out.println(stu2.country);
32         
33     }
34 }

   ·解析main()函数

public:说明是公共的
static:说明是静态的,随着类的加载进入静态区,可以直接通过类来调用
void:说明没有返回值
String[] args:参数是字符串数组 

 1 class Test
 2 {
 3     public static void main(String[] args){
 4        String[] arr={"haha","hehe","xixi"};
 5        Demo7.main(arr);
 6     }
 7 }
 8 class Demo7 
 9 {
10     public  static void main(String[] args){ //java Demo7 hello hehe haha xixi   命令行参数
11         System.out.println(args.length);
12         //for(int i=0;i<args.length;i++)
13             //System.out.println(args[i]);
14         Demo7 d = new Demo7();
15         d.main(77);
16     }
17     public void main(int a){ //非静态方法,通过对象访问
18        System.out.println(a);
19     }
20 }

什么情况下成员变量可以被static修饰:
   当成员变量的值被所属类的所有对象共享时
什么情况下方法可以被static修饰:
   当该方法没有用到所属类中的非静态成员

 1 class Person{
 2     int age;
 3     Person(int age){
 4        this.age=age;
 5     }
 6     public static void isEqual(Person person){
 7          System.out.println(person.age);
 8     }
 9 }
10 class Demo8 
11 {
12     public static void main(String[] args) {
13         Person ren = new Person(20);
14         Person.isEqual(ren);
15     }
16 }

静态的应用:工具类(此代码省略)

   ·静态代码块:

static{...} 随着类(字节码)的加载而执行,只执行一次,优于main函数的执行
 把程序中初始化功能通常写在静态代码块中。

 1 class Test
 2 {
 3     static int num=10;
 4     static{
 5        System.out.println("C");
 6     }
 7     public static void show(){
 8         System.out.println(num);
 9     }
10 }
11 class Demo10 
12 {
13     static{
14        System.out.println("A");
15     }
16 
17     public static void main(String[] args) {
18         //Test t=new Test();
19         //Test.show();//加载Test.class
20         Test t=null;
21     }
22     static{
23        System.out.println("B");
24     }
25 }

   ·构造代码块:{...}

对象一创建就执行,优先于构造函数
 所有对象共性的功能可以写在构造代码块中。

 1 /*
 2 构造代码块:对象一创建就执行,优先于构造函数执行
 3 
 4 所有对象共性的功能可以写在构造代码块中
 5 */
 6 class Person
 7 {
 8     String name;
 9 
10     {                                    //构造代码块
11        System.out.println("呵呵");
12     }
13 
14     Person(String name)
15     {
16        this.name=name;
17        System.out.println(name);
18     }
19 }
20 class Demo11 
21 {
22     public static void main(String[] args) {
23         new Person("李四");
24 
25         new Person("张三");
26     }
27 }

 day7

 1 class Point
 2 {
 3     private int x;
 4     private int y;
 5     Point(){}
 6     Point(int x,int y){
 7        this.x=x;
 8        this.y=y;
 9     }
10     public void movePoint(int dx,int dy){
11         x=dx;
12         y=dy;
13     }
14     public void setX(int x){
15        this.x=x;
16     }
17     public void setY(int y){
18        this.y=y;
19     }
20     public int getX(){
21        return x;
22     }
23     public int getY(){
24        return y;
25     }
26 }
27 class Test2 
28 {
29     public static void main(String[] args) {
30         /*
31         定义一个点类Point,包含2个成员变量x,y,分别表示x和y坐标,创建两个构造方法Point()和Point(int x,int y),
32         创建一个方法movePoint(int dx,int dy)实现点的位置的移动,在main方法中创建两个Point对象p1,p2,分别调用movePoint方法后,
33         显示p1和p2的坐标
34         */
35         Point p1=new Point(5,8);
36         Point p2=new Point(6,10);
37         p1.movePoint(6,9);
38         p2.movePoint(8,8);
39         System.out.println("p1的坐标:x="+p1.getX()+",y="+p1.getY());
40         System.out.println("p2的坐标:x="+p2.getX()+",y="+p2.getY());
41     }
42 }
 1 class Test4 {
 2     public static void main(String[] args) {
 3         /*
 4           某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,加密规则如下:
 5           每位数字都加上5,然后用和除以10的余数代替该数字,再将第一位和第四位交换,第二位和第三位交换。
 6         */
 7         int num=6789,c;
 8         int[] arr=new int[4];
 9         int index=arr.length;
10         while(num!=0){
11             arr[--index]=num%10;
12             num=num/10;
13         }
14         for(;index<arr.length;index++){
15             arr[index]=(arr[index]+5)%10;
16         }
17         for(int i=0,j=arr.length-1;i<j;i++,j--){
18              c=arr[i];
19              arr[i]=arr[j];
20              arr[j]=c;
21         }
22         for(int i=0;i<arr.length;i++)
23             System.out.print(arr[i]+" ");
24     }
25 }

   ·对象初始化的过程

 1 //对象的初始化过程:
 2 /*
 3 1:因为对象的创建是使用字节码,所以先加载字节码到方法区
 4 2:如果有静态代码块执行静态代码块
 5 3:在堆中开辟内存
 6 4:给属性赋默认值
 7 5:如果有初始值再赋初始值
 8 6:执行构造代码块
 9 7:执行构造函数
10 8:把对象在堆中的地址赋给在栈中的变量
11 */
12 class Person{
13     private String name="xiaohong";
14     private int age=23;
15     private static String country="CN";{
16         System.out.println(name+"  "+age);
17     }
18     public Person(String name,int age){
19         this.name = name;
20         this.age = age;
21     }
22     public void setName(String name){
23        this.name = name;
24     }
25     public String getName(){
26         return name;
27     }
28 }
29 class  Demo1{
30     public static void main(String[] args) {
31         Person p = new Person("小白",20);
32         //p.setName("小黑");
33     }
34 }

 

 

    ·设计模式-单例模式

设计模式:解决某一类问题最有效的方式
单例设计模式:解决的是类在内存中只有一个对象的问题
   1.一个类不能有多个对象,那么构造方法不能被使用(构造方法私有化)
      private 类名(){}
   2.构造方法private之后,一个对象都不能创建了
      私有的构造方法在本类中是可以使用的
      在本类中创建一个对象
   3.为了防止外界随意操作这个对象,修饰为private
   4.为了能让外界得到这个唯一的对象,需要定义一个方法
           因为类不能创建对象,所以该方法必须是public static的, 由于方法是静态的,所以创建对象也必须是static的,

   ·单例设计模式中的:懒汉式与饿汉式

 1 //饿汉式
 2 class QianFeng
 3 {
 4    private static QianFeng qf=new QianFeng();
 5    private QianFeng(){}
 6    public static QianFeng getInstance(){
 7        return qf;
 8     }   
 9 }
10 //懒汉式
11 class Single{
12     private static Single single;//null
13     private Single(){}
14     public static Single getInstance(){
15          if(single==null)
16              single=new Single();
17          
18          return single;
19     }
20 }
21 
22 class Demo2 {
23     public static void main(String[] args) {
24         //QianFeng qianfeng = QianFeng.getInstance();
25         //QianFeng qianfeng2 = QianFeng.getInstance();
26         //System.out.println(qianfeng==qianfeng2);
27 
28         Single s1=Single.getInstance();
29         Single s2=Single.getInstance();
30 
31         System.out.println(s1==s2);
32     }
33 }

   ·继承(extends):

  子类继承父类的属性和行为
       作用: 1.  实现了代码的重复使用   2.使类和类之间产生了关系。
java中的继承是单继承的:
    单继承:一个类可以继承另外一个类
    多继承:一个类可以继承多个类
    java支持多层继承。A extends B, B extends C。
为什么是单继承的: 因为多继承会出现调用的不确定性。
父类中定义的是子类共性的东西,子类除了具备父类的东西还可以定义自己特有的东西,所以子类比父类功能更多
 1 class Demo6 {
 2     public static void main(String[] args) {
 3         System.out.println("Hello World!");
 4     }
 5 }
 6 class Person  //父类 是子类的共性的属性和行为
 7 {
 8     String name;
 9     int age;
10 
11     public void eat(){
12        System.out.println("吃吃吃");
13     }
14 }
15 class Student extends Person{
16     public void study(){
17        System.out.println("study");
18     }
19 }
20 
21 class Worker extends Person
22 {
23     public void work(){
24        System.out.println("工作");
25     }
26 
27 }
28 
29 class A{
30     public void laugh(){
31        System.out.println("傻笑");
32     }
33 }
34 class B extends A{
35     public void eat(){
36        System.out.println("吃饭");
37     }
38 }
39 class C extends A{
40 }
41 class D extends B{
42 }

   ·继承中成员变量的特点:

   当子父类中出现同名的属性或方法时,使用super来区分,super表示访问他的父类,super. 。
   父类中的属性都定义成private的,子类继承了但是无权使用,所以父类需要定义public的set和get方法,子类通过这些public方法来使用属性

 1 //继承中成员变量的特点
 2 // 当子父类中出现同名的属性或方法时,使用super来区分
 3 class Fu{
 4     private int num=6;
 5     public void setNum(int num){
 6        this.num=num;
 7     }
 8     public int getNum(){
 9        return num;
10     }
11 }
12 class Zi extends Fu{
13     public void show(){
14        System.out.println(getNum());//继承过来了,但无权使用,通过public的方法来使用属性
15     }
16 }
17 class Demo7 {
18     public static void main(String[] args) {
19         Zi z = new Zi();
20         z.show();
21     }
22 }
 

   ·重写

继承中成员方法的特点:
       子类和父类有相同的行为,但是行为的表现方式不同,java认为子类没有必要单独再定义一个方法,所以有了重写,也叫覆盖,
重写(覆盖):子类中出现了和父类一样的方法,当创建子类对象,调用这个方法时,执行的总是重写之后的。
重写的前提:存在继承。
重写注意事项:
   父类中private的方法不能被子类重写
   子类在重写时,方法权限要大于等于父类中方法的权限   public>=public
   父类中的方法是静态的,子类在重写时必须是静态的。
 1 class Fu{
 2     public void show(){
 3        System.out.println("show fu");
 4     }
 5     public static void ff(){
 6        System.out.println("static fu");
 7     }
 8 }
 9 class Zi extends Fu{
10     public void show(){
11        System.out.println("show fu");
12     }
13     public static void ff(){
14        System.out.println("static zi");
15     }
16 }
17 class Demo8 {
18     public static void main(String[] args) {
19          Zi z = new Zi();
20          z.show();
21 
22         //ZhangXiaoSan xiaosan =new ZhangXiaoSan();
23         //xiaosan.eat();
24     }
25 }
26 class ZhangSan{
27     public void eat(){
28         System.out.println("细嚼慢咽的吃");
29     }
30 }
31 class ZhangXiaoSan extends ZhangSan{
32      //子类和父类有相同的行为,但是行为的表现方式不同
33     //java认为子类没有必要单独再定义一个方法
34     public void eat(){
35        //super.eat();
36        System.out.println("狼吞虎咽的吃");
37     } 
38 }

   ·继承中构造函数的特点:

在创建子类对象时,总是先执行父类的构造函数,再执行子类的构造方法。
 原因是系统自动在子类的构造方法的第一行加入了super();调用父类中无参的构造方法。
 构造方法不能被继承。
为什么先执行父类的构造方法:因为子类继承父类必然会继承父类的属性,先执行父类的构造方法可以利用父类构造方法中为属性赋值的语句
注意:一个类都要写空参的构造方法
系统默认有无参构造函数,如果自己写了,系统默认的无参构造函数就没了,自己可以再加一个无参构造函数。
 1 class Fu{
 2     private int age;
 3     private String name;
 4     String address;
 5     int weight;
 6 
 7     Fu(){}
 8 
 9     Fu(int age,String name,String address,int weight){
10       this.age=age;
11       this.name=name;
12       this.address=address;
13       this.weight=weight;
14     }
15     public int getAge(){
16       return age;
17     }
18     public String getName(){
19        return name;
20     }
21 }
22 //构造方法不能被继承
23 class Zi extends Fu{
24     Zi(){//super();}
25 
26     Zi(int age,String name,String address,int weight){
27       super(age,name,address,weight);//自己写了super语句,系统就不再加入super();
28     }
29 }
30 class Demo9 {
31     public static void main(String[] args) {
32         Zi z = new Zi();
33          //Zi z = new Zi(20,"李四","北京",200);
34          //System.out.println(z.getAge()+","+z.getName());
35     }
36 }

   ·继承中this与构造函数

  下列代码第11行,由于this调用构造方法时,this()必须在第一行,而super()是系统自带的,所以super()加不进去,不会执行super()

 1 class Fu{
 2     int age;
 3     
 4     Fu(int age){
 5       this.age=age;
 6     }
 7 }
 8 
 9 class Zi extends Fu{
10     Zi(){
11       this(20);//super(); 加不进来,因为第一行已经被占用
12     }
13     Zi(int age){
14       super(age);
15     }
16 }
17 class Demo10 {
18     public static void main(String[] args){
19         Zi z = new Zi();
20         System.out.println(z.age);
21     }
22 }

 day8

   ·final修饰符

1.final:是一个修饰符,可以修饰类,方法,成员变量,局部变量
final 修饰类:该类不能被继承
final 修饰方法:该方法不能被子类重写(覆盖)
final 修饰成员变量,变量的值不能被修改
final 修饰局部变量,变量的值不能被修改

   ·单例和final

 引用类型被final修饰,意思是该引用不能指向其他对象
 1 /*
 2 class Test
 3 {
 4    public final void show()
 5     {
 6        System.out.println("show");
 7     }
 8 }
 9 class B extends Test
10 {
11     public  void show()
12     {
13        System.out.println("hello");
14     }
15 }
16 */
17 //计算圆形的面积
18 class Circle
19 {
20     public static final double PI=3.1415;//值不能被修改,符号常量,程序中用到的固定的数据,用符号常量表示
21 
22     //public static final int PAY=1;
23     //public static final int NOPAY=2;
24     private double radius;
25 
26     Circle(){}
27 
28     Circle(double radius){
29        this.radius=radius;
30     }
31     public double area(){
32        return  PI*radius*radius;
33     }
34 }
35 class Demo1{
36      public static void main(String[] args) {
37          final int a=6;
38          //a=99;//无法为最终变量a分配值
39          int num=add(5,5);
40          System.out.println(num);
41     }
42     public static int add(final int a,final int b)//当希望接收到的值不能被修改时
43 {
44         //a=66;
45         //b=99;
46         return a+b;
47     }
48 }
49 //单例
50 class Single {
51     private static final Single single=new Single();//引用类型被修饰为final,意思是该引用不能指向其它对象
52     private Single(){}
53     public static Single getInstance(){
54         //single=new Single();
55         return single;
56     }
57 }

   ·abstract 抽象  

例:public abstract void 吼叫();    //没有实现的方法----抽象方法

抽象方法不能被调用,因为该方法没有实现
抽象类,是在对子类提取共性的过程中,出现了无法确定如何实现的行为,因为子类对该行为有各自的表现方式,
那么父类不确定该如何实现该方法,所以父类就不实现该方法,该方法就成了抽象方法,所以这个父类就是抽象类了。

 1 abstract class 犬科动物{    
 2     int age;
 3     public void eat(){
 4       System.out.println("吃肉");
 5     }
 6     public abstract void 吼叫();// 没有实现的方法----抽象方法
 7 }
 8 classextends 犬科动物{   
 9     public void 吼叫(){
10         System.out.println("嗷嗷叫");
11     }
12 }
13 classextends 犬科动物{
14     public void 吼叫(){
15         System.out.println("汪汪叫");
16     }
17     public static void main(String[] args){
18        犬科动物 d=new 犬科动物();
19        d.吼叫();//抽象方法不能被调用,因为该方法没有实现
20     }
21 }

   ·抽象类的特点:


   1.抽象类不能创建对象
   2.一个类继承了抽象类,如果没有重写父类中的抽象方法,那么这个类也是抽象类
      (子类含有抽象方法,那么该子类也是抽象类)
抽象类一定是父类吗    一定
抽象类和普通类的区别:
   共同点:都是类 能被继承
   不同点:抽象类不能创建对象,普通类可以创建对象
 抽象类含有抽象方法,普通类不含有抽象方法
抽象类有构造函数吗
   不能创建对象,但是有构造函数,构造函数是给子类使用的。
abstract不能喝哪些关键字同时使用:
   static:静态方法可以通过类名调用,abstract修饰的方法不能被调用 ;(一起用会报错非法的修饰组合:abstract和static)
   final:   final修饰的方法不能被重写,abstract方法必须能被重写。
   private:私有的方法不能被重写,abstract方法必须能被重写。
抽象类不一定含有抽象方法 (当希望一个类不能被创建对象时,这个类修饰为abstract,但是这个类中没有抽象方法)
但是含有抽象方法的类一定是抽象类

 

 1 abstract class Person{
 2   public void eat()
 3   {
 4   }
 5   public void sleep()
 6   {
 7   }
 8 }
 9 //计算圆形和长方形面积
10 abstract class Shape{
11    public  abstract double area();//非法的修饰符组合: abstract和static  Shape.area()  非法的修饰符组合: abstract和private
12 }
13 
14 abstract class Circle extends Shape{
15     public static final double PI=3.1415;
16     private double radius;
17 
18     Circle(){}
19     Circle(double radius){
20       this.radius=radius;
21     }
22 
23     //该子类含有抽象方法,那么该子类也是抽象类
24 
25     /*
26     public double area()//需要重写父类中的抽象方法,否则该子类也是抽象类
27     {
28        return PI*radius*radius;
29     }
30     */
31 }
32 
33  class Rectangle extends Shape{
34     private double length;
35     private double width;
36 
37     Rectangle(){}
38     Rectangle(double length,double width){
39        this.length=length;
40        this.width=width;
41     }
42     public double area(){
43         return length*width;
44     }
45 }
46 class Demo3 {
47     public static void main(String[] args) {
48         //Shape shape=new Shape();//Shape是抽象的; 无法实例化
49         Rectangle rectangle=new Rectangle(8,5);
50         double mianji = rectangle.area();
51         System.out.println(mianji);
52         Person ren = new Person();
53     }
54 }
 1 /*
 2 需求:公司中程序员有姓名,工号,薪水,工作内容。
 3 项目经理除了有姓名,工号,薪水,还有奖金,工作内容。
 4 对给出需求进行数据建模。
 5 */
 6 abstract class Employee{
 7     private String name;
 8     private int number;
 9     private double salary;
10     Employee(){}
11     Employee(String name,int number,double salary){
12        this.name=name;
13        this.number=number;
14        this.salary=salary;
15     }
16    public abstract void work();
17 }
18 class Programmer extends Employee{
19     Programmer(){}
20     Programmer(String name,int number,double salary){
21         super(name,number,salary);
22     }
23     public  void work(){
24        System.out.println("敲代码");
25     }
26 }
27 class Manager extends Employee{
28     private double bonus;
29     Manager(){}
30     Manager(String name,int number,double salary,double bonus){
31         super(name,number,salary);
32         this.bonus=bonus;
33     }
34     public void work(){
35        System.out.println("管理程序员");
36     }
37 }
38 class Demo4 {
39     public static void main(String[] args) {
40     Programmer yuan=new Programmer("猿","007",20000);
41     yuan.work();
42     Manager manager=new Manager("老猿","009",50000,10000);
43     manager.work();
44         System.out.println("Hello World!");
45     }
46 }

   ·接口:interface 

interface 接口名
{      
     public static final 成员变量                 //注意:这里不写public static final,属性也是这种
     public abstract 成员方法                   
 }
接口是用来实现的,用implements ,
接口解决java单继承的问题,接口是可以多实现的:因为接口中的方法都是抽象的,当创建子类对象调用这个方法时,
   很明确是在调用重写之后的方法,不会出现调用不确定的情况。

 1 interface inter{
 2      public static final int NUM=66;
 3      public abstract void show();
 4      //jdk1.8开始,可以定义实现了的方法
 5      public default void fun(){
 6         System.out.println("ok");
 7      }
 8 }
 9 interface inter2{
10      public abstract void show();
11      /*
12      public default void fun()
13      {
14         System.out.println("kk");
15      }*/
16 }
17 class Test implements inter,inter2 //类就继承了接口中的成员
18 {
19      public  void show(){
20          System.out.println("Hello");
21      }
22 }
23 class Demo5 {
24     public static void main(String[] args) {
25          Test t = new Test();
26          System.out.println(inter.NUM);
27          System.out.println(Test.NUM);
28          System.out.println(t.NUM);
29          t.fun();
30     }
31 }

   ·Lambda表达式

lambda表达式jdk1.8之后推出的新特性。本质上来说,lambda表达式就是一个匿名函数。可以使用lambda表达式简洁的实现接口中的方法。

 1 interface Calculate {
 2     int calculate(int a, int b);
 3 }
 4 class Addition implements Calculate {
 5     @Override
 6     public int calculate(int a, int b) {
 7         return a + b;
 8     }
 9 }
10 
11 class Program {
12     public static void main(String[] args) {
13         // 给接口类型的引用进行赋值,右侧需要是这个接口的实现类类型对象。
14         Calculate calculate = new Addition();
15         int result = calculate.calculate(10, 20);
16         
17         // 如果使用lambda表达式来完成同样的操作
18         Calculate calculate2 = (a, b) -> a + b;
19         int result2 = calculate2.calculate(10, 20);
20     }
21 }

lambda表达式对接口的要求

并不是所有的接口都可以使用lambda表达式来实线。lambda表达式毕竟只是一个匿名方法,如果接口中只有一个方法必须要实现,则可以使用lambda表达式;但是如果接口中必须要实现的方法比较多。

lambda表达式只能对 函数式接口 进行简洁的实现。

   ·lambda表达式的基础语法

lambda表达式,从本质来讲,就是一个匿名方法。一个方法的组成,有 返回值、方法名、参数、方法体 部分。

而lambda表达式是匿名方法,所以,方法名可以忽略。另外,在lambda表达式中,返回值类型也可以忽略。

因此,对于lambda表达式只需要关注两点即可:

  • 参数 : 以()括起来,将参数写入到()中。

  • 方法体 : 以 {} 括起来,将方法体写入到 {} 中。

对于lambda表达式,还需要记住一个新的语法: ->

  • lambda运算符 -> : 可以分隔参数和方法体。

1 // 说明需要实现一个无参、无返回值的方法
2 () -> { System.out.println("hello world"); }
3 // 说明需要实现一个 (int, int) 参数的、int返回值的方法
4 (int a, int b) -> { return a + b; }
 1 // 无参无返回
 2 NoneParameterNoneReturn lambda1 = () -> {
 3     System.out.println("hello world");
 4 };
 5 lambda1.test();            // 最终的实现,是lambda表达式中的实现
 6 
 7 
 8 // 多个参数、有返回
 9 MutipleParameterSingleReturn lambda2 = (int x, int y) -> {
10     return x + y;
11 };
12 int ret2 = lambda2.test(10, 20);
13 System.out.println(ret2);

   ·lambda表达式的语法进阶

lambda表达式是为了简洁的实现接口的,所以某些部分是可以省略的。

1、参数的类型,已经在接口的方法中有明确规定了,因此在lambda表达式中,可以省略参数的类型。

   注意:如果要省略形参的类型,则每一个形参都必须省略。不能出现有的形参带类型,有的没有。

1 MutipleParameterNoneReturn lambda1 = (a, b) -> {
2     System.out.println("a = " + a + ", b = " + b);
3 };
4 lambda1.test(10, 20);

2、如果参数列表中,形参的数量只有一个,此时可以省略小括号。

1 SingleParameterNoneReturn lambda2 = a -> {
2     System.out.println("a = " + a);
3 };
4 lambda2.test(10);

lambda表达式的函数引用


推理:

lambda表达式可以简洁的实现一个接口,但是,一般情况下,在lambda表达式中的都是简单的逻辑。如果需要处理的逻辑比较复杂,不推荐将复杂的逻辑直接的写到lambda表达式中。

 

如果需要在lambda表达式中进行的复杂的逻辑处理,已经在其他的方法中实现过了,可以直接调用这个方法即可。或者可以使用函数引用,将引用的函数,实现接口中的方法。

public class CSyntax {
public static void main(String[] args) {
// 需求:
// 计算a和b的最大公约数

// 这是个函数引用,使用calculate方法实现接口中的方法
MutipleParameterSingleReturn lambda = CSyntax::calculate;

int result = lambda.test(12, 8);
System.out.println(result);
}

public static int calculate(int a, int b) {
// 1、找出最小值
int min = a > b ? b : a;
// 2、从最小值开始,向下递减直到1,找到一个能够同时整除a和b的数字
for (int i = min; i >= 1; i--) {
if (a % i == 0 && b % i == 0) {
return i;
}
}

return -1;
}
}

 

构造方法的引用

如果接口中的方法,需要返回一个对象,则此时,可以引用构造方法。

public class DSyntax {
public static void main(String[] args) {
/*
GetPerson lambda = () -> new Person();
Person xiaoming = lambda.get();
System.out.println(xiaoming);
*/
// 引用的构造方法
GetPerson lambda2 = Person::new;
System.out.println(lambda2.get("xiaoming", 10));
}
}

interface GetPerson {
Person get(String name, int age);
}


class Person {
String name;
int age;

public Person() {
super();
System.out.println("Person的无参构造方法执行了");
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
System.out.println("Person的有参构造方法执行了");
}

@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}

   ·继承和实现结合:

 类和类之间是继承关系,类和接口之间是实现的关系,接口和接口之间是继承的关系
 通过继承可以得到体系中的基本的功能和属性
 通过实现可以得到体系以外的功能和属性

 1 interface inter{
 2     public abstract void show();
 3 }
 4 class Person{
 5     int age;
 6     String name;
 7     public void eat()
 8     {}
 9 }
10 class Student extends Person implements inter{
11     public  void show()
12     {
13     }
14 }
15 interface a{
16 }
17 interface b {
18 }
19 interface c extends a,b{
20 }

 

 1 /*
 2 狗生活在陆地上(是一种陆生动物),既是哺乳类的也是肉食性的。
 3 狗通常的时候和人打招呼会通过“摇摇尾巴”,在被抚摸情绪很好的时候,
 4 会“旺旺叫”,而在受到惊吓情绪烦躁时,会发出“呜呜”声;
 5 
 6 猫也生活在陆地上(是一种陆生动物),既是哺乳类的也是肉食性的。
 7 猫通常的时候和人打招呼会发出“喵~”的声音,在被抚摸情绪很好时,
 8 会发出“咕噜咕噜”声,而在受到惊吓时,会发出“嘶嘶”声;
 9 
10 青蛙是一种两栖动物(既是水生动物也是陆生动物),既不是哺乳类的也不是肉食性的,
11 属于卵生。青蛙通常的时候和人打招呼会通过“呱呱叫”,当青蛙情绪好的时候,
12 会在岸边“呱呱呱”的唱歌,而在受到惊吓时,会“扑通一声跳入水中”
13 */
14 abstract class Animal
15 {
16     public static final int HAPPY=1; // 1表示情绪好
17     public static final int UNHAPPY=2;//2表示情绪不好
18     protected boolean mammal;//哺乳
19     protected boolean carnivorous;//肉食
20     private int mood;
21 
22     public boolean isMammal(){
23         return mammal;
24     }
25     public boolean isCarnivorous(){
26         return carnivorous;
27     }
28     public void setMood(int mood){
29         this.mood=mood;
30     }
31     public int getMood(){
32        return mood;
33     }
34     public abstract String sayHello();
35     public abstract String sayHello(int mood);
36 }
37 interface Land{
38     public abstract int getNumberOfLegs();
39 }
40 interface Warter{
41     public abstract boolean getGillFlags();
42     public abstract boolean getLayEggsFlags();
43 }
44 class Dog extends Animal implements Land{
45     private int numberOfLegs=4;//几条腿
46     Dog(){
47        this.mammal=true;
48        this.carnivorous=true;
49     }
50     public  String sayHello(){
51        return "摇摇尾巴";
52     }
53     public  String sayHello(int mood){
54          setMood(mood);
55          switch(getMood()){
56            case HAPPY:
57                  return "旺旺叫";//break;
58            case UNHAPPY:
59                  return "呜呜";
60 
61            default:
62                  return "摇摇尾巴";
63          }
64     }
65     public  int getNumberOfLegs(){
66         return numberOfLegs;
67     }
68 }
69 class Demo7 {
70     public static void main(String[] args){
71         Dog gou = new Dog();
72         if(gou.isMammal())
73             System.out.println("狗是哺乳动物");
74         else
75             System.out.println("狗不是哺乳动物");
76 
77         if(gou.isCarnivorous())
78             System.out.println("狗是肉食动物");
79         else
80             System.out.println("狗不是肉食动物");
81 
82         System.out.println("狗通常情况下打招呼的方式是:"+gou.sayHello());
83 
84         System.out.println("狗情绪好时打招呼的方式是:"+gou.sayHello(Animal.HAPPY));
85 
86         System.out.println("狗受到惊吓时打招呼的方式是:"+gou.sayHello(Animal.UNHAPPY));
87 
88         System.out.println("狗是陆生动物,狗有"+gou.getNumberOfLegs()+"条腿");
89 
90     }
91 }


   ·多态

  父类类型的引用指向子类对象,即把子类对象看成父类类型 ,
多态的弊端:在多态中只能使用父类中定义的行为,父类中未定义的不能使用
多态的前提:存在继承或实现
多态的优点:通常都是方法的参数使用多态,这样可以接收所有父类的子类类型的对象,节省了很多函数的定义

 1 abstract class Animal{
 2     public abstract void eat();
 3 }
 4 class Cat extends Animal{
 5     public  void eat(){
 6        System.out.println("猫吃鱼");
 7     }
 8     public void catchMouse(){
 9        System.out.println("猫抓耗子");
10     }
11 }
12 class Demo9 {
13     public static void main(String[] args) {
14         //Cat mao = new Cat();
15         //mao.eat();
16         //mao.catchMouse();
17 
18         Animal mao = new Cat();
19         mao.eat();
20         //mao.catchMouse();//错误: 找不到符号 mao.catchMouse();
21     }
22 }

   ·多态中如何使用子类特有的功能 ---转型

向上转型

  • 由子类类型转型为父类类型。

  • 向上转型一定会成功,不需要任何额外的操作,是一个隐式转换。

  • 向上转型后的对象,将只能够访问父类中存在的成员,子类特有的成员将无法访问。

向下转型

  • 由父类类型转型为子类类型。

  • 向下转型存在失败的可能性,需要额外进行强制操作,是一个显式转换。

  • 向下转型后的对象,将可以访问子类中特有的成员。

 由于多态中,父类引用指向子类对象,只能使用父类中定义的行为;
 方法如:Animal mao=new Animal(); //向上转型
       Cat m=(Cat)mao; //向下转型   强转
                      instanceof(实例)用于判断对象具体是什么类型的

 1 abstract class Animal{
 2     public abstract void eat();
 3 }
 4 class Cat extends Animal{
 5     public  void eat(){
 6        System.out.println("猫吃鱼");
 7     }
 8     public void catchMouse(){
 9        System.out.println("猫抓耗子");
10     }
11 }
12 class Dog extends Animal{
13     public  void eat(){
14        System.out.println("狗吃肉");
15     }
16     public void kanJia(){
17         System.out.println("狗看家");
18     }
19 }
20 class Demo11 {
21     public static void main(String[] args) {
22         //在多态中使用子类特有的功能
23         Animal  mao = new Cat();//向上转型
24         //使用子类特有的功能
25         Cat m=(Cat)mao;//向下转型
26         //m.eat();
27         //m.catchMouse();
28 
29         Cat cat = new Cat();
30         chi(cat);
31 
32         Dog gou = new Dog();
33         chi(gou);
34     }
35 
36      //使用子类特有的功能
37     public static void chi(Animal dongwu)//Animal dongwu=new Dog();
38     {
39         dongwu.eat();
40 
41         if(dongwu instanceof Cat)//使用instanceof判断对象具体是什么类型的
42         {
43             Cat mao = (Cat)dongwu;
44             mao.catchMouse();
45         }
46         if(dongwu instanceof Dog){
47            Dog gou = (Dog)dongwu;
48            gou.kanJia();
49         }
50     }
51 }

day9

   ·重写的特殊情况

重写总结:
 public father run(){}
 public son run(){}  //是重写
 
 protect a run(){}
 public a run(){}  //是重写
 
 私有的private修饰的方法不能被重写
 

    子类在重写父类中的方法时,如果父类中的方法返回值是本身,本身当引用数据类型,那么子类在重写时,可以和父类方法的返回值一致,也可以是父类方法返回值类型的子类类型

 1 class Test{
 2        public Fu show(){
 3            return new Z1();
 4        }
 5 }
 6 class Tests extends Test{
 7      public Z2 show() //子类在重写时返回值类型可以和父类方法一致,也可以是父类方法返回值的子类类型
 8      {
 9          return new Z2();
10      }
11 }
12 class Fu{
13     public void fun(){
14         System.out.println("fun");
15     }
16 }
17 class Z1 extends Fu{    
18 }
19 class Z2 extends Fu{
20 }
21 class Demo2 {
22     public static void main(String[] args) {
23         Tests t = new Tests();
24         Z2 z = t.show();
25         z.fun();
26     }
27     public static Fu ff(){
28        return new Z2();
29     }
30 }

 

   ·接口和多态

多态同样适用于接口
 一个方法的参数类型可以是接口类型
 一个方法的返回值类型可以是接口类型

 1 interface inter //接口是引用数据类型 inter.class{
 2     public abstract void show();
 3 }
 4 class Test1 implements inter{
 5     public  void show(){
 6        System.out.println("show1");
 7     }
 8 }
 9 class Test2 implements inter{
10     public  void show(){
11        System.out.println("show2");
12     }
13 }
14 class Demo3 {
15     public static void main(String[] args) {
16         Test1 t1 = new Test1();
17         ff(t1);
18 
19         Test2 t2 = new Test2();
20         ff(t2);
21 
22         inter t=fun(); //inter t=new Test1()   注释的此行就是接口可用于多态的核心
23         t.show();
24     }
25     public static inter fun()//返回值类型是接口类型
26     {
27        return new Test1();
28     }
29     public static void ff(inter in)//inter in=new Test2();父接口类型的引用指向了子类对象
30     {
31         in.show();
32     }
33 }

   ·多态中成员的特点

 1 /*
 2 多态中成员的特点:
 3 
 4 成员变量的特点:编译时期看父类,运行结果看父类
 5 非静态成员方法的特点: 编译时期看父类, 运行结果看子类
 6 静态成员方法的特点:编译时期看父类,运行结果看父类
 7 
 8 非静态成员方法看子类,其它的都看父类
 9 */
10 class Fu{
11     int num=5;
12     
13     public void show(){
14        System.out.println("show fu");
15     }
16     public static void ff(){
17         System.out.println("fu static");
18     }
19 }
20 class Zi extends Fu{
21     int age=6;
22 
23     public void show(){
24        System.out.println("show zi");
25     }
26     public void fun(){
27        System.out.println("fun");
28     }
29     public static void ff(){
30         System.out.println("zi static");
31     }
32 }
33 class Demo4 {
34     public static void main(String[] args) {
35         Fu zi=new Zi();
36         //System.out.println(zi.num);
37         //System.out.println(zi.age);
38         //zi.show();
39         //zi.fun();
40         zi.ff();
41     }
42 }

   ·object

是任何一个类的直接或间接父类,超类,最大的那个类,Object没有父类
 Object提取的是所有对象的共性:Object中定义的属性和行为是任何一个对象都具备的
 构造方法Object(){}

object中的方法:equals()方法,
 toString()方法,返回的是对象的字符串表示形式,由类名加哈希值(16进制)组成。
 如果直接输出对象,默认调用了对象的toString的方法
 hashCode()方法,返回对象的哈希值(10进制)

   ·模板设计模式

模板设计模式:实现一个功能,功能的一部分是能确定,一部分是不能确定的,确定的那部分会用到不确定的部分,
                把不确定的部分暴露出去,让子类去实现

 1 /*
 2 模板设计模式:实现一个功能时,功能的一部分是能确定如何实现的,一部分不能确定如何实现,确定的那部分会用到不确定的部分
 3               把不确定的部分暴露出去,让子类去实现
 4 
 5  计算程序的运行时间
 6 
 7 */
 8 abstract class Test{
 9     public final void runTime(){
10         //记录开始时间
11         long start = System.currentTimeMillis();
12         //程序代码
13         fun();
14         //记录结束时间
15         long end = System.currentTimeMillis();
16         System.out.println("程序运行时间:"+(end-start));
17     }
18     public abstract void fun();
19 }
20 class Demo extends Test{
21     public  void fun(){
22         for(int i=1;i<=3000;i++){
23             System.out.println(i);
24         }
25     }
26 }
27 class Demo6 {
28     public static void main(String[] args) {
29         Demo d = new Demo();
30         d.runTime();
31     }
32 }

   ·内部类

在一个类内部定义的类,属于外部了的成员,成员内部类,成员之间可以相互使用

外部类Outer,内部类Inner,使用的时候,为Outer.Inner
非静态内部类对象的创建:由于内部类是非静态的,需要外部类对象调用,所以使用外部类对象创建内部类对象
 Outer.Inner inner=new Outer().new Inner();

      内部类看成外部类的成员
      内部类既然是成员,所以可以被修饰为static的
      内部类中含有静态成员,那么内部类必须是静态的
      内部类得到外部类对象 : 外部类名.this

 1 //内部类:在一个类内部定义的类,属于外部类的成员,成员内部类,成员之间可以相互使用
 2 //static可以修饰成员
 3 class Outer{
 4     private int num=66; //成员变量
 5     class Inner //成员内部类
 6     {
 7         public void show(){
 8            System.out.println(num);
 9            fun();
10         }
11     }
12     public  void  fun()//成员方法
13     {
14        Inner in = new Inner();
15        in.show();
16     }
17 }
18 
19 class Person{
20    class Heart{
21     }
22 }
23 
24 class Demo7 {
25     public static void main(String[] args) {
26         //Outer out = new Outer();
27         //out.fun();
28         //创建内部类对象,因为内部类是非静态的,所以需要创建Outer的对象
29         Outer.Inner inner=new Outer().new Inner();
30         inner.show();
31     }
32 }
 1 class Outer{
 2     private static int num=6;
 3     static class Inner  //内部类中的成员是静态的,那么内部类必须是静态的
 4     {
 5         public static void show() // new Outer().new Inner().show()   new Outer.Inner() Outer.Inner.show()
 6         {
 7            System.out.println(num);
 8         }
 9     }
10 
11 }
12 
13 class Demo8 {
14     public static void main(String[] args) {
15         //因为show方法不是静态的,所以必须通过Inner的对象来调用
16         //访问静态内部类中的非静态方法
17         Outer.Inner in = new Outer.Inner();
18         in.show();
19 
20         //访问静态内部类中的静态方法
21         Outer.Inner.show();
22     }
23 }
 1 //内部类得到外部类对象:  外部类名.this
 2 class Outer{
 3     private int num=6;
 4     class Inner{
 5         int num=8;
 6         public void show(){
 7            int num=7;
 8            System.out.println(Outer.this.num);
 9         }
10     }
11     
12     public void fun(){
13        Inner in = new Inner();
14        in.show();
15     }
16 }
17 class Demo9{
18     public static void main(String[] args) {
19         Outer out = new Outer();
20         out.fun();
21     }
22 }

   ·局部内部类

在一个类的函数里的类

 1 //局部内部类
 2 class Outer{
 3     public void fun(){
 4        class Inner{
 5            public void show(){
 6               System.out.println("Hello");
 7            }
 8        }
 9        new Inner().show();
10     }
11 }
12 class Demo10 
13 {
14     public static void main(String[] args) 
15     {
16         Outer out = new Outer();
17         out.fun();
18     }
19 

 

   ·匿名内部类

在类的方法里,   new  类 (){};

 1 /*
 2 匿名内部类:作用是为了简化书写
 3 */
 4 abstract class Test{
 5     public abstract void show();
 6 }
 7 class Outer{
 8     /*
 9    class Inner extends Test{
10        public  void show(){
11           System.out.println("show");
12        }
13        public void fun(){
14            System.out.println("fun");
15        }
16    }
17    */
18    public void ff(){
19         //Inner in = new Inner();
20         //in.show();
21         //in.fun();
22         //创建的是Test的子类对象
23         new Test(){
24             public  void show(){
25               System.out.println("show");
26             }
27             public void fun(){
28                System.out.println("fun");
29             }
30         }.show();
31 
32         //父类类型的引用指向了子类对象
33         Test t = new Test(){
34             public  void show(){
35               System.out.println("show");
36             }
37             public void fun(){
38                System.out.println("fun");
39             }
40         };
41         t.show();//只能调用show方法
42 
43         System.out.println(new Object(){
44             String name="李四";
45             int age=20;
46              
47             public String toString(){
48                return name+","+age;
49             }
50         });
51     }
52 }
53 class Demo11 {
54     public static void main(String[] args) {
55         Outer out = new Outer();
56         out.ff();
57     }
58 }

 

   ·private

子类继承父类,子类拥有了父类的所有属性和方法。(private 自己的,私有的)
  私有属性不能直接得到,私有属性可以通过public修饰的getter和setter方法访问到,但是私有方法不行。

       私有方法不能被重写可以被重载,私有方法可通过public方法得到。

day10

   ·接口(interface)与匿名内部类

注意
 a.run().start(); //因为.start()需要对象调用,所以run()的返回值是一个对象

 

 1 interface T{
 2     abstract void start();
 3 }
 4 class A{
 5     public static void main(String args[]){
 6         A a=new A();
 7         a.run().start();
 8     }
 9     public static T run(){
10         return new Test();
11     }
12 }
13 class Test implements T{
14     public void start(){
15         System.out.println("start方法被调用了");
16     }
17 }

 

   ·String : 字符串类

   java把字符串面向对象,定义了一个描述字符串的类 String
   特点:字符串是不能改变的,它们的值在创建后不能更改
            字符串是存储在方法区中的常量池中 (如果常量池中已经存在一个字符串那么直接使用已有的字符串)
   常量:不能被修改的量,由于字符串存储在方法区的常量池中,所以双引号里的内容不能被修改
 
String类重写了Object中的boolean equals(Object obj)方法和toString方法
equal:比较双引号中的内容(字符串中的内容是否一样)
   String str1=new String("1000"); //有两个对象,一个是new的对象,一个是字符串对象
   String str2="1000";
   String str3="1000";2
   str1.equals(str2); 
//返回值是false,由于str1指向的是new String 在堆中的地址
   str2.equals(str3); //返回值是true,由于两个都直接取了"1000"的值
总之:equals比较“”里面的,(老师说的)
 
数组中的length是属性
获取字符串的长度 int length();
String中的length() 如"1000".length(), 是方法

 

 1 //判断用户名和密码是否正确
 2      //参数:用户名和密码 admin,admin
 3      //返回值:boolean
 4 
 5      public static boolean check(String username,String password){
 6         if(username!=null && password!=null){
 7              if(username.equals("admin") && password.equals("admin"))
 8                  return true;
 9              else
10                  return false;
11          }
12          else
13              return false;
14      }

   ·String类中的各种方法

length(), char charAt(int index),int indexOf(char ch),int indexOf(String ch,int start), int lastIndexOf(char ch)

 1 /*
 2   获取:
 3      获取字符串的长度
 4         int length()
 5      获取某一个位置上的字符
 6         char charAt(int index)
 7      获取字符在字符串中的位置
 8      如果要找的字符或者字符串不存在,返回值为-1
 9         int indexOf(char ch)//返回字符在字符串中第一次出现的位置
10         int indexOf(int ch, int fromIndex)//第二个参数用于指定开始找的位置
11 
12         int indexOf(String str) //获取一个字符串在字符串中出现的位置
13         int indexOf(String str, int fromIndex)//第二个参数用于指定开始找的位置
14 
15         int lastIndexOf(char ch)//最后一次出现的位置
16 */
17 
18 class Demo4 {
19     public static void main(String[] args) {   
20         int num = "oiwueroieuro".length();
21         sop(num);//数组的length,是属性
22 
23         char ch="hello".charAt(1);
24         sop(ch);
25 
26         int index = "hello wo ".indexOf('o');//返回第一次出现的下标
27         sop(index);//4
28 
29         index = "hello wo hoo".indexOf('o',6);// 指定开始查找的位置
30         sop(index);//7
31 
32         index="hello world".indexOf("llo");
33         sop(index);//2
34 
35         index="hello world llo".indexOf("llo",5);
36         sop(index);//12
37 
38         index="hello world llo".lastIndexOf("llo");//最后一次出现的下标
39         sop(index);//12
40 
41         index="haha".indexOf('w');
42         sop(index);//-1
43     }
44     public static void sop(Object obj){
45        System.out.println(obj);
46     }
47 }

   ·String类中的其它方法

 length(), char charAt(int index),int indexOf(char ch),int indexOf(String ch,int start), int lastIndexOf(char ch)
     contains()  equals() startsWith() endsWith() equalsIgnoreCase()
     new String(char[] ch)  "lsjdkl".toCharArray()    new String(byte[] arr)  "oiwueori".getBytes()
     "   oiwueroe   ieri    ".trim()  toUpperCase()  toLowerCase()   replace(old,new)
  1 /*
  2    判断:
  3         判断是否包含一个字符串
  4           boolean contains(CharSequence s) 
  5         判断两个字符串的内容是否相同
  6           boolean equals(Object anObject) 
  7         忽略大小写判断两个字符串的内容是否相同
  8           boolean equalsIgnoreCase(String anotherString) 
  9          判断是否以某字符串开头
 10            boolean startsWith(String prefix)
 11          判断是否以某字符串结尾
 12            boolean endsWith(String suffix) 
 13     转换:将字符数组转换成字符串
 14               1:使用构造方法
 15                  String(char[] value) 
 16                  String(char[] value, int offset, int count) 
 17               2:使用静态方法
 18                  static String copyValueOf(char[] data) 
 19                  static String copyValueOf(char[] data, int offset, int count) 
 20           将字符串转成字符数组
 21               char[] toCharArray() 
 22  
 23           将字节数组转成字符串
 24               String(byte[] bytes) 
 25               String(byte[] bytes, int offset, int length)
 26               String(byte[] bytes, String charsetName)//使用指定的编码将字节数组转换成字符成
 27           将字符串转成字节数组
 28               byte[] getBytes() 
 29  
 30 
 31           将基本数据类型转换成字符串
 32               String.valueOf()
 33     替换:
 34          String replace(char oldChar, char newChar) 
 35  
 36     子串:
 37          String substring(int beginIndex)  
 38          String substring(int beginIndex, int endIndex) //包含起始位置,不包含结束位置,到结束位置的前一位
 39  
 40     转换,去除空格,比较:
 41          大小写转换
 42              String toLowerCase() 
 43              String toUpperCase()
 44          将字符串两端的空格去掉
 45              String trim() 
 46          按字典顺序比较两个字符串
 47              int compareTo(String anotherString)
 48     切割: String[] split(String)
 49 
 50 */
 51 class Demo5 {
 52     public static void main(String[] args) {
 53         //panDuan();
 54         //zhuanHuan();
 55         //qiTa();
 56         lasts();
 57     }
 58 
 59     public static void lasts(){
 60         //按字典顺序比较两个字符串  int compareTo(String anotherString)
 61         int num = "a".compareTo("c");//前边的小于后边的返回负数,前边大于后边,返回一个正数,前边等于后边返回0
 62         sop(num);//0
 63 
 64         //切割: String[] split(String str)
 65         String str="zhangsan,lisi,wangwu,zhaoliu";
 66       
 67         String[] arr=str.split(",");  
 68         sop(arr.length);
 69         for(int i=0;i<arr.length;i++){
 70           sop(arr[i]);
 71         }
 72     }
 73 
 74     public static void qiTa(){
 75         // String replace(char oldChar, char newChar)
 76         String  ss="hello".replace('e','w');  //"hello"没有被改变,是根据hello得到了一个新的字符串
 77         sop(ss);
 78 
 79         String s1="hello world".substring(6);
 80         sop(s1);
 81 
 82         s1="hello world".substring(6,9);//包含起始位置,不包含结束位置,到结束位置的前一位
 83         sop(s1);
 84 
 85         s1="hello world".substring(6,7);//StringIndexOutOfBoundsException 第二个值不要小于第一个值
 86         sop(s1);
 87 
 88         sop("hello".toUpperCase());
 89         sop("HELLO".toLowerCase());
 90 
 91         sop("   hehe     ".trim());
 92     }
 93 
 94     public static void zhuanHuan()
 95     {
 96         //将字符数组转换成字符串
 97         char[] arr={'a','b','c','d'};  //"abcd"
 98 
 99         //使用构造方法 String(char[] value) 
100         String str = new String(arr);
101         sop(str);//abcd
102         
103         //static String copyValueOf(char[] data)
104         String ss = String.copyValueOf(arr,1,3);
105         sop(ss);//bcd
106 
107         //将字符串转成字符数组   char[] toCharArray() 
108         char[] b = "hello".toCharArray();
109         for(int i=0;i<b.length;i++){
110           sop(b[i]+"  ");
111         }
112 
113         //将字节数组转成字符串
114         byte[] c={65,66,67,68};
115         String ss2=new String(c);
116         sop(ss2);
117 
118          //将字符串转成字节数组
119         byte[] d = ss2.getBytes();
120         for(int i=0;i<d.length;i++){
121           sop(d[i]+"  ");
122         }
123 
124         //将基本数据类型转换成字符串 String.valueOf()
125         String ss3=String.valueOf(new Demo5());
126         sop(ss3);
127     }
128 
129     public static void panDuan(){
130         boolean b = "hello world".contains("wo");
131         sop(b);
132 
133         b = "hello".equals("hello");
134         sop(b);
135 
136         b="hello".equalsIgnoreCase("HELLO");//忽略大小写
137         sop(b);//true
138 
139         b="my.java".endsWith(".java");
140         sop(b);
141 
142         b="my.java".startsWith("my");
143         sop(b);
144     }
145 
146     public static void sop(Object obj){
147        System.out.println(obj);
148     }
149 }

   ·StringBuffer

  字符串缓冲区
  可以被改变的字符串序列(与String类的区别)
append();往字符串中添加, 里面可以是任意类型的
Object中的toString()输出的是类名+哈希值
StringBuffer中的toString()重写了Object中的toString(),输出的是字符串
StringBuffer:jdk1.0,线程安全的,可以安全地被多个线程使用 (适合多线程)
StringBuilder:多线程不安全的,提高代码执行效率
 1 //StringBuffer:可变的字符序列
 2 /*
 3 存储:
 4     StringBuffer append(boolean b) 
 5     StringBuffer insert(int offset, boolean b) 
 6 删除:
 7      StringBuffer delete(int start, int end) 
 8      StringBuffer deleteCharAt(int index)
 9 修改:
10      StringBuffer replace(int start, int end, String str) 
11      void setCharAt(int index, char ch) 
12 获取:
13      char charAt(int index) 
14      int indexOf(String str)
15      int indexOf(String str, int fromIndex)
16      int lastIndexOf(String str) 
17           返回最右边出现的指定子字符串在此字符串中的索引。 
18      int lastIndexOf(String str, int fromIndex) 
19           返回最后一次出现的指定子字符串在此字符串中的索引。 
20      int length() 
21           返回长度(字符数)。 
22 反转:
23      StringBuffer reverse() 
24 
25 
26 StringBuffer:JDK1.0,线程安全的,可以安全地被多个线程使用
27 
28 StringBuilder:可变的字符序列,jdk1.5,多线程不安全的,提高代码执行效率
29 
30 */
31 class Demo6 {
32     public static void main(String[] args) {
33         //String str= new String("hello");
34 
35         StringBuffer sb = new StringBuffer("hello"); //添加,修改,删除
36 
37        // StringBuffer sb1=sb.append(false);//添加完之后返回的还是原来的StringBuffer对象
38         //sop(sb==sb1);
39 
40          //加入对象时加入的是对象的字符串表示:类名+哈希值
41         sb.append(66).append(true).append(new Object());//加入到StringBuffer的都被转成字符串
42 
43 
44         //得到StringBuffer中的字符串
45         //sop(sb.toString());//StringBuffer重写了Object中的toString方法,返回的是存储的字符串
46         
47 
48         sb.insert(5,"world");
49         sop(sb);
50 
51        //删除
52        sb.delete(5,10);//不包括结束位置
53        sop(sb);
54 
55        sb.deleteCharAt(5);
56        sop(sb);
57 
58        //修改
59        sb.replace(6,10,"false");
60        sop(sb);
61 
62        sb.setCharAt(5,'8');
63        sop(sb);
64 
65       //反转
66       sb.reverse();
67       sop(sb);        
68     }
69     public static void sop(Object obj){
70        System.out.println(obj);
71     }
72 }

   ·StringBuilder

StringBuffer:jdk1.0,线程安全的,可以安全地被多个线程使用 (适合多线程)
StringBuilder:多线程不安全的,提高代码执行效率(适合单线程)

 1 class Demo7 {
 2     public static void main(String[] args) {
 3         boolean b =checkEmail("zhangsan163.com");
 4         //System.out.println(b);
 5         juXing(5,10);
 6     }
 7     //显示一个矩形,用StringBuilder存储一个矩形,并打印
 8      //参数:行,列
 9      //返回值:无
10      public static void juXing(int row,int col){
11          StringBuilder sb = new StringBuilder();
12          for(int i=1;i<=row;i++){
13             for(int j=1;j<=col;j++){
14                 sb.append("*");
15              }
16              sb.append("\r\n");
17          }
18         System.out.print(sb.toString());
19      }
20 
21     //验证邮箱格式是否正确  lisi@163.com
22     //参数:字符串类型的邮箱
23     //返回值:boolean
24 
25     public static boolean checkEmail(String email) {
26         if(email!=null){
27             if(email.indexOf("@")==-1)
28                 return false;
29             else if(email.indexOf(".")==-1)
30                 return false;
31             else if(email.indexOf("@")>email.indexOf("."))
32                 return false;
33             else
34                 return true;
35         }else
36             return false;
37     }
38 }

   ·包装类 及 String的相关转换

把基本类型变为引用类型,即java的面向对象的思想,由类来调用方法,提高程序的编写。

byte  Byte
short  Short
int Integer
long Long
char  Character
float Float
double  Double
boolean  Boolean

 1 /*
 2 包装类:
 3   基本类型转字符串类型三种方式
   String new String(int a); //String new String (int[] arr) 数组转字符串
  
   String String.valueOf(double d)
4 String Double.toString(double d)

   String String.valueOf(int a);
5 String Integer.toString(int a) 6 7 字符串类型转基本类型两种方式
8 int Integer.parseInt("66") 9 Integer i=Integer.valueOf("66"); int i2=i; 10 11 十进制转其他进制 12 String s1=Integer.toHexString(60); 13 String s2=Integer.toOctalString(60); 14 String s3=Integer.toBinaryString(60); 15 16 其他进制转十进制 17 Integer.parseInt("3c",16) 18 Integer.parseInt("74",8) 19 Integer.parseInt("110",2) 20 */ 21 class Demo8 { 22 public static void main(String[] args) { 23 char ch='我'; 24 int max=Integer.MAX_VALUE; 25 sop(max); 26 27 String str = Integer.toString(66);//String.valueOf() 28 sop(str); 29 sop(""+66); 30 31 int age = Integer.parseInt("66"); 32 sop(age); 33 double weight=Double.parseDouble("88.88"); 34 sop(weight); 35 36 //十进制转其他进制 37 38 String s1=Integer.toHexString(60); 39 sop(s1); 40 String s2=Integer.toOctalString(60); 41 sop(s2); 42 String s3=Integer.toBinaryString(60); 43 sop(s3); 44 45 //其他进制转十进制 46 sop(Integer.parseInt("3c",16)); 47 sop(Integer.parseInt("74",8)); 48 sop(Integer.parseInt("110",2)); 49 } 50 public static void sop(Object obj){ 51 System.out.println(obj); 52 } 53 }

   ·装箱与拆箱  

自动装箱 Integer num=6;   //jdk1.5之后     相当于Integer num=new Integer(6)

自动拆箱 int n=num;  //自动拆箱,
自动拆箱   num=num+5;     //num.intValue()+5       先拆箱,再装箱    
装箱与拆箱的具体细节,由系统内部完成

在一个字节的范围内(-128---127),如果已经使用过,那么再定义时使用已有的

 1 class Demo9 {
 2     public static void main(String[] args) {
 3         //jdk1.5之前的写法
 4         Integer shu = new Integer(6);
 5         System.out.println(shu.intValue());//此方法能得到6
 6 
 7         Integer num=6;// new Integer(6)  自动装箱
 8         System.out.println(num);
 9       
      int n=num;    //自动拆箱,将num拆成了int
10 num=num+5;//num.intValue()+5 先拆箱 11--->Integer 再装箱 11 12 Integer m=127; //new Integer(127) int m=127; 13 Integer n=127; 14 System.out.println(m==n);//true 15 16 m=128; 17 n=128; 18 System.out.println(m==n);//false 19 20 //在一个字节的范围内(-128---127),如果已经使用过,那么再定义时使用已有的 21 } 22 }

 

 1 package com.zqf;
 2 public class Test{
 3     public static void main(String args[]){
 4         int n=128;
 5         int x=128;
 6         Integer m=128;
 7         Integer z=128;
 8         System.out.println(z==m);//不在-128---127内,所以z用的对象是新创建的对象
 9         
10         System.out.println(m==n);
11         System.out.println(n==x);
12         
13         System.out.println(z==n);
14         Integer d=127;
15         Integer e=127;
16         System.out.println(d==e);    //在-128---127内,所以e用的对象还是d的对象
17     }    
18 }

 

day11

   ·异常

定义:程序在运行时出现的不正常情况

java把程序运行时出现的各种不正常情况面向了对象,为各种不正常情况封装了实体类,
实体类应该实现显示异常名称,异常信息,异常发生的位置
 
   Throwable:(Error类和Exception类的父类)
      -- Error: 错误
      --Exception:异常

当发生异常时,因为这种异常对应的异常类在Java内部已经定义了,所以系统会创建对应该异常的异常类对象,因为main处理不了这种异常,
抛给了JVM,JVM默认的处理方式是调用异常类对象的printStackTrace()方法,该方法会显示异常名称,异常信息,异常发生的位置, 然后程序中断

1 class Demo10 {
2     public static void main(String[] args) {
3         int[] arr=new int[3];
4         System.out.println(arr[3]);  //throw  new ArrayIndexOutOfBoundsException()  printStackTrace()方法
5         System.out.println("hehe");    
6     }
7 }

 

 try{
 可能发生异常的代码
}catch(异常类 e){
 e.getMessage()
 e.toString()
 e.printStackTrack()
 }finally{

     //finally中的代码一定会执行,除非catch中有system.exit(1);

}

默认情况下,可以处理也可以不处理,存在的问题是程序编译通过,运行时发生异常,应该让问题在编译时期就发现,
而不是编译正常,运行出问题,使用throws
没有使用throws时,调用者处理或不处理编译都通过,存在的问题是编译正常,运行出问题,
使用了throws,调用者必须处理,不处理编译不通过

一个方法使用了throws声明了异常,必须进行处理
两种处理方式:
   使用try{}catch{}
   使用throws继续声明异常

 

多重异常:
 try{}catch{}...catch{}
当catch中有子类异常,也有父类异常时,子类异常在父类异常之前。(要是父类异常在子类异常之前,就都能处理了,会在编译时报错)

异常:
 Excepiton的子类,编译时检测的异常
 RuntimeException或其子类
 其子类有arithmeticException,NullPointException(),ArrayIndexOutOfBoundsException()等...

编译时不检测,运行时检测的异常:RuntimeException或其子类,这种异常是因为传递数据出错,
java认为此时应该程序中断,希望人为的将参数改成正确的,否则影响后面的代码使用
是因为数据错误造成的,当发生这种异常时,不该处理,就应该中断程序,去修改错误
 1 //定义了一个被除数为负数时,会产生的异常
 2 package com.zqf;
 3 class fuShuException extends Exception{
 4     public fuShuException(String message) {
 5         super(message);
 6     }
 7     public static void run(int a,int b) {
 8         if(a<0){
 9             try{throw new fuShuException("负数异常啊 ,秀啊");  //手动创建异常类对象
10             
11             } catch (fuShuException e) {
12                 System.out.println(e.getMessage());
13                 e.printStackTrace();
14             }
15         }
16         int c=a/b;
17         System.out.println(c);
18     }
19     public static void main(String[] args)  {
20         run(-1,2);
21     }
22 }

 

任何执行try 或者catch中的return语句之前,都会先执行finally语句,如果finally存在的话。
                  如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的,

     注:finally子句是异常处理的出口,释放资源、关闭文件、关闭数据库都是由finally子句完成

day12

   ·异常总结

throw: 抛出异常类对象,java定义的异常类不需要自己手动创建异常类对象,自定义的需要字节手动创建异常类对象
           在方法内部使用了throw,该方法必须处理,处理方式有两种,捕获或声明,如果不处理,编译不通过
throws:在方法的后边声明可能发生异常,调用了有throws声明的方法,调用者必须处理,处理方式有两种,捕获或声明,如果不处理,编译不通过
非运行时异常符合上边的规则
运行时异常:
 传参错误的是运行时异常
 特殊的异常,不符合上边的规则RuntimeException或其子类
 在方法内部使用了throw抛出了运行时异常对象,那么可以不处理
 使用throws声明了运行时异常,可以不处理
 
 因为运行时异常都是因为数据错误造成的,如果处理了,比如使用try{}catch{}处理了,那么发生异常时,
 会执行catch,然后程序继续执行,但是应该让程序停下来,去解决错误的数据,所以不该处理
 运行时异常可以处理,但是不好
自定义异常:
   如果是运行时异常不需要处理,非运行时异常处理
 

   ·Date及SimpleDateFormat

 1 import java.util.Date;
 2 import java.text.DateFormat;
 3 import java.text.SimpleDateFormat;
 4 //java.lang.System;
 5 class Demo2 {
 6     public static void main(String[] args) {
 7         Date date = new Date();
 8         //sop(date);//Wed Sep 11 10:43:26 CST 2019
 9 
10         long time=System.currentTimeMillis();// 1970.1.1 0点
11         //sop(time);
12 
13         //把一个long类型的时间的毫秒值转成Date类型
14         Date d=new Date(time);
15         //sop(d);
16 
17         //把Date类型的日期格式进行转换,转成成容易看的格式
18         //得到具备格式化功能的对象
19         DateFormat  df =DateFormat.getDateTimeInstance(DateFormat.FULL,DateFormat.SHORT);
20         //String format(Date date) 
21         String str = df.format(new Date());
22         //sop(str);
23 
24         //创建日期格式化对象,同时指定格式
25         SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");
26         String ss = sdf.format(new Date());
27         sop(ss);
28     }
29 
30     public static void sop(Object obj){
31         System.out.println(obj);
32     }
33 }

 

 1 1、将一个Date对象转成指定格式的时间字符串
 2 
 3 ```java
 4 Date date = new Date();
 5 // 1、实例化SimpleDateFormat对象
 6 //   但是,一般情况下,实例化的同时,会设置格式化的格式
 7 //   2019-10-14 10:58:45
 8 //   y:年    M:月        d:日     H:时(24)        h:时(12)        m:分        s:秒        S:毫秒
 9 //   年: yyyy长年分    yy短年份
10 //   月: MM    如果月份不到10,会往前补0         M
11 //   
12 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
13 // 2、将date进行格式化
14 String timeStr = sdf.format(date);
15 ```
16 
17 
18 
19 2、将指定格式的时间字符串转成Date对象
20 
21 ```java
22 String str = "2019-10-14 17:54:68";
23 
24 // 1、实例化一个SimpleDateFormat对象
25 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
26 
27 // 2、解析
28 try {
29     Date date = sdf.parse(str);
30     System.out.println(date);
31     
32 } catch (ParseException e) {
33     e.printStackTrace();
34 }
35 ```

 

   ·calendar

 1 import java.util.Calendar;
 2 class Demo3 {
 3     public static void main(String[] args) {
 4         Calendar cal=Calendar.getInstance();
 5         //sop(cal.toString());
 6 
 7         String[] months={"1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"};
 8         String[] weeks={"","星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
 9 
10         int nian = cal.get(Calendar.YEAR);
11         int yue = cal.get(Calendar.MONTH);
12         int ri = cal.get(Calendar.DAY_OF_MONTH);
13 
14         int week=cal.get(Calendar.DAY_OF_WEEK);
15 
16         sop(nian+"年"+months[yue]+ri+"日,"+weeks[week]);
17     }
18     public static void sop(Object obj){
19         System.out.println(obj);
20     }
21 }

 

   ·Math及Random

 1 import java.util.Random;
 2 class Demo4{
 3     public static void main(String[] args) {
 4         sop(Math.ceil(56.6));//返回大于这个数的最小整数,返回值是double类型
 5 
 6         sop(Math.floor(56.6));//返回小于这个数的最大整数,返回值是double类型
 7 
 8         sop(Math.pow(2,3));//计算2的3次方
 9 
10         sop(Math.sqrt(4));//开方
11 
12         sop(Math.abs(-5));//绝对值
13 
14         sop(Math.round(5.8));//四舍五入取整
15 
16         sop(Math.random());//生成大于等于0.0小于1.0的随机数,
17 
18         //生成1-10之间的随机数
19         /*
20         for(int i=1;i<=5;i++){
21             sop((int)(Math.ceil(Math.random()*10)));
22         }*/
23 
24         Random r = new Random();
25         for(int i=1;i<=5;i++){
26            sop(r.nextInt(10)+1);// >=1 <11
27         }
28     }
29     public static void sop(Object obj){
30         System.out.println(obj);
31     }
32 }

 

   ·正则表达式

  专门针对字符串的,为了简化操作

  正则表达式,最主要是用来做字符串的校验、匹配。校验一个字符串是否满足指定的规则。

1.正则表达式匹配的规则:依次比较字符串中的每一个字符,和正则表达式中定义的规则进行校验。

2.字符串的边界匹配

1 // ^: 匹配一个字符串的开头
2 // $: 匹配一个字符串的结尾
3 // 在java中matches,正则表达式会自动的添加一个^$
4 System.out.println("hello world".matches("^hello world$"));

3.一位字符的匹配

 1 // []: 匹配一位字符
 2 // [abc]: 这一位字符可以是a,也可以是b,也可以是c
 3 System.out.println("aello world".matches("[hwl]ello world"));
 4 // [^abc]: 这一位的字符可以是除了a、b、c之外的任意字符
 5 System.out.println("aello world".matches("[^hwl]ello world"));
 6 // [a-z]: 这一位的字符可以是[a,z]之间的任意字符
 7 System.out.println("Hello world".matches("[a-z]ello world"));
 8 // [^a-z]: 这一位的字符可以是除了 [a,z] 之外的任意字符
 9 System.out.println("Hello world".matches("[^a-z]ello world"));
10 // [a-zA-Z0-9]: 这一位的字符可以是任意的字母或数字
11 System.out.println("Hello world".matches("[a-zA-Z0-9]ello world"));
12 // [^a-z[klt]]: 这一位的字符不可以是a-z之间的任意字符,但是klt除外
13 System.out.println("lello world".matches("[^a-z[klt]]ello world"));
14 
15 // .: 表示通配符,可以匹配任意的一位字符
16 System.out.println("hello world".matches(".ello world"));
17 // 转义字符: \
18 System.out.println(".ello world".matches("\\.ello world"));
19 
20 
21 // \d: 匹配所有的数字 [0-9]
22 // \D: 匹配所有的非数字 [^0-9]
23 // \w: 匹配所有的单词字符 字母数字下划线
24 // \W: 匹配所有的非单词字符 非字母数字下划线
25 System.out.println("hello world".matches("\\Dello world"));

4.多位匹配

 1 // +: 前面的一位或者一组字符,连续出现了1次或多次。
 2 // ?: 前面的一位或者一组字符,连续出现了0次或1次。
 3 // *: 前面的一位或者一组字符,连续出现了0次、1次或多次。
 4 System.out.println("helo".matches("hell+o"));
 5 System.out.println("heo".matches("hel?o"));
 6 System.out.println("hello".matches("hel*o"));
 7 
 8 // {m}: 前面的一位或者一组字符,连续出现了m次。
 9 // {m,}: 前面的一位或者一组字符,连续出现了至少m次。
10 // {m,n}: 前面的一位或者一组字符,连续出现了至少m次,最多n次。
11 System.out.println("helllllllllo".matches("hel{2,10}o"))

5、或 |

一般是用在一个分组中,表示这个分组中的内容可以是几种情况之一。组成的几种情况,长度可以不一样。

1 System.out.println("fine, thank you, and you".matches("hello|hi|nihao|你好"));

 

 

 

 

 1 class Demo5{
 2     public static void main(String[] args) {
 3         //正则表达式:专门针对字符串的
 4 
 5         boolean b = checkQQ("7654320987aaa");
 6 
 7         String regex="[1-9]\\d{4,14}";//正则本身也是字符串    两个\表示一个\,代表转义的作用,\d表示第二个为数字,{4,14}表示数字字少有4,最多14个
 8         
 9         boolean boo = "928349sddtt493".matches(regex);
10 
11         sop(boo);
12         //sop(b);
13     }
14 
15     //验证QQ号的功能 :5-15,不能以0开头,全是数字 "923y98374908"
16     public static boolean checkQQ(String qq){
17           int length=qq.length();
18           if(length>=5 && length<=15){
19               if(!qq.startsWith("0")){
20                   try{
21                     long num= Long.parseLong(qq);//NumberFormatException
22                     return true;
23                   }catch(NumberFormatException e)
24                   {   
25                   }
26               }else
27                   sop("qq号以0开头了");
28           }else
29               sop("qq号长度不合法");
30           return false;
31     }
32     public static void sop(Object obj){
33         System.out.println(obj);
34     }
35 }
 1 class Demo6 
 2 {
 3     public static void main(String[] args) {
 4         String regex="bo?k";  // * 0次或多次,? 0次或1次    +  1次或多次
 5         boolean b = "bok".matches(regex);
 6         sop(b);
 7     }
 8     public static void sop(Object obj){
 9         System.out.println(obj);
10     }
11 }

   ·正则表达式针对字符串的常用操作:

正则:专门针对字符串的
匹配:  boolean matches(String regex)
切割:  String[] split(String regex)
替换:  String replaceAll(String regex,String str)
获取:1:根据要获取的内容定义正则表达式
          2:根据正则表达式得到Pattern对象
          3:使用Pattern对象得到Matcher对象
          4:使用Matcher对象的find()方法来查找,找到了返回true,否则返回false
          使用Matcher对象的group()方法获取找到的内容
 1 import java.util.regex.Pattern;
 2 import java.util.regex.Matcher;
 3 class Demo7 {
 4     public static void main(String[] args) {
 5         //piPei();
 6         //qieGe();
 7         // tiHuan();
 8         huoQu();
 9     }
10     public static void huoQu(){
11         //从字符串中获取四个字母构成的词儿
12         String str="zhu yi la, ming tian fang jia";
13         String regex="[a-z]{4}";
14 
15         //把正则表达式转换成Pattern类型的对象
16         Pattern pattern = Pattern.compile(regex);
17 
18         //使用Pattern类型的对象得到Matcher类型的对象,Matcher对象具备获取的功能
19         Matcher m = pattern.matcher(str);
20 
21         while(m.find()) //find()方法找到了返回true,没找到返回false
22         {
23            System.out.println(m.group()); // group()方法返回找到的符合正则表达式的内容
24         }    
25     }
26     public static void tiHuan(){
27         //String str="zhangsan*****lisi############wangwu&&&&&&&&zhaoliu";
28         //String regex="(.)\\1+";
29         //String ss = str.replaceAll(regex,"$1");//在正则表达式之外取某一组的值使用$
30 
31         //String str="owieuowe9827349287498324iwsjdhfkshd049586045860456wesdf765432109";
32         //String regex="\\d{8,}";
33         //String ss = str.replaceAll(regex,"****");
34 
35         String str="15699788866";
36         String regex="(\\d{3})\\d{4}(\\d{4})";
37         String ss = str.replaceAll(regex,"$1****$2");
38         System.out.println(ss);
39     }
40     public static void qieGe(){
41         //String str="zhangsan.lisi.wangwu.zhaoliu";
42         //String regex="\\.";//普通字符点儿
43 
44         //String str="zhangsan   lisi      wangwu         zhaoliu";
45         //String regex=" +";
46 
47         String str="zhangsan*****lisi############wangwu&&&&&&&&zhaoliu";
      //下面的(.)中,.是代表任意字符,()代表分组,\\1被转义为第二组要和第一组的数相同,+表示这个组至少还有一个或多个
48 String regex="(.)\\1+";//()用来分组,从左到右,依次是第一组,第二组 49 50 String[] arr = str.split(regex); 51 for(int i=0;i<arr.length;i++){ 52 System.out.print(arr[i]+" "); 53 } 54 } 55 public static void piPei(){ 56 //验证手机号是否合法 57 String regex="1[34578]\\d{9}"; 58 59 boolean b = "12838384381".matches(regex); 60 61 System.out.println(b); 62 } 63 }

 

   ·集合(包装类)

用于存储不同类型的对象,

集合和数组的区别:
  集合:可以存储不同类型的对象,随着存储的对象的增加,集合的容量也会随着增大
  数组:数组的长度是固定的,另外java提供的数组的功能有限

 

 

 1 class Cat{}
 2 class Person{}
 3 class BoSiMao extends Cat{}
 4 class Demo8 {
 5     public static void main(String[] args) {
 6          Object[] arr=new Object[10];
 7          arr[0]=new Cat();
 8          arr[1]=new Person();
 9          arr[2]=new Object();
10 
11          Cat[] mao = new Cat[5];
12          mao[0]=new BoSiMao();
13     }
14 }

   ·collection接口

  (不能操作下标,子接口list可以)

 1 /*
 2 Collection中定义的是整个集合体系最共性的功能
 3 
 4 添加:
 5    boolean add(Object o) 
 6    boolean addAll(Collection<? extends E> c)  
 7 删除:
 8    boolean remove(Object o)  
 9    boolean removeAll(Collection<?> c)
10    void clear()
11 判断:
12    boolean contains(Object o) 
13    boolean containsAll(Collection<?> c)
14    boolean isEmpty() //判断集合是否为空
15    boolean equals(Object o) 
16 获取:
17    Iterator<E> iterator() //获取集合中的对象
18    int size() //获取集合中对象的个数
19 集合变数组:
20    Object[] toArray()
21 */
22 import java.util.*;
23 class Demo9 {
24     public static void main(String[] args) {
25         Collection coll=new ArrayList();
26 
27         coll.add("java1");
28         coll.add("java2");
29         coll.add("java3");
30         coll.add(88);
31 
32         //sop(coll);
33 
34         Collection c = new ArrayList();
35         c.add("hadoop");
36         c.add("mysql");
37 
38         coll.addAll(c);//把别的集合中的数据加入到当前集合中
39         sop(coll);
40 
41         //删除集合中某个对象
42         coll.remove(88);
43         sop(coll);
44 
45         coll.removeAll(c);
46         sop(coll);
47 
48         //coll.clear();//清空集合,删除集合中所有对象
49         //sop(coll);
50 
51         boolean boo = coll.contains("java1");
52         //sop(boo);
53 
54         //coll.clear();
55         //sop(coll.isEmpty());//判断集合是否为空
56 
57         boo = coll.equals(c);
58         sop(boo);
59 
60         sop(coll.size());//3
61 
62          //Object[] toArray()
63 
64          Object[] arr = coll.toArray();
65          for(int i=0;i<arr.length;i++)
66              sop(arr[i]);
67     }
68 
69     public static void sop(Object obj){
70         System.out.println(obj);
71     }
72 }

 

 day13

    ·迭代器

因为集合中存储的是多个数据,需要一个一个的取到每个数据,这就叫集合的遍历
//Iterator<>  iterator()    //该方法返回一个Iterator接口的子类对象

 

 

 

 1 package com.zqf;
 2 
 3 import java.util.*;
 4 class  Demo1{
 5     public static void main(String[] args) {   
 6         //因为集合中存储的是多个数据,需要一个一个的取到每个数据,这就叫集合的遍历
 7 
 8         // Iterator<E> iterator() //该方法返回一个Iterator接口的子类对象(也是ArrayList的内部类对象),该对象可以实现对集合的遍历
 9         ArrayList coll =new ArrayList();
10 
11         coll.add("java");
12         coll.add("hadoop");
13         coll.add("mysql");
14 
15         Iterator ite = coll.iterator();//拿到了内部类对象
16 
17         while(ite.hasNext()){
18             Object obj =  ite.next();
19             String str = (String)obj;
20             sop(str.toUpperCase());
21         }
22     }
23     public static void sop(Object obj){
24        System.out.println(obj);
25     }
26 }

 

   ·list接口   ArrayList类

  (需要掌握)

 1 /*
 2 Collection中定义的是整个集合体系最共性的功能
 3     ---List(子接口):存储的数据是有序的(集合中数据的顺序和添加数据的顺序是一致的),存储的数据是可以重复的
 4         
 5 List接口特有的功能都是可以操作下标的功能
 6 
 7 增:
 8     void add(int index, E element) 
 9     boolean addAll(int index, Collection<? extends E> c) 
10 
11 12    E remove(int index) 
13 
14 15    E set(int index, E element)
16 
17 18      ListIterator<E> listIterator() 
19      返回此列表元素的列表迭代器(按适当顺序)。 
20      ListIterator<E> listIterator(int index) 
21 
22      List<E> subList(int fromIndex, int toIndex) 
23      E get(int index) 
24 */
25 import java.util.*;
26 class Demo2 {
27     public static void main(String[] args) {
28         List coll =new ArrayList();
29 
30         coll.add("java");
31         coll.add("hadoop");
32         coll.add("mysql");
33 
34         coll.add(1,"h5");
35         //sop(coll);
36 
37         //coll.remove(1);
38         //sop(coll);
39 
40         coll.set(1,"python");
41         //sop(coll);
42 
43         //List<E> subList(int fromIndex, int toIndex)  截取子集合
44         List list = coll.subList(1,3);
45         //sop(list);
46 
47         //Object obj = coll.get(1);
48         //sop(obj);
49       /*
50         Iterator ite = coll.iterator();
51         while(ite.hasNext()){
52            Object obj = ite.next();
53            sop(obj);
54         }
55 
56         for(Iterator it=coll.iterator();it.hasNext();){
57             Object o=it.next();
58             sop(o);
59         }
60 
61         for(int i=0;i<coll.size();i++){
62            sop(coll.get(i));
63         }*/
64 
65         while(!coll.isEmpty()){
66             sop(coll.remove(0));//remove会返回被删除的对象
67         }
68 
69         sop(coll.size());
70     }
71 
72     public static void sop(Object obj){
73        System.out.println(obj);
74     }
75 }

 

   ·list接口     Vector类

  (了解即可)

 1 /*
 2 Collection中定义的是整个集合体系最共性的功能
 3     ---List(子接口):存储的数据是有序的(集合中数据的顺序和添加数据的顺序是一致的),存储的数据是可以重复的
 4             ArrayList:底层使用的数据结构是数组,线程不安全的,查找数据的速度快(内存是连续的),增删速度慢
 5             Vector:底层使用的数据结构是数组,线程安全的,查找数据的速度快,增删速度慢
 6 */
 7 import java.util.*;
 8 class Demo3 {
 9     public static void main(String[] args) {
10         Vector v = new Vector();
11         v.add("java01");
12         v.add("java02");
13         v.add("java03");
14 
15         Enumeration en = v.elements();
16         while(en.hasMoreElements()){
17             Object obj=en.nextElement();
18             sop(obj);
19         }
20     }
21     public static void sop(Object obj){
22        System.out.println(obj);
23     }
24 }

   ·List接口   LinkedList类

  (了解即可)

 1 /*
 2 Collection中定义的是整个集合体系最共性的功能
 3     ---List(子接口):存储的数据是有序的(集合中数据的顺序和添加数据的顺序是一致的),存储的数据是可以重复的    
 4             ArrayList:底层使用的数据结构是数组,线程不安全的,查找数据的速度快(内存是连续的),增删速度慢
 5             Vector:底层使用的数据结构是数组,线程安全的,查找数据的速度快,增删速度慢
 6             LinkedList:底层使用的数据结构是链表,线程不安全的,查找数据的速度慢,增删速度快
 7 
 8 LinkedList特有的功能:
 9 
10 void addFirst(E e) 
11 void addLast(E e) 
12 
13 getFirst() 
14 getLast() 
15 
16 removeFirst() 
17 removeLast() 
18 
19 jdk1.6才出现以下方法(暂不掌握)
20 
21 offerFirst()  
22 offerLast()
23 
24 peekFirst()
25 peekLast()
26 
27 pollFirst()
28 pollLast()
29 */
30 import java.util.*;
31 class Demo4 {
32     public static void main(String[] args) {
33         LinkedList list=new LinkedList(); 
34 
35         list.addFirst("java1");
36         list.addFirst("java2");
37         list.addFirst("java3");
38 
39         //sop(list);
40         while(!list.isEmpty()) {
41            sop(list.removeFirst());//先进后出
42         }
43         //list.getFirst();//集合中没有则异常
44         list.peekFirst();//集合中没有不会异常
45 
46         //list.removeFirst();//NoSuchElementException
47         list.pollFirst();//集合中没有不会异常
48     }
49     public static void sop(Object obj){
50        System.out.println(obj);
51     }
52 }

 

 1 import java.util.*;
 2 
 3 //使用LinkedList实现队列,使队列面向对象
 4 //自定义一个队列(先进先出)
 5 class Queues{
 6      private LinkedList link;
 7 
 8      Queues(){
 9          link=new LinkedList();
10      }
11      //入队
12      public void enQueue(Object obj){
13          link.addLast(obj);
14      }
15      //出队
16      public Object deQueue(){
17         return link.removeFirst();
18      }
19      //队列是否为空
20      public boolean isNull(){
21         return link.isEmpty();
22      }    
23 }
24 class Demo5 {
25     public static void main(String[] args) {
26         Queues duilie = new Queues();
27 
28         duilie.enQueue("hehe");
29         duilie.enQueue("haha");
30         duilie.enQueue("xixi");
31         
32         while(!duilie.isNull()){
33             sop(duilie.deQueue());
34         }
35     }
36     public static void sop(Object obj){
37        System.out.println(obj);
38     }
39 }

   ·小练习

 1 import java.util.*;
 2 class Demo6 {
 3     public static void main(String[] args) {
 4         ArrayList list =new ArrayList();
 5 
 6         list.add("java01");
 7         list.add("java02");
 8         list.add("java03");
 9         list.add("java01");
10        
11         ArrayList lists=quChong(list);
12 
13         System.out.println(lists);
14     }
15     //去除集合中的重复数据 :参数:集合,返回:集合
16     public static ArrayList quChong(ArrayList list){ 
17         ArrayList list2=new ArrayList();
18         for(int i=0;i<list.size();i++){
19             Object obj = list.get(i);
20             if(!list2.contains(obj))
21                 list2.add(obj);
22         }
23         return list2;
24     }
25 }

 

 1 abstract class Drink{
 2     abstract void taste();
 3     public void getDrink(int drinkType){
 4         switch(drinkType){
 5             case 1:System.out.println("咖啡");
 6             case 2:System.out.println("牛奶");
 7             case 3:System.out.println("啤酒");
 8        }
 9         return ;
10     }
11 }
12 abstract class Coffee extends Drink{
13     private int drinkType;
14     void taste(int drinkType){
15         this.drinkType=drinkType;
16     }
17     void taste(){
18         System.out.println("咖啡的味道:香味浓郁,有持久水果味。 ");
19     }
20     }
21     abstract class Milk extends Drink{
22         private int drinkType;
23 
24         void taste(int drinkType){
25             this.drinkType=drinkType;
26     }
27     void taste(){
28         System.out.println("牛奶的味道:淡而醇");
29     }
30 }
31 abstract class Beer extends Drink{
32     private int drinkType;
33 
34     void taste(int drinkType){
35        this.drinkType=drinkType;
36     }
37     void taste(){
38         System.out.println("啤酒的味道:苦而辣");
39     }
40 }
41 public class Test{
42     public static void main(String[]args){
43         Coffee c1=new Coffee(){};
44         Milk m1=new Milk() {};
45         Beer b1=new Beer() {};
46         c1.taste(1);
47         c1.taste();
48         m1.taste(2);
49         m1.taste();
50         b1.taste(3);
51         b1.taste();
52     }
53 }

 

 day14

Collection
   List:有序,可以重复( 可以存储相同的对象)
      ArrayList:数组,内存连续,查找速度快
      LinkedList:链表,内存不连续,查找慢,增删快
         contains方法是依据equals方法,当有特殊需求时,需要重写equals方法
   Set:无序,不可以重复( 不可以存储相同的对象)
      HashSet:无序,不可以重复,底层是哈希表 ,线程不安全,保证不重复:int hashCode()(哈希算法)    boolean equals(Object obj)
             
      TreeSet:排序,无序,不可以重复 ,底层是二叉树,线程不安全 ,在使用add方法添加对象时,就调用compareTo方法进行了比较大小 
       Comparable:默认TreeSet调用加入到集合的对象的compareTo方法来确定谁大谁小,所以通常只要对象所属的类实现了
     Comparable接口的compareTo方法,就可以排序,compareTo返回值为0认为是同一个对象,不加入集合

       Comparator:如果对象所属的类实现了 Comparable接口的compareTo方法,但是比较方式不是我们需要的,那么需要自定义
     比较方式,自定义的比较方式需要实现Comparator接口的int compare方法,compare返回值为0认为是同一个对象,不加入集合
 

   ·contains的具体实现

 1 /*
 2   Collection中定义的是整个集合体系最共性的功能    Iterator hasNext()  next()
 3 
 4     ---List(子接口):存储的数据是有序的(集合中数据的顺序和添加数据的顺序是一致的),存储的数据是可以重复的
 5             
 6             ArrayList:底层使用的数据结构是数组,线程不安全的,查找数据的速度快(内存是连续的),增删速度慢
 7                  
 8             Vector:底层使用的数据结构是数组,线程安全的,查找数据的速度快,增删速度慢
 9                    Enumeration   hasMoreElements()   nextElement()
10 
11             LinkedList:底层使用的数据结构是链表,线程不安全的,查找数据的速度慢,增删速度快
12 */
13 import java.util.*;
14 class Student{
15     private String name;
16     private int  age;
17 
18     Student(){}
19 
20     Student(String name,int age){
21        this.name=name;
22        this.age = age;
23     }
24 
25     public boolean equals(Object obj){
26         if(!(obj instanceof Student))
27             throw new RuntimeException("类型不对");
28 
29         Student stu=(Student)obj;
30 
31         System.out.println(this.name+"对比:"+stu.name);
32         return this.name.equals(stu.name)&&this.age==stu.age;
33     }
34 
35     public String toString(){
36       return name+","+age;
37     }
38 }
39 class  Demo1{
40     public static void main(String[] args) {
41         //需求:姓名年龄相同的认为是同一个人,对集合去重
42         ArrayList list =new ArrayList();
43 
44         list.add(new Student("lisi",12));
45         list.add(new Student("wangwu",27));
46         list.add(new Student("zhaoliu",19));
47         list.add(new Student("lisi",12));
48 
49         ArrayList jihe = quChong(list);
50         sop(jihe);    
51     }
52     public static ArrayList quChong(ArrayList list){ 
53         ArrayList list2=new ArrayList();
54         for(int i=0;i<list.size();i++){                                                        
55             Object obj = list.get(i);                          
56             if(!list2.contains(obj))//判断是不是包含某个对象,内部依据的是equals方法
57                 list2.add(obj);
58         }
59         return list2;
60     }
61     public static void sop(Object obj){
62        System.out.println(obj);
63     }
64 }

   

   ·Set接口   HashSet类

 1 /*
 2    ----Set:没有特有的功能
 3 
 4            存储的数据是无序的(集合中数据的顺序和添加数据的顺序不一致),存储的数据是不可以重复的
 5         
 6        HashSet:如何保证对象不重复的:依据的是int hashCode()方法(哈希值)和 boolean equals(Object obj)方法
 7                 (底层使用的数据结构是哈希表,线程是不安全的)
 8                向集合中添加对象时,先用要添加的对象的哈希值和集合中已有的对象的哈希值分别比较,当哈希值都不相同
 9                时,对象直接加入集合,当出现了哈希值相同的对象时,再调用equals方法对两个对两个对象比较,equals方法
10                返回true,怎认为是同一个对象,不加入集合,否则认为是不同的对象,加入集合
11 
12                注意:哈希值相同的不一定是同一个对象,同一个对象哈希值一定相同
13                     考虑不可重复时,使用HashSet
14        
15 */
16 import java.util.*;
17 class Person{
18     public int hashCode(){
19        return 88;
20     }
21     public boolean equals(Object obj){
22       return true;
23     }
24 }
25 class Demo2 {
26     public static void main(String[] args) {
27         HashSet hs = new HashSet();
28 
29         hs.add(new Person());
30         hs.add(new Person());// 88  new Person().equals(new Person()); false
31         hs.add(new Person());//88
32         
33         sop(hs);
34         /*
35        //在使用add方法添加对象时就保证了对象的唯一
36        hs.add(66);  66.hashCode()
37        hs.add(77);
38        hs.add(99);
39        hs.add(66);*/
40 
41        sop(hs);   
42     }
43     public static void sop(Object obj){
44        System.out.println(obj);
45     }
46 }

   HashSet的运用

 1 import java.util.*;
 2 class Student{
 3     private String name;
 4     private int  age;
 5 
 6     Student(){}
 7 
 8     Student(String name,int age){
 9        this.name=name;
10        this.age = age;
11     }
12 
13     public int hashCode(){
14        return name.hashCode()+age*66;
15     }
16 
17     public boolean equals(Object obj){
18          if(!(obj instanceof Student))
19              throw new RuntimeException("类型错误");
20 
21          Student stu = (Student)obj;
22          return this.name.equals(stu.name)&&this.age==stu.age;
23     }
24 
25     public String toString(){
26       return name+","+age;
27     }
28 }
29 class Demo3 {
30     public static void main(String[] args) {  
31         HashSet hs = new HashSet();
32          //需求:姓名年龄相同的认为是同一个对象,不能被加入集合
33 
34         hs.add(new Student("lisi",19));
35         hs.add(new Student("zhaoliu",29));//不同的对象哈希值肯定不同(前提:没有重写hashCode方法)
36         hs.add(new Student("wangwu",17));
37         hs.add(new Student("lisi",19));
38 
39         sop(hs);
40 
41         boolean boo=hs.contains(new Student("lisi",19)); //也是依据 hashCode() 方法和equals方法
42         sop(boo);//true
43 
44         hs.remove(new Student("lisi",19));//也是依据 hashCode() 方法和equals方法
45         sop(hs.size());
46     }
47     public static void sop(Object obj){
48        System.out.println(obj);
49     }
50 }

 

   ·Set接口   TreeSet类

 1 /* 
 2        TreeSet: 具备Set的基本特征,还可以进行排序
 3 
 4                 TreeSet排序是调用添加到集合中的对象的compareTo()方法确定下来谁大谁小
 5                 才能排序的,所以如果添加到集合中的对象所属的类没有实现compareTo方法,TreeSet是不能排序的
 6 
 7                 底层数据结构使用的是二叉树(红黑树):
 8 */
 9 import java.util.*;
10 class Person implements Comparable  //只要是实现了Comparable接口的就是可以排序的
11 {
12     public int compareTo(Object obj){
13          return 9;
14     }
15 }
16 class Demo4{
17     public static void main(String[] args) {
18         TreeSet ts = new TreeSet();
19 
20         ts.add(new Person());//
21         ts.add(new Person());// new Person().compareTo(new Person())
22         ts.add(new Person());//new Person().compareTo(new Person())  new Person().compareTo(new Person())
23 
24         sop(ts);
25 
26         /*
27         //在使用add方法添加时就比较大小了  因为String类实现了Comparable接口中的compareTo方法,所以TreeSet可以对字符串进行排序
28         ts.add("hello");
29         ts.add("aaabbbccc");
30         ts.add("dell");
31         ts.add("hello");  //"hello".compareTo("hello")==0  compareTo方法的返回值为0,认为是同一个对象,不加入集合
32 
33         sop(ts);
34         */
35     }
36     public static void sop(Object obj){
37        System.out.println(obj);
38     }
39 }

   ·comparable接口与compareTo()

   Comparable: 默认是TreeSet调用加入到集合的对象的cmopareto方法来确定谁大谁小, 所以通常只要对象所属的类实现了comparable接口的compareTo方法,就可以排序

 


 1 package com.zqf;
 2 import java.util.*;
 3 public class Test{
 4     public static void main(String[] args) {
 5         Set<Person> set=new TreeSet<Person>();
 6         set.add(new Person("zhangsan",12));
 7         set.add(new Person("lisi",14));
 8         set.add(new Person("wanger",13));
 9         System.out.println(set);
10     }
11 }
12 class Person implements Comparable<Person>{
13     private String name;
14     private int age;
15     public String getName() {
16         return name;
17     }
18     public void setName(String name) {
19         this.name = name;
20     }
21     public int getAge() {
22         return age;
23     }
24     public void setAge(int age) {
25         this.age = age;
26     }
27     public Person(String name, int age) {
28         super();
29         this.name = name;
30         this.age = age;
31     }
32     public Person() {
33         super();
34     }
35     @Override
36     public String toString() {
37         return "Person [name=" + name + ", age=" + age + "]";
38     }
39     @Override
40     public int compareTo(Person p) {
41         //按照年龄
42 /*        if(this.age>=p.age) {
43             return 1;
44         }else {
45             return -1;
46         }
47 */        
48         //按照姓名
49         int compareTo = this.name.compareTo(p.name);
50         return compareTo;
51     }
52 }

 


   ·HashSet和TreeSet的应用

 1 import java.util.*;
 2 class Demo6 {
 3     public static void main(String[] args) {
 4         //随机生成5个互不相同的1--10之间的随机数  Set,HashSet
 5         Random r = new Random();
 6         HashSet hs =new HashSet();
 7 
 8         while(hs.size()<5){
 9            int num = r.nextInt(10)+1;
10            hs.add(num);
11         }
12         System.out.println(hs);
13     }
14 }
 1 import java.util.*;
 2 class Demo7 {
 3     public static void main(String[] args) {
 4         String str="12,4,56,123,67";//对字符串中的数值进行排序
 5         String[] arr=str.split(",");
 6         TreeSet ts = new TreeSet();
 7         for(int i=0;i<arr.length;i++){
 8             //ts.add(arr[i);            //    不能用这个,这个使用的是字符串中的compareTo,是字典顺序    
 9            ts.add(Integer.parseInt(arr[i]));
10         }
11         System.out.println(ts);
12     }
13 }

   ·Comparator接口   compareTo()方法

 1  /*
 2  TreeSet: 具备Set的基本特征,还可以进行排序
 3 
 4                 TreeSet排序是调用添加到集合中的对象的compareTo()方法确定下来谁大谁小
 5                 才能排序的,所以如果添加到集合中的对象所属的类没有实现compareTo方法,TreeSet是不能排序
 7                 底层数据结构使用的是二叉树(红黑树)
10                 排序的第二种方式:Comparator  int compare(Object obj1,Object obj2)
11 
12                 当类本身具备的排序方式不能满足我们的需求时,那么使用自定义比较方法
 1 package com.zqf;
 2 import java.util.*;
 3 public class Test{
 4     public static void main(String[] args) {
 5         //Set<Person> set=new TreeSet<Person>((l1,l2) -> l1.getName().compareTo(l2.getName()));  //按姓名排序
 6         Set<Person> set=new TreeSet<Person>((l1,l2) -> l1.getAge()-l2.getAge());           //按年龄排序
 7         
 8         set.add(new Person("zhangsan",12));
 9         set.add(new Person("lisi",14));
10         set.add(new Person("wanger",13));
11         System.out.println(set);
12     }
13 }
14 class Person {
15     private String name;
16     private int age;
17     public String getName() {
18         return name;
19     }
20     public void setName(String name) {
21         this.name = name;
22     }
23     public int getAge() {
24         return age;
25     }
26     public void setAge(int age) {
27         this.age = age;
28     }
29     public Person(String name, int age) {
30         super();
31         this.name = name;
32         this.age = age;
33     }
34     public Person() {
35         super();
36     }
37     @Override
38     public String toString() {
39         return "Person [name=" + name + ", age=" + age + "]";
40     }
41     
42     
43 }

 

 
 

 

  ·泛型

  通过<引用数据类型>指定集合中存储的对象的类型,在程序编译时就会检查集合中存储的数据是不是泛型指定的类型
      如果不是,那么编译不通过,从而把运行时期的问题转移到了编译时期,是程序更安全,提高了程序的安全性

 1 import java.util.*;
 2 class Demo10 {
 3     public static void main(String[] args) 
 4     {   //使用了泛型,只要编译通过,运行就不会出问题
 5         //ArrayList<E>
 6         ArrayList<String> list=new ArrayList<>();//通过泛型限定集合中存储数据的类型,使程序更安全
 7 
 8         list.add("66");
 9         list.add("77");
10         list.add("44");
11         //list.add(55);
12 
13         Iterator<String> ite = list.iterator();
14         while(ite.hasNext()){
15             //Object obj = ite.next();
16             //String str=(String)obj;
17             String str = ite.next();
18             System.out.println(Integer.parseInt(str));
19         }
20     }
21 }

 day15

   ·泛型

在类上定义泛型
   class Demo<T>
   {
   }
   Demo<String > demo=new Demo<String>(); //在创建类的对象时才能确定泛型,泛型属于非静态类型
在方法上定义泛型
   class Test<E>{
    public void ff(E e){
    }
    public <E> void show(E e){
    }
    public static <T> void fun(T t){  //静态方法只能自己用泛型
    }
   }

在接口上定义泛型
   interface inter<E>{
    void ff(E e);
   }

   ·泛型中的通配符:?

 1 //通配符:  ?
 2 import java.util.*;
 3 class Demo3 {
 4     public static void main(String[] args) {
 5         ArrayList<String> list1=new ArrayList<>();
 6         list1.add("java");
 7         list1.add("mysql");
 8         list1.add("hadopp");
 9 
10         //bianLi(list1);
11         dieDai(list1);
12 
13         ArrayList<Integer> list2=new ArrayList<>();
14         list2.add(77);
15         list2.add(88);
16         list2.add(99);
17 
18         //bianLi(list2);
19         dieDai(list2);
20     }
21     //通配符: ?  表示什么类型都行
22     public static  void dieDai(Collection<?> coll){
23          Iterator<?> ite=coll.iterator();
24          while(ite.hasNext()){
25              //? obj=ite.next();非法的表达式开始
26              System.out.println(ite.next());
27          }
28     }
29 
30     //通用的遍历的方法:泛型方法
31     public static <E> void bianLi(Collection<E> coll){
32          Iterator<E> ite=coll.iterator();
33          while(ite.hasNext()){
34             E obj=ite.next();
35 
36             System.out.println(obj);
37          }
38     }
39 }

 

   ·泛型限定

泛型限定:  ? extends E:限定了上限(E类型或其子类类型)  ? super E:限定了下限,E类型或其父类类型

 1 //泛型限定:  ? extends E:限定了上限(E类型或其子类类型)  ? super E:限定了下限,E类型或其父类类型
 2 import java.util.*;
 3 class Person implements Comparable<Person>{
 4     private String name;
 5     private int  age;
 6 
 7     Person(){}
 8 
 9     Person(String name,int age){
10       this.name=name;
11       this.age=age;
12     }
13     public int compareTo(Person ren){
14         return this.age-ren.age;
15     }
16     public String getName(){
17        return this.name;
18     }
19     public String toString(){
20       return name+","+age;
21     }
22 }
23 class ComByName implements Comparator<Person>{
24     public int compare(Person p1,Person p2){
25         return p1.getName().compareTo(p2.getName());
26     }
27 }
28 class Student extends Person{
29      Student(){}
30      Student(String name,int age){
31        super(name,age);
32      }
33 }
34 class Worker extends Person{
35     Worker(){}
36     Worker(String name,int age){
37        super(name,age);
38     }
39 }
40 class Demo4 {
41     public static void main(String[] args) {
42         ArrayList<Student>  list=new ArrayList<>();
43 
44         list.add(new Student("lisi",20));
45         list.add(new Student("wangwu",18));
46         list.add(new Student("amen",28));
47 
48         dieDai(list);
49 
50         ArrayList<Worker>  list2=new ArrayList<>();
51 
52         list2.add(new Worker("zhangsi",29));
53         list2.add(new Worker("zhaoliu",38));
54         list2.add(new Worker("liming",18));
55 
56         dieDai(list2);
57 
58         ArrayList<Integer>  list3=new ArrayList<>();
59         list3.add(66);
60         list3.add(666);
61         list3.add(6666);
62         
63         //dieDai(list3);
64     }
65     public static  void dieDai(Collection<? extends Person> coll)//集合中对象的类型必须是Person或Person的子类类型
66     {
67          Iterator<?> ite=coll.iterator();
68          while(ite.hasNext()){
69              System.out.println(ite.next());
70          }
71     }
72 }

 

   ·Map接口   HashMap类

Map<k,v>接口
   是一个单独的接口,属于集合,但没有继承Collection,存储的是简直对,一对一对的存,键不能重复,值可以重复
   (当存在映射关系的情况下,使用Map)

Map<String,String> m = new HashMap<>();
m.put("name","lisi");
m.remove("name")
m.get("name");
m.size()
m.isEmpty()
m.containsKey("name")
m.containsValue("lisi")
Collection<String> v = m.values()
HashMap:保证键唯一,原理和HashSet一样 
TreeMap:根据键排序,原理和TreeSet一样

 1 /*
 2 Map<K,V>:是一个单独的接口,属于集合,但没有继承Collection,存储的是键值对儿,一对一对的存,键不能重复
 3 
 4     HashMap:
 5 
 6     TreeMap:
 7 
 8 Map接口中定义的功能:
 9 
10 添加:
11  V put(K key, V value) 
12  void putAll(Map<? extends K,? extends V> m)  //addAll()
13  
14 删除:
15  V remove(Object key) 
16  void clear() 
17          
18 获取:
19   V get(Object key) 
20 
21   Set<K> keySet() 
22   Set<Map.Entry<K,V>> entrySet() 
23 
24   int size() 
25   Collection<V> values() 
26 判断:
27    boolean isEmpty() 
28    boolean containsKey(Object key) 
29    boolean containsValue(Object value)
30 */
31 import java.util.*;
32 class Demo6{
33     public static void main(String[] args) {
34         Map<String,String>  map = new HashMap<>();
35         /*
36         //String v=map.put("aa","lisi");//返回的是被覆盖的键值对的值
37         //sop(v);//null
38 
39         String vv=map.put("aa","zhangsan");//把上一个同名的键值对覆盖掉
40         //sop(vv);//lisi
41 
42         */
43         //键不能重复
44         map.put("name","zhangsan");
45         map.put("age","20");
46         map.put("address","上海");
47 
48         //map.remove("address");//根据键删除键值对
49         //map.clear();
50 
51         //sop(map.size());//得到集合中键值对儿的对儿数
52         //sop(map.isEmpty());
53 
54         // Collection<V> values()  得到集合中所有的值
55         Collection<String>  vs = map.values();
56 
57         Iterator<String> ite=vs.iterator();
58         while(ite.hasNext()){
59           sop(ite.next());
60         }
61         // V get(Object key) 根据键获取值
62         String zhi = map.get("age");
63         sop(zhi);
64 
65         //boolean containsKey(Object key) 判断集合是否包含某个键
66          boolean b = map.containsKey("names");
67          sop(b);
68 
69         //boolean containsValue(Object value)判断集合是否包含某个值
70          b=map.containsValue("上海");
71          sop(b);
72     }
73     public static <E> void sop(E obj){
74         System.out.println(obj);
75     }
76 }

 

   ·Map接口   两种遍历方法

 1 /*
 2 Set<K> keySet() :   取到所有的键存到一个Set集合,并返回该集合对象,因为Set有迭代器,所以得到迭代器,每次迭代出来的是一个键
 3                     根据键获取值
 4 
 5 
 6 Set<Map.Entry<K,V>> entrySet() : 得到每个键值对儿对应一个Map.Entry(映射关系)类型的值,存到一个Set集合中,Set有迭代器
 7                                  没次迭代出来的是一个Map.Entry(映射关系)类型的值,这个值中既包括键,也包括值
 8                                  Entry是定义在Map内部的静态成员,Entry是对Map集合内部的键值对的映射关系的描述,所以定义在Map
 9                                  的内部
10 
11 */
12 import java.util.*;
13 class Demo7{
14     public static void main(String[] args) {
15         //Map没有迭代器
16         //Map 实现遍历的方法: Set<K> keySet()   Set<Map.Entry<K,V>> entrySet() 
17 
18         Map<String,String> map = new HashMap<>();
19 
20         map.put("name","zhangsan");
21         map.put("age","20");
22         map.put("address","上海");
23 
24        Set<Map.Entry<String,String>> en= map.entrySet();
25 
26        Iterator<Map.Entry<String,String>> ite=en.iterator();
27        while(ite.hasNext()){
28             Map.Entry<String,String> e=ite.next();
29             String jian=e.getKey();
30             String zhi=e.getValue();
31 
32             System.out.println(jian+"="+zhi);
33         } 
34        /*
35         Set<String> keys=map.keySet();
36         Iterator<String> ite=keys.iterator();
37 
38         while(ite.hasNext()){
39             String key=ite.next();
40             String value=map.get(key);
41             System.out.println(key+"="+value);
42         }
43        */        
44     }
45 }

   ·HashMap详解

底层使用数据结构是哈希表,HashSet:保证对象不重复
保证键不重复:int hashCode()    boolean equals(Object obj)

 1  import java.util.*;
 2  class Student implements Comparable<Student>{
 3      private String name;
 4      private int age;
 5      Student(){}
 6      Student(String name,int age){
 7        this.name=name;
 8        this.age=age;
 9      }
10      public int compareTo(Student stu){
11          int num=this.age-stu.age;
12          return num==0?this.name.compareTo(stu.name):num;
13      }
14      
15      public int hashCode(){
16          return name.hashCode()+age*56;
17      }
18      public boolean equals(Object obj){
19         if(!(obj instanceof Student))
20             throw new ClassCastException("类型错误");
21 
22         Student stu = (Student)obj;
23 
24         return this.name.equals(stu.name)&&this.age==stu.age;
25      }
26 
27      public String getName(){
28         return name;
29      }
30      public int getAge(){
31         return age;
32      }
33      public String toString(){
34        return name+","+age;
35      } 
36  }
37 class Demo8 {
38     public static void main(String[] args) {
39         //什么情况下使用Map:当存在映射关系的时候,每个学生有一个住址
40 
41         //底层数据结构是哈希表,HashSet:保证对象不重复
42         //保证键唯一:int hashCode()  boolean equals(Object obj) 
43         HashMap<Student,String> map = new HashMap<>();
44 
45         //姓名,年龄相同认为是同一个对象
46         map.put(new Student("zhangsan",28),"北京");
47         map.put(new Student("wangwu",18),"上海");
48         map.put(new Student("lisi",38),"深圳");
49         map.put(new Student("lisi",38),"纽约");
50 
51         Set<Student> keys = map.keySet();
52         Iterator<Student> ite=keys.iterator();
53 
54         while(ite.hasNext()){
55             Student stu =ite.next();
56 
57             String address=map.get(stu);
58 
59             sop(stu+"="+address);
60         }
61     }
62     public static void sop(Object obj){
63       System.out.println(obj);
64     }
65 }

 

   ·Map接口   TreeMap类

TreeMap,按照键的顺序排序,方法与TreeSet相同

 1 import java.util.*;
 2 //自定义比较方式
 3 class ComByName implements Comparator<Student>{
 4     public int compare(Student stu1,Student stu2 ){
 5          int num = stu1.getName().compareTo(stu2.getName());
 6 
 7          return  num==0?stu1.getAge()-stu2.getAge():num;
 8     }
 9 }
10 class Demo9 {
11     public static void main(String[] args) {
12         //底层是二叉树    TreeSet:add
13         //根据键排序,无序
14         ComByName cn = new ComByName();
15         TreeMap<Student,String> map = new TreeMap<>(cn);
16         
17         //使用put添加键值对的时候就排序了
18         map.put(new Student("zhangsan",28),"北京");
19         map.put(new Student("wangwu",18),"上海");
20         map.put(new Student("lisi",38),"深圳");
21         map.put(new Student("lisi",38),"纽约");
22 
23 
24         Set<Map.Entry<Student,String>>  en = map.entrySet();
25         Iterator<Map.Entry<Student,String>> ite=en.iterator();
26 
27         while(ite.hasNext()){
28              Map.Entry<Student,String> e=ite.next();
29              Student key=e.getKey();
30              String value=e.getValue();
31 
32              sop(key+"="+value);
33         }
34     }
35     public static void sop(Object obj){
36       System.out.println(obj);
37     }
38 }

    ·Map的运用

import java.util.*;
class Demo10 {
    public static void main(String[] args) {
        //每个班级对应多个学生

        HashMap<String,List<Student>> school=new HashMap<>();

        List<Student> list1=new ArrayList<>();
        list1.add(new Student("lisi",20));
        list1.add(new Student("wangsi",28));
        list1.add(new Student("zhaosi",19));

        List<Student> list2=new ArrayList<>();
        list2.add(new Student("lisi2",22));
        list2.add(new Student("wangsi2",25));
        list2.add(new Student("zhaosi2",18));

        school.put("gp1905",list1);
        school.put("gp1904",list2);

        Set<String> keys = school.keySet();

        Iterator<String> ite=keys.iterator();
        while(ite.hasNext()){
             String banji = ite.next();
             sop("班级名称:"+banji);
             sop("班级人员有:");

             List<Student>  stus=school.get(banji);

             //sop(stus);
             
             Iterator<Student> it=stus.iterator();
             while(it.hasNext()){
                  Student ss=it.next();
                  sop(ss);
             }
        }
    }
    public static void sop(Object obj){
      System.out.println(obj);
    }
}

   ·数组转集合,数组转字符串

数组转字符串:Arrays.toString()
数组转集合:Arrays.asList()

 1 import java.util.*;
 2 class Demo12 {
 3     public static void main(String[] args) {
 4         
 5         //数组转字符串
 6         int[] arr={12,34,56,67,23,8};
 7         String str = Arrays.toString(arr);
 8         sop(str);
 9         
10         //static <T> List<T> asList(T... a)  
11 
12         //数组转集合:使用集合的方法
13         String[] arr2={"hello","java","mysql","hadoop"};
14         List<String> list = Arrays.asList(arr2);
15         //sop(list);
16         //数组转成的集合不能执行添加,删除,否则异常
17         //list.add("h5");//UnsupportedOperationException
18 
19         boolean b = list.contains("java");
20         sop(b);
21 
22         int[] c={3,4,5,6};
23         List<int[]> jihe = Arrays.asList(c); //集合中存的是引用类型的数据,数组是引用数据类型,所以把整个数组存到集合中
24         sop(jihe.get(0)[0]);//  1
25     }
26     public static void sop(Object obj){
27         System.out.println(obj);
28     }
29 }

   ·集合转数组

集合转数组:<T> T[] toArray(T[] t)

 1 import java.util.*;
 2 class Demo13 {
 3     public static void main(String[] args) {
 4         
 5         //集合转数组  <T> T[] toArray(T[] a)  
 6         List<String> list= new ArrayList<>();
 7 
 8         list.add("hello");
 9         list.add("java");
10         list.add("mysql");
11 
12         //给定的数组的长度大于集合中数据的个数,使用给定的
13         //给定的数组的长度小于集合中数据的个数,不使用给定的
14         //最好给定义一个长度和集合相同的数组
15         String[] arr = list.toArray(new String[list.size()]);
16         sop(arr.length);
17 
18         for(int i=0;i<arr.length;i++){
19            sop(arr[i]);
20         }
21     }
22     public static void sop(Object obj){
23         System.out.println(obj);
24     }
25 }

   ·增强for循环

 for(数据类型  变量名:被遍历的Collection集合或数组){}                

可用来遍历collection集合和数组

 1 /*
 2 增强的for循环
 3     for(数据类型  变量名:被遍历的Collection集合或数组){   }
 4 */
 5 import java.util.*;
 6 class Demo14 {
 7     public static void main(String[] args) {
 8         int[] arr={23,4,67,12,78};
 9 
10         for(int num:arr){
11             sop(num);
12         }
13 
14         List<String> list= new ArrayList<>();
15 
16         list.add("hello");
17         list.add("java");
18         list.add("mysql");
19 
20         for(String str:list){
21            sop(str.toUpperCase());
22         }
23 
24         Map<String,String> lm = new HashMap<>();
25         lm.put("name","lisi");
26         lm.put("age","20");
27         lm.put("weight","200");
28 
29         Set<String> keys = lm.keySet();
30         for(String key:keys){
31              String v = lm.get(key);
32              sop(key+"="+v);
33         }
34 
35         Set<Map.Entry<String,String>> en=lm.entrySet();
36         for(Map.Entry<String,String> me:en){
37            String key = me.getKey();
38            String value=me.getValue();
39 
40            sop(key+"="+value);
41         }        
42     }
43     public static void sop(Object obj){
44         System.out.println(obj);
45     }
46 }

 day16

   ·Collections集合工具类

 Collections集合工具类
 Collections.sort(list);   //排序
 Collections.reverseOrder()
 Collections.reverse()
 Collections.max()
 Collections.min()

 1 List<Integer> list = new ArrayList<>();
 2 List<Integer> dest = new ArrayList<>();
 3 
 4 // 1、向集合中添加元素
 5 Collections.addAll(list, 10, 20, 30, 10, 0, 9, 8, 11, 17, 21);
 6 Collections.addAll(dest, 0,0,0,0,0,0,0,0,0,00,0,0,0,0,0,0,0,0,0);
 7 
 8 // 2、找出一个集合中的最大值
 9 System.out.println(Collections.max(list));
10 
11 // 3、找出一个集合中的最小值
12 System.out.println(Collections.min(list));
13 
14 // 4、将集合中的元素进行随机排列
15 Collections.shuffle(list);
16 
17 // 5、排序
18 // 使用这个方法进行排序的时候,需要保证集合中的元素对应的类实现Comparable接口
19 Collections.sort(list);    
20 // 使用指定的排序规则,对集合中的数据进行排序
21 Collections.sort(list, (e1, e2) -> e2 - e1);
22 
23 // 6、元素拷贝
24 Collections.copy(dest, list);
25 
26 // 7、翻转
27 Collections.reverse(dest);
28 
29 // 8、交换两个下标的元素
30 Collections.swap(list, 0, 1);
31 
32 // 9、用指定的元素填充满集合
33 Collections.fill(dest, 1);
34 
35 // 10、将指定的集合转成线程安全的集合。
36 // Collection Collections.synchronizedCollection(list);
37 // List Collections.synchronizedList(list);
38 // Set Collections.synchronizedSet(s);
39 // Map Collections.synchronizedMap(m);
40 
41 System.out.println(dest);

 

   ·可变参数

  简化书写,原理是数组,注意:可变参数必须位于参数列表的最后。
   fun(1,2,3,53,65,3);
   fun(int ... a) 

 1 /*
 2 可变参数:简化书写,原理是数组,注意:可变参数必须位于参数列表的最后
 3 */
 4 class Demo2 {
 5     public static void main(String[] args) {
 6 
 7          //int[] b={12,34,45,23,5,67};
 8          int he = add(12,34,45,23,5,67,12,3);
 9          sop(he);
10     }
11 
12     public static int add(int ... arr){
13         int sum=0;
14         for(int i=0;i<arr.length;i++){
15            sum=sum+arr[i];
16         }
17         return sum;
18     }
19     public static void sop(Object obj){
20         System.out.println(obj);
21     }
22 }

   ·properties类

 Map的子类,属于集合,存储的键和值必须是String类型的,适合存储属性  (了解即可)
 得到所有的键:stringPropertyNames();
 存放键值对:   setProperty(String key,String value);
 根据键获取值:getProperty(String key);

 1 import java.util.*;
 2 class Demo3 {
 3     public static void main(String[] args) {
 4         //  Properties: 是一个Map集合类,存储的键和值必须是String类型的,适合存储属性
 5 
 6         //得到系统属性
 7         Properties pro =  System.getProperties();
 8         sop(pro);
 9 
10         //得到集合中所有的键  keySet()
11         /*
12         Set<String> keys= pro.stringPropertyNames();
13         for(String key:keys){
14             //根据键获取值
15             String value = pro.getProperty(key);
16             sop(key+"="+value);
17         }*/
18         pro.setProperty("user.country","china");//put
19 
20         Set<String> keys= pro.stringPropertyNames();
21         for(String key:keys){
22             //根据键获取值
23             String value = pro.getProperty(key);
24             sop(key+"="+value);
25         }
26     }
27 
28     public static void sop(Object obj){
29         System.out.println(obj);
30     }
31 }
 1 // 1、实例化一个Properties对象
 2 Properties properties = new Properties();
 3 
 4 // 2、加载某一个.properties文件,读取这个文件中的信息
 5 try {
 6     properties.load(new FileReader("file\\info.properties"));
 7 } catch (IOException e) {
 8     e.printStackTrace();
 9 }
10 
11 // 3、获取
12 String name = properties.getProperty("name");
13 System.out.println(name);
14 
15 String height = properties.getProperty("height", "111");
16 System.out.println(height);
17 
18 // 4、修改、添加
19 properties.setProperty("name", "xiaohei");
20 properties.setProperty("weight", "123");
21 
22 
23 // 5、对Properties进行操作,结束之后,一定要同步到文件中,否则这些数据只能存在于内存
24 try {
25     properties.store(new FileWriter("file\\info.properties"), "hello world");
26 } catch (IOException e) {
27     // TODO Auto-generated catch block
28     e.printStackTrace();
29 }
30 
31 // 6、遍历
32 properties.forEach((k, v) -> System.out.println(k + " : " + v));

 

 1 import java.io.FileInputStream;
 2 import java.io.FileOutputStream;
 3 import java.io.IOException;
 4 import java.util.Properties;
 5 
 6 public class Test1 {
 7     public static void main(String[] args) throws IOException {
 8         Properties pro = new Properties();
 9         FileInputStream fis = new FileInputStream("a.properties");
10         FileOutputStream fos  = new FileOutputStream("a.properties");
11 
12         pro.load(fis);
13 
14     pro.setProperty("name","lisi");
15 
16     pro.store(fos,"ok");
17 
18     fis.close();
19         fos.close();
20     }
21 }

 


   ·静态导入

  例:  import static java.util.Ararys.*;
             类名相同,通过包名区分
       方法名相同,通过类名区分

 1 import java.util.*;
 2 import static java.util.Arrays.*;//静态导入
 3 class Demo4 //toString(){
 4     public static void main(String[] args) {
 5         int[] arr={12,34,45,56,67,78};
 6         sort(arr);
 7         int index =binarySearch(arr,56);
 8         String str=java.util.Arrays.toString(arr);//方法名相同,类名不能省略,类名相同,通过包名区分
 9         System.out.println(str);
10     }
11 }
12 class Arrays {}

   ·IO流(Input ,Output)

输入输出流:用来实现设备之间的数据传输
 分类: 按照方向分类:输入流,输出流(相对于内存) 对内存是进数据就是输入流,出数据就是输出流保存文件是输出,打开是输入
        按照操作的数据分类:
       字节流:可以操作任何类型的数据,文本,图片,视频,音频
       字符流:只能操作文本数据,因为字符涉及到编码,在字节流的基础上加入了编码方便操作文本数据。
          ASCII  GBK   utf-8
字节流:
  InputStream 字节输入流父类
  OutputStream 字节输出流父类
字符流
  Reader   字符输入流父类
  Writer     字符输出流父类 
                  记住:Writer输出流可以对文本写入,Reader输入流对文本读出
输入设备:键盘,文件,网络,内存
输出设备:控制台,文件,网络,内存
以硬盘设备为例
 

   ·向文本写入数据

 (从内存中读取数据)

 1 import java.io.*;
 2 class Demo5 {
 3     public static void main(String[] args) throws IOException{
 4         //向文本文件写入数据
 5         //因为是文本文件所以使用字符流,又因为是写入所以使用字符输出流(Writer),又因为是文件(硬盘),
 6          //所以使用 Writer的可以操作文件的子类FileWriter
 7 
 8         //1:创建文件输出流对象和文件相关联  FileWriter(String fileName) 
 9         //文件可以事先不存在,系统会自动创建
10         FileWriter fw = new FileWriter("temp.txt");
11 
12         //2:使用输出流对象向与其关联的文件中写入数据
13         fw.write("abc");//写入到内部的数组了,因为需要查表
14         
15         //fw.flush();//把内部数组的数据刷到文件中
16 
17         fw.write("def");//刷完之后还可以继续写
18 
19         //释放资源:流对象
20         fw.close();//关闭流的同时会刷新流
21 
22         //fw.write("ww");//流已关闭,不能继续写入数据
23     }
24 }
 1 import java.io.*;
 2 class Demo6 {
 3     public static void main(String[] args) {
 4         FileWriter fw=null;
 5         try{
 6             fw = new FileWriter("temp.txt");//系统找不到指定的路径
 7             fw.write("abcdef"); 
 8         }catch(IOException e){
 9             e.printStackTrace();
10         }finally{
11            try{
12                if(fw!=null)    //这个意思是当文件存在时,可以关闭,否则会报空指针异常
13                    fw.close();//null.close();
14            }catch(IOException ee){
15                throw new RuntimeException("字符输出流关闭失败");
16            }    
17         }
18     }
19 }

   ·文件的续写

 1 import java.io.*;
 2 class Demo7 {
 3     public static void main(String[] args) throws IOException{
 4           String SEPARATOR=System.getProperty("line.separator");
 5 
 6           //文件的续写:默认都是从文件的末尾写入数据
 7           FileWriter fw= new FileWriter("temp.txt",true);
 8           fw.write("hello");
 9           fw.write(SEPARATOR);
10           fw.write("world");
11           fw.close();
12     }
13 }

   ·读取文本文件数据的两种方式

  使用字符时,num=fr.read();   num表示每一个字符的编码,当num到最后时,变成-1

  使用数组时,char[] arr=new char[1024] ; num=fr.read(arr),   num此时表示字符的个数,当到最后时,变成-1

  使用字符

 1 import java.io.*;
 2 class Demo8 {
 3     public static void main(String[] args) throws IOException{
 4         //从文本文件中读取数据  1.先确定是字符流还是字节流,2再确定用输入流还是输出流,3最后确定什么设备
 5 
 6         //因为是文本文件,所以使用字符流,又因为是读取所以使用输入流,因为是文件所以使用Reader的可以操作文件的子类FileReader
 7 
 8         //1:创建文件输入流对象和文件相关联
 9         //文件需要事先存在
10         FileReader fr =new FileReader("temp.txt");
11 
12         //2:使用输入流对象读取数据
13 
14         //int read()  读一个字符 效率低
15 
16         int num;
17         while((num=fr.read())!=-1){
18             System.out.print((char)num);
19         }
20         fr.close();
21     }
22 }

  使用数组

 1 import java.io.*;
 2 class Demo9 {
 3     public static void main(String[] args)throws IOException {
 4         FileReader fr =new FileReader("temp.txt");
 5 
 6         char[] arr=new char[1024];
 7         int num;
 8 
 9         while((num=fr.read(arr))!=-1){
10            System.out.print(new String(arr,0,num));
11         }
12 
13         fr.close();
14     }
15 }

   ·文本复制

 1 import java.io.*;
 2 class Demo10 {
 3     public static void main(String[] args) throws IOException {
 4         //实现复制一个文本文件,Demo3.java, 读取Demo3.java写入到一个新的文件
 5 
 6         FileReader fr=new FileReader("Demo3.java");
 7         FileWriter fw = new FileWriter("Demo3_copy.java");
 8         int num;
 9 
10         while((num=fr.read())!=-1){
11             fw.write(num);
12         }
13         
14         fr.close();
15         fw.close();
16     }
17 }
 1 import java.io.*;
 2 class Demo11{
 3     public static void main(String[] args) {
 4         FileReader fr = null;
 5         FileWriter fw = null;
 6         try{
 7              fr=new FileReader("Demo5.java");
 8              fw=new FileWriter("Demo5_copy.java");
 9 
10              char[] arr=new char[1024];
11              int num;
12              while((num=fr.read(arr))!=-1){
13                  fw.write(arr,0,num);
14              }    
15         }catch (IOException e){
16              e.printStackTrace();
17 
18         }finally{
19             if(fr!=null)
20                try{
21                   fr.close();
22                }
23                catch (IOException ee){
24                    throw new RuntimeException("字符读取流关闭失败");
25                }
26 
27            if(fw!=null)
28                try{
29                   fw.close();
30                }
31                catch (IOException ee){
32                    throw new RuntimeException("字符输出流关闭失败");
33                }
34         }
35     }
36 }

   ·文件夹的复制

 1 package com.zqf;
 2 
 3 /**
 4  * 
 5  * 复制文件夹d:/java下面所有文件和子文件夹内容到d:/java2。
 6     提示:涉及单个文件复制、目录的创建、递归的使用
 7  */
 8 import java.io.BufferedInputStream;
 9 import java.io.BufferedOutputStream;
10 import java.io.File;
11 import java.io.FileInputStream;
12 import java.io.FileNotFoundException;
13 import java.io.FileOutputStream;
14 import java.io.IOException;
15 import java.util.Scanner;
16 
17 public class Test{
18     public static void main(String[] args) {
19         Scanner scanner = new Scanner(System.in);
20         System.out.print("From:");
21         String sourcePath = scanner.nextLine();
22         System.out.print("To:");
23         String newPath = scanner.nextLine();
24         copyDir(sourcePath, newPath);
25     }
26     
27     //文件夹的拷贝
28     public static void copyDir(String sourcePath, String newPath) {
29         File start = new File(sourcePath);
30         File end = new File(newPath);
31         String[] filePath = start.list();       //获取该文件夹下的所有文件以及目录的名字
32         if(!end.exists()) {
33             end.mkdir();
34         }
35         for(String temp:filePath) {
36             //查看其数组中每一个是文件还是文件夹
37             if(new File(sourcePath+File.separator+temp).isDirectory()) {
38                 //为文件夹,进行递归
39                 copyDir(sourcePath+File.separator+temp, newPath+File.separator+temp);
40             }else {
41                 //为文件则进行拷贝
42                 copyFile(sourcePath+File.separator+temp, newPath+File.separator+temp);
43             }
44         }
45     }
46     
47     //文件的拷贝
48     public static void copyFile(String sourcePath, String newPath) {
49         File start = new File(sourcePath);
50         File end = new File(newPath);
51         try(BufferedInputStream bis=new BufferedInputStream(new FileInputStream(start));
52             BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(end))) {
53             int len = 0;
54             byte[] flush = new byte[1024];
55             while((len=bis.read(flush)) != -1) {
56                 bos.write(flush, 0, len);
57             }
58             bos.flush();
59         }catch(FileNotFoundException e) {
60             e.printStackTrace();
61         }catch(IOException e) {
62             e.printStackTrace();
63         }
64     }
65 }

 

 

 

day17

   ·字符缓冲流

字符缓冲流:只是用来提高读或写的效率
    缓冲流本身不具备读或写的功能
    使用缓冲流必须结合着读流或写流
纯粹来提高效率的
字符输入缓冲流:BufferedReader 就只有一个特殊的方法,String readLine();   读一行,返回的一行字符不包括换行符
字符输出缓冲流:BufferedWriter 就只有一个特殊的方法,void newLine()   换行

    ·字符缓冲流文本写入数据-BufferedWriter

 1 import java.io.*;
 2 class Demo1 {
 3     public static void main(String[] args)throws IOException{
 4         //使用缓冲流向文本文件中写入数据  FileWriter(具备写入功能的流类)
 5 
 6         //1.因为缓冲流不具备写入的功能,所以需要先创建FileWriter对象
 7         FileWriter fw = new FileWriter("tt.txt");
 8 
 9         //2.为了提高FileWriter对象fw 写入的效率,创建输出缓冲流对象
10         //BufferedWriter(Writer out) 
11         BufferedWriter bw=new BufferedWriter(fw);
12 
13         for(int i=1;i<=5;i++){
14            bw.write("java"+i);
15            bw.newLine();//跨平台的写入换行符  
16            bw.flush();
17         }
18         bw.close();
19     }
20     public static void sop(Object obj){
21         System.out.println(obj);
22     }
23 }

   ·字符缓冲读取文本数据-BufferReader

 1 import java.io.*;
 2 class Demo2 {
 3     public static void main(String[] args)throws IOException{
 4         //使用缓冲流读取文本文件
 5 
 6         //1.因为缓冲流不具备读取的功能,所以需要先创建FileReader对象
 7         FileReader fr = new FileReader("tt.txt");
 8 
 9         //2.为了提高FileReader对象fr 读的效率,创建输入缓冲流对象
10         //  BufferedReader(Reader in) 
11         BufferedReader br=new BufferedReader(fr);
12         String line = null;
13 
14         while((line=br.readLine())!=null){//返回的一行字符不包括换行符
15         
16               System.out.println(line);
17         }
18 
19         br.close();//关闭缓冲流就是关闭文件读取流
20     }
21 }

 

   ·字符缓冲流文件的复制

 1 import java.io.*;
 2 class Demo5 {
 3     public static void main(String[] args){
 4         //使用缓冲流实现文件的复制
 5         BufferedReader br=null;
 6         BufferedWriter bw = null;
 7         try{
 8                br=new BufferedReader(new FileReader("Demo3.java"));
 9                bw=new BufferedWriter(new FileWriter("Demo3_copy.java"));
10 
11                String line=null;
12                while((line=br.readLine())!=null){
13                   bw.write(line);
14                   bw.newLine();//加入换行
15                }    
16         }catch (IOException e){
17             e.printStackTrace();
18         }finally{
19             try{
20                 if(br!=null)
21                     br.close();
22             }
23             catch (IOException ee){
24                 throw new RuntimeException("文件读取流关闭失败");
25             }
26             try{
27                 if(bw!=null)
28                     bw.close();
29             }
30             catch (IOException ee){
31                 throw new RuntimeException("文件写入流关闭失败");
32             }
33         }
34     }
35     public static void sop(Object obj){
36         System.out.println(obj);
37     }
38 }

   ·字节流

字节流:可以操作任何类型的数据
InputStream
OutputStream

 1 import java.io.*;
 2 /*
 3 字节流:可以操作任何类型的数据
 4 InputStream
 5 OutputStream
 6 */
 7 class Demo8 {
 8     public static void main(String[] args)throws IOException{
 9         //writeFile();
10         //readFile();
11         //readFile2();
12         fun();
13     }
14     public static void fun()throws IOException{
15          //int available() 
16          FileInputStream fis = new FileInputStream("temp.txt");
17          int n = fis.available();//得到总的字节数 3
18          byte[] arr=new byte[n];//创建一个和文件大小相同的字节数组,不用循环读取了
19          int num = fis.read(arr);
20          sop(new String(arr,0,num));
21     }
22 
23     public static void readFile2()throws IOException{
24        //int read(byte[] b) 返回的是读取的字节的个数
25        
26        FileInputStream fis = new FileInputStream("temp.txt");
27        int num;
28        byte[] arr=new byte[1024];
29 
30        while((num=fis.read(arr))!=-1){
31            System.out.println(new String(arr,0,num));    
32         }
33        fis.close();
34     }
35 
36     //从文件中读取数据
37     public static void readFile()throws IOException{
38        FileInputStream fis = new FileInputStream("temp.txt");
39        //int read()  一次读一个字节
40        int num;
41        while((num=fis.read())!=-1){
42          System.out.print((char)num);
43        }
44        fis.close();    
45     }
46 
47     //向文件中写入数据
48     public static void writeFile()throws IOException{
49        FileOutputStream  fos = new FileOutputStream("temp.txt");
50        fos.write("abc".getBytes());//byte[] getBytes()
51        fos.close();
52     }
53     public static void sop(Object obj){
54         System.out.println(obj);
55     }
56 }

   ·字节流复制文件

 1 import java.io.*;
 2 class Demo9 {
 3     public static void main(String[] args)throws IOException{
 4         //复制一张图片
 5         FileInputStream fis =new FileInputStream("m.jpg");
 6         FileOutputStream fos =new FileOutputStream("m_copy.jpg");
 7 
 8         int num;
 9         while((num=fis.read())!=-1){
10            fos.write(num);
11         }
12 
13         fis.close();
14         fos.close();
15     }
16     public static void sop(Object obj){
17         System.out.println(obj);
18     }
19 }

   ·缓冲字节流

 1 import java.io.*;
 2 class Demo10 {
 3     public static void main(String[] args){
 4         //使用字节缓冲流实现图片复制
 5         BufferedInputStream bis = null;
 6         BufferedOutputStream bos =null;
 7         try{
 8             bis = new BufferedInputStream(new FileInputStream("m.jpg"));
 9             bos= new BufferedOutputStream(new FileOutputStream("mm.jpg"));
10 
11             byte[] arr=new byte[1024];
12             int num=0;
13 
14             while((num=bis.read(arr))!=-1){
15                bos.write(arr,0,num);
16             }    
17         }catch (IOException e){
18             e.printStackTrace();
19         }finally{
20             if(bis!=null)
21                 try{
22                     bis.close();
23                 }
24                 catch (IOException ee){
25                     throw new RuntimeException("字节缓冲读取流关闭失败");
26                 }
27             if(bos!=null)
28                 try{
29                     bos.close();
30                 }
31                 catch (IOException ee){
32                     throw new RuntimeException("字节缓冲写入流关闭失败");
33                 }
34         }
35     }
36     public static void sop(Object obj){
37         System.out.println(obj);
38     }
39 }

    ·转换流

 1 import java.io.*;
 2 
 3 /*
 4 
 5 使用System.in实现一次读一行的功能,代码实现很麻烦
 6 
 7 代码实现和BufferedReader的readLine()方法的代码实现类似
 8 
 9 能不能使用 BufferedReader的readLine()方法实现键盘输入
10 
11 System.in        InputStream  字节输入流
12 
13 BufferedReader   Reader       字符输入流
14 
15 
16 转换流:把字节流转成字符流
17 
18 InputStreamReader:是从字节流到字符流的桥
19 
20 OutputStreamWriter:
21 */
22 class Demo12 {
23     public static void main(String[] args) throws IOException{
24         InputStream  in = System.in;//字节输入流
25 
26         InputStreamReader ir = new InputStreamReader(in);//转换流
27 
28         BufferedReader  br = new BufferedReader(ir);
29 
30         PrintStream  out=System.out;//字节输出流
31 
32         OutputStreamWriter os=new OutputStreamWriter(out);
33 
34         BufferedWriter bw = new BufferedWriter(os);
35 
36         
37         String line=null;
38 
39         while((line=br.readLine())!=null)//读键盘读不到null
40         {
41              if("over".equals(line))
42                  break;
43              bw.write(line);
44              bw.newLine();
45              bw.flush();
46              //System.out.println(line);
47         }
48        br.close();
49     }
50 }

day18

   ·File文件流

把文件和文件夹面向对象的描述类
  createNewFile()
  mkDir()
  isFile()
  isDirectory()
  getName()
  getPath()
  getAbsolutePath()
  lastModified()
  File[] listFiles()
  delete()

 1 import java.io.*;
 2 import java.util.*;
 3 import java.text.*;
 4 class Demo2 {
 5     public static void main(String[] args)throws IOException {
 6         // File: 把文件和文件夹面向对象的描述类
 7 
 8         //File(String pathname) 
 9         File f1=new File("e:\\1905\\day18\\Demo1.java");
10 
11 
12         //File(String parent, String child) 
13         File f2=new File("e:\\1905\\day18","Demo1.java");
14 
15         //File(File parent, String child) 
16         File ff =new File("e:\\1905\\day18");
17         File f3=new File(ff,"Demo1.java");
18 
19 
20         //method1();
21         method2();
22     }
23     public static void method2(){
24         File file = new File("test.txt");
25 
26         sop(file.getName());//得到文件名
27         sop(file.getPath());
28         sop(file.getParent());
29         sop(file.getAbsolutePath());//得到绝对路径(全路径)
30 
31         //long lastModified()  
32         sop(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(file.lastModified())));//得到的是最后一次修改时间
33 
34         sop(file.delete());
35     }
36 
37     public static void method1()throws IOException{
38         File file1 = new File("f:\\hehe.txt");
39         File file = new File("f:\\haha");
40 
41         if(!file.exists())
42             //file.createNewFile();//创建文件
43             file.mkdir();//创建文件夹
44 
45        sop(file1.isFile());//判断是不是文件 true
46 
47        sop(file.isDirectory());//判断是不是文件夹
48 
49        sop(file.isHidden());
50     }
51     public static void sop(Object obj){
52        System.out.println(obj);
53     }
54 }

   ·获取文件夹中的文件目录:String[] list()     File[] listFiles()

 1 import java.io.*;
 2 class Demo3 {
 3     public static void main(String[] args) throws IOException {
 4 
 5         //String[] list()
 6         
 7         File file=new File("e:\\1905\\day17");
 8 
 9         /*
10         String[] arr = file.list();//得到某个文件夹下的所有的目录内容
11         for(String str:arr){
12            sop(str);
13         }*/
14 
15         //File[] listFiles() 
16         
17         File[] arr=file.listFiles();//得到某个文件夹下的所有的带绝对路径的内容
18         for(File ff:arr){
19             sop(ff);
20         }
21 
22         //File[] listRoots() 
23         /*
24         File[] arr = File.listRoots();//
25         for(File file:arr){
26           sop(file);
27         }*/
28     }
29     public static void sop(Object obj){
30        System.out.println(obj);
31     }
32 }

   ·以...结尾的文件判断

 1 import java.io.*;
 2 /*
 3 class FilterByName implements FilenameFilter{
 4     private String ends;
 5 
 6     FilterByName(){}
 7 
 8     FilterByName(String ends){
 9        this.ends=ends;
10     }
11     public boolean accept(File dir, String name)  {
12          if(name.endsWith(ends))
13               return true;
14          else
15              return false;
16     }
17 }*/
18 class Demo4 {
19     public static void main(String[] args) throws IOException {
20         File dir = new File("e:\\1905\\day17");
21 
22         File[] arr = dir.listFiles(new FilenameFilter(){
23             
24             public boolean accept(File dir, String name)  {
25                  if(name.endsWith(".txt"))
26                       return true;
27                  else
28                      return false;
29             }
30         });
31         for(File ff:arr){
32             sop(ff.getName());
33         }
34         /*
35         File [] arr = dir.listFiles(new FilterByName(".txt"));
36 
37         for(File ff:arr){
38             sop(ff.getName());
39         }
40         */
41     }
42     public static void sop(Object obj){
43        System.out.println(obj);
44     }
45 }

   ·递归

函数自己调用自己

 1 //递归:函数自己调用自己,当函数调用次数太多的时候,容易内存溢出
 2 class Demo5 {
 3     public static void main(String[] args) {
 4         int n = sum(3);
 5         System.out.println(n);
 6     }
 7     public static int sum(int num){
 8         if(num==1)
 9             return 1;
10         else
11             return num+sum(--num);
12     }
13 }

 

   ·列出某个目录下的所有文件名,包括子目录下的文件名

 1 import java.io.*;
 2 public class Test2 {
 3     public static void main(String[] args) throws IOException{
 4         //列出某个目录下的所有内容,包括子目录中的内容
 5         File dir=new File("C:\\Users\\machenike\\Desktop\\培训\\java\\作业");
 6         lists(dir);
 7     }
 8     //列出某个目录下的所有内容,包括子目录中的内容
 9     public static void lists(File dir){
10         System.out.println("dir:"+dir);
11 
12         File[] ff=dir.listFiles();
13 
14         for(File file:ff){
15             if(file.isDirectory()){
16                 lists(file);
17             }else
18                 System.out.println("file:"+file);
19         }
20     }
21 }

   ·删除某个目录下的内容,包括子目录里的内容

 1 import java.io.*;
 2 class Demo7 {
 3     public static void main(String[] args) throws IOException{
 4          //删除指定目录下的内容,包括子目录中的内容  文件夹中的内容全部删除,这个文件夹才能删除
 5 
 6         File dir=new File("e:\\1905\\day171");
 7         delDir(dir);
 8     }
 9     //删除指定目录下的内容,包括子目录中的内容
10     public static void delDir(File dir)throws IOException{
11         File[] files=dir.listFiles();
12         for(File ff:files){
13             if(ff.isDirectory()){
14                delDir(ff);
15             }else
16                 System.out.println(ff.getAbsolutePath()+":"+ff.delete());
17         }
18         System.out.println(dir.getAbsolutePath()+":"+dir.delete());
19     }
20 }

   ·Scanner类

这个类,其实本质来说,不是一个流。它是一个浏览器、扫描器。可以从一个流中读取数据,也可以直接从一个文本中读取数据。
虽然Scanner不是一个流,在使用结束之后,也需要调用close()方法,进行关闭操作。
Scanner类也是AutoCloseable接口的实现类,因此,可以直接在try小括号中进行实例化,完成自动关闭。

 1 package com.zqf;
 2 import java.io.*;
 3 import java.util.Scanner;
 4 public class Test{
 5     public static void main(String[] args) throws FileNotFoundException, IOException {
 6         Scanner sc=new Scanner(new File("C:\\Users\\machenike\\Desktop\\a.txt"));
 7         while(sc.hasNextLine()) {
 8             
 9             System.out.println(sc.nextLine());
10         }
11     }
12 }

 

   ·打印流和直接输入输出流

 1 package com.zqf;
 2 
 3 import java.io.File;
 4 import java.io.FileNotFoundException;
 5 import java.io.PrintStream;
 6 
 7 //重定向输出流: 标准输出流可以将数据写到控制台展示
 8         // 我们可以重定向标准输出流,实现将数据写入到某一个文件中
 9 
10 public class Test{
11     public static void main(String[] args) throws FileNotFoundException  {
12         PrintStream ps =new PrintStream(new File("C:\\Users\\machenike\\Desktop\\a.txt"));
13         System.setOut(ps);
14         System.out.println("你好啊");
15     }
16 }
 1 public class Test{
 2     public static void main(String[] args) throws FileNotFoundException  {
 3         File f=new File("C:\\Users\\machenike\\Desktop\\a.txt");
 4         System.setIn(new FileInputStream(f));
 5         Scanner sc=new Scanner(System.in);
 6         while(sc.hasNextLine()) {
 7             System.out.println(sc.nextLine());
 8         }
 9     }
10 }

 

 

 

 

 

   ·SequenceInputStream序列流

 1 import java.io.*;
 2 import java.util.*;
 3 class Demo10 {
 4     public static void main(String[] args) throws IOException{
 5         
 6         //序列流:SequenceInputStream
 7 
 8         //Demo7,Demo8,Demo9  合并到一个新的文件中
 9         FileInputStream fis1 =new FileInputStream("Demo7.java");
10         FileInputStream fis2 =new FileInputStream("Demo8.java");
11         FileInputStream fis3 =new FileInputStream("Demo9.java");
12 
13         Vector<FileInputStream> v=new Vector<>();
14         v.add(fis1);
15         v.add(fis2);
16         v.add(fis3);
17 
18         Enumeration en = v.elements();
19 
20         SequenceInputStream ss =new SequenceInputStream(en);
21 
22         FileOutputStream fos = new FileOutputStream("other.java",true);
23 
24         byte[] arr=new byte[1024];
25         int len;
26         while((len=ss.read(arr))!=-1){
27            fos.write(arr,0,len);
28         }
29         ss.close();
30         fos.close();
31     }
32 }

   ·文件的分割

 1 import java.io.*;
 2 import java.util.*;
 3 class Demo11 {
 4     public static void main(String[] args) throws IOException{
 5         //文件的分割
 6         File file = new File("ok.jpg");
 7         qieGe(file);
 8     }
 9     //文件的分割
10     public static void qieGe(File file) throws IOException{
11         //判断是不是文件
12         if(!file.isFile())
13             return;
14 
15         //把分割出的多个文件同一放在同一个文件夹下
16         File dir = new File("fenge");
17         if(!dir.exists())
18             dir.mkdir();
19 
20         //读取被拆分的文件
21         FileInputStream fis = new FileInputStream(file);
22 
23         FileOutputStream fos=null;
24 
25         byte[] arr=new byte[1024*1024*2];//每读够2M,就写入到一个新的文件
26 
27         int len=0,num=1;
28         while((len=fis.read(arr))!=-1)
29         {
30             fos=new FileOutputStream(new File(dir,(num++)+".suipian"));
31             fos.write(arr,0,len);
32         }
33 
34         //附加说明信息,说明文件的类型,说明文件的个数
35         Properties pro = new Properties();
36         
37         String fileName=file.getName();//ok.jpg
38         String ext=fileName.substring(fileName.lastIndexOf(".")+1);
39 
40         pro.setProperty("fileType",ext);//put
41 
42         pro.setProperty("fileNumber",String.valueOf(--num));
43 
44         //把集合中的说明信息写入到文件
45         //void store(OutputStream out, String comments)  
46         fos=new FileOutputStream(new File(dir,"readme.txt"));
47       
48         pro.store(fos,"切割信息说明");//集合会把自己的键值对通过输出流对象写入到文件
49 
50         fis.close();
51         fos.close();  
52     }
53 }

   ·Serializable   序列化接口

对象的序列化:向文件中写入对象

对象的反序列化:从文件中读取对象

注意:如果需要序列化多个对象到本地,可以将这多个对象放到一个集合中,直接将这个集合序列化到本地即可。此时要求集合中的元素对应的类,必须实现Serializable接口。
误区: 序列化的文件中,不要同时存储多个对象的信息。

 1 import java.io.*;
 2 class Person  implements Serializable  //序列化接口 java.io.NotSerializableException: Person
 3 {
 4     static final long serialVersionUID = 42L; //建议自己定义UID
 5 
 6     private   transient String name;  //瞬态 不参与序列化     //-6731926871520872939 52943123420856159
 7     private int age;
 8 
 9     Person(){}
10     Person(String name,int age){
11        this.name=name;
12        this.age=age;
13     }
14 
15     public String getName(){
16        return name;
17     }
18     public int getAge(){
19       return age;
20     }
21    
22     public String toString(){
23        return name+","+age;
24     }
25 }
26 class Demo12 {
27     public static void main(String[] args)throws IOException, ClassNotFoundException {
28         // ObjectOutputStream  ObjectInputStream
29         writeObj();
30 
31         readObj();
32     }
33 
34     //从文件中读取对象--反序列化(依据Person.class)
35     public static void readObj()throws IOException, ClassNotFoundException{
36         ObjectInputStream ois=new ObjectInputStream(new FileInputStream("object.txt"));
37         
38         //Object readObject()  
39         Person ren=(Person)ois.readObject();////-6731926871520872939 Person.class
40 
41         System.out.println(ren.getName()+","+ren.getAge());
42     }
43 
44     //向文件中写入对象
45     //输出对象---对象的序列化(要求:对象所属的类必须实现 Serializable接口)
46     public static void writeObj()throws IOException {
47         ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("object.txt"));
48         
49         oos.writeObject(new Person("李四",28));//-6731926871520872939
50 
51         oos.close();
52     }
53 }

   ·RandomAccessFile随机访问流

随机访问流
                      只能访问文件
            内部既有字节输入流,也有字节输出流
                       内部使用了数组,使用指针实现随机访问

 

可以使用指针

 1 import java.io.*;
 2 class Demo13 {
 3     public static void main(String[] args) throws IOException,FileNotFoundException{
 4          //writeFile();
 5          readFile();
 6     }
 7 
 8     public static void readFile()throws FileNotFoundException,IOException{
 9        RandomAccessFile rf =new RandomAccessFile("random.txt","r");
10 
11        //默认从文件开头开始读
12        byte[] arr=new byte[4];
13        int len=rf.read(arr);
14 
15        int age=rf.readInt();
16        System.out.print(new String(arr,0,len)+","+age);
17 
18        rf.seek(16);
19        len = rf.read(arr);
20        age=rf.readInt();
21 
22        System.out.print(new String(arr,0,len)+","+age);
23     }
24 
25     public static void writeFile()throws FileNotFoundException,IOException{
26        RandomAccessFile rf =new RandomAccessFile("random.txt","rw");
27        
28        //默认从文件的开头开始写入
29         rf.write("赵四".getBytes());
30         rf.writeInt(48);
31 
32         //获取指针指向的位置  long getFilePointer()  
33 
34         long num = rf.getFilePointer();//8
35         System.out.println(num);
36 
37         rf.seek(16);//控制指针指向的位置
38 
39         rf.write("刘能".getBytes());
40         rf.writeInt(58);
41 
42         num = rf.getFilePointer();//24
43         System.out.println(num);
44 
45         rf.close();
46     }
47 }

 day19

   ·内存流

ByteArrayInputStream:从内存中读     ByteArrayInputStream(byte[] buf)
ByteArrayOutputStream:向内存中写   ByteArrayOutputStream() 该类内部有一个字节数组,把数据写入到内部的字节数组

 1 import java.io.*;
 2 class  Demo1{
 3     public static void main(String[] args) throws IOException{
 4         //内存流: ByteArrayInputStream:从内存中读     ByteArrayInputStream(byte[] buf) 
 5         
 6         //        ByteArrayOutputStream:向内存中写   ByteArrayOutputStream() 该类内部有一个字节数组,把数据写入到内部的字节数组
 7 
 8          byte[] arr = "owieuroeuroeir".getBytes();
 9 
10          ByteArrayInputStream bis =new ByteArrayInputStream(arr);
11          ByteArrayOutputStream bos = new ByteArrayOutputStream();
12 
13          byte[] b=new byte[1024];
14          int len=0;
15 
16          while((len=bis.read(b))!=-1){
17              bos.write(b,0,len);
18          }
19 
20          byte[] c = bos.toByteArray();//得到内部的字节数组
21          System.out.println(new String(c));
22     }
23 }

   ·数据字节流

 1 import java.io.*;
 2 class  Demo2{
 3     public static void main(String[] args) throws IOException{
 4         // DataInputStream  DataOutputStream    
 5         writeData();
 6         readData();
 7     }
 8     public static void readData()throws IOException{
 9 
10         DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
11 
12         double d = dis.readDouble();
13         boolean b = dis.readBoolean();
14         long l=dis.readLong();
15 
16         System.out.println(d+","+b+","+l);
17     }
18     public static void writeData()throws IOException{
19        DataOutputStream  dos = new DataOutputStream(new FileOutputStream("data.txt"));
20 
21        dos.writeDouble(6.66);
22        dos.writeBoolean(false);
23        dos.writeLong(77);
24 
25        dos.close();
26     }
27 }

 

   ·转换流设置编码

 1 import java.io.*;
 2 class  Demo3{
 3     public static void main(String[] args) throws IOException{
 4         //转换流可以设置编码
 5         //writeFile();
 6         readFile();
 7     }
 8     public static void readFile()throws IOException{
 9         InputStreamReader isr = new InputStreamReader(new FileInputStream("utf.txt"),"GBK");
10 
11         char[] arr=new char[10];// char ch;
12         int num = isr.read(arr);
13         System.out.println(new String(arr,0,num));    
14     }
15     public static void writeFile()throws IOException{
16         //平台默认编码是GBK
17         OutputStreamWriter isr = new OutputStreamWriter(new FileOutputStream("utf.txt"),"UTF-8");
18 
19         isr.write("你好");
20         isr.close();   
21     }
22 }
 1 import java.util.*;
 2 /*
 3 编码:把字符转成字节
 4       byte[] getBytes() 
 5              使用平台的默认字符集将此 String编码为字节序列,将结果存储到新的字节数组中。  
 6       byte[] getBytes(Charset charset) 
 7              使用给定的charset将该String编码为字节序列,将结果存储到新的字节数组中。
 8 
 9 解码:把字节转成字符
10       String(byte[] bytes) 
11              通过使用平台的默认字符集解码指定的字节数组来构造新的 String 。 
12       String(byte[] bytes, Charset charset) 
13              构造一个新的String由指定用指定的字节的数组解码charset 。 
14 */
15 class  Demo4{
16     public static void main(String[] args)throws Exception {
17 
18          byte[] arr = "你好".getBytes();  //编码 [-60, -29, -70, -61]
19 
20         System.out.println(Arrays.toString(arr));
21 
22         System.out.println(new String(arr));//解码
23 
24 
25          arr = "你好".getBytes("UTF-8");  //编码 [-28, -67, -96, -27, -91, -67]
26 
27         System.out.println(Arrays.toString(arr));
28 
29         System.out.println(new String(arr,"UTF-8"));//解码
30 
31         //解码用的码要和编码用的码一致,否则乱码
32 
33         //编码编对了,解码解错了,处理方式:再编码,再解码
34 
35         byte[] b="你好".getBytes();//GBK编码
36 
37         String str=new String(b,"ISO8859-1");//解码 ????
38         
39         System.out.println(str);
40 
41         byte[] c=str.getBytes("ISO8859-1"); //再编码
42 
43         str=new String(c);//再解码
44 
45         System.out.println(str);    
46     }
47 }

   ·进程与线程

 1 /*
 2 进程:
 3      正在进行中的程序
 4      也就是在内存中开辟的一块空间
 5 
 6 线程:负责程序执行的一条执行路径
 7       也称为一个执行单元
 8       进程的执行实际上是线程在执行
 9       一个进程至少包括一个线程
10       如果一个进程包括多个线程,那么就是多线程程序了
11 
12 多线程实现了同时执行的效果,多个线程在互相争抢cpu,谁抢到谁执行,直到
13 线程把自己的代码全部执行完,线程结束
14 
15 多线程一定能提高效率吗?不一定,但是能合理的利用cpu资源,关键是实现了
16 不同功能或相同功能的同时执行的效果 
17 
18 java程序是多线程程序吗?
19 有一个负责程序正常执行的线程,主线程---》执行的是main方法中的代码
20 有一个负责垃圾回收的线程,垃圾回收线程 --》执行的是finalize方法中的代码
21 
22 任务:线程执行的代码
23       任务代码都有其存放位置
24 
25       主线程的任务代码在main方法中
26       垃圾回收线程的任务代码在finalize方法中
27 
28 线程是随着任务的存在而存在,随着任务的执行结束而结束
29 */
30 //垃圾回收的功能定义在Object中   void  finalize()
31 class Test{
32     public void finalize(){
33        System.out.println("被回收了...");
34     }
35 }
36 class Demo5 {
37     public static void main(String[] args){ //一个程序至少会有一个线程:主线程,主线程负责执行main中的代码
38            new Test();  //new Test().finalize()
39            new Test();
40            new Test();  //垃圾回收线程执行的垃圾回收的代码,任何一个对象都能被回收
41 
42            System.gc();//主线程执行完这行代码,说明主线程和垃圾回收线程挣抢cpu
43 
44            System.out.println("hello");    
45     }
46 }

   ·线程创建一

 1 /*
 2 张三和李四同时show:
 3 
 4 给张三创建一个线程
 5 给李四创建一个线程
 6 
 7 创建线程的方式:
 8 
 9 1 创建一个Thread的子类
10 2.该子类重写run方法
11     创建线程是为了执行任务,任务需要有存放位置
12     run方法就是任务代码的存放位置
13 3.创建子类的对象
14 4.启动 start():
15      具备启动线程的功能
16      启动的线程当得到cpu时会去执行run方法中的任务代码
17 
18 
19 
20 public static void main(String[] args) //主线程
21     {
22            Thread t1=new Thread();
23            Thread t2=new Thread();
24 
25            t1.start();
26            t2.start();
27 
28            Thread 类中的run方法没有实现任何功能,任务代码又必须写在run方法中
29            只能是继承Thread类,重写run方法
30     }
31 */
32 class Test extends Thread{
33     private String name;
34     Test(){}
35     Test(String name){
36        this.name=name;
37     }
38     public void run(){//该方法中写的是子线程的任务代码
39        for(int i=1;i<=10;i++){                           //子线程的名字: Thread-编号  编号从0开始
40             System.out.println(Thread.currentThread().getName()+":"+name+"......show"+i);
41         }
42     }
43 }
44 class Demo6 {
45     public static void main(String[] args){ //主线程
46 
47         Test t1=new Test("张三");//创建了一个线程  子线程
48         Test t2=new Test("李四");//创建了一个线程
49 
50         t1.start();
51         t2.start();
52 
53         System.out.println(Thread.currentThread().getName());//main
54     }
55 }

   ·线程间异常互不影响

 1 //每个线程发生异常只是这个线程自己的事儿,不会影响其它线程
 2 class Test extends Thread{
 3     private String name;
 4     Test(){}
 5     Test(String name){
 6        this.name=name;
 7     }
 8     public void run(){
 9         //int[] arr=new int[5];
10        for(int i=1;i<=10;i++){       
11             //System.out.println(arr[5]);
12             System.out.println(Thread.currentThread().getName()+":"+name+"......show"+i);
13         }
14     }
15 }
16 class Demo7{
17     public static void main(String[] args) {
18         Test t1=new Test("张三");
19         Test t2=new Test("李四");
20 
21         t1.start();
22         t2.start();
23 
24         //System.out.println(5/0);
25         System.out.println(Thread.currentThread().getName());
26     }
27 }

   ·线程状态

 day20

   ·创建线程第二种方法(常用)

 1 /*
 2 
 3 四个窗口同时卖票:
 4 
 5 因为是同时所以使用多线程
 6 创建四个线程,每个线程的任务都是卖票
 7 因为都是卖票,所以只需要创建一个继承Thread的子类
 8 
 9 创建四个线程,出现了200张票,所以需要把票修饰为static的
10 
11 并不是每个成员变量都适合修饰为static,那么在不使用static的情况下怎么让
12 4个线程共享50张票?
13 
14 创建线程的第二种方式:
15 
16 1: 定义一个类实现Runnable接口
17 2:子类重写run方法
18 3:创建子类的对象
19 4:创建Thread对象,同时把子类对象作为参数传递给Thread对象
20 */
21 
22 //定义任务类:把任务面向对象,这个任务类和线程没关系
23 //线程执行什么任务不再重要了,只要是实现了Runnable接口的子类对象都可以作为参数传递给线程对象
24 //这种方式更面向对象,任务有任务类,线程有线程类,把线程执行的任务作为参数传递给线程
25 
26 //实现接口的同时还可以再继承其它类
27 class Ticket implements Runnable//extends Thread{
28     private  int num=50;
29     //任务:卖票
30     public void run(){
31         while(true){
32             if(num>0){
33                 System.out.println(Thread.currentThread().getName()+"...sale..."+num--);
34             }
35         }
36     }
37 }
38 class Demo2 {
39     public static void main(String[] args) {
40         Ticket t=new Ticket();//任务对象
41         
42         Thread t1=new Thread(t);//线程对象,创建一个线程
43         Thread t2=new Thread(t);
44         Thread t3=new Thread(t);
45         Thread t4=new Thread(t);
46         t1.start();t2.start();t3.start();t4.start()    
47     }
 

   ·多线程安全   锁机制 同步synchronized

 1 /*
 2 多线程程序的安全问题:
 3           因为每个线程再次抢到cpu,直接执行后边的代码,所以会出现0,-1,-2
 4 
 5           出现安全问题的原因:
 6           1:多个线程用到了共享数据
 7           2:操作共享数据的语句有多条,当操作共享数据的多条语句还没执行完就被抢走了cpu
 8 
 9           解决方式:一个线程在执行操作共享数据的多条语句时,只有全部执行完这多条语句其它线程才能执行
10 
11           同步代码块:
12           synchronized(对象){
13               需要被同步的代码(操作共享数据的多条语句)
14           }
15 
16           使用同步代码块解决了安全问题:
17                 同时程序性能会降低,因为需要获取锁,释放锁,没有拿到锁的线程还得反复的判断锁
18 */
19 class Ticket implements Runnable
20 {
21     private  int num=50;
22     private Object obj = new Object();
23 
24     public void run()//throws InterruptedException//重写的方法,需要和父类中的方法一致
25     {
26         while(true)
27         {
28             synchronized(obj)//获取锁:锁可以是任意对象
29             {
30                 if(num>0)
31                 {
32                     //睡眠的线程放弃cpu了,睡眠的线程不会释放锁
33                     try{Thread.sleep(10);}catch(InterruptedException e){e.printStackTrace();}
34                     System.out.println(Thread.currentThread().getName()+"...sale..."+num--);//1 0 -1  -2
35                 }
36             }//释放锁
37         }
38     }
39 }
40 
41 class Demo4 
42 {
43     public static void main(String[] args) 
44     {
45         Ticket t=new Ticket();
46         
47         Thread t1=new Thread(t);
48         Thread t2=new Thread(t);
49         Thread t3=new Thread(t);
50         Thread t4=new Thread(t);
51 
52         t1.start();t2.start();t3.start();t4.start();
53         
54     }
55 }

 

 

   ·设计一个死锁

 1 package com.zqf;
 2 
 3 public class Test {
 4     public static void main(String[] args) {
 5         Lock l=new Lock();
 6         Lock2 l2=new Lock2();
 7         Thread A=new Thread(l);
 8         Thread B=new Thread(l2);
 9         A.start();B.start();
10     }
11 }
12 class Lock implements Runnable{
13     public void run() {
14         synchronized ("A") {
15             System.out.println("A线程A锁已经获得,等B锁");
16             synchronized ("B") {
17                 System.out.println("A线程B锁也获得了");
18                 "B".notify();
19             }
20         }
21     }    
22 }
23 class Lock2 implements Runnable{
24     public void run() {
25         synchronized ("B") {
26             System.out.println("B线程B锁获得了,等A锁");
27             try {
28                 "B".wait();
29             } catch (InterruptedException e) {
30                 // TODO Auto-generated catch block
31                 e.printStackTrace();
32             }
33             synchronized ("A") {
34                 System.out.println("B线程A锁也获得了");            
35             }
36         }
37     }    
38 }

 

   ·银行存钱

 

public synchronized  void save(double money)//同步函数:函数中的代码全部放在了同步代码块中那么该函数可以是同步函数

 1 //这个是我自己写的
 2 package com.zqf;
 3 public class Test{
 4     public static void main(String[] args) {
 5         Cun c=new Cun();
 6         Thread t=new Thread(c,"小明");
 7         Thread t2=new Thread(c,"小黄");
 8         t2.start();t.start();
 9     }
10 }
11 class Cun implements Runnable{
12     int num=0;
13     @Override
14     public void run() {
15         
16             for(int i=0;i<20;i++) {
17                 synchronized (Cun.class) {
18                 num=num+100;
19                 System.out.println(Thread.currentThread().getName()+num);
20             }
21         }
22         
23     }
24     
25 }

//下面为老师写的

 1 /*
 2 有一个银行,可以存钱
 3 有两个客户,同时存钱,每人存3次,每次存100
 4 */
 5 class Bank{
 6     private double sum;//总的钱数
 7     private Object obj = new Object();
 8     //存钱
 9     public synchronized  void save(double money)//同步函数:函数中的代码全部放在了同步代码块中那么该函数可以是同步函数
10     {
11        // synchronized(obj)
12         //{
13             sum=sum+money;
14             System.out.println("sum="+sum);
15         //}
16     }
17 }
18 //任务类
19 class Comstomer implements Runnable{
20      private Bank bank = new Bank();
21      public void run() {
22         for(int i=1;i<=3;i++){
23              bank.save(100);
24          }
25      }
26 }
27 class Demo5 {
28     public static void main(String[] args) {
29         Comstomer com=new Comstomer();
30 
31         Thread t1=new Thread(com);
32         Thread t2=new Thread(com);
33 
34         t1.start();
35         t2.start();
36     }
37 }

   ·同步函数与异步函数的锁

 1 /*
 2  同步函数的锁是this
 3  静态同步函数:静态进内存的时候没有对象,只有那个字节码,所以锁是其所在类的字节码
 4 */
 5 class Ticket implements Runnable{
 6     private static int num=50;
 7     private Object obj = new Object();
 8     boolean flag=true;
 9 
10     public void run(){
11         if(flag){
12             while(true){
13                 synchronized(Ticket.class)//t1 obj 字节码也是对象
14                 {
15                     if(num>0){                        
16                         try{Thread.sleep(10);}catch(InterruptedException e){e.printStackTrace();}
17                         System.out.println(Thread.currentThread().getName()+"...sale..."+num--);
18                     }
19                 }
20             }
21         }else{ 
22              while(true) //t2 this
23                  fun();
24         }
25     }
26     public static synchronized void fun(){
27         if(num>0){        
28             try{Thread.sleep(10);}catch(InterruptedException e){e.printStackTrace();}
29             System.out.println(Thread.currentThread().getName()+"...sale..."+num--);
30         }
31     }
32 }
33 class Demo6 {
34     public static void main(String[] args) {
35         Ticket t=new Ticket();
36         
37         Thread t1=new Thread(t);
38         Thread t2=new Thread(t);
39         
40         t1.start();
41 
42         try{Thread.sleep(10);}catch(InterruptedException e){e.printStackTrace();}
43          
44         t.flag=false;
45 
46         t2.start();    
47     }
48 }

   ·单例设计模式懒汉式多线程安全问题

 1 //单例设计模式懒汉式多线程安全问题
 2 
 3 //饿汉式
 4 class Single {
 5     private static Single s;
 6     private Single(){}
 7 
 8     public static Single getInstance(){
 9        synchronized(Single.class){
10             if(s==null)    {  
11                  try{Thread.sleep(10);}catch(InterruptedException e){e.printStackTrace();}
12                  s = new Single();
13             }
14         }
15          return s;
16     }
17 }
18 class Task implements Runnable{
19     public void run(){
20         Single ss = Single.getInstance();
21         System.out.println(ss);
22     }
23 }
24 class Demo7 {
25     public static void main(String[] args) {
26         Task task = new Task();
27 
28         Thread t1 = new Thread(task);
29         Thread t2 = new Thread(task);
30 
31         t1.start();   t2.start();
32     }
33 }

   ·多线程通信

线程间的通信:多个线程的任务不同,但是操作的数据相同
共同操作的数据
 
wait(),notify()(唤醒一个线程),notifyAll()(唤醒所有线程)这些方法必须使用锁
锁是任意的对象,说明这些方法wait(),notify(),notifyAll()是任意对象都能方法用的方法
 1 //线程间的通信:多个线程的任务不同,但是操作的数据相同
 2 
 3 //共同操作的数据
 4 
 5 /*
 6 
 7 wait(),notify()(唤醒一个线程),notifyAll()(唤醒所有线程)这些方法必须使用锁
 8 锁是任意的对象,说明这些方法wait(),notify(),notifyAll()是任意对象都能方法用的方法
 9 */
10 class Res{
11     String name;
12     String sex;
13     boolean flag;
14 }
15 
16 //实现赋值的线程的任务
17 class Input implements Runnable{
18     private Res res;
19     Input(Res res){
20        this.res=res;
21     }
22     public void run(){
23          int i=0;
24          while(true){
25            synchronized(res){
26                 //先判断能不能赋值
27                 if(res.flag==true){
28                     try{
29                           res.wait();//等待的线程会释放锁
30                     }catch(InterruptedException e){
31                         e.printStackTrace();
32                     }
33                  }
34                 if(i==0){
35                    res.name="张征";
36                    res.sex="男";
37                  }else{
38                    res.name="王财昌";
39                    res.sex="女";
40                  }
41                  res.flag=true;
42                  res.notify();//如果没有等待的线程则是空唤醒  
43              }
44             i=(i+1)%2;
45          }
46     }
47 }
48 
49 //实现输出值的线程任务
50 class Output implements Runnable{
51     private Res res;
52 
53     Output(Res res){
54        this.res=res;
55     }
56     public void run(){
57        while(true){
58            synchronized(res){
59                //先判断能不能输出值
60                if(res.flag==false){
61                    try{
62                           res.wait();//等待的线程会释放锁  让res这个锁上的线程去等待
63                     }catch(InterruptedException e){
64                         e.printStackTrace();
65                     }
66                 }
67                System.out.println(res.name+"..."+res.sex);
68 
69                res.flag=false;
70                res.notify(); //唤醒res这个锁上的线程
71             }
72         }
73     }
74 }
75 
76 class Demo9 {
77     public static void main(String[] args) {
78         //创建数据
79         Res res =new Res();
80 
81         //创建赋值线程的任务对象
82         Input in=new Input(res);
83 
84         //创建输出值线程的任务对象
85         Output out = new Output(res);
86 
87         //创建赋值的线程
88         Thread t1 = new Thread(in);
89 
90         //创建输出值的线程
91         Thread t2 = new Thread(out);
92 
93         t1.start();
94         t2.start();
95     }
96 }

  第二种方法:

 1 class Res{
 2     private String name;
 3     private String sex;
 4     private boolean flag;
 5 
 6     //赋值功能
 7     public synchronized void set(String name,String sex){
 8        if(flag){
 9            try{
10                this.wait();
11            }catch(InterruptedException e){
12                e.printStackTrace();
13            }
14         }
15 
16        this.name=name;
17        this.sex=sex;
18 
19        flag=true;
20        this.notify();
21     }
22 
23     // 输出值
24     public synchronized void out(){
25           if(!flag){
26                try{
27                    this.wait();
28                }catch(InterruptedException e){
29                    e.printStackTrace();
30                }
31            }
32           System.out.println(name+"..."+sex);
33 
34           flag=false;
35           this.notify();
36     }
37 }
38 
39 //实现赋值的线程的任务
40 class Input implements Runnable{
41     private Res res;
42     Input(Res res){
43        this.res=res;
44     }
45     public void run(){
46          int i=0;
47          while(true){
48                 if(i==0){
49                     res.set("张征","男");
50                  }else{
51                     res.set("王财昌","女");
52                  }                
53                i=(i+1)%2;
54          }
55     }
56 }
57 
58 //实现输出值的线程任务
59 
60 class Output implements Runnable{
61     private Res res;
62     Output(Res res){
63        this.res=res;
64     }
65     public void run(){
66        while(true){
67             res.out();
68         }
69     }
70 }
71 
72 class Demo10{
73     public static void main(String[] args) {
74         //创建数据
75         Res res =new Res();
76 
77         //创建赋值线程的任务对象
78         Input in=new Input(res);
79 
80         //创建输出值线程的任务对象
81         Output out = new Output(res);
82 
83         //创建赋值的线程
84         Thread t1 = new Thread(in);
85 
86         //创建输出值的线程
87         Thread t2 = new Thread(out);
88 
89         t1.start();
90         t2.start();
91     }
92 }

   ·消费者与生产者

 1 //自己写的
 2 package com.zqf;
 3 
 4 import com.sun.swing.internal.plaf.synth.resources.synth;
 5 
 6 public class Test2{
 7     public static void main(String[] args) {
 8         Product p=new Product();
 9         ShengChan sc=new ShengChan(p);
10         XiaoFei xf=new XiaoFei(p);
11         Thread t=new Thread(sc,"商家");
12         Thread tw=new Thread(xf,"买家");
13         t.start();tw.start();
14     }
15 }
16 class Product{
17     private String name;
18     private int count=0;
19     private boolean flag;
20     public Product() {
21         super();
22     }
23     public Product(String name, int count) {
24         super();
25         this.name = name;
26         this.count = count;
27     }
28     public String getName() {
29         return name;
30     }
31     public void setName(String name) {
32         this.name = name;
33     }
34     public int getCount() {
35         return count;
36     }
37     public void setCount(int count) {
38         this.count = count;
39     }
40     @Override
41     public String toString() {
42         return "Product [name=" + name + ", count=" + count + "]";
43     }
44     
45     public synchronized void sheng(String name) {
46         if(flag==true) {
47             try {
48                 this.wait();
49             } catch (InterruptedException e) {
50                 // TODO Auto-generated catch block
51                 e.printStackTrace();
52             }
53         }else {
54             this.name=name;
55             count+=1;
56             System.out.println(Thread.currentThread().getName()+"---生产---"+name+"有"+count);
57             flag=true;
58             this.notify();
59         }
60     }
61     public synchronized void xiao() {
62         if(flag==false) {
63             try {
64                 this.wait();
65             } catch (InterruptedException e) {
66                 // TODO Auto-generated catch block
67                 e.printStackTrace();
68             }
69         }else {
70             System.out.println(Thread.currentThread().getName()+"---消费---"+name+"有"+count);
71             flag=false;
72             this.notify();
73         }
74     }
75 }
76 class ShengChan implements Runnable{
77     private Product p;
78     public ShengChan(Product p) {
79         super();
80         this.p = p;
81     }
82     public  void run() {
83         while(true) {
84             p.sheng("哆啦A梦");
85         }
86     }    
87 }
88 class XiaoFei implements Runnable{
89     private Product p;
90     public XiaoFei(Product p) {
91         super();
92         this.p = p;
93     }
94     public  void run() {
95         while(true) {
96             p.xiao();
97         }
98     }    
99 }

 

 1 /*
 2 生产者消费者问题
 3 
 4 生产者负责生产
 5 消费者负责消费
 6 
 7 生产者有生产任务
 8 消费者有消费任务
 9 
10 需要定义生产任务
11 需要定义消费任务
12 
13 还需要定义产品
14 */
15 class Product {
16     private String name;
17     private int count;
18     private boolean flag;
19 
20     //生产功能
21     public synchronized void produce(String name){
22          if(flag==true)
23              try{this.wait();}catch(InterruptedException e){e.printStackTrace();}
24 
25          this.name=name+"..."+count;
26          count++;
27 
28          System.out.println(Thread.currentThread().getName()+"...生产了..."+this.name);
29 
30           flag=true;
31           this.notify();
32     }
33     //消费功能
34 
35     public  synchronized void consume(){
36         if(!flag)
37            try{this.wait();}catch(InterruptedException e){e.printStackTrace();}
38         
39         System.out.println(Thread.currentThread().getName()+"...消费了..."+this.name);
40 
41         flag=false;
42         this.notify();
43     }
44     
45 }
46 
47 //生产任务
48 class Produce implements Runnable{
49      private Product  pro;
50 
51      Produce(Product pro){
52         this.pro = pro;
53      }
54 
55      public void run(){
56         while(true){
57            pro.produce("笔记本");
58          }
59      }
60 }
61 
62 class Consume implements Runnable{
63      private Product  pro;
64 
65      Consume(Product pro){
66         this.pro = pro;
67      }
68 
69      public void run(){
70         while(true){
71             pro.consume();
72          }
73      }
74 }
75 
76 class Demo11 {
77     public static void main(String[] args) {
78         Product pro = new Product();
79 
80         Produce produce = new Produce(pro);
81 
82         Consume consume = new Consume(pro);
83 
84         Thread t1 = new Thread(produce);
85         Thread t2 = new Thread(consume);
86 
87         t1.start();
88         t2.start();
89     }
90 }

 

   ·线程池

  线程池,可以理解为是一个容器,存储线程对象。
  当我们需要开辟一个线程的时候,就去开辟一个新的线程。当这个线程使用结束之后,这个线程就会被销毁。然后再使用到线程的时候,再去开辟新的线程。这样的过程,对CPU来讲,是一种消耗。
     线程池,最核心的原理是“复用”。当我们需要使用到一个线程的时候,从线程池中获取;如果线程池中没有线程,此时再去实例化新的线程。当一个线程使用结束之后,再把这个线程不是销毁掉,而是放入线程池,以便下次继续使用。

 1 public ThreadPoolExecutor(int corePoolSize,
 2                               int maximumPoolSize,
 3                               long keepAliveTime,
 4                               TimeUnit unit,
 5                               BlockingQueue<Runnable> workQueue,
 6                               RejectedExecutionHandler handler)
 7 
 8 在上述的构造方法中,有几个参数说明:
 9 
10 int corePoolSize: 核心池的大小。
11 int maximumPoolSize: 线程池中最多有多少线程。(包括核心线程和临时开辟的线程)
12 long keepAliveTime: 临时开辟的线程最多可以空闲的时间。
13 TimeUnit unit: 空闲时间的单位。
14 BlockingQueue<Runnable> workQueue: 任务的等待队列。
15     ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue
16 RejectedExecutionHandler handler: 拒绝访问策略。
17     AbortPolicy                : 丢弃新的任务,并抛出异常 RejectedExecutionException
18     DiscardPolicy            : 丢弃新的任务,但是不抛出异常
19     DiscardOldestPolicy        : 丢弃等待队列中最早的任务
20     CallerRunsPolicy        : 不会开辟新的线程,由当前线程执行这个任务

注意事项:
 在使用线程池的时候,不需要我们手动的开辟线程。在使用线程池的时候,需要注意的地方,就是任务的处理。在线程池中有一个方法 execute(Runnable r) ,往线程池中添加任务。线程池内部的线程开辟与销毁由自己处理,与我们无关。

execute(Runnable r):向线程池中添加任务,线程池会自动的分配线程去处理这个任务。

shutdown():停止线程池。
     线程池的停止,是需要我们手动关闭的。而且,这个方法并不是立即停止掉线程池。
     如果线程池中还有线程在处理任务,此时这个方法不会让线程池立即停止,而是发出一个停止的信号。等这个线程处理完了任务,线程池才会终止。

 shutdowNow(): 立刻停止线程池。

 

   ·使用工具类获取线程池

工具类:Executors

 1 // 1、获取一个线程池,这个线程池中只有一个核心线程,等待队列中的任务数量是 Integer.MAX_VALUE
 2 ExecutorService executor1 = Executors.newSingleThreadExecutor();
 3 executor1.submit(new MyTask(1));
 4 executor1.shutdown();
 5 
 6 // 2、获取一个线程池,这个线程池中有指定数量的核心线程和最大线程,等待队列中的任务数量是 Integer.MAX_VALUE
 7 ExecutorService executor2 = Executors.newFixedThreadPool(5);
 8 executor2.submit(new MyTask(1));        
 9 executor2.submit(new MyTask(2));        
10 executor2.submit(new MyTask(3));        
11 executor2.submit(new MyTask(4));        
12 executor2.submit(new MyTask(5));        
13 executor2.submit(new MyTask(6));        
14 
15 executor2.shutdown();
16 
17 // 3、获取一个线程池,这个线程池中没有核心线程,有Integer.MAX_VALUE数量的临时线程
18 ExecutorService executor3 = Executors.newCachedThreadPool();
19 executor3.submit(new MyTask(1));        
20 executor3.submit(new MyTask(2));        
21 executor3.submit(new MyTask(3));        
22 executor3.submit(new MyTask(4));        
23 executor3.submit(new MyTask(5));        
24 executor3.submit(new MyTask(6));
25 
26         executor3.shutdown();

 

   ·线程池的应用

 1 package com.zqf;
 2 
 3 import java.util.concurrent.ArrayBlockingQueue;
 4 import java.util.concurrent.ThreadPoolExecutor;
 5 import java.util.concurrent.TimeUnit;
 6 
 7 public class Test {
 8     public static void main(String[] args) {
 9         // 1、实例化一个线程池对象
10         /*
11          public ThreadPoolExecutor(int corePoolSize,
12                               int maximumPoolSize,
13                               long keepAliveTime,
14                               TimeUnit unit,
15                               BlockingQueue<Runnable> workQueue,
16                               RejectedExecutionHandler handler)
17          */
18         ThreadPoolExecutor pool = new ThreadPoolExecutor(5, 
19                                                          10, 
20                                                          1, 
21                                                          TimeUnit.SECONDS, 
22                                                          new ArrayBlockingQueue<>(5), 
23                                                          new ThreadPoolExecutor.CallerRunsPolicy());
24         
25         // 线程池属性的设置:
26         // pool.setCorePoolSize(5);
27         // pool.setMaximumPoolSize(10);
28         // pool.setKeepAliveTime(2, TimeUnit.DAYS);
29         // pool.setRejectedExecutionHandler(handler);
30         
31         for (int i = 0; i < 16; i++) {
32             // 往线程池中添加任务
33             pool.execute(new MyTask(i));
34         }
35         
36         // 关闭线程池
37         pool.shutdown();        
38         // pool.shutdownNow();
39     }
40 }
41 class MyTask implements Runnable {
42 
43     private int id;
44     public MyTask(int id) {
45         this.id = id;
46     }
47 
48     @Override
49     public void run() {
50         System.out.println("线程: " + Thread.currentThread().getName() + "准备处理" + id + "号任务");
51         
52         // 模拟任务的处理
53         try {
54             Thread.sleep(2000);
55         } catch (InterruptedException e) {
56             e.printStackTrace();
57         }    
58         
59         System.out.println("线程: " + Thread.currentThread().getName() + "已经处理完" + id + "号任务!");
60     }
61 }

 

 

 

 

·反射   获取字节码对象

 Class<?> aClass = Class.forName("com.reflect.Person");//Person.class    最常用,其它两个了解即可

Class claz =  Person.class;

Person person = new Person();
          Class<? extends Person> claz = person.getClass();//Person.class

 1 package com.reflect;
 2 
 3 public class Person {
 4     private String name;//Field
 5     private int age;
 6 
 7     public Person() { }
 8 
 9     public Person(String name, int age){ //Constructor
10     
11         this.name = name;
12         this.age = age;
13     }
14     public String getName() {
15         return name;
16     }
17     public void setName(String name) {
18         this.name = name;
19     }
20     public int getAge() {
21         return age;
22     }
23     public void setAge(int age) {
24         this.age = age;
25     }
26     public static void ff(){
27         System.out.println("hello");
28     }
29     public void show(){ //Method
30    
31         System.out.println("show");
32     }
33     public void fun(String name){
34         System.out.println(name);
35     }
36     public String toString() {
37         return "Person{" +"name='" + name + '\'' +", age=" + age +'}';
38     }
39 }
 1 package com.reflect;
 2 
 3 public class Demo1 {
 4     //反射:动态获取字节码对象,并对其执行
 5     public static void main(String[] args) throws ClassNotFoundException{
 6         // m1();
 7          //m2();
 8          //m3();
 9     }
10     /*
11     // alt+enter   alt+insert
12     public static void m3() throws ClassNotFoundException{    //static Class<?>    forName(String className)
13         Class<?> aClass = Class.forName("com.reflect.Person");//Person.class
14         Class<?> aClass2 = Class.forName("com.reflect.Person");
15         System.out.println(aClass==aClass2);
16     }
17 
18     public static void m2(){
19         //每种数据类型都有一个class类型的属性,这个属性得到的就是字节码对象
20         Class claz =  Person.class;
21         Class claz2 = Person.class;
22         System.out.println(claz==claz2);
23     }
24 
25     //得到Person.class   Class<?>  getClass()
26     //这种方式需要事先创建一个Person对象
27     public static void m1(){
28           Person person = new Person();
29           Class<? extends Person> claz = person.getClass();//Person.class
30           Class<? extends Person> claz2 = person.getClass();//Person.class
31 
32            System.out.println(claz==claz2);
33     }
34     */
35 }

   ·反射   创建类对象

 1 package com.reflect;
 2 
 3 import java.lang.reflect.Constructor;
 4 import java.lang.reflect.InvocationTargetException;
 5 
 6 public class Demo2 {
 7 
 8     //动态得到字节码,并创建对象
 9     public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException {
10         m2();
11     }
12 
13     public static void m2() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
14         Class claz=Class.forName("com.reflect.Person");
15         // 得到构造方法对应的Constructor类型的对象
16        Constructor con = claz.getConstructor(String.class,int.class);
17 
18        //使用带参数的构造方法创建对象 newInstance(Object... initargs)
19         Object obj = con.newInstance("李四", 20);
20 
21         System.out.println(obj);
22     }
23 
24     public static void m1() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
25 
26         Class claz=Class.forName("com.reflect.Person");//Person.class
27 
28         //创建对象  Person ren = new Person();
29 
30         Person o = (Person) claz.newInstance();//使用的空参的构造方法,使用Class类提供的newInstance()方法创建对象
31 
32         System.out.println(o);
33     }
34 }

   ·反射   获取属性并赋值

 1 package com.reflect;
 2 import java.lang.reflect.Field;
 3 public class Demo3 {
 4     //动态得到字节码对象,并给属性赋值
 5     public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
 6 
 7         Class claz=Class.forName("com.reflect.Person");
 8 
 9         //给name属性赋值   Field     getField(String name)
10 
11         //Field field=claz.getField("name");//只能得到public权限的属性
12         //System.out.println(field);//java.lang.NoSuchFieldException: name
13        Field field= claz.getDeclaredField("name");
14 
15        //void set(Object obj, Object value)
16         //name是非静态属性,必须通过对象来赋值
17         Person obj=(Person)claz.newInstance();
18 
19         //void setAccessible(boolean flag)
20         field.setAccessible(true);// 设置为可访问的
21         field.set(obj,"张三");
22 
23         System.out.println(obj);
24     }
25 }

   ·反射   获取类方法并使用

 1 package com.reflect;
 2 import java.lang.reflect.InvocationTargetException;
 3 import java.lang.reflect.Method;
 4 
 5 public class Demo4 {
 6     public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
 7         m3();
 8     }
 9     public static void m3() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
10         Class claz=Class.forName("com.reflect.Person");
11 
12         Method m = claz.getMethod("ff",null);
13 
14         m.invoke(null,null);
15     }
16     public static void m2() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
17         Class claz=Class.forName("com.reflect.Person");
18 
19         Method m = claz.getMethod("fun",String.class);
20 
21         Person ren = (Person)claz.newInstance();
22 
23         m.invoke(ren,"呵呵");
24     }
25     public static void m1() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
26 
27         Class claz=Class.forName("com.reflect.Person");
28 
29        //getMethod(String name, Class<?>... parameterTypes) 
30 
31         Method method = claz.getMethod("show", null);
32 
33         //执行方法,这个方法是非静态方法 invoke(Object obj, Object... args)
34         Person ren = (Person)claz.newInstance();
35         method.invoke(ren,null);
36     }
37 }

 day21

   ·sql

DDL**Data Definition Language):数据定义语言,用来定义数据库对象:库、表、列等; CREATEALTERDROP

DML***Data Manipulation Language):数据操作语言,用来定义数据库记录(数据);     INSERTUPDATEDELETE

DCLData Control Language):数据控制语言,用来定义访问权限和安全级别;grant

DQL*****Data Query Language):数据查询语言,用来查询记录(数据)。select

 


       数据库创建好以后,需要指定使用哪一个数据库:use 数据库名;
       查看当前被使用的数据库:   select database();
       删除数据库: drop database 数据库名;
 
数据库是用表来存放数据的:在数据库中创建表
        create table 表名(
  字段名   数据类型,
  字段名   数据类型,
  字段名   数据类型,
  。。。。
  字段名   数据类型
 );

        数据类型:
      数值型:int,tinyint,bigint
      小数: float(x,y)  double(x,y)  decimal(x,y)
      字符型: varchar(50)  实际需要的字符个数小于50,只分配需要的空间大小,
              lisi 分配4个字符的空间

       char(50)    实际需要的字符个数小于50,依然分配50个字符的空间大小
       lisi 分配50个字符的空间
       text:大文本

             日期时间类型:
              date:日期   年月日
              time:时间  时分秒 
              datetime: 日期时间类型  年月日时分秒
       timestamp:时间戳类型  年月日时分秒  2023
              二进制类型: blob

 
         查看所有表: show tables;
  修改表的时候添加字段:   alter table worker add image blob;
  修改表的时候修改字段:   alter table worker modify name varchar(60);
  修改表的时候删除字段:   alter table worker drop age;
  修改表名: rename table worker to yuangong;
  查看创建表的sql语句: show create table 表名;
  修改表的编码:alter table 表名 character set utf8;
  删除表: drop table 表名;
  表的编码默认和所在的数据库的编码一致
 

向表中添加记录:一次添加一条记录
         insert into 表名 values(数值1,数值2,。。。)
         
         向表中所有字段上添加值
  insert into yuangong  values(110,'lisi','nan','2009-12-10',120.5,'hehe');

  向表中部分字段添加值,需要把字段名列出来
  insert into yuangong(number,name,sex) values(119,'zhangsan','nv');

  注意:  数值要和表中字段在个数,顺序,类型上保持一致
 
修改表中记录:
         update 表名 set 字段名=值,字段名=值,...[where 条件]
 
删除记录:delete from 表名 [where 条件]
          truncate table 表名

一个网站的访问的用户是不能添加,修改,删除数据的
我们从京东网站上看到的商品信息是从数据库中查询出来的

查询:
 
-- 条件查询
SELECT * FROM stu
-- 查询性别为女,并且年龄15的记录
SELECT * FROM stu WHERE gender='female' AND age=15

-- 查询学号为S_1001,或者姓名为liSi的记录
SELECT * FROM stu WHERE sid='S_1001' OR sname='liSi'

-- 查询学号为S_1001,S_1002,S_ 1003的记录
SELECT * FROM stu WHERE sid='S_1001' OR sid='S_1002' OR sid='S_1003'
SELECT * FROM stu WHERE sid IN('S_1001','S_1002','S_1003') 
SELECT * FROM stu WHERE sid NOT IN('S_1001','S_1002','S_1003')
-- 查询年龄为null的记录
SELECT * FROM stu WHERE age IS NULL  -- 查询年龄未知的学生

-- 查询年龄不为null的记录 -- 查询有年龄的学生
SELECT * FROM stu WHERE age IS NOT NULL
-- 查询年龄在20到40之间的学生记录
SELECT * FROM stu WHERE age>=20 AND age<=40
SELECT * FROM stu WHERE age BETWEEN 20 AND 40
-- 查询性别非男的学生记录
SELECT * FROM stu WHERE gender!='male'
SELECT * FROM stu WHERE gender<>'male'
SELECT * FROM stu WHERE gender='female'
SELECT * FROM stu WHERE NOT gender='male'

-- 模糊查询
-- 查询姓名由5个字母构成的学生记录
   SELECT * FROM stu WHERE sname LIKE '_____'

-- 查询姓名由5个字母构成,并且第5个字母为“i”的学生记录
   SELECT * FROM stu WHERE sname LIKE '____i'
-- 查询姓名以“z”开头的学生记录
   SELECT * FROM stu WHERE sname LIKE 'z%'
-- 查询姓名中第2个字母为“i”的学生记录
   SELECT * FROM stu WHERE sname LIKE '_i%'
-- 查询姓名中包含“a”字母的学生记录
   SELECT * FROM stu WHERE sname LIKE '%a%'

  
  
   SELECT * FROM emp
-- 去除重复 DISTINCT
   SELECT DISTINCT deptno FROM emp

-- 查雇员的月薪与佣金之和 :任何类型的数据和NUll运算,结果是NULL
   SELECT ename,sal+IFNULL(comm,0)  FROM emp
-- 给字段起别名
   SELECT ename,sal+IFNULL(comm,0) AS 总工资  FROM emp

-- 查看雇员的月薪与佣金之和
   SELECT ename,sal+IFNULL(comm,0) 总工资  FROM emp
  
  
   -- 排序  order by 字段 默认是升序排序(ASC)  降序(DESC)
SELECT * FROM stu
-- 查询所有学生记录,按年龄升序排序--默认是升序排序
SELECT * FROM stu ORDER BY age ASC
-- 查询所有学生记录,按年龄降序排序
SELECT * FROM stu ORDER BY age DESC
-- 查询所有学生记录,按姓名降序排序
SELECT * FROM stu ORDER BY sname DESC

SELECT * FROM emp
-- 查询所有雇员,按月薪降序排序,如果月薪相同时,按编号升序排序
SELECT * FROM emp ORDER BY sal DESC,empno   -- 先按照前边的字段排序,再按照后边的字段排序

 day22

数据库:存储、维护和管理数据
mysql,oracle,db2,sql server属于关系型数据库
mysql是一个数据库服务: 有自己占用的端口 3306 (0-65535,0-1024)
使用mysql必须保证服务是启动的:
启动方式:手动:到服务中找到mysql服务名,然后右击启动
          使用命令启动:net start mysql     net stop mysql
 
连接到mysql  :  
        mysql -u root -p

SQL:Structure Query Language。(结构化查询语言)
SQL的分类:
DDL: 数据定义 create alter drop
DML:  数据操作 insert  delete  update
DCL:  数据控制
DQL:  数据查询 select

使用mysql首先需要创建数据库:
   create  database 数据库名;
   show databases; 查看数据库

   数据库中存储的是文本数据,所以数据库有编码,编码就是在安装mysql时设置的,查看数据库编码的方式如下:
        show create database d2;
 +----------+-------------------------------------------------------------+
 | Database | Create Database                                             |
 +----------+-------------------------------------------------------------+
 | d2       | CREATE DATABASE `d2` /*!40100 DEFAULT CHARACTER SET utf8 */ |
 +----------+-------------------------------------------------------------+
     
       create database d3 character set GBK;  -- 在创建数据库时指定编码

       show character set;  -- 查看所有编码
       create database d4 character set gbk collate  gbk_chinese_ci;  --  设置编码,同时设置排序方式
       alter database d4 character set utf8;  -- 修改数据库的编码

       --正常都使用默认的编码和默认的排序方式
       数据库创建好以后,需要指定使用哪一个数据库:use 数据库名;
       查看当前被使用的数据库:   select database();
       删除数据库: drop database 数据库名;
 
数据库是用表来存放数据的:在数据库中创建表
        create table 表名(
  字段名   数据类型,
  字段名   数据类型,
  字段名   数据类型,
  。。。。
  字段名   数据类型
 );

        数据类型:
      数值型:int,tinyint,bigint
      小数: float(x,y)  double(x,y)  decimal(x,y)
      字符型: varchar(50)  实际需要的字符个数小于50,只分配需要的空间大小,
              lisi 分配4个字符的空间

       char(50)    实际需要的字符个数小于50,依然分配50个字符的空间大小
       lisi 分配50个字符的空间
       text:大文本

             日期时间类型:
              date:日期   年月日
              time:时间  时分秒 
              datetime: 日期时间类型  年月日时分秒
       timestamp:时间戳类型  年月日时分秒  2023
              二进制类型: blob

 
         查看所有表: show tables;
  修改表的时候添加字段:   alter table worker add image blob;
  修改表的时候修改字段:   alter table worker modify name varchar(60);
  修改表的时候删除字段:   alter table worker drop age;
  修改表名: rename table worker to yuangong;
  查看创建表的sql语句: show create table 表名;
  修改表的编码:alter table 表名 character set utf8;
  删除表: drop table 表名;
  表的编码默认和所在的数据库的编码一致
 

向表中添加记录:一次添加一条记录
         insert into 表名 values(数值1,数值2,。。。)
         
         向表中所有字段上添加值
  insert into yuangong  values(110,'lisi','nan','2009-12-10',120.5,'hehe');

  向表中部分字段添加值,需要把字段名列出来
  insert into yuangong(number,name,sex) values(119,'zhangsan','nv');

  注意:  数值要和表中字段在个数,顺序,类型上保持一致
 
修改表中记录:
         update 表名 set 字段名=值,字段名=值,...[where 条件]
 
删除记录:delete from 表名 [where 条件]
          truncate table 表名

一个网站的访问的用户是不能添加,修改,删除数据的
我们从京东网站上看到的商品信息是从数据库中查询出来的

查询:select * from 表名

      =  !=  <>   >  >=  <  <=
      in 
      between and
      not
      and
      or
      is null
      is not null

      模糊查询: like  适用于字符串数据   _  %
      distinct
      order by  字段 ASC DESC
 

     聚合函数:sum()  count()  avg()  max()  min()
     分组:group by
     注意: group by后边的字段才能用在select后边

     select 字段 .... from 表名 where 条件 order by 。。 group by  。。 having
 
数据的完整性:保证表中的数据准确可靠
     实体完整性:
                 表中的一条记录对应一个实体,实体具备独一无二性,那么记录也应该是独一无二的
                 所以在创建表的时候就得保证表中每条记录必须是互不相同的

     实现实体完整性的三种方式:
                 主键:primary key   被设置为主键的字段上的值是不能重复的,不能为null,一个表只能有一个主键
   Unique(唯一约束): 被设置为unique的字段,该字段上的值不能重复,但是可以为null
   AUTO_INCREMENT(自动增长):适合于整型字段,被设置为自动增长的字段上的值是由数据库来生成的 这个值从1开始,每次增加1
 
     域完整性:
             域:每个字段上的值都有一个取值范围,保证用户添加的数据在字段的取值范围内
             所以在创建表的时候就得保证域完整性
      create table tt(
          id int primary key,
   name varchar(20) not null,-- 默认name字段的值是可以为null的
                 sex varchar(4) default '男'
   )
     
      数据类型
      非空约束(not null)
     
      默认值约束(default)
         
     引用完整性:外键,一个表可以有多个外键
                foreign  key(字段名)  references 被引用的表(被引用的字段)
  数据库需要维护外键,会增加数据库开销,降低性能

   
  三个完整性都是为了保证表中数据的准确可靠。

  一张表对应同一类实体
  因为实体和实体之间有关系
  所以表和表之间有关系
  关系型数据库
  表和表之间的关系: 一对一,一对多,多对多

  多表查询:
  1:?合并结果集;
 
       UNION
       UNION ALL
-- UNION 会去除重复的记录
SELECT * FROM a
UNION
SELECT * FROM b
-- UNION all 不会去除重复的记录
SELECT * FROM a
UNION ALL
SELECT * FROM b

2:?连接查询
     内连接:  inner join
     外连接
        左外连接  left outer join
 右外连接  right outer join

3:子查询
4:自连接
 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

package com.zqf;
import java.util.*;
public class Test{
 public static void main(String[] args) {
  Set<Person> set=new TreeSet<Person>();
  set.add(new Person("zhangsan",12));
  set.add(new Person("lisi",14));
  set.add(new Person("wanger",13));
  System.out.println(set);
 }
}
class Person implements Comparable<Person>{
 private String name;
 private int age;
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
 public Person(String name, int age) {
  super();
  this.name = name;
  this.age = age;
 }
 public Person() {
  super();
 }
 @Override
 public String toString() {
  return "Person [name=" + name + ", age=" + age + "]";
 }
 @Override
 public int compareTo(Person p) {
  //按照年龄
/*  if(this.age>=p.age) {
   return 1;
  }else {
   return -1;
  }
*/  
  //按照姓名
  int compareTo = this.name.compareTo(p.name);
  return compareTo;
 }
}

posted @ 2019-08-27 12:00  齐方  阅读(981)  评论(0编辑  收藏  举报