0%

2017年6月29日 上午9:08

1.文档注释
接口,dao,biz,service中类的说明方法及方法写文档注释
2.java的八大数据基本数据类型
3.num + num + String =
String + num + num =
num+char=num
4.命名首字符:字符 下划线 $
不可以关键字 保留字 %
5.定义变量的两种形式
========================6 16 数据类型 =======================
1.类型转换,向大的类型转换
char sex = 12 + ‘c’;1.7不会报错,但是不能超过char的容量和ASSIC

int  age = 20 ;
char sex = age + ‘c';会报错

当大的类型转小的类型,要强制转换

2.long 型(64) l or L
short(16)
3.int age = (int)1234566789;报错 不能抢转
4.boolean yes = 1 ; 报错
5.运算优先级 算数 比较 || !
6.int n1=1;
int n2 = 01;八进制
int n3 = 0x1;16进制
7.String name1 = “abc”;
String name2 = “abc”;相等 这里的“abc”是把上一句定义的额拿出来用

String name3 = new String("abc");
String name4 = new String("abc"); 不相等

8.流程图
9.jdk1.6中switch不可以字符串 ,double 都不支持
条件-确定区间的开头,break决定退出
不要少break
于if的不同:
switch 可以转换成if ,但是if不一定能转成switch
switch 有类型的限制,而if没有
10.循环的流程图

=======================6.19 循环==========================
1.for(;;){}
2.for(;;i++,j++) 从左到右
3.for(){
switch(){
case 11:
;
continue;作用和break一样
}
}
4.while 里面不能用continue
5.记录错误
6.
int count=0; 第1行
int x[ ] = new int[10]; 第2行
for(int i = 0; i < 5;i++){ 第3行
count++; 第4行
i++; 第5行
} 第6行
System.out.println(x[5]); 第7行

  1. int n;
    double s;
    s=1.0;
    for(n=10;n>1;n–){
    s=s+1.0/n;
    }
    System.out.println(s);

  2. String s;
    System.out.println(s);
    局部变量初始化
    =========================6.20==========================

  3. 数组长度固定,不是基本类型,是引用类型。
    数组会赋初值

  4. 两种赋值方式
    2.1int num[]= new int[10];必须说明长度 int初始化为0

    2.2
    int []num;
    num=new int[5]

    2.3
    int num[]=new int[]{1,2,34}
    String str[]= new String[]{“”,””} 赋值空字符串

    错的
    String str[] = new String[];
    str[]={}这个必须写成两行,不能单独写{}

    String classes[] = new String[3]{“c#”,”java”,”php”};长度不能定义两次

3.异常yarrayIndexOutOFBoundsException为运行时异常
4.arrays.sort(数组名)
正序 逆序
5.求最大值 最小值时 要先获取值完之后 才假设最大值and最小值,否则会出错。
他会将你附的那个值也参与比大小。
index = 0 ;
输入;
比较;
如果这里的输入全是负值,那么最大值就是一开始附的0

6.if (a = b) 编译错
7.String s;
System.out.println(s); 编译错
8.\r 光标最前
9.思路:因为层数是确定的,所以所有的规律都要找于层数的关系,也就是与i的关系【找去已知条件的关系】

==================== ==6.21 ==========================
1.成员变量 局部变量的位置
2.封装 继承 多态的english
encapsulation 封装
Inheritance 继承
Polymorphism 多态
3.及时保存
4.oo Object Oriented
5.return;
6. Admin admin[] = new Admin[10];
for(int i = 0;i < admin.length;i++){
admin[i]= new Admin();
}
单独第一句会报空指针异常,因为初始值为null
7.public String toString()重写,在syso输出对象的时候为toString()方法内容。如果没有重写,那么输出对象的类名和地址等
8.同一个包里的class不用import直接就可以生成对象
9.实例方法=必须通过对象来调用的方法 实例=对象
10。实例 = 对象 抽象=类 对象和类的关系
11.实例方法在一个类中可以直接调用 不用this就可以
而,不同类之间的调用必须先声明对象,在调用
12.不能return 两个变量。
return a,b;错
13.不能函数之外直接写逻辑,逻辑必须写在函数中
14.
String.valueOf(); 其他所有类型转 String
str.toCharArray(); str转char[]
15. int num[] = {1,2,3,4,5} 对的
16.字符转数字

1
2
3
4
5
6
Scanner scan = new Scanner(System.in);
String string = scan.next();
char ch[]= string.toCharArray();
for(int i = 0 ;i < ch.length;i++){
System.out.println(ch[i]-48);
}
字符1 -48 = 数字1

========================6.22=========================
1.int num[][]= new int[3][];
2.scan.nextLine() scan.next()的区别
can.nextLine():读的是行为单位
scan.next():一空白符为单位
3.String 于 普通对象的对比

1
2
3
4
5
6
7
8
9
10
11
12
		String string = new String();
System.out.println(string);
// System.out.println(string.equals(""));

StudentBiz stu1 = new StudentBiz();
System.out.println(stu1);

String str[]= new String[10];
System.out.println(str[0]);

StudentBiz stu2[] = new StudentBiz[10];
System.out.println(stu2[0]);
输出:

    StudentBiz@6f94fa3e
    null
    null

4.null是没有空间的
5.java中的包名小写 + 不以.为开头 + ;
6.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Student student  = new Student();
Student stu[] = new Student[3];
Scanner scanner = new Scanner(System.in);
for(int i = 0 ;i < 3;i++){
student.name = scanner.next();
stu[i]=student;
System.out.println(stu[i].name);
}

for(int i = 0; i< 3;i++){
System.out.println(stu[i].name);
}

scanner.close();
解释:真正的空间就一个 new Student();
       其他的 student+stu[] 其实就是一个指针。
        多个指针指向为一个的一个空间,当然会造成所谓的“覆盖”

========================6.23============================
1.String 的使用
java.lang包
String str = “”;长度为0
String str = “ “;长度为1
中文的长度也是1
String类是final类
== 内存池

栈区:编译器自动分配释放
    存放函数值+局部变量
堆:有程序员new分配释放,若程序员不释放,程序结束时os释放

全局区:全局变量+静态变量  放在堆中初始化之后放在一起,没有初始化的放在旁边的一块区域。程序结束后系统释放
文字常量区:“abc”
程序代码区:

equals()的比较原理 一个个字符的比较
== 比较是不是相同的地址,内存的首地址

toLowerCase()
toUpperCase()
equalsIgnoreCase()


A.concat(B);B接到A后面
String s1 = "你好";
String name ="张三";
String sen = s1.concat(name);
;不影响s1的值
s1 = s1.concat(name);
;这个才影响s1的值

提取方法:返回第一个匹配的位置
    indexOf(int ch);
    indexOf(String value);

    lastIndexOf(int ch)
    lastIndexOf(String value)

提取:返回字符串的一部分
    subString(int index);
    subString(int index_start,int index_end);包括start不包括end
    tirm();清楚前后空格,重新产生对象,不影响本身

str.replace()->替换replace

转:
str.valueOf() -> 字符串  -> toCharArray()
                     -> charAt()

2.int num[10];编译出错 说明长度情况下,必须要有指向的内容
3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scan = new Scanner(System.in);
System.out.println("请输入用户名");
String str1 = scan.next();
Verify(str1,str2,str3);
System.out.println("str1:"+str1);

}

public static void Verify(String str1,String str2,String str3){
str1 = "acb";
System.out.println("str1:"+str1);
}
请输入用户名
abc
str1:acb
str1:abc

总结:verify()的参数 就是指针 而不是真正的对象。
    基本类型数组

?4.c++中对象 指针
5.String ,StringBuffer ,StringBuilder
StringBuffer
1. toString();
2. insert();
3. append();
6.String str[] = new String[3]{“1”,”2”,”3”}; 编译错
7.temp = input3.split(‘-‘);错
参数是字符串,而不是字符
总结:看eclipse的提示
8:java string类型最后是没有’\n’的,这与c++不同
9:bat 批处理
?10:在做完项目之后,我们要进行项目总结,自己当初如何分析的,有没有可以改进的地方
?11:面向对象的抽象
?12:设计模式
13:

1
2
3
4
5
6
7
8
9
public Dog(){

}//当写了构造方法之后,就得加上空的构造方法了额
public Dog(String name,int health,int love,String dif){
this.name = name;
this.health = health;
this.love = love;
this.dif = dif;
}//当参数和成员变量同名时,使用this来区分

14:source生成构造方法
15:方法的重载
16:

1
2
3
4
5
public void print(int a , String b);
public void print(String a,int b);//是重载

public void print(int a ,int b);
public void print(int b,int a);//不是重载
重载的条件
1.同一个类中
2.参数列表不同
3.方法名相同
4.和返回值,访问修饰符无关

override 重写
overload 重载

17:类名不能直接访问成员变量 要写成static
18:static 三种用途
1.属性 在堆中 位置:全局变量+static方法中
2.静态块 常用去提前配置
static {
syso(“*”)
}
3.方法
不能直接访问非静态的方法+成员变量(也不能定义)
可以通过 对象. 去访问

public void play(){
    static int local = 5;    错
}

19:override:覆写,”实现类”实现了”接口”定义的方法
overwrite:重写,”子类”重新实现了”父类”定义的方法
overload:重载

20:
封装步骤
1.private
2.getter setter方法
3.写逻辑

21:option + command + s = gettter setter
private int a = 0;

public int getA() {
    return a;
}
public void setA(int a) {
    this.a = a;
}

22:this() 调用构造方法 必须放类的第一句

========================6.23=======================
1.
public static void main(String[] args) {
String str=null;
str.concat(“abc”);
str.concat(“def”);
System.out.println(str);
}
A. 输出:null
B. 输出:abcdef
C. 编译错误
D. 运行时出现异常

总结:现在运行时异常一共有两种:
    1.数组越界 2.对象空间为null进行.操作的方法

2.int num = (int)(Math.random()100);
int num = (int)Math.random()
100;
总结:强制转换的优先级高
第二个是先对Math.random 强制转化成int 这就造成了num的值一定为0
3.char c = 100;
举例:

1
2
3
4
5
6
7
char x= 100;	
System.out.println(x);
System.out.println(x + 0);

int y = 100;
System.out.println(y);
System.out.println((char)y);
输出:
    d
    100
    100
    d

总结:他们内存本质是一样的,唯二的区别是
     1.int是16位,char是8位
     2.输出时的方式不同

4.错题
8) 在Java语言的控制结构中,break语句是经常用到的语句。下面一段代码中break语句起到(A,c)的作用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int pointer = 0;
while (pointer <= 10) {
switch (pointer % 3) {
case 1:
pointer += 1;
break;
case 2:
pointer += 2;
break;
default:
pointer += 3;
break;
}
}
    A.    结束当次循环,使控制权直接转移到控制循环的条件表达式
    B.    从嵌套循环内部跳出最里面的循环
    C.    终止switch语句的语句序列,提高switch-case语句性能
    D.    退出循环
总结:少选了

19)    给定一个Java程序的代码如下所示,则编译运行后,输出结果是( A)。
1
2
3
4
5
6
7
8
9
10
public class Test {
int count = 9;
public void count() {
System.out.println("count=" + count++);
}
public static void main(String args[]) {
new Test().count();
new Test().count();
}
}
    A.    count=9
        count=9
    B.    count=10
        count=9
    C.    count=10
        count=10
    D.    count=9
        count=10
总结:注意到这里是声明了两个互补干扰的对象,他们之间是没有影响的

20)    有关Java中的类和对象,以下说法错误的是( b)。
    A.    同一个类的所有对象都拥有相同的特征和行为
    B.    类和对象一样,只是说法不同
    C.    对象是具有属性和行为的实体
    D.    类规定了对象拥有的特征和行为
总结:我以为的是:不同对象之间相同的属性但是有不同的值,也算拥有不同的特征

22)    在Java语言中,有如下代码:(b,d)
1
2
3
4
5
6
7
8
9
10
11
switch(x) {
case 100 :
System.out.println("One hundred");
break;
case 200 :
System.out.println("Two hundred");
break;
case 300 :
System.out.println( "Three hundred");
break;
}
    下列x的定义中,( )可以使得上段代码编译通过。
        A.    double x = 100;
        B.    char x = 100;
        C.    String x = "100";
        D.    int x = 100;
总结:在switch中 case中的条件类型只能有一种,不能同时又int 或者 String
      但是 int和char是可以同时出现,因为char本身就是int,只是换了一种表现形式

5.ASCII 有意义的范围是0-127
128-255 也能定义,但输出后像乱码

举例:
1
2
3
char x= 230;	
System.out.println(x);
System.out.println(x + 0);
输出
æ
230

====================6.26 继承 重载 多态======================

  1. super()
    super(a,b) 调用带参构造
    super.属性
    super.方法

  2. 先执行父类构造,再执行子类构造

  3. debug 鼠标放到变量上

  4. 无参构造
    子类默认调用父类的无参构造,当父类无参构造不存在时,子类不会自动调用父类的有参构造

  5. super不在过构造方法时,可以不放在第一行

  6. pet dog = new dog();
    dog.print();默认调用子类的print方法(print方法,子类父类中都有)

    pet dog = new dog();
    dog.method();不能调用子类特有方法(method 只有子类中有)

  7. 子类不可以调用父类的有:
    private
    构造方法
    不在同一个包
    默认类型的成员

  8. 修饰符:

    本类 同包 子类 其他(不同包)            唯一的标准

    private 🐶 是否在 同一个类
    frendly 🐶 是否在 同包 默认的
    protect 🐶 是否 继承
    public 🐶 都行

9.包名不能建成package
10.不同包继承时,父类不能放在默认的包中(default package中)
11.super总结

1
2
3
4
5
6
7
8
9
10
11
12
super只能在写方法中
package package1;

import package2.A;

public class B extends A {

//super.a =2;//Syntax error on token "{", { expected after this token
public B(){
super.a =2;
}
}
super不在过构造方法时,可以不放在第一行

super不能访问父类private成员


super()
super(a,b) 调用带参构造
super.属性
super.方法

12.❤️❤️❤️❤️❤️❤️❤️❤️重写 重载 对比
重写
1.重写
2.类型相同/父类返回类型的子类 + 修饰符只能扩大,不能缩小 + 方法名,参数列表相同
3.构造方法不能重写

重载的条件
1.同一个类中
2.参数列表不同
3.方法名相同
4.和返回值,访问修饰符无关
13.
抽象类不能实例化 — 因为没有意义
Pet pet = new Dog() pet是abstract
是对的 这只是一个指针指向 没有分配空间进行实例化

抽象类中可以有0个或者多个抽象方法  
子类中,抽象方法在子类中必须实现

14.final
方法 重写
变量属性 修改 (当变量为对象时,final对象不可以=new Object(),但是仍然可以改变这个对象的属性)
类 继承
15.this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//父类
package package3;

public class Car {
private int site = 4; //座位数

Car(){
System.out.println ("载客量是"+site+"人");
}
public void setSite(int site){
this.site = site;
}
void print(){
System.out.print("载客量是"+this.site+"人");
}
}

//子类
package package3;

public class Bus extends Car {
Bus(int site){
//这三个的输出结果是一样的
//this.setSite(site);
//super.setSite(site);
setSite(site);
}
// public void setSite(int site){
// super.site = site;
// //this.site = site;
// }
public void show(){
System.out.println("Bus_print");
}
}

//测试类
package package3;

public class Test {

public static void main(String[] args) {
// TODO Auto-generated method stub
Bus bus = new Bus(20);
bus.print();

}

}
总结:
       1. 在继承中,如果子类没有重写父类的方法,那么子类是调用的是父类的方法
       2. ❤️这里的调用,是在父类中执行,而不是在子类中执行(原来理解的是在子类中执行)
       3. 即使,这三个的输出结果是一样的
       this.setSite(site); 
       super.setSite(site);
       setSite(site);

       4. 继承不是拥有这项技能,而是能让父类帮你干,你自己其实不会。
  1. super.name

  2. 用构造方法不一定会生成对象
    eg:pet pet = new dog()
    这调用了父类的构造方法,也调用了子类的构造方法,但是,但是只生成了子类对象

  3. 多态:同一个引用类型,使用不同的实例而执行不同操作

    父类存在的地方一般都能使用子类代替

    要素:

    1.子类重写父类分方法
    2.使用父类的类型

    使用的地方:

    1.方法参数
    2.方法返回值
  4. ❤️Pet 是一个abstract类,他不能new一个对象,但是却可以调用方法pet.eat();

  5. pet instanceof Dog
    instanceof 使用:对象.instanceof(父类/接口)

    Dog dog = (Dog)pet;强制转换
    (Dog)pet.dark();这的是错的,之后转换了之后才可以进行特有dog方法的调用


  6. MotoVehicle moto[] =new MotoVehicle[4];
    这个MotoVehicle是abstract类,但是能用new,这个例子就充分的说明了,new != 分配空间。
    在这里,他仅仅说明了moto[]的长度

    对象数组的初始化方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    第一种:
    MotoVehicle moto[] = new MotoVehicle[]{
    new Car(1,"宝马1","红色",1000,20),
    new Car(2,"宝马2","红色",1000,20),
    new Bus(3,"金龙1","绿色",1000,"x"),
    new Bus(3,"金龙2","绿色",1000,"xx"),
    new Bus(5,"金龙3","绿色",1000,"xxx"),
    new Ka(6,"Ka1","兰色",1000,100)
    };
    1
    2
    3
    4
    5

    第二种:
    for(int i = 0 ;i < n;i++){
    moto[i]= new Car(****);//只能生成一种Car类型的
    }

22.abstract的作用
1.对于架构设计者,他可以写好abstract类 ,以及其中的abstract方法,这就规定了这个类的子类必须要实现这个方法
2.abstract的方法其实还是可以调用的,于instanceof+重写(重写不仅仅用于abstract),可以实现工厂模式+抽象工厂模式——也就有了扩展性

23.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
类B
package package6;

public class B extends A{
int a;
public void show(){
a = 2;
System.err.println(this.a);
System.err.println(super.a);
}
}

类A
package package6;

public class A {
int a;
}

Test类
package package6;

public class Test {

public static void main(String[] args) {
// TODO Auto-generated method stub
B b = new B();
b.show();
}

}
输出结果
2
0

=================6.27接口+ 异常================
1.接口
接口不能实例化
实现类必须实现接口的所有方法
变量都是静态变量
现类可以实现多个接口

2.interface implements
3.interface的默认
方法:public abstract void service(); 不能用static
变量:public staic final double PI = 3.14;
4.❤️实例化两种 (UDisk implememts UsbInterface)
UDisk u = new UDisk();
UsbInterface u2 = new UDisk();

5.❤️接口实现方式和设计模式的不同

在设计模式中,door是雇主,而lock是雇员,他们两个都是抽象类(可以方便的横向扩展),door中有lock的对象(仍然是两个对象)
但是在接口中,没lock的对象,而是直接拿到了lock的方法,两个对象合二为一(合二为一为重点)


总结:
    设计模式是类,对象之间相互组合,至少也有两个对象(把功能分配给不同的对象去完成)
    而抽象和接口,本质是把一个类的方法进行拆分,分别放在抽象类和接口类中,让其他类也可以用(把功能分成方法集,方便其他类用)

接口改成类后更加灵活:
当把一个接口A写成类A,B不是通过implement来使用,而是在类B中声明一个new A对象,
这种改法使得B类可以更加灵活,因为可以通过更改A的实例,让B有新的功能。
相同的功能,如果更改在B中更改A的接口方法,那么就必须去更改方法本身,而不是简单的换个对象就行了

6.❤️接口和抽象类的区别
1.定义,关键词
2.抽象类是单继承,extends,接口可以实现的多个,implement
3.其中包含的内容,抽象类可以有变量,成员方法,接口中有final变量+abstract方法
4.使用的场合
抽象类:is a
接口: has a
5.相同点:都不能生成实例对象,都没有构造方法

❤️❤️❤️❤️❤️❤️决定使用抽象类 还是接口
is a   ---->abstract  防盗门是门    (一个类别=抽象)
has a  ---->接口       门用到锁       (一个部分=接口)


总结:在类,接口,抽象中选择
    is a                   (一个类别=抽象)
    has a (二选一)      (一个部分=接口)
                    (可更换的部分=类)
注:现在我的认识是:类一定比接口好,接口的功能全能用类来实现!当然这是错的!
  1. 先写接口 -> 抽象类 ->实现类 -> test测试
    接口 -> 实现类 -> test测试

  2. 接口的优势
    多继承
    设计和实现完全分离
    更自然使用多态
    更容易搭建程序框架
    更容易更换

  3. 算数异常

  4. has.nextInt();

  5. 五个关键字
    try 执行可能产生异常的代码
    catch 捕获异常
    finally 终会执行
    throw 抛出
    throws 声明

  6. java.lang.Exception

  7. e.printStacktTrace() 堆栈追踪功能
    这个注释掉,就没有异常信息输出了

  8. try catch的三种情况 ,以及执行情况
    没异常 try->继续
    有异常,捕获 try->catch->打印出catch中的异常->继续
    有异常,没捕获 try->中断->jvm打印出异常

    总结:catch 只有匹配了异常才能执行,当参数写Exception时,一定能匹配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

*****例子1;*******

try {
Scanner scan = new Scanner(System.in);
System.out.println("请输入第一个数");
int input1 = scan.nextInt();
System.out.println("请输入第二个数");
int input2 = scan.nextInt();
System.out.println(String.format("%d/%d=%d", input1,input2,input1/input2));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.err.println("_____catch_____");
}
System.out.println("程序结束");
输出:
请输入第一个数
1
请输入第二个数
0
程序结束
java.lang.ArithmeticException: / by zero
    at package6.Exception1.main(Exception1.java:16)
_____catch_____
1
2
3
******例子2;*******
将 System.err.println("_____catch_____");
改为 System.out.println("_____catch_____");
输出:
请输入第一个数
1
请输入第二个数
0
_____catch_____
程序结束
java.lang.ArithmeticException: / by zero
    at package6.Exception1.main(Exception1.java:17
1
2
3
******例子3;*******
将 } catch (Exception e) {
改为 } catch (InputMismatchException e) {
输出:
    请输入第一个数
    1
    请输入第二个数
    0
    Exception in thread "main" java.lang.ArithmeticException: / by zero
        at package6.Exception1.main(Exception1.java:18)


    请输入第一个数
    q
    _____catch_____
    程序结束
    java.util.InputMismatchException
        at java.util.Scanner.throwFor(Scanner.java:864)
        at java.util.Scanner.next(Scanner.java:1485)
        at java.util.Scanner.nextInt(Scanner.java:2117)
        at java.util.Scanner.nextInt(Scanner.java:2076)
        at package6.Exception1.main(Exception1.java:15)

15.getMessage();输出一个异常的描述信息
自定义异常 system.err.print();

16.常见异常
arrayInexOutOfBounds 数组越界
NULLPointer 空指针异常
ClassNotFound 类没有定义
IllegalArgument 不合法参数
ClassCast 对象强制转换异常
NumberFormat abc->数字
NoSuchMethod
IO
SQL
17.error exception的不同
error
18.RuntimeException
19.finally
1.是否发生异常都执行
2.system.exit(1) 唯一可能不执行finally的情况

20 return 和 finally 的关系
try{

}catch(Exception e){
    syso(“*”);
    return 2;
}finall{
    syso();
}

当捕获到异常时,并且catch有返回return时,先执行finally,在执行return

21.
*
22.
按catch的顺序:先父类 后子类

23.main方法不能改
public static int main(String[] args) {

错误: main 方法必须返回类 package6.Exception1 中的空类型值, 请
将 main 方法定义为:

public static void main(String[] args)
24.throws用法

“嗨哥们,这个A方法容易出错,调用这个A方法的B方法必须进行处理”
处理方法:
    1.B()throws Exception{}
    2.B(){
        try{
            A();
        }catch(Exception e){
            e.
        }
    }

注:1方法输入让jvm处理异常,那么,可能会中断程序

25.throw 的用法

1
2
3
4
5
6
7
8
9
10
********例子1******
public void setAge(int age) throws Exception {//这里要声明throws

if(age > 0 && age < 130){
this.age = age;
}
else{
throw new Exception("年龄必须大于0 小于130");
}
}
输出:
Exception in thread "main" java.lang.Exception: 年龄必须大于0 小于130
at package7.Person.setAge(Person.java:16)
at package7.ExceptionTest.main(ExceptionTest.java:6)    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
********例子2******
public void setAge(int age) {

if(age > 0 && age < 130){
this.age = age;
}
else{
try {
throw new Exception("年龄必须大于0 小于130");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
输出:
java.lang.Exception: 年龄必须大于0 小于130
at package7.Person.setAge(Person.java:17)
at package7.ExceptionTest.main(ExceptionTest.java:6)
0

总结:
    写了throw之后,必须进行2选一的操作

26.log 日志的作用
1.用来记录系统运行中的而一些中亚操作信息
2.便于见识系统运行,帮助用户提前发现和避开可能出现的问题,或出现问题后根据日志找到原因
27.日志的分类
sql日志 记录增删该查
异常日志 记录异常
业务日志 记录业务操作
28.输出级别 8
OFF
Fatal
ERROR
warn
info
debug
trace
all
29.
配置日志格式
输出位置
文件名.log

2017年6月29日 上午8:02

1.

Object

Java.lang.Object
1. equal()
2. toString()
3. getClass() 返回运行时类
4. finalize()
5. notify() 唤醒在此对象监视上等待的单个线程
6. notifyAll()
7. wait()

Math

java.util.Math
都是静态方法
1. abs()
2. max()
3. min()
4. random() 0.0~1.0 包括0.0 不包括1.0
5. sin()
6. exp()
7. sqart(9) = 3
8. Pow(2.3) = 8

Date

1. 日期转字符串1(DateFormat.getDateInstance)
1
2
3
4
Date date = new Date();
DateFormat df = DateFormat.getDateInstance(DateFormat.FULL);
String string= df.format(date);
System.out.println(string);
2. 日期转字符串2(SimpleDateFormat)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//日期转换成字符串
Date date = new Date();

//这里的"yyyy-MM-dd" 要与 “String time = "1995-2-27"”格式对应
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String string = sdf.format(date);
System.out.println(string);

//字符串转换成日期
String time = "1995-2-27";
try {
Date dtime = sdf.parse(time);
System.out.println(dtime);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Calendar//默认指向的是当前时间,站在当前日期的角度

操作的步骤一般是1-4
1. 获取对象
Calendar.getInstance()
2. 修改默认时间
1. cal.add()
2. cal.set(年,月,日)
1. 月是0-11
3. 对当前设置的时间进行转换
1. cal.get(Calendar.DAY_OF_WEEK)
1. 星期日=1
2. 获取当前设置日期的星期几
4. 得到Date类型的时间
1. cal.getTime()

1
2
3
4
5
6
7
8
9
10
11
12
//获取操作对象
Calendar cal = Calendar.getInstance();
//修改当前时间
cal.add(Calendar.MONTH, -1);//修改当前日期
cal.set(1995, 1, 27);//覆盖了上一句
System.out.println("输出星期几:"+cal.get(Calendar.DAY_OF_WEEK));
//得到当前时间
Date date = cal.getTime();
//对时间进行转换
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String string = sdf.format(date);
System.out.println("设置的当前时间:"+string);

包装类

  1. 八个基本类型对应一个包装类
  2. 数字和字符之间的转换
    1. Integer.parseInt(str)
      1
      2
      3
      4
      String str="123";
      int num1 = Integer.parseInt(str);
      double num2 = Double.parseDouble(str);
      Sysytem.out.print(num1 + num2);
    2. String.valueOf(num1)
      1
      2
      String str = num1 + "";
      String str = String.valueOf(num1);
  3. 装箱 拆箱
    1
    2
    3
    4
    5
    Integer integer = new Integer(20);  //手动装箱
    Integer integer = 20;//自动装箱

    int i = new Integer(5).intValue();//手动拆箱
    int i = new Integer(5);//自动拆箱
  4. Integer 不能自动转换为 Float
    1
    2
    3
    4
    5
    6
    public static void main(String args[]){
    method(5);//这里要改成method(5f)
    }
    public static void method(Float f){
    System.out.println(f);
    }

2017年6月29日 下午4:15


JULY说学习算法最好的方法:
1. 抓住算法是为了解决什么样的问题
2. 可以帮助自己理解

我对算法的理解:
1. 算法的第一步不是去看懂程序,而是,能把一个具体的例子,一步一步的仔细完整额走下来这部分才是真正的算法本身
1. JULY所说的,正是说明例子步骤的一种好的方式
2. 然后才是,想办法对例子进行总结提炼概括(抽象),找到表达的方式
3. 最后才动笔写程序
注:描述一个算法,也应该是这样的思路
在读的时候对自己的要求:
1. 摘抄一些算法关键性的说明,容易漏掉的部分
2. 说明一些不太懂的地方
3. 说出自己的理解

A*搜索算法

地址:一、A*搜索算法 - 结构之法 算法之道
1. 所谓启发式搜索,就在于当前搜索结点往下选择下一步结点时,可以通过一个启发函数来进行选择,选择代价最少的结点作为下一步搜索结点而跳转其上(遇到有一个以上代价最少的结点,不妨选距离当前搜索点最近一次展开的搜索点进行下一步搜索)。
2. DFS和BFS在展开子结点时均属于盲目型搜索,也就是说,它不会选择哪个结点在下一次搜索中更优而去跳转到该结点进行下一步的搜索。
3. A算法最为核心的部分,就在于它的一个估值函数的设计上: *f(n)=g(n)+h(n)
4. 解决的问题:
1. 求有向图 两点之间的最短路径

5. 通过上图,我们可以看出::A算法最为核心的过程,就在每次选择下一个当前搜索点时,是从所有已探知的但未搜索过点中(可能是不同层,亦可不在同一条支路上),选取f值最小的结点进行展开。
6. 而所有“已探知的但未搜索过点”可以通过一个*
按f值升序的队列(即优先队列)进行排列。
7. 当任何
第二次走到一个点的时候,判断最小步骤是否小于记录的内容,如果是,则更新掉原最小步数,一直到所有的路径点都不能继续都了为止,最终那个点被标注的最小步数既是最短路径,
8. **理解不了的:

1. A算法与广度、深度优先和Dijkstra 算法的联系就在于:当g(n)=0时,该算法类似于DFS,当h(n)=0时,该算法类似于BFS。且同时,如果h(n)为0,只需求出g(n),即求出起点到任意顶点n的最短路径,则转化为单源最短路径问题,即Dijkstra算法。这一点,可以通过上面的A搜索树的具体过程中将h(n)设为0或将g(n)设为0而得到。
2. 算法流程1-3这样讲解算法有用吗

Dijkstra 算法初探

来源:经典算法研究系列:二、Dijkstra 算法初探 - 结构之法 算法之道
1. 解决的问题
1. 算法解决的是有向图中单个源点其他顶点的最短路径问题
2. 针对的是非负值权边。
3. 下面两个图是对算法的举例说明的过程


4. 发现,其实在举例说明的过程中,我们就可以发现“哎,这个东西用某某东西就能描述
注:我现在不考虑算法的实现算法的效率,我知道知道实现之间的区别!!

2017年6月28日 下午10:14

  1. 查询时的三种思维
    1. 先连接 ,后删除
    2. 先选取 ,后连接—–in
    3. 一个个的试,从小范围到大范围 exists
    4. 注:后两种所查询出来的信息必须在一张表中
      1. 第一种可以拼接多个表数据的原因是两个表通过笛卡尔积进行了拼接
  2. eg:从sc表中筛选出所有计算机系的学生选课情况
    1. select sc.* from sc,student where sc.sno=student.sno and student.dept=’计算机系’
    2. select * from sc where sno in (select student.sno from student where student.dept=’计算机系’)
    3. select * from sc where exists (select * from student where student.sno=sc.sno and student.dept=’计算机系’);
      1. 我拿上sc表的第一条数据的学号,用这个学号作为条件,看是否在学生表中存在一条数据满足:有这个学号的学生,并且她是计算机系的
    4. select * from sc where ‘计算机系’= (select dept from student where student.son=sc.sno)—这个稍微短点
      1. 这个是exists的改写版,虽然没有出现exist,但是就是exist
  3. 范式
    1. 范式问题只看两个东西
      1. 依赖
        1. 1.多值 and 非多值
        2. 2.主要通过画图解决
        3. 3.使用范围是1-3+bc范式
      2. 候选码
        1. 能唯一标识元组的码

依赖:

1. 平凡与非平凡依赖
    1. 非平凡: (Sno,Cno) ->Grade
    2. 平凡:        (Sno,Cno)   ->Sno
                 (Sno,Cno)   ->Cno
2. 部分与完全函数依赖
    1. 完全:    (Sno,Cno)->Grade
    2. 部分:    (Sno,Cno)->Sname
3. 传递与直接函数依赖

范式:

BCNF与1,2,3NF的区别:
    BC是主属性之间的依赖,而1,2,3是非主属性与主属性之间的依赖

结论:

1. 如果不存在依赖—>化为4NF
2. 如果是全码为候选码(无非主属性)->至少BC
3. 依赖与候选码之间的关系  ->确定2NF 3NF


注:
像图片中所显示依赖关系,你是画不出依赖图的
必须先进行处理,求最小函数依赖集

2017年6月28日 下午10:08

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
创建存储过程
mysql> create procedure insert_user()
-> begin
-> insert into user(username) values('czh');
-> end
-> //


delimiter //
create procedure insert_user()
begin
insert into user(username) values('czh');
select now();
end
//
delimiter ;


创建事件
mysql> create event e_insert
-> on schedule every 10 second starts '2016-5-14 20:00:00'
-> on completion preserve
-> do call insert_user();


create event e_insert
on schedule every 10 second starts '2016-5-14 20:00:00'
on completion preserve
do call insert_user();

建数据表
mysql> create table table1(
-> id int primary key auto_increment,
-> time_start date not null,
-> time_long int not null
-> );
对表中的数据进行date类型的操作(增加)
select date_add((select time_start from table1 where id=1),interval(select time_long from table1 where id=1) day);

比较两个date类型的数据
mysql> set @d1=now();
Query OK, 0 rows affected (0.00 sec)

mysql> select @d1;
+---------------------+
| @d1 |
+---------------------+
| 2016-05-14 21:15:41 |
+---------------------+
1 row in set (0.00 sec)

mysql> set @d2=date_add(@d1, interval 30 day);
Query OK, 0 rows affected (0.00 sec)

mysql> select @d2;
+---------------------+
| @d2 |
+---------------------+
| 2016-06-13 21:15:41 |
+---------------------+
1 row in set (0.00 sec)

mysql> @d1>@d2;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@d1>@d2' at line 1

mysql> select @d1>@d2;
+---------+
| @d1>@d2 |
+---------+
| 0 |
+---------+
1 row in set (0.18 sec)

mysql> select @d1<@d2;
+---------+
| @d1<@d2 |
+---------+
| 1 |
+---------+
1 row in set (0.00 sec)


mysql> delimiter //
mysql> create procedure proc1()
-> begin
-> declare no_more_record int default 0;
-> declare time_start1 date;
-> declare time_long1 int;
-> declare id1 int;
-> declare if_date date;
-> declare cur_record cursor for select time_start,time_long,id from table1;
-> DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_more_record = 1;
-> open cur_record;
-> fetch cur_record into time_start1,time_long1,id1;
->
-> while no_more_record !=1 do
-> set if_date=date_add(time_start1,interval time_long day);
-> if if_date>now() then
-> update table1 set status=1 where id=id1;
-> end if;
-> fetch cur_record into time_start1,time_long1,id1;
-> end while;
->
-> close cur_record;
->
-> end;
-> //


delimiter //
create procedure proc1()
begin
declare no_more_record int default 0;
declare time_start1 date;
declare time_long1 int;
declare id1 int;
declare time_add date;
declare time_now date;
declare cur_record cursor for select time_start,time_long,id from table1;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_more_record = 1;
open cur_record;
fetch cur_record into time_start1,time_long1,id1;
set time_now=now();

select time_now;
select time_start1;
select time_long1;
select id1;

while no_more_record !=1 do
set time_add=date_add(time_start1,interval time_long1 second);

select time_add;

if time_add<time_now then
update table1 set status=1 where id=id1;
end if;
fetch cur_record into time_start1,time_long1,id1;
end while;
close cur_record;
end
//
delimiter ;

create event e_proc1
on schedule every 1 second starts '2016-5-14 20:00:00'
on completion preserve
do call proc1();

//如何进行对存储过程中的变量进行测试
delimiter //
CREATE PROCEDURE test()
begin

declare a varchar(10);

set a = "test";

select a;

select a;

end
//
delimiter ;


procedure中传参的区别
Ⅰ. IN参数例子-----------------------IN 输入参数:表示该参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值
创建:
mysql > DELIMITER //
mysql > CREATE PROCEDURE demo_in_parameter(IN p_in int)
-> BEGIN
-> SELECT p_in;
-> SET p_in=2;
-> SELECT p_in;
-> END;
-> //
mysql > DELIMITER ;

执行结果:
mysql > SET @p_in=1;
mysql > CALL demo_in_parameter(@p_in);
+------+
| p_in |
+------+
| 1 |
+------+

+------+
| p_in |
+------+
| 2 |
+------+

mysql> SELECT @p_in;
+-------+
| @p_in |
+-------+
| 1 |
+-------+

以上可以看出,p_in虽然在存储过程中被修改,但并不影响@p_id的值

Ⅱ.OUT参数例子-----------------------------OUT 输出参数:该值可在存储过程内部被改变,并可返回
创建:
mysql > DELIMITER //
mysql > CREATE PROCEDURE demo_out_parameter(OUT p_out int)
-> BEGIN
-> SELECT p_out;
-> SET p_out=2;
-> SELECT p_out;
-> END;
-> //
mysql > DELIMITER ;

执行结果:
mysql > SET @p_out=1;
mysql > CALL sp_demo_out_parameter(@p_out);
+-------+
| p_out |
+-------+
| NULL |
+-------+

+-------+
| p_out |
+-------+
| 2 |
+-------+

mysql> SELECT @p_out;
+-------+
| p_out |
+-------+
| 2 |
+-------+

2017年6月28日 上午8:14

最重要的

  1. 看源码的第一步一定是了解他的业务流
  2. 语言的基础功底一定要扎实

编码规范 (见文知意)

  1. 方法名和类名要有准确的意思
  2. 每个类 每个方法都要写清楚注释
  3. 目录结构

    工具的使用

  4. UML 生成类图:simpleUML(这个插件自己按)
    1. 先看有什么
      1. stepMode类 和 CountDownTimer是抽象类
      2. StepCallBack是接口
      3. StepInAcceleration和StepPedometer是继承自StepMode
      4. 左边为一个整体,右边为单独的部分
    2. 再分析结构
      1. 左边是一个策略模式,StepService包含进其他两个蓝色类中
      2. 右边也被用到了左边的类中,但是不是通过UML中的组合_继承_等
    3. 具体看类:
      1. StepDate:是作为model ,在一个类中放在List集合中
      2. Constant 和 DbUtils:他们中全是static属性和方法,直接通过类名来使用
      3. CountDownTimer:是抽象类,在这个项目中是用于声明内部类
      4. MainActivity:是一个activity,主要与StepService进行交互
  5. Structure:快速查看类方法,属性,以及他们的类型
  6. 断点:跟踪执行路径

在敲代码之前,他们就知道了整体的结构图

问自己这些问题:

  1. 类有哪些
  2. 他们之间的关系是怎样的
  3. 哪些需要拆分
  4. 哪些需要合并
  5. 这个功能通过这些类能不能实现进行带入测试

就像我当初设计数据库的时候,花了我半个月

2017年6月28日 上午8:05

1.java.util.

collections:算法集合
collection
List set
arraylist Linkedlish hashset treeSet

collection 不唯一 无序
List 不唯一 有序
Set 唯一 无序

Map :键值对

Arraylist : 长度可变的数组

* list.size()    
* list.get(index) 返回类型是Object (一般需要强转)
* list.add(“AA”);
* list.add(2,”BB”);
    * 当index小于size()时,会后移,不会覆盖
    * 当大于时,数组越界
* list.add(Object)
* list.addAll(collection)
* 可重复
* for(Object ob : list){}这里必须为Object,不能写具体的对象类
* Object o = list.remove(index) 删除执行位置,返回这个对象
* Boolean ans  = list.remove(Object)删除指定第一个对象  返回true false
    * remove()的两个方法容易混
    * remove()的删除时,注意:删一个移动一次,后面所有元素下标都会改变,容易越界错误,或者元素位置判断错误
* list.contains(Object) 返回true  false
* list可以添加null元素
* list.clear()移除所有
* list.indexOf(Object)
* list.empty()
* list.toArray();
* 首次,默认长度为10,以后没有增加原先的一半
* list没有insert()方法
* 改变list中的内容 
1
2
3
//改变list中的内容 
list.remove(i);
list.add(i,strings.toString());

LinkedList : 链表的存储方式

* list.addFirst()
* list.addLast()
* list.removeLast()
* list.removeFirst()
* List list = new LinkedList();
    * 这个list对象不可以调.addFirst()方法,这是子类的特有方法
* list.getFirst()
* list.getLast() 

set

* Set set = new HashSet()
* set.add(“aa”);
* set.remove(“aa”);
* 当再插入”aa”时,不会报错,但是只有一个“aa”
* set没有get方法,因为是无序的

map

* Map map = new HashMap();
* map.put(“key”,”value”);
    * map.put(null,null)正确
    * map.put(“key1”,”value1”)
    * map.put(“key1”,”value2”)
    * 这时 value1 就被覆盖了
    * map.put(“key”,Object)
* map.get(“key”); 返回Object
* map.size();
* map.keySet();key集合  返回set
* map.Values();value集合 返回collection
    * 如果value是Object,那么会执行toString()方法
* map.containsKey(“key”);是否包含  true false
* map.remove(“key”);
* **map不可以直接遍历,但可以直接打印**
1
2
3
4
5
6
7
8
Map map = new HashMap();	
map.put(1, penguin1);
map.put(2, penguin2);
map.put(3, penguin3);
System.out.println(map);

输出
{1=Penguin [name=czh1, id=1, love=100], 2=Penguin [name=czh2, id=2, love=100], 3=Penguin [name=czh3, id=3, love=100]}

vector 与 ArrayList的区别

* vector线程安全,ArrayList是重速度,轻安全,线程非安全
* 长度增长时,Vector默认增长一倍,ArrayList增长50%

HashTable 和 HashMap的异同

* 实现原理,功能相同,可以互用
* 主要区别
    * HashTable 继承Dictionary类,hashMap实现Map接口
    * HashTables线程安全,HashMap线程非安全
    * HashTable 不允许null值,HashMap允许null

iterator

  • 两种遍历方式(iterator 和 增强型for循环)
    1
    2
    3
    4
    Iterator it = map.keySet().iterator();
    while(it.hasNext()){
    syso(it.next())
    }
    1
    2
    3
    for(Object ob:map.values()){
    syso(ob);
    }
    1
    2
    3
    for(Iterator it = map.values().iterator();it.hasNext();){
    System.out.println(it.next());
    }
  • map不可以获取iterator(),其他的list类和set都可以通过iterator来遍历

总结:
* 如何选定集合?
* 如何判断他们能执行的方法?
* 通过存储方式!!!

泛型的作用

  • 类型限定
  • 取出来的元素不用做强制转换了

    2.toString()方法可直接生成,打印属性

    3.打架包批文件

    4.知识在项目会用才算会用

    5.文件

    java.io.file

    方法:

    • exists()
    • isFile()
    • isDirectory()
    • getName()
    • getPath()返回相路径
    • getAbsolutePath()返回绝对路径
    • length()字节为单位 如果不存在返回OL
    • createNewFile()
    • delete()

      路径

    • File file = new File(“hello.txt”)
    • File file = new File(“e:\hello.txt”)

System.getProperty(“user.dir”);
获取当前项目路径
_Users_czh_Documents_workspace/Class628

读写文件

流:一连串流动的字符,是以先进先出方式发送消息的通道
输入输出流相对于计算机内存来说

分类

* 按照流向分
    * InputStream  Reader 都是抽象类
    * OutputStream Writer 
* 按照处理单位分
    * 字符流
    * 字节流    

字节流是8位通用字节流
字符流是16位Unicode字符流

FileInputStream fio = new FileInputStream(“hello.txt”);
不能直接用InputStream(outStream)他们是抽象类

FileInputStream读

* fio.read()
    * 对一个字节
* fio.read(byte []b)
    * **返回读出的字节数   而不是数据本身**
    * 最大长度为b.length
    * 没有读出返回-1
* fio.read(byte []b , int off , int  len)
    * 写入位置从off开始
    * 读入的个数为len个

FileOutputStream写

* fio.write()
    * 写一个字节
* fio.write(byte []b)  
    * 无返回 
    * **if(fio.write(b) != -1){}这的写是错的**
* fio.write(byte []b , int off ,int len )
    * 无返回
**不要对同一个文件同时读 写**
1
2
3
4
5
6
byte []b = new byte[1024];
int i = fio.read(b)
while(i != -1){
//这里可以把b插入到其他文件中
i = fio.read(b);
}

FileReader 字符读

1
2
3
4
5
6
7
8
9
10
StringBuffer sb = new StringBuffer();
FileReader reader = new FileReader(“hello.txt”);
BufferedReader br = new BufferedReader(reader);
String str= br.readLine();
while(str! = null){
sb.append(str);
str = br.readline();
}
br.close();
Reader.close();

FileWriter 字符写 (这里不要写成FIileWrite)

1. 第二个参数 = true 可以设置成追加
2. bw.flush(); 写的时候必须刷新缓存
3. bw.newLine(); 
4. close 注意:**关闭流时的原则:先开后关,后开的先关**
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/*
*循环字节流插入
*/
public class FileReaderTest {

public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub

// file("hello3.txt");
FileWriter fw = new FileWriter("hello4.txt");
BufferedWriter bw = new BufferedWriter(fw);

FileReader fr = new FileReader("hello3.txt");
BufferedReader br = new BufferedReader(fr);

String string = new String();
string = br.readLine();
while(string != null){
string = string.replace("{name}", "小花")
.replace("{type}", "猫")
.replace("{master}","czh");

bw.write(string);
bw.flush();
bw.newLine();

string = br.readLine();
}

br.close();
fr.close();

bw.close();
fw.close();
}
/*
* 创建新的文件
*/
public static void file(String name) throws IOException{
File file = new File(name);
if(file.exists()){
System.out.println(file.getName());
System.out.println(file.getAbsolutePath());
System.out.println(file.getPath());
//file.delete();
//System.out.println("以删除文件");
}
else{
file.createNewFile();
System.out.println("已经创建文件");
}
}
}

DateInputStream 读写二进制文件

1. **他们两的参数是FileInputStream()**
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void main(String args[]) throws IOException{
DataInputStream dis = new DataInputStream(new FileInputStream("1.jpg"));
DataOutputStream dos = new DataOutputStream(new FileOutputStream("2.jpg"));

byte[] b = new byte[1024];
int i = dis.read(b);
while(i != -1){
dos.write(b,0,b.length);
i = dis.read(b);
}
dos.flush();
System.out.println("完成");
dos.close();
dis.close();

}

ObjectInputStream 这个必须序列号

1
2
3
public class Pet implements  Serializable  {

}

总结:

1. 一共有四种 
    1. 文件字节读写  FileInputStream
    2. 字符读写 FileReader + BufferedReader
    3. 二进制读写  FileInputStram + DataInputStream
2. 二进制读写是万能的方法,不用管复制的文件是啥。

练习(用文件实现用户登陆系统-有数据登陆,没数据添加)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String name;
String pwd;

String rname;
String rpwd;

String str[] = new String[10];
//从文件中取出rname rpwd
FileReader fr = new FileReader("hello1.txt");
BufferedReader br = new BufferedReader(fr);

//将数据取出到str[]中
String string = new String();
string = br.readLine();
int i = 0;
while(string != null){
str[i++]=string;
string = br.readLine();
}
br.close();
fr.close();

Scanner scan = new Scanner(System.in);
System.out.println("请输入用户名");
name = scan.next();
System.out.println("请输入密码");
pwd = scan.next();

//将取出的数据分解到rstr做判断
String rstr[] = new String[2];
int flag = 0;
// System.out.println(str.length);
// for(int j = 0 ;j < str.length;j++){
for(int j = 0 ;j < i;j++){
rstr = str[j].split(" ");
if(rstr[0].equals(name) && rstr[1].equals(pwd)){
flag = 1;
break;
}
}

if(flag == 1){
System.out.println("登陆成功");
}
else{
//将name 和 pwd写入hello1.txt中
FileWriter fw = new FileWriter("hello1.txt",true);
BufferedWriter bw = new BufferedWriter(fw);
bw.newLine();
bw.write(name+" "+pwd);
bw.flush();

bw.close();
fw.close();
System.out.println("登陆失败,数据已写入");
}

}

6.报错

Unreachable code
原因:return 之后写代码

char 不能写成 Char

7.StringBuffer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package package1;

public class Test2 {

public static void main(String[] args) {
// TODO Auto-generated method stub
String string[] = new String[10];
System.out.println("string[0]的值:"+string[0]);
string[0] = "abc";
System.out.println("string[10]的长度:"+string.length);


StringBuffer sb[] = new StringBuffer[10];
System.out.println("stringBuffer[0]得值:"+sb[0]);

sb[0] = new StringBuffer();
sb[0].append("abc");
System.out.println("stringbuffer[10]的长度:"+sb.length);


StringBuffer sb1 = new StringBuffer();
// sb1 = "开始";//Type mismatch: cannot convert from String to StringBuffer
sb1.append("开始");
method_buffer(sb1);
System.out.println("stringbuffer 引用传参:"+sb1);

String string1 = new String();
string1 = "开始";
method_string(string1);
System.out.println("string 值传参:"+string1);

Student student = new Student();
method_student(student);
System.out.println("student 引用传参"+student.getAge());

}

public static void method_buffer(StringBuffer sb){
sb.append("abc");
}
public static void method_string(String string){
string = string+"abc";
}
public static void method_student(Student student){
student.setAge(20);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package package1;

public class Student {
private int age = 0;

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

}
1
2
3
4
5
6
7
8
输出:
string[0]的值:null
string[10]的长度:10
stringBuffer[0]得值:null
stringbuffer[10]的长度:10
stringbuffer 引用传参:开始abc
string 值传参:开始
student 引用传参20

总结:String对象是值传递,其他的对象(stringbuffer+自定义student)都是引用传递

2017年6月27日 上午6:47

2020年4月11日 下午1:18复习

从问题的角度总结一下这几个模式:

  1. 介绍一下工厂模式
    1. 首先,工厂模式说人话来解释就是:我程序员在面向对象语言中,希望可以有一个对象的类,这个类中可以将完成某一任务需要的对象组织在一起,而不是零散的,这样对程序员来说,思维上更加清晰,一次性的就可以获得所有需要的类,直方便的要死。
      1. 这里面的关键就是:将完成某一任务需要的对象进行组织,组织在工厂类A中;当我们需要添加新的任务线时,我们只需要新建一个工厂子类,这个子类又会组织一个新的对象集合B。
      2. 程序员在完成功能的时候就会想:我是选择工厂类A还是工厂类B
    2. 其次,说道工厂模式设计到三个细分的模式:工厂模式,抽象工厂模式,原型模式,这三个模式是不断递进的关系
    3. 抽象工厂模式在工厂模式的基础上考虑到了所谓product这部分可以将来会扩展,也就是有多个product,基本的工厂模式本身的设计只考虑到了一个product的情况。
    4. 原型模式在抽象工厂模式的基础上,考虑到了在抽象工厂模式和工厂模式中,工厂子类A,工厂子类B中各自包含的对象是在我们定义这个子类的时候就写死的,那么程序员需要再编程的时候,自由的组装一些类呢?此时这种固定的工厂子类就不好用了,我们可能需要再定义一个工厂子类C才可以满足我们的需要。另外一种办法就是使用这里的原型模型,这里的原型两个字,我把他理解成抽象类,我的工厂类此时包含的我们完成某些功能需要的各种帮手类的上层abstract抽象类,因为使用的是抽象类,那么程序员就可以在使用原型模式的时候自己定义其中抽象类的子类,这样给程序员的自由度就大了,它就不需要在定义一个新的工厂子类C了
  2. 介绍一下熟悉的模式?
    1. 在各种模式里面,我认为有关于各个类进行组合完成功能的都是比较简单的设计模式,也可以说的高端一些叫做:组合由于继承。具体来说:
    2. 组合模式:这个模式他解决的问题十分的明确:如果不用组合模式,那么就无法自己包括自己。对于这种目的性很清晰的设计模式,我们可以很快的判断我们需要不需要使用,何时使用
      1. 组合模式自带的一个特性就是递归,因为自己可以包含多个自己
      2. 组合模式下的对象可以展开成一个树,结合数据结构的知识,那么我们就可以对树进行遍历,这个任务就落在了下面 访问者模式中。
    3. 访问者模式:为什么要写在组合模式的后面,因为访问者模式其中就包含组合模式,访问模式在组合模式的基础上添加了一个访问者,这个访问者的任务就是可以对组合模式下的对象进行递归的遍历,在一层一层的遍历树的的过程中统计一些信息
    4. 另外还要一个典型使用组合的模式:策略模式。策略模式将本来是自己儿子的子类,变成了自己的partner的关系。这样做的目的:当我们需要再父子类继承关系之间插入新的关系时,就会造成子类的重复,这是我们不需要看到的。
  3. 最后在介绍一下比较难的观察者模式:这个模式其实就是策略模式,观察者就是原先的partner,用来辅助主类的工作,在UML中和策略模式一样,使用的是组合的符号,但是有一点不一样:观察者模式加了一个新的需求:一个partner对象只能被我指定的主类对象使用,所以在partner帮助主类完成功能的时候,partner需要验证一下是不是指定的主类在让我帮他忙,如果不是我就不帮你干。这个新的需求需要两个步骤来完成:在定义parner的时候,就需要从通过构造方法指定主类对象,另外,在帮忙的时候,partner需要自己验证一下是否和自己定义时的主类是一个人。

2019年3月28日 下午2:33 复习
从名字的角度就可以直观的理解

  1. 组合模式:有非常多的子类,他们之间的层级关系并不是十分的固定,有的甚至会出现递归的情况
  2. 解释器模式:如果要想编出一个类似于人类语言解释的程序,这时就可以考虑。
  3. 访问者模式:有访客来你家,他会了解到你的家庭情况,并可以单独的做出判断。有点像查户口的。
  4. 策略模式:类的层次太多的时候,要考虑组合优于继承。
  5. 观察者模式:其实可以把观察者理解成”监工“,检测别人的行为是否正确,并且可以有多重验证。
  6. 工厂模式:每次产生一对一,一个是manager,一个是干活的
  7. 抽象工厂模式:每次产生一对多,一个manager,多个干活的
  8. 原型模式:原型的意思就是不是成品。给你个原型,可以让用户更好的DIY,更加灵活一些。

来源:深入php,面向对象,模式与实践{书}

​分类:

  1. 生成对象:单例模式,工厂模式,抽象工厂模式,原型模式
  2. 构建类和对象:组合模式,装饰模式,外观模式
  3. 执行和描述任务:解释器模式,策略模式,观察者模式,访问者模式,命令模式
  • 每个模式的产生都对应着一个问题,而这个问题正是指导我们使用哪种模式的根本原因!

  • 我将以上的模式按照我自己的理解重新编排的顺序,使他们成为递进的关系,通过比较同一类型的几个之间不同之处,加深理解。

    • 工厂模式->抽象工厂模式->原型模式 生成对象(集)
    • 策略模式->观察者模式 雇主和雇员
    • 组合模式->解释器模式->访问者模式 组合
    • 修饰模式 父子
    • 单例模式

工厂模式:

问题:

* 在**代码运行**的时候才知道要生成对象的类型
* 要轻松的加入一些**新的**产品类型
* 每个产品类型都可以**指定特定的功能**


图1

图2

图3
注:
* 图一失败案例
* 图三体现了从图二的扩展,说明了工厂模式的横向扩展性

抽象工厂模式

问题:

* 在大型应用中,我们可能需要工厂来产生**一组**相关的类
* 图4中,左面增加一个,右面就增加四个,**一对多的关系**
* 工厂模式**一对一**,抽象工厂模型**一对多**


图1

图2

图3

图4
注:
* 图1,体现了要实现纵向扩展性
* 从图3 到 图4 体现了横线纵向扩展
* 工厂方法使用了多态
* 那么他就只能使用父类的方法,无法使用子类中特有方法

原型模式

问题

* 工厂模式和抽象工厂模式生成对象都在工厂的方法中,也就说是**写死的**
* 原型中因为对象是作为参数传进去的,所以,可以**自由组合**
* 也可以在生成对象时,根据**构造方法**传不同的参数,产生不同的对象
* **原型模式其实就是善用了构造方法**

注:
* 以上者三个模式,关系都是《create》 ,是用来生成对象或对象组合的

组合模式

总结:

* 组合模式中继承结构是**树形结构**,由根部的基类开始,分支到各个不同的子类,在继承树中可以轻松的生成枝叶,也可容易的**遍历整个树中的对象**
* 如果不用组合模式,那么就无法**自己包括自己**


图1

装饰模式

总结

* 没有装饰模式,无法生成**同时 被污染+有钻石 的对象**
* 有了装饰模式,不用创建PollutedDiamondPlains就可以生成上述对象


图1

图2
注:
* new PollutionDecorator(new DiamondDecorator(new Plain()))
* 装饰模式也强调使用构造方法
* 这里的符号是组合

外观模式

总结

*  外观模式为复杂多变的系统创建一个简单清晰的接口
* 我的话来说,**就是把好几步的东西放在一个类中**,自己只需要第一步,其他后面的自动走完了     

解释器模式

总结

* 解释器模式是组合模式的应用
* 组合模式组合的方式是通过**方法**,而解释器模式是通过**构造方法**     
* 组合模式中仅仅是组合的,但是却没有利用可以**递归的这一特性**
* 并且还运用UML中组合,将一个对象放入抽象类的中


图1
注:
* 最后的效果:先通过构造方法生成一条表达式,然后传入参数,看这条表达式是否成立
* 同样是强调使用构造方法

图2

图3

策略模式


图1

图2

图3
总结:
* 图2 是 图1 的扩展,但是发现这样会造成代码的重复
* 出现的原因是:向中间插入了一层
* 解决:将重复的类,单独拿出来,通过组合优于继承来解决

观察者模式

总结

* 观察者模式是策略模式的增强版
* 策略模式模式通过主类(左边)来调用自己的方法将 副类(右边)添加到主类(左边)中
* 但是,无法保证**这个主类就是规定的能调用副类的那个主类**,也就是说,怕有的人胡乱用副类
* 解决:**这个副类 来添加 主类,通过构造方法,在构造方法中再去执行主类添加副类这一操作**,在构造方法中做了类型限定。这样就可以避免那样的问题。


图1

图2
注: 2019年3月28日 下午3:08

  1. 从上面的图来看的话,其实可以把观察者理解成”监工“,检测login登录的是否正确,并且可以有多重验证。

访问者模式

总结

*  访问者模式开起来很高深,但是用我的话来说就是“原来是在Composite中添加方法,每增加一个递归的功能就增加一个方法,现在是Composite直接提供了一个接口,让这些功能共同使用,当然外面需要一个类似于ArmyVistior的抽象,来提供多态支持”
* 作者的话“现在只需要添加几个方法,新功能就可以方便的添加到组合类中,而不需要包含他们的接口,也不会产生大量的重复的遍历代码”


图1

图2
注:
* 这里的$main_army->accept($taxcollector)就像一个开关一样,触发了递归
* 这里传进去一个实例,但是通过观察者模式的震撼,其实传进去的实例并不代表要低一个等级,说不定也是老大!