java基础个人总结

java基础个人总结………………………………………………………………………………………………………………… 6

Ø 写程序需要注意的事项……………………………………………………………………………………………….. 6

Ø 容易犯错误的地方……………………………………………………………………………………………………… 6

Ø Eclipse常用快捷键……………………………………………………………………………………………………. 8

  1. 最常用:………………………………………………………………………………………………………………. 8
  2. 次常用:………………………………………………………………………………………………………………. 8
  3. Eclipse………………………………………………………………………………………………………………… 9

Ø 第一天:………………………………………………………………………………………………………………… 10

1,常用DOS命令………………………………………………………………………………………………….. 10

2,path & classpath…………………………………………………………………………………………………. 10

3, jvm jre jdk 区别……………………………………………………………………………………………….. 11

4,java程序的编写注意事项…………………………………………………………………………………….. 11

Ø 第二天:………………………………………………………………………………………………………………… 12

一、 常量…………………………………………………………………………………………………………….. 12

二、 进制转换:……………………………………………………………………………………………………. 12

三、 变量…………………………………………………………………………………………………………….. 12

四、 引用型数据类型:………………………………………………………………………………………….. 13

五、 运算符:………………………………………………………………………………………………………. 13

Ø 第三天……………………………………………………………………………………………………………………. 15

一、 if语句………………………………………………………………………………………………………….. 15

二、 switch(翻译:开关,切换)语句……………………………………………………………………… 15

三、 循环语句………………………………………………………………………………………………………. 15

四、 break;continue用法……………………………………………………………………………………….. 16

五、 在练习题中需要掌握……………………………………………………………………………………….. 16

Ø 第四天……………………………………………………………………………………………………………………. 17

一、 函数 (也称方法)………………………………………………………………………………………… 17

二、 数组…………………………………………………………………………………………………………….. 18

Ø 第五天……………………………………………………………………………………………………………………. 20

数组应用技巧………………………………………………………………………………………………………… 20

第六天  开始–面向对象……………………………………………………………………………………………….. 23

Ø 第七天……………………………………………………………………………………………………………………. 27

一、 静态(static关键字)………………………………………………………………………………………….. 27

二、 文档注释–javadoc…………………………………………………………………………………………… 28

三、 Singleton 单实例……………………………………………………………………………………………. 29

四、 静态代码块……………………………………………………………………………………………………. 31

Ø 第八天 继承……………………………………………………………………………………………………………. 32

一、 继承 extends………………………………………………………………………………………………….. 32

二、 super…………………………………………………………………………………………………………….. 33

三、 final……………………………………………………………………………………………………………… 33

四、 继承中的构造函数………………………………………………………………………………………….. 34

五、 抽象abstract…………………………………………………………………………………………………… 34

Ø 第九天  多态………………………………………………………………………………………………………….. 35

一、 接口 interface………………………………………………………………………………………………… 35

二、 多态…………………………………………………………………………………………………………….. 36

三、 多态之经典模式……………………………………………………………………………………………… 38

Ø 第十天……………………………………………………………………………………………………………………. 38

一、 Object类……………………………………………………………………………………………………….. 38

二、 内部类………………………………………………………………………………………………………….. 40

三、 匿名内部类……………………………………………………………………………………………………. 41

Ø 第十一天 异常…………………………………………………………………………………………………………. 42

一、 异常处理………………………………………………………………………………………………………. 42

二、 包 package…………………………………………………………………………………………………….. 44

三、 import 关键字……………………………………………………………………………………………….. 46

Ø 第十二天 多线程……………………………………………………………………………………………………… 46

一、 多线程………………………………………………………………………………………………………….. 46

二、 多线程同步……………………………………………………………………………………………………. 48

Ø 第十三天………………………………………………………………………………………………………………… 50

一.死锁………………………………………………………………………………………………………………… 50

二.线程之间通讯之生产者消费者………………………………………………………………………………. 51

  1. 三. 中断线程…………………………………………………………………………………………………………. 55
  2. 四. 线程一些常用方法:……………………………………………………………………………………………. 56

Ø 第十四天: String类…………………………………………………………………………………………………… 57

一、 String类……………………………………………………………………………………………………….. 57

Ø 第十五天………………………………………………………………………………………………………………… 63

一、 StringBuffer类……………………………………………………………………………………………….. 63

二、 基本数据类型包装类……………………………………………………………………………………….. 65

Ø 第十六天 集合…………………………………………………………………………………………………………. 66

一、 Collection集合接口…………………………………………………………………………………………. 66

二、 Iterator迭代器—重点………………………………………………………………………………………. 68

三、 List集合(接口)……………………………………………………………………………………………….. 69

Ø 第十七天………………………………………………………………………………………………………………… 70

一、 ListIterator接口………………………………………………………………………………………………. 70

二、 ArrayList类…………………………………………………………………………………………………… 71

三、 List接口下的LinkedList…………………………………………………………………………………… 72

四、 Set集合–之HashSet………………………………………………………………………………………… 73

五、 重写hashcode值和equals…………………………………………………………………………………. 75

Ø 第十八天………………………………………………………………………………………………………………… 76

一、 TreeSet集合类……………………………………………………………………………………………….. 76

二、 Comparable(自然顺序)与Comparator(比较器接口)…………………………………………………. 76

三、 LinkedHashSet………………………………………………………………………………………………… 77

四、 泛型…………………………………………………………………………………………………………….. 78

Ø 第十九天………………………………………………………………………………………………………………… 79

一、 map集合………………………………………………………………………………………………………. 79

二、 Collections工具类…………………………………………………………………………………………… 82

三、 Arrays(数组)工具类…………………………………………………………………………………………. 84

四、 增强for循环…………………………………………………………………………………………………. 85

五、 静态导入………………………………………………………………………………………………………. 85

六、 方法的可变参数……………………………………………………………………………………………… 86

七、 System类………………………………………………………………………………………………………. 86

八、 Runtime类…………………………………………………………………………………………………….. 87

九、 Math             数学类                                                                                                       87

十、 Date  时间日期类…………………………………………………………………………………………… 88

十一、 DateFormat 时间日期格式化类………………………………………………………………………. 88

十二、 集合总结:…………………………………………………………………………………………………… 90

Ø 第二十天 IO流………………………………………………………………………………………………………… 92

一、 1.Calendar抽象类……………………………………………………………………………………………. 92

十三、 File类……………………………………………………………………………………………………….. 93

十四、 递归………………………………………………………………………………………………………….. 96

Ø 第二十一天……………………………………………………………………………………………………………… 98

一、 字符流的写入 FileWriter………………………………………………………………………………….. 98

二、 字符流的读取 FileReader……………………………………………………………………………….. 101

三、 字符写入缓冲流BufferedWrite…………………………………………………………………………. 104

四、 字符读取缓冲流BufferedReader……………………………………………………………………….. 105

五、 LineNumberReader用法………………………………………………………………………………….. 106

Ø 第二十二天……………………………………………………………………………………………………………. 107

(一) 字符流与字节流框架与转换…………………………………………………………………………. 107

(二) 字节流读写数据(重点)………………………………………………………………………………… 108

(三) 用字节缓冲流读写数据……………………………………………………………………………….. 109

(四) 转换流……………………………………………………………………………………………………… 110

(五) 流的操作规律:…………………………………………………………………………………………. 111

Ø 第二十三天:…………………………………………………………………………………………………………… 112

一、 打印流:……………………………………………………………………………………………………….. 112

二、 对象流………………………………………………………………………………………………………… 114

三、 properties集合………………………………………………………………………………………………. 116

四、 编码与解码………………………………………………………………………………………………….. 118

Ø 第二十四天……………………………………………………………………………………………………………. 119

一、 GUI可视化编程……………………………………………………………………………………………. 119

二、 枚举…………………………………………………………………………………………………………… 124

Ø 第二十五天 网络编程……………………………………………………………………………………………… 124

Ø 第二十六天: 正则…………………………………………………………………………………………………… 130

一、 正则表达式:…………………………………………………………………………………………………. 130

二、 URL类和URLConnection类 了解……………………………………………………………………. 131

三、 JAVA反射机制:…………………………………………………………………………………………….. 132

Ø 第二十七天–html……………………………………………………………………………………………………. 135

一、 html……………………………………………………………………………………………………………. 135

二、 html网页数据提交………………………………………………………………………………………… 138

Ø 二十八天–ccs…………………………………………………………………………………………………………. 140

Ø 第二十九天–javaScript…………………………………………………………………………………………….. 143

Ø 第三十天:–DOM与BOM…………………………………………………………………………………………. 148

Ø 第三十一天: DHTML编程事例………………………………………………………………………………….. 151

一、 DHTML应用………………………………………………………………………………………………… 151

Ø 第三十二天–DHML综合运用与javaScript表单校验………………………………………………………. 155

一、 DHML综合运用……………………………………………………………………………………………. 155

二、 javaScript表单校验……………………………………………………………………………………….. 159

三、 DHTML总结:……………………………………………………………………………………………….. 162

java基础个人总结

Ø  写程序需要注意的事项

  1. 每写完一个小功能,作一个注释,并测试下,看能否成功。
  2. 看代码,首先看格式,看格式上下都要看,格式很重要!
  3. 写代码要细心,不然一会报一大堆错,你就郁闷了.
  4. 出错了要淡定~~

Ø  容易犯错误的地方

  1. 如果数组直接定义内容 int[] in = new int[]{2,3,4};[]里不可以有长度!
  2. 打印是print 输出是out, “字段”表示成员变量,”方法”也是函数.
  3. 有运算符参与运算,为一个表达式,这个表达式必须要有结果,且结果与里面变量结果属于两个类型,如int x=1;x++==2:结果为false,其实加个=就可以明白,运算必须有结果.
  4. \表示转义,字符串里要用两个一起用,比如:“\\.”才表示 .
  5. 变量的作用域是在本方法{}内有效!

成员变量(在类中)可以与局部变量(在方法中)同名,因为存储区域不一样,成员变量在堆内存中,局部变量在栈内存中,this来区分,但局部变量不可以和局部变量同名

public class  Test

{

int x =0;成员变量

public static void main(String[] args)

{

int x =5;局部变量

if (true)

{

int x = 6;局部变量 (这里不合法!!)

}

class Test3

{

int x=7;成员变量,所以这里也合法

}

System.out.println(“Hello fada!”);

}

}

  1. public 及static类型修饰符只能修饰类成员.而final可以修饰方法内的属性.
  1. 创建对象时,里面的成员变量首先自动初始化,然后如果构造函数有赋值操作,再进行赋值操作.
  2. 字符型一旦参与运算,自动强转为整数型参与运算.
  3. 引用型数据类型为默认为null
  4. java执行就近原则,也就是本{}内有,先用自已的, 没有,再去外{}中寻找。
  5. java内存中是先进后出,先进行运行的方法要等后面进去的方法运行完以后再消失.
  6. java对空格没有严格限制,没空格的地方,都可以有空格,多几个与少几个无所谓,但是如果有空格的,绝对不能成为无空格,也就是只能没空格的转为有空格,需要空格的,不能没有空格,如:int[]==int []   但int a!=inta;
  7. 有new就会在堆内存中开辟空间.然后把地址值赋给栈内存.形成指向引用.
  8. 成员变量在类中都有效,但主方法除外.因为主方法是static修饰,只能使用静态成员变量.
  9. 类的属性(变量)可以是任意数据类型.
  10. 构造函数只能用权限修饰符修饰,如public private
  11. class Demo

{

void Demo(){}//这个不是构造函数!!!构造函数格式:[修饰符] 类名(){}没有返回值

}

静态大多与资源有关,因为静态代码块最先执行,且只加载一次.

  1. 每个构造函数第一行默认有一个super();父类的构造函数引用.但一但自已定义了一个super()或super(参数)或this()或this(参数);;那么就不会有!!且super或this在构造函数中,有且只能有一个!这一切都是因为:thissuper在构造函数中只能在第一行!!!!有多个,那么其它的放哪????
  2. this和super只能用于方法中.
  3. java是没有多继承,但接口除外
  4. Test t = new Test(); 假如里面有一个show方法 那么show()==new.Test().show();另外匿名对象,可以独立成一行语句..
  5. 类里有实例属性和类属性,实例方法与类方法.注意一点,实例属性随对象在堆内存中,而类属性在方法区.被static修饰的属性和方法叫类属性和类方法.
  6. final修饰的成员属性没有赋值,还是默认值的情况下,允许在构造函数中赋值一次.(注意:如果同时被static 和final修饰则不允许)
  7. 多态中父类的引用调用属性时,是父类的,调用非静态方法,是子类的重写方法,调用静态方法,即使子类重写了方法,实际调用的还是父类的.\
  8. 类包含属性和方法,但是对象只包含非静态属性,方法在方法区,我们用对象调用方法,所以对象里的内容是非静态属性.
  9. 质数与积数的区别,质数就是只能被本身和1整除的数.唯一的区别就是比积数多一个—2.
  10. 在try{}catch(){}finally异常处理函数中,finally一定会被执行,前提是try之前代码运行正常,没有异常.
  11. for 或if可以不加括号,那么只表示对其下面的一条语句起作用.一个for循环表示一个语句
  12. exit退出虚拟机
  13. i基本数据类型,精度由低到高: byte–short—int—long—float—double
  14. 让一个类不能实例化,两种方法,一是让其为抽象类二是私有化构造函数
  15. 接口没有构造方法.
  16. 基本数据类型的对象缓存:

Integer num3 = 127;

Integer num4 = 127;

System.out.println(num3 == num4);超过127就是false

  1. 集合用增强for循环遍历时,不可以修改里面的元素.
  2. 转换流只能转换字符文件,不然会乱码

Ø       Eclipse常用快捷键

1.      最常用:

Ctrl+N                        创建

Ctrl+D                        删除行

Alt+Down, Alt+Up          移动行

Ctrl+Alt+Down                复制行

Shift+Enter                向下插入行

Ctrl+Shift+Enter        向上插入行

Alt+/                           内容提示

Ctrl+1                         快速修正

Ctrl+/                          单行注释

2.      次常用:

Ctrl+Shift+F                     格式化代码

Ctrl+Shift+/                     多行注释

Ctrl+Shift+\                  取消      多行注释

Alt+Shift+M                     抽取方法

Alt+Shift+R               改名

Crtl+Shift+o               导包

Ctrl+t                         看到一个类的继承结构

Ctrl+Shift+y                    转换成大写

Ctrl+Shift+x                    转换成小写

F3(ctrl+鼠标左键)            看源代码,回来用Alt+左方向键

Ctrl+Shift+o               导包

Ctrl+F                        该 / 为 \

ctrl+L                         去哪一行

ctrl+2+L                     生成变量名

ctrl+T                         看继承关系

ctrl+y                          向前进与ctrl+z相反

alt+left                返回上一个方法(在看源码时用)

ctrl + shift  + t               看源代码

ctrl+鼠标左键或者直接F3           看源码

3.      Eclipse

1.解压缩

从www.eclipse.org下载后解压缩即可使用

使用Eclipse For JavaEE版本, 3.7.2, 路径不要包含中文.

2.启动

选择工作空间, 存放代码的文件夹. use this as default. 如果需要修改, 可以使用File – Switch workspace

3.视图

点击右上角的加号, 选择Java视图

关闭所有视图, 从 window – show view – 打开package explorer, 打开 console

4.编写Java代码

File – new – java project – 输入工程名 – finish

File – new – package – 输入包名 – finish

File – new – Class – 输入类名 – 选择public static void main – finish

编写代码 – 保存时自动编译

点击运行按钮即可运行

6.修改快捷键

Window – Preferences – General – Keys – 搜索要修改的快捷键

例如: 搜索Ctrl+F6, 改为Ctrl+Tab

7.代码生成

右键 – Source

Get和Set方法: Generate Getters And Setters

有参构造函数:   Generate Constructor using Fields

无参构造函数:   Generate Constructor from Superclass

toString:              Generate toString()

equals:                 Generate hashCode() And equals()

8.导入工程

在Package Explorer中右键 – Import – General – Existing project into workspace – Browse

注意不能同时打开同名的工程, 在工程上按F2可以改名

9.修改配置

字体修改: window – preferences – appearance – color and font – basic – text font

拼写检查: window – preferences – 搜索spelling – 取消

Ø  第一天:

1,常用DOS命令

cd 目录 打开目录

cd.. 返回上一层目录

cd\ 返回根目录

md (make directory)创建目录

rd (remove directory)删除目录:不能删除非空目录。

start 在当前dos窗口下创建一个新的dos窗口。

cls 清除当前屏幕

* 作为通配符,可通配文件名,也可通配文件类型,也可作省略用。

tab键: 在当前目录下切换文件

方向键:切换之前输入过的命令行。

2,path & classpath

path就是windows系统可执行程序的环境变量

特点:

设置好后,只需要在运行栏和dos任意目录下输入程序名称便可以运行,不用当程序所在目录。

如何使用:

把程序所在目录位置,放入:windows属性—高级—环境变量—path栏下,并用分号与与其它的环境变量设置隔开。

在dos窗口下,set 显示所有环境变量,

set path 显示path环境变量的所有设置,

set path= 在当前dos窗口下临时清除所有环境变量下的设置。

set path=设置,这表示在当前窗口临时设置。会把之前path设置临时覆盖,如果要保留,则用分号隔开后,在后面加上%path% ,即引用变量。

什么时候用:

你虽要把哪些目录下的程序在dos任意目录打开就去设置。

classpath:只对class文件有效。需要查找当前目录是,前面加.  后面加号也会执行当前目录。后面加分号,则搜寻完设置目录还会搜寻本目录下。

3, jvm jre jdk 区别

jvm java虚拟机,jre(Java Runtime Environmnt )是java运行环境。

jdk(Java Development Kit)开发人员编程工具。

特点:

jdk包含开发工具包和jre,jre包含jvm和java程序所需要的核心类库。

4,java程序的编写注意事项

写程序前三大步骤:需求 思路 和实现步骤。

写程序过程中必须要有注释,三种注释,单行,多行,文档注释。

一个程序,必须要有主方法,且只有一个主方法。

特点:

java严格区分大小写

java必须每一行语句结束后加分号,代表这行语句结束。

标识符就是能自已定义的名称,这些个名称就叫标识符,标识符不能和关键字相同。

由0~9 a~Z $ _组成,无限制长度。

关键字:java给定义了特殊含义的标识符。

Ø  第二天:

一、常量

有六种

整数型常量,浮点型(小数型)常量,字符型常量,字符串常量,布尔型常量,null常量(不在内存开辟空间)。

字符常量 里面只能有一个数字或一个字母或一个符号

二、进制转换:

二进制转八进制 三个二进制位为一组

二进制转十六进制 四个二进制位为一组

8个二进制位表示一个字节

以0开头,这个数值是8进制的

以0x开头,这个数值是16进制

记住一个快捷表:

3个1是7

4个1是15

8个1是255

 1    1   1   1   1   1   1   1  

128  64  32  16   8   4   2   1

三、变量

1.    格式:

数据类型 标识符 = 值;

int d =5;

要先初始化才能使用。

int d;

d=5;这样也可以.

有变化的值是要用到变量。

2.    基本数据类型:

1,整数型变量 byte 1个字节,short 两个字节,int 四个字节 long 八个字节

2,浮点型变量 float 后面可以有6个小数点 double后面可以有12位小数

如果用float a = 4.5f;后面要加f,不然会提示损失精度。long,如果定义的值超过int范围,后面要加l.

整数型和浮点型都属于数值型

3,字符型变量 char 两个字节,java使用unicode表,可以查到绝大部分字符所对应的int型数值。字符型一旦参与运算,自动强转为整数型参与运算.

常用的a=97 b =98 ;A =65 B=66;

4,布尔型变量:ture false

整型  默认值 0    默认类型是int

浮点  默认值 0.0  默认类型double

字符  默认值 \0x0000

布尔  默认值  false

四、引用型数据类型:

有三种:

数组:数组类型[] 数组名=new 数据类型[个数]

接口:interface

类:class

变量特点:

变量之间可以相互转换,可分为自动转换和强制转换。

定义一个变量,其作用范围是在本方法{}内有效。

自动转换:两个不同类型值之间运算,精度低向精度高的转换。

精度从高到低:double –long –int –float—short-char)–byte

强制转换:例如:(char)(值)

五、运算符:

1.    算术运算符:

必须出结果,省略=

例:int x = 1;x++;虽然x==2;但是x++==1

+ ,-,*,/,%(模,用来取余数),++,- –

2.    赋值运算符:

=(最后运算,运算顺序从右到左),+=,-=,*=,/=,%=(可以简化运算)

shoat a =3; a+=4;(这个会自动强转运算==char a=(char)(a+4))

比较运算符:

> , >=,<,<=,  只能操作数值

!=,==,能操作任何类型数据

比较运算符得到的结果是boolean类型

3.    逻辑运算符

只操作条件表达式,结果也为boolean型。

& 与  有假为假

|或 有真为真

!非  相反

&& 双与  ||双或   只要前面满足,不判断后面

^ 异或  两边相同为假,不同这真

单与 单或 用于逻辑判断较少,一般用于位运算。

4.    位运算

比较高效

>>:右移,最高位是0补0,是1补1 ,右移几位,则这个数除以2的几个次方。

<<:左移,移出的舍弃,左移几位,则这个数乘以2的几个次方。

>>>:无条件右移,空位都补零。

用来操作二进制  1 为true  0 为false

& 都为真才是真,也就是都是1,结果才是1,所以可以用来,提取想要位数,用来转进制。

|  有假为假,也就是有1,就为1  用来干嘛?

^ 两边相同为0,不同为1,一个数^同一个数两次,则为其本身,可以用来加密和交换两个数的位置。a=a^b; 10^5   b=a^b; 10^5^5  a=a^b; 10^5^10

~ 取反 1变0 , 0变1. 可以实现 进制转换 正负转换(负数==正数取反加1)

5.    三元运算符

(结果为boolean型的表达式)?(结果为值的表达式1):(结果为值表达示2)

boolean结果为真,执行?后面的表达式;为假,执行:后面的表达式。

//定义两个整数变量,求出其中最大值

int a=12;

int b=45;

int max=a>b?a:b;

System.out.println(“这两个数”+a+”,”+b+”中的最大值是”+max);

Ø  第三天

一、if语句

有三种

if (){};

if(){};else(){};

if(){};else if(){};else if(){};……..最后可以有else 也可以没有。

只和离其最近的if成一个组合起作用,且与if之间不可插入别的语句。

二、switch(翻译:开关,切换)语句

格式:switch(只能是byte ,short,int ,char类型的值)1.7后可以是String

{

case 常量1 :语句1;break;

case 常量2 :语句2;break;

…..可以有多个

default :语句;break;

}

case后只能是常量,且可以不可以重复。default可以不写

如果case后面没有对应的break,那么执行时,就会穿透,会将下面case的语句也执行,直到遇到break结束,或者到结尾.

三、循环语句

1.    while(多用于不确定循环次数)

格式:

while(必须要有条件表达示)

{}

定义的初始化变量在本方法内有效。

2.    do while(do语句首先执行一次)

格式:

do

{}

while(也必须要有条件表达示)

3.    for(多用于能确定循环次数)

格式:

for (初始化变量表达式 ;循环条件表达示 ;步长)   里面三个都可以没有。

{}

四、break;continue用法

break可以用于选择语句switch中和循环语句中;用于结束这个语句。

continue只能用于循环中;用于停止本次循环执行下一次。

语句可以带标号?

如果是带标号的break,continue,它控制的就是标号对应的循环

五、在练习题中需要掌握

1,累加操作

打印0–100的所有值。

for (int x=1;.x<=100;x++)

{System.out.println(x);}

2,计数器操作

//3000米长的绳子,每天减一半,问,需要多少天,绳子会小于5米?

double a =3000;一直减半可能有小数,所以用浮点型。

int day =0;定义一个变量用于计数

while (a>=0)

{

a/=2;

day++;

if (a<5)

{

break;

}

}

System.out.println(“第”+day+”天绳子长度小于5, “+”第”+day+”天绳子长度为:”+a);

//第10天绳子长度小于5, 第10天绳子长度为:2

3,循环嵌套

for (int x =1;x<=4;x++ )

{

for (int y=4; y>x;y– )

{

System.out.print(” * “);

}

Ø  第四天

一、函数 (也称方法)

1.什么是函数?

函数就是完成一个功能的特定代码块。

2.函数有什么用?

可以把一个功能用特定的代码块封装好,让其它方法需要时调用,以便提高函数的复用性,让程序更加合理,减少代码

3.函数怎么用?

方法写在类中,与其它方法并列。

先定义一个方法以实现一个功能:

定义方法前先做两个判断:

1,是否有返回值也就是看运行结束后否有结果需要返回:决定是否要用return.

2,是否有外部数据参与运算:决定是否要使用参数。

用【】表示可以不写,用n代表个数没有限制。

格式:【修饰符 …n】 返回值类型 函数名(【参数类型1 参数名1,参数类型2 参数名2,…..n..】)

{

方法体;

}

需要这个功能时调用:

格式:函数名(【参数1,参数2,…n..】);

4.函数什么时候用?

当想完成某个功能时,我们定义一个方法,让其它方法需要时调用。

5.函数有什么特点?

函数如果设了参数,那么使用时一定要传递参数。

参数只在本在方法中有效,也就是运行方式是接收一个参数然后运行。

函数只能并列不能嵌套。

一般一个方法只定义一个功能。

一个方法中遇到return,这个方法结束。

return后面可以不返回任何值,这个时候当跳出方法用。

6.函数重载

当一个类中具有某一类功能,我们将这类功能定义为一个函数名,通过赋予不同参数进行重载来实现这类功能里的某一个特定功能。

只看参数,有三种方式:

参数类型不同。

参数个数不同。

参数排列顺序不同。

二、数组

1.什么是数组?

数组是装一类数据类型集合的容器。

2.数组有什么用?

可以将相关数据作一个统一管理.

3.数组怎么用?

分为静态与动态两种

动态:元素类型[] 数组名=new 元素类型[长度] 例如:int[] arr = new int[6],

静态定义数组  格式  元素类型[] 数组名={元素值1,元素值2,..}

元素类型[] 数组名=new 元素类型[]{元素值1,元素值2,..};

注意:等号左边[]位置没有限制

操作数组时直接使用数组名

静态数组不能定义长度

操作数组里的元素:数组名[下标]

二维数组:

nt[][] arr = new int [6] [];同样,=左边[]无位置限制.注意:数组里的数组可以没有长度,没有值,但最外层数组一定要有.

如果是一维数组   一层循环就可以遍历

如果是二维数组   二层循环就可以遍历

4.数组什么时候用?

当有同一类型数据且有一定关联,需要进行管理时,要用到数组.

5.数组有什么特点?

1,等号左边[]位置没有限制,

必须同一类型,

必须固定长度,长度为数组名.length

排列有序,从下标0开始,至数组名.length-1结束.

数组元素类型无限制,可以是任意型.

数组在堆内存中,里面的元素也在堆内存中

静态数组不能定义长度

使用数组需要注意的地方

(1)ArrayIndexOutOfBoundsException  数组下标越界

1.超过了最大值

2.出现了负数

  • NullPointerException 以后经常见到 一般情况下都是引用类型为null

Ø  第五天

数组应用技巧

1.    最值

思路:

定义一个变量与数组中每个元素做比较,如果大于变量的值,那么将数组的值赋予变量

public static void max(int[] arr)

{

int max=0;

for (int x = 0;x<arr.length ;x++ )

{

if (arr[x]>max)

{

max=arr[x];

}

}

System.out.println(“最值是”+max);

}

2.    选择排序

将每个数和数组里其它所有的元素比,让最值一直在最左边,比完一轮,最值不参与下一轮.

public static void chooseSort(int[] arr)

{

for (int x=0;x<arr.length-1 ;x++ )

{

for (int y =x+1;y<arr.length ;y++)

{

if(arr[x]<arr[y])

{

swap(arr,x,y);//交换

}

}

}

}

3.    冒泡排序

将两个相邻的数组元素进行比较,让所有的最值向右走,每跑一轮,最值不参与下一轮.

public static void bubbingSort(int[] arr)

{

for (int x=0;x<arr.length-1;x++)

{

for (int y =0; y<arr.length-x-1;y++ )

{

if (arr[y]>arr[y+1])

{

swap(arr,y,y+1);

}

}

}

}

4.    选择排序优化

思路:定义一个指针,让其代替其中一个元素下标且去和每其它元素比较,把每一轮元素最值下标赋予指针,每轮结束后得到的就是最值的下标,然后,把最值换到最左边.

public static void chooseSortOptimaze(int [] arr)

{

for (int x=0 ;x<arr.length-1 ;x++ )

{

int index =x;

for (int y=x+1; y<arr.length;y++ )

{

if (arr[index]>arr[y])

index=y;

}

swap(arr,index,x);

}

}

5.    折半查找

只针对有有序数组

定义三个指针,一个代表开头,一个代表末尾,一个代表中间值.

假设数组从小到大,因为有序,如果数值小于中间数,那么这个数只可能存在于中间数的左边,结尾指针移动到中间指后一位,针反这则在右边,每比完一轮,数少一半,没有找到再比,最终开头下标大于到最后都没有找到.则结束.

public static void reduceSort(int[] arr,int x)

{

int start=0,end =arr.length-1,mid=(start+end)/2;

while (start<=end)

{

if (x==arr[mid])

{

System.out.println(mid);

}

if (x<arr[mid])

{

end=mid-1;

mid=(start+end)/2;

}

if (x>arr[mid])

{

start=mid+1;

mid=(start+end)/2;

}

}

if (start>end)

{

System.out.println(“数组里没有这个数”);

}

}

6.    数组倒转

思路:定义一个变量初始值为数组0下标和再定义一个变量为数组最后一个下标,

两个的值交换,然后同时向中间移动,直到交插结束.

public static void inversion(int[] arr)

{

for (int x=0,y=arr.length-1; x<=y;x++,y– )

{

swap(arr,x,y);

}

}

7.    查表法之进制转换

思路:2,8,16进制每位最小表示是0,最大的F,那么可以定义一个有序数组,

包含所有进制标识(从0到F),那么其下标也是0到15,而转换进制,最多是&15,

得出的结要最大也是15,刚好一一对应,因为整数有四个字节,

所以其最大元素个数为-1的二进制32个,那么可以定义一个32长度的char数组,

接收每次查表对应得到的表值,再倒过来打印.就得到进制转换后的值.

public static void tableLookup(int x,int y,int z)

{

char[] arr ={‘0′,’1′,’2′,’3′,’4′,’5′,’6′,’7′,’8′,’9′,’A’,’B’,’C’,’D’,’E’,’F’};

char[] arr1=new char[32];

int b=0;

do

{

arr1[b++]=arr[x&y];

x =x>>>z;

}

while (x>0 );

for (int c =b-1; c>=0;c– )

{

System.out.print(arr1[c]+” “);

}

System.out.println();

}

第六天  开始–面向对象

一、类与对象

1.       类与对象之间的关系?

类是对象是一种抽象

而对象是类的一个具体化,真实存在的实体.

我们定义一个类,其时就是定义了一种引用数据类型

2.       如何对类进行分析?

类就是一类事物的归纳,要将一个类事物描述清楚,从两方面入手,一个是分析事物具有哪些外部特征,即属性,二是分析这类事物具有什么行为,即方法.

类的属性(变量)可以是任意数据类型.

3.       如何用对象?

创建对象方法:类名 对象名 =new 构造函数名(参数)

使用对象

对象名.成员变量;

对象名.方法名();

4.       对象的内存分布图?

new 一个对象是,先在堆内存中开辟一片空间建立一个对象,再在栈内存是开辟一片空间建立对象名并把堆内存中对址值赋予给对象名,实现这个对象名对对象的指向,这就建立好了一个对象.

5.       匿名对象

格式:new 构造函数名();

特点:可以做为参数进行传递,只在存在的语句中有效.

6.       类中成员变量和局部变量的区别?

成员变量在本类中都有效(主方法除外),局部变量只在方法里的{}范围内有效.

成员变量存在于堆内存的对象中,所以其用完后不会马上消息,等java垃圾回收机制回收.而局部变量存在于栈内存中,用完马上消失.

另外由于成员变量存在于堆内存中,所以就算其没有初始化,也会随对象建立自动初始化为该类型的默认值.

二、封装 (关键字:private)

1.       什么是封装?

封装就是隐藏实现细节,提供公共的访问方式,

开发中常用的是用private饰类的成员,让其只在本类是有效,再提供公共的方法让外部访问被private修饰的成员属性.

2.       封装有什么用?

提高类成员安全性,使用方便,复用性高,可以控制其变化

3.       封装怎么用?

在变量类型前和方法的返回值类型前加上private,就可以私有化这个变量或方法.

然后再提供getName方法获得变量的值,用setName方法给变量赋值.

private修饰的方法放于开放的方法中,这样才能让外部访问

4.       什么时候用封装?

私有的使用。

当我们要对一个成员变量或方法进行改变和调用控制时,我们就用private私有.

5.       封装有什么特点:

封装可以修饰类的成员属性和方法,当一个成员被私有化后,只能在类中使用,不能够直接通过创建对象调用,而要通过其它公共访问方法,让外部去访问.

三、构造方法

1.       什么是构造方法?

构造方法就是类中一定存在的以类名命名的一个方法.

2.       有什么作用?

用于给对象初始化.

3.       怎么用?

格式:[修饰符] 类名(){}

1.方法名必须与类名相同

2.构造方法没有返回值类型  void也没有

3.构造方法只可以用权限修饰符修饰

4,不可以用return

4.       什么时候用?

建立一个类,就要建立构造函数

5.       有什么特点?

1,当一个类中没有构造方法时,jvm加载时会为其添加一个默认的构造方法,该方法是无参空的方法.(默认的是看不到的)

2,当我们手动添加一个构造方法后,默认的构造方法就不会在添加.

3,构造方法可以重载,重载后的好处是我们可以有多种方式来实例化这个类的对象

4,只能用权限修饰符修饰,如public private,不能用static

四、this关健字

1.       有什么用?

三个代表,在类中代表对象引用成员变量

在函数中代表对象调用函数

在构造函数中代表构造函数的引用

2.       怎么用?

this只能用在方法中,代表对象的引用,因为成员变量里加载于对象创建之前.

this.成员变量名:在方法中代表对象引用成员变量

this,方法名() :在函数中代表对象调用函数

格式this(变量):用于构造函数间的相互调用,而且只能放在构造函数的第一行。

然后先初始化其this调用的构造函数,再初始化本身的构造函数。

因为所有构造函数名是一样的,都是重载函数,

所以,通过变量来标记构造函数,用this去引用

3.       什么时候用?

当需要引用时?

4.       有什么特点?

this只能应用在本类中.可以修饰类的成员也可以修饰类的成员.

但凡本类功能内部使用到了本类对象,用this表示。

看到this就是有代表对象,代表哪个对象就看其所在功能被哪个对象调用。

这样就知道谁在参与运算。

Ø  第七天

一、静态(static关键字)

1.    什么是静态?

类的成员用static修饰后,就叫静态.

2.    静态有什么用?

静态可以让类的成员随类的加载而加载,先于对象存在,可以真接用类名访问,不用先创建象.

静态成员只在随类加载一次,并给所有对象共享,这样可以节省内存空间,不用在每个对象中生成.

3.    静态怎么用?

静态可以修饰类的成员里的成员变量,成员方法,和构造代码块.

静态使用格式为:在成员前面加static 就可以.

修饰后 类的成员调用格式,类名.类属性     类名.类方法

4.    静态什么时候用?

有时你希望定义一个类成员,使它的使用完全独立于该类的任何对象。通常情况下,类成员必须通过它的类的对象访问,但是可以创建这样一个静态成员,它能够被它自己使用,而不必引用特定的实例。

或者一个类的成员变量,你不需要为各个对象所独有,而是由所有对象共享,任意对其改变将影响所有的对象,即当对象中出现共享数据时,使用静态修饰。

当功能内部没有访问到非静态数据时,(即对象的特有数据)那么可以使用静态修饰。

5.    静态有什么特点?

静态只能修饰类的成员变量和方法,而不能修饰局部变量

静态成员可以直接通过 类名.类属性     类名.类方法

被static修饰后,类属性与类方法加载到方法区的静态区内,普通实例属性是在对象中存在,也就是说它在堆内.

static修饰后的成员属于类的,当类被创建时创建,当类销毁时销毁。它的生命周期比实例变量的生命周期长.

static修饰的属性也是有默认值的。Static属性它被类的对象所共享,实例属性是每一个对象自己的。

(在使用static方法时,要注意只能使用static成员。在实例方法中可以使用任意成员

static中不可以使用this,super关键字,为什么不能使用this关键字,因为static成员是在对象创建前就被加载的,这时还没有对象产生,所以不能用this。this 指代对象的。

二、文档注释–javadoc

1.    什么是文档注释?

通过jdk工具javadoc 生成了很多xxx.html文件  首页是index.html

2.    有什么用?

文档注释可以给java文件里面存在的属性及功能作一个解释说明.

3.    怎么用?

是将/** 内容 */中,并用javadoc的内容进行解析

格式:javadoc -d 存放目录 -@author  -@version 类名.java

avadoc注释标签语法
@author 对类的说明标明开发该类模块的作者
@version 对类的说明标明该类模块的版本
@see 对类、属性、方法的说明 参考转向,也就是相关主题
@param 对方法的说明对方法中某参数的说明
@return 对方法的说明 对方法返回值的说明
@exception 对方法的说明 对方法可能抛出的异常进行说明

4.    有什么特点?

文档注释有编译工具进行,具体一个要注意的地方是:类名前必须要有public修饰。要编译的方法名必须有public 修饰

三、Singleton 单实例

1.     是什么?

该类只能生成一个对象.

2.    有什么用?

我们只想获得同一个对象时可以采用单实例。

节省内存  我们在操作时,只创建一个对象就可以帮助我们去完成操作,那么就可以使用单实例.

3.    怎么实现?

  • 构造方法私有化 private
  • 在类中定义本类的一个对象 private static修饰
  • 在本类中提供一个公共的方法让外界可以获取这个对象 public static

两种方式:

饿汉式

class Er

{

private Er(){};

private static Er e =new Er();

public static Er getEr()

{

return e;

}

}

懒汉式

class Er

{

private Er(){};

private static Er e =null;

public static Er getEr()

{

if(e==null)

e=new Er();

return e;

}

}

 

虽然懒汉式可以延迟加载对象,但为代码的简洁性和安全性,日常用的还是饿汉式。

4.    有什么特点:

有两种方法,饿汉式,及懒汉式

延时加载的问题

我们在开发中使用不是延时加载   线程安全

我们在面试时写延时加载      线程不安全

四、静态代码块

1.    是什么?

是被static修饰的构造代码块

2.    有什么用?

提供一个地方给类的公共信息初始化.它是为类的信息服务

给类作初始化的,

3.    怎么用?

在构造代码块加static

4.    什么时候用?

当类存在共性时,可以将这个共性提取出来

5.    有什么特点?

构造代码块是为对象服务的。

而静态代码块优先与main加载,可以有多个,类在加载时就加载了。是给类作初始化的.

它只被执行一次.

1.静态代码快,只能定义在类里面,它独立于任何方法,不能定义在方法里面

2.静态代码块里面的变量都是局部变量,只能在本块中有效

3.静态代码块会在类被加载时自动执行,无论加载着是jvm还是其他类

4.一个类总允许定义多个静态代码块,执行的顺序根据定义的顺序进行

Ø  第八天 继承

面向对象三大特性:封装 继承 多态

一、继承 extends

1.    什么是继承?

继承就是把两个存在关系的类,把里面共有特性提取出来,形成一个父类,或者跟据自已的特性派生出来一个子类,然后子类通过继承拥有父类的所有属性和方法,子类可以可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。

继承分为普通继承和多重继承.

普通继承  A 继承B

多重继承 C继承B, B又继承A.  那么C中具有A和B的所有属性.—-这个不是多继承,要区分开来

2.    继承有什么有?

复用性强,子类通过继承就拥有了父类的所有属性和方法,子类可以直接使用这些方法,也可对在此基础上增加新的数据或新的功能,若类B继承类A,那么建立类B时只需要再描述与基类(类A)不同的少量特征(数据成员和成员方法)即可。这种做法能减小代码和数据的冗余度,大大增加程序的重用性,使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发费用。比如可以先定义一个类叫车,车有以下属性:车体大小,颜色,方向盘,轮胎,而又由车这个类派生出轿车和卡车两个类,为轿车添加一个小后备箱,而为卡车添加一个大货箱。

继承通过增强一致性来减少模块间的接口和界面,大大增加了程序的易维护性。

通过继承可以展现多态,Java中的多态的两种最基本表现形式:重载与重写

3.    继承怎么用?

子类类名后加上extends 父类名,就实现在继承

继承属性

继承属性时,子类拥有父类除private修饰外的所有变量

通过super可以调用子类中隐藏的父类属性.当子类有同名变量的话,

用tthis和super来区分子类成员和父类成员. super.变量名 super.方法名();

如果无同名变量,那么也可以用this来调用父类属性.

但一般不在父类中定义类变量,,因为类变量可以直接用类名访问,如果定义了,那么一般是对子类做一些限制

继承方法

继承方法可以对方法什么也不做,也可以对方法进行重写

重写就是让方法名一样,但里面给其在原有基础上进行扩展或重新定义新的功能.

重写时需要注意的是权限修饰符,子类不可以使用比父类更严格的权限修饰符.

也就是子类的权限只能更宽泛,不能更严格,public>protected >什么都不写>private

重写的目的,两个目的,一个是对被重写的方法进行功能性扩展, 另一个是重新建立新的功能行为.

也可以通过super来调用被隐藏的行为.同样,如果没有重写,那么也可以用this调用.

继承在构造函数中的用法

在构造函数中,默认在第一行调用super(),父类的无参构造,一旦我们指定后,super(参数),或this(),后,就不会再自动调用了.

4.    继承什么时候用?

如果类中的特性或行为与被继承类中的行为,特性功能相同,可以使用继承。不可以为了去使用其某个行为而继承

父类是将所有子类中共性的行为抽象出来的。

5.    继承有什么特点?

一个子类中只能有一个父类,就是只能单继承

java中支持多重继承,就是B继承A,C又继承B,那么C拥有A和B的所有成员

java中继承能继承父类的除private外所有的成员.

二、super

super也只能用于方法中!

super与this基本相同,但有区别,this(),在构造函数中不一定要有,但super()如果没有指认,就一定有.

三、final

可以修饰类,方法,属性

类:修饰的类不可以被继承

方法:修饰的方法不可以被重写

属性:修饰的属性,是常量,不可以更改.

但如果修饰的属性没有赋值,还是默认值的情况下,允许在构造函数中赋值一次.(注意:如果同时被static 和final修饰则不允许)

四、继承中的构造函数

继承父类所有非private成员,不包括构造函数.

五、抽象abstract

1.    什么是抽象?

抽象是从众多的事物中抽取出共同的、本质性的特征,而舍弃其非本质的特征。例如苹果、香蕉、生梨、葡萄、桃子等,它们共同的特性就是水果。得出水果概念的过程,就是一个抽象的过程。或这个方法是这类事物所共有的,然而每个子类的实现方式不一样.抽象在java只能修饰类与方法,被其修饰的类就叫抽象类,被其修饰的方法就叫抽象方法.

2.    抽象有什么用?

抽象主要是为了方便继承的.

抽象修饰的类不可以建立对象,其修饰的方法没有具体实现,这样就可以子类可以跟据自已的需要实现自已的内容

3.    抽象怎么用?

在类或方法前加abstract.,加了abstract的方法就不可以写{}了

格式:[修饰符]abstract 方法名(参数);

4.    什么时候用抽象?

当子类都具备这项功能,但具体实现不一样,那么就可以用抽象.

5.    抽象有什么特点?

抽象类不可以建立自已的对象,

抽象方法没有具体实现

抽象类里不一定有抽象方法,但有抽象方法一定是抽象类

抽象abstract不可以和final共存,其作用刚好相反

也不可以和static共存,static中只能用静态成员,而抽象方在重写时如果只用静态成员,则意义不大

抽象类的子类必须重写所有父类所有抽象方法,但如果子类是抽象类除外,因为抽象类允许存在抽象方法.

Ø  第九天  多态

一、接口 interface

1.    什么是接口?

java为了弥补单继承的缺陷,定义了一功能接口,可以多实现.接口是java中一系列方法的声明,是一些方法特征的集合, 其里面所有的方法都是抽象方法,所以也可以称其为一个特殊的抽象类,里面的成员有固定的修饰符,不写也会自动加.

成员变量前默认加:public static final

成员方法前默认加 public abstract

2.    接口有什么作用?

接口就是用来实现的,接口一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。那么接口就类似于制定了规则,外部实现其的类必须重写其所有方法.

接口可以多实现,那么就大大增强扩展性.

通过接口实现两个功能的对接,会大大降低二者耦合性.有利于程序的维护.

3.    接口怎么用?

格式:

interface 接口名

{

[public static final] 属性

[public abstract] 方法

}

interface 接口名 extends 接口1,接口2……. ——-接口的继承,支持多继承

{

不用重写方法

}

class 类名 implements 接口1,接口2……—–类对接口的多实现

{

重写所有方法;

}

abstract class 类名 implements 接口1,接口2,……

{

方法可以重写也可以不重写

}

4.    接口什么时候用?

当一个类只有方法的特征,而方法的实现各不相同,同是这个功能又有较强的括展性

这个时候就可以定义一个接口,

5.    接口有什么特点?

接口没有构造函数

接口的属性都是常量

接口可以多实现,因为接口中的方法全是抽象方法,没有具体方法实现,我们如果发现不同接口中出现相同的方法,那么只需要实现一次.

接口与接口可以多继承

抽象类与接口的区别

1.类是单继承,接口可多实现

2.继承 is a    实现 like a

3.抽象类中可以有实体方法,接口中全是抽象方法

二、多态

6.    什么是多态?

多态就是同一实体有多种表现状态

面象对象语言的核心就是多态,多态即一个对象有着多重特征,可以在特定的情况下,表现不同的状态,从而对应着不同的属性和方法。

方法的重载与重写是多态的两种基本表现形式

7.    多态有什么用?

多态可以实现父类引用指向子类对象.

父类的引用也可以接收自己的子类对象。

这样大大提高了程序的扩展性和可维护性

因为,父类引用可以指向子类对象且可以接收子类对象,那么假如程序子类对象要需要修改就不要再改引用名,直接换一个对象就可以了,动一下引用名,会牵涉到的代码远远大于改其指向对象.

8.    多态怎么用?

格式:父类名 对象名=new 子类名()

在方法的参数中方法名(父类类型即父类名  子类引用)

多态父类的引用只能调用与子类继承或实现过去的方法.

如果调用属性,那么结果看引用,如父类有一个 int x =4,子类有一个int x =5,那么多态的时候,引用代表的值是4,和父类一至,也就是引用所属的类里面的变量值.

如果调用方法结果看引用的对象

而如果是方法的话,就是调用子类重写的方法,如果没有重写,那就是调用子类里隐藏的继承的父类方法

如果要调用特有属性那么要强转

类型转换:向上转换是自动的:

比如:B继承A,那么 A a = new B(),表示B类型向更高的A类型转换,因为A类包含B类,所以是向上转,这是自动的

强转可以先判断下两个类是否是从属关系,也就是看类是否是继承或实现

格式 :引用  instanceof  类型

比如看a引用是否是A类型 , a instanceof A 如果是为true 不是结果为false

而如果a要转成B类,这就是向更低的子类,则要强转 a=(B)a;[转完后才能调用子类特有属性

实现和继承用法一样  只不过叫法不一样 不叫父类引用指向子类对象,而是叫接口回调.

多态中父类的引用调用属性时,是父类的,调用非静态方法,是子类的重写方法,调用静态方法,即使子类重写了方法,实际调用的还是父类的.

9.    多态什么时候用?

多态在有继承或实现的类中使用,

开发中基本都是用父类引用指向子类对象以提高代码的扩展性,并便于维护

10. 多态有什么特点?

多态有三种,可以是一个类的多态,也可以是一个抽象类,也可以是一个接口,但一般是抽象类和接口多态用的多

我们只能使用父类,接口中定义的行为,而不能去使用子类特有的行为

要使用必须强转回对象类引用

方法的重载与重写是多态的两种基本表现形式

多态的前提

必须是类与类之间有关系。要么继承,要么实现。

通常还有一个前提:存在覆盖。

三、多态之经典模式

1.    静态工厂模式

思路:

2.    代理模式

3.    策略模式

4.    模板模式

5.

Ø  第十天

一、Object类

1.    什么是Object类?

Object类是java集成的一个类,是所有类的超类,就是父类.所有的类都继承它,只有不过有的是继承,有的是多重继承.

2.    有什么作用?

Object里面有一些方法,我们可以在任意类里,直接使用,或重写后使用里面的方法.

3.    怎么用?

1比较方法: public static boolean equals(Object obj){}传回一个ture 或false

这个方法默认用来比较两个对象的地址是否一样,和===作用一样

所以我们一般重写方法去实现比较两个个对象里面的属性是否一致.

2或得对象的字符化, public String toString(){} 默认是返回对象的地址值

当我们打印对象时,其就会自动调用这个函数,这时我们可以打印这个函数重写后的内容

p.color=”黑桃”;

p.num=”A”;

public String toString() {

return this.color+this.num;

}

System.out.println(p);//结果就是红桃A

3,获得引用所指向的对象的真实类型 getClass :public Class getClass(){}

A a=new B();

System.out.println(a.getClass().getName());

结果是返a的真实类型B,

其中.a.getClass()是是相当于得到这个.class文件的对象化形式,也就是一个对象.其调用Class类下的getName()方法获得a的真实类型

4,finalize方法

作用:System.gc();垃圾回收

protected void finalize() throws Throwable{

System.out.println(“垃圾回收执行”);

}

一般情况下,我们不重写这个方法.System.gc();

当gc执行时,这个方法会被调用

当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。子类重写 finalize 方法,以配置系统资源或执行其他清除。

面试题:final、finally、finalize的却别?

Final:是一个修饰符,可以用来修饰类、方法、变量。修饰类不可以被继承、修饰方法不可以被覆盖,修饰变量时是一个最终变量。

Finally:异常处理当中一定会被执行的语句,常常用来关闭资源,只有遇到System.exit(0);才不执行

Fianlize:垃圾回收方法,需要被垃圾回收器调用。

public int hashCode()  得到的就是一个数字

可以简单理解成就是对象的地址值,是通过hash算法得到

一般在做对象比较时,要求相等的对象的hashCode也是一样的。

所以在重写equals方法时,可能会出现对象属性一致,但是哈西值不一样,这个时候也要将其hashCode方法重写.修改其哈西值,这样才能让两个对象完全一样.

4.    什么时候用?

当我们虽要实现Object类中已存在的功能时,就可以按我们需求重写这些方法.

5.    有什么特点?

Object类里的方法可以被所有的类使用

大部分要重写后再使用.

二、内部类

1.    什么是内部类?

内部类就是在类里面的类

有两种

一种定义于类中与成员并列

一种定义于方法中

2.    有什么作用?

当一个类里还存在其它对象时,比如人,人身体里有心脏,那把心脏定义成一个方法显然不合适 因为心脏是个实体,不是一个行为

这个时候就可以把心脏作为一个内部类定义在人的类里面.

3.    怎么用?

直接在类里写一个类

内部类可以使用外部成员,但外部类要访问内部类必须创建对象.静态内部类除外

如果内部类成员重名,那么使用格式:外部类名.this.成员,

1,普通在外部创建内部类的对象

格式: 外部类名.内部类名 引用 =new 外部类名().new 内部类名()

2,静态内部类里面的方法不静态

格式: 外部类名.内部类名 引用=new 外部类名.内部类名()

3,静态内部类,方也是静态的

那么不用创建对象也可以直接用里面的方法

格式 : 外部类名.内部类名.方法名():

4.    什么时候用?

在设计阶段,如果发现一个实物中还存在另一个实体,这是一般会内部类来描述这个部实体

5.    有什么特点?

内部类可以被成员修饰符所修饰 如 static private

内部类可以直接使用外部类的成员

如果,内部类成员被static修饰,那么类一定要被static修饰!

但被静态修饰的内部类成员可以不用static修饰.

三、匿名内部类

1.    匿名内部类是什么?

匿名内部类是一种内部方法的简写

其没有自已的引用,而是直接用对象调用内部方法

2.    有什么用?

匿名内部类可以简化内部类的代码

主要用来重写方法

比如实现了两个同名方法,而返回值不一样,这个时候就要加一个匿名内部类用来区分.

class A implements B,C{

void show(){}

C c = new C(){

int show(x)

{

return x;

};

}

}

3.    怎么用?

格式:父类或接口名 引用= new 父类或接口名(){};分号不能忘

引用.匿名内部类的方法

或直接用对象掉

4.    什么时候用?

要想类里有两个同名方法 但返回值不一样, 一起存在,可以使用匿名内部类

5.    有什么特点?

这个匿名内部类必须要有继承或实现.

其实匿名内部类就是一个匿名子类对象。

Ø  第十一天 异常

一、异常处理

1.    何为异常处理?

异常就是程序在运行过程中产生的问题,并且这种问题可以用代码去解决,我们解决的过程就叫异常处理

java内部对各种异常作了定义,我们在使用过程中,jvm发现哪里出现了异常,就会在内部创建这个对象,将这个对象的内容打印在控制台上

我们也可以通过继承对去自定义异常 名称有规范,:自已定义了一个名称的后面加Exception.如 NumException .SumException

,异常有两种:运行时异常 和编译时异常

所以处理方式也不一样.

2.    异常处理有什么用?

可以让程序更合理,完善,把一些问题通过代码处理了,避免以后出现bug,

3.    怎么用?

在一个方法的实现部分,如果有可能出现异常,那么可以直接在程序处理了

如果不处理那么就要抛出,抛出后,分两种情况:

1,如果是运行时异常,在其所在方法上可以不抛出声名,也可以抛,

2,如果是编译时异常,那么方法上必须抛出异常声名.

然后在调用这个函数的方法内要么处理,不处理,同样,抛出,只要没处理就一直抛,直到当主函数抛了后,直接抛回给jvm了,然后over.

格式

……..方法名() throws

{

try

{

可能会产生异常的代码(一旦这句产生了异常,下面的语句便无法执行)

这里可以加其它的语句也可以不加,也可以直接抛异常

例如直接抛个异常:throw new Exception(“run异常”);这个异常可以不放在try里,而放在方法里,但不管放哪里,在一个{}内,其只可以放在最下面一行,也就是下面不可以放语句,因为肯定执行不到,java默认有问题,编译无法通过..

}

catch(异常类名1 e)catch用来接收异常对象并处理.

{

处理方式…..

}

catch(异常类名2 e)

catch 可以有多个,但是:如果里面的异常名存在继承关系,那么前面catch里的异常类只能是后面catch的子类.

{

处理方式代码…..

}

finally可有可没有,一般用于切断数据联接,用来结束资源暂用.

{

只要在try前面没有被被其它异常所终止,那么这里的语句一定会执行.

}

}

4.    什么时候用?

1当程序在调用方法时,而这个方法可能会抛出异常时,这个时候则必须做异常处理

要么try做处理,要么也在方法上抛出.

2当一段代码可能出现异常时,也可以做异常处理.

5.    有什么特点?

异常要么try,要么抛,try还可以在方法上抛异常

多个catch时,如果出现了子父类,那么一定要注意,在上面的catch里的异常不能是下面catch的父类.

方法里抛了非运行时异常,那么方法上一定要抛异常

一旦方法里抛出了一个异常,而又没用try catch去处理,那么其下面的代码都不会运行.

只要存在方法调用,就可能会用到异常处理.不一定在主方法中.不一定在一个类中.

在子类中:

1,如果父类抛了异常,那么子类可以不抛异常,也可以不抛,

2但是如果子类要抛,只能抛与父类一样的,或其子集

3,如果父类中方法没有做异常处理,子类重定的方法也不能定义.

4如果子类方法中出现了异常,那么一定要处理,不能抛!

throws 后可以抛出多个异常

 

二、包 package

1.    什么是包?

包就是一个文件夹,存放生成的class文件

2.    有什么作用?

1,可以将class文件与java 文件分离,提高安全性.

2当我们的class文件比较多时,特别是在开发时,会有大量的.class文件,那么全放在一个文件夹下显然不合适,为了便于管理,我们按自已的需求用包来管理这些.calss文件

3.    怎么用?

格式:

在java源代码文件的第一行写上要放入的包名:

package 包名.包名.包名 (.后代表多层)

javac -d 路径 文件名.java 这里文件名前不要加包名.!

使用:

前题:要在包所在目录下,或者设制classpath=目录;包与包之前访问,类必须public修饰.

包名命名规制与标识符一样

源文件存在其它的类的引用,则一定要把其它的包编译完后,再导入包,多个引用时,哪个类先用,先编译哪个

导入格式:import 包名.*;(当包里只有一个类时,不可以用*;)或import 包名.类名;

java 包名.文件名

如果想在任意目录下实现

4.    什么时候用?

管理class文件时用.

5.    有什么特点?

包的访问权限

public  protected  default  private

包与包         ok

不同包子类    ok           ok

包中              ok           ok                  ok

类中              ok           ok                  ok           ok

在不同包中,有两个权限可以用,public protected ,但还要注意的是(protected这在不同包中,只能是子类用.)

三、import 关键字

1.    是什么?

import是一个导包的关键字

2.    有什么用?

开发中,我们把class文件分类管理.时,每个类的全名是包名.类名,这个时候写代码就会很麻烦

所以我们把类的包名用import导入进去,这样写代码是类及对象的调用,就不用写包名了.

例如:有两个class文件,A在a包中,B在b包中,

如果不导包,那么在A中创建B对象格式是:b.B 引用名= new b.B();

3.    怎么用?

格式: import 包名

4.    什么时候用?

当java源文件虽要调用其它包中的成员时.

5.    有什么特点?

导包之前要设制classpath

lang包中是文件不用导入.java默认了,

Ø  第十二天 多线程

一、多线程

1.    什么是多线程?

每个程序在运行时,里面的各功能操作可以同时运行,这些操作,可以理解为线程,可以同时运行这种现象,叫多线程.

2.    有什么用?

多线程让程序各功能可以同时进行,效率大大提升.

3.    怎么用?

两个关键字:Thread(类)  Runnable(接口)  Thread实现了Runnable

两种方式:

一,继承Thread

继承后重写run方法 把需要实现的代码放入里面去.然后通过创建这个类的对象,因为其继承了Thread,所以有start()方法,用对象可以调用start方法启线程

例:

class A extends Thread

{

A(Srting name)这个方法可以给线程命名,如果要命名就写

{

super(name)

}

public void run{

要实现的代码

System.out.println(Thread.currentThread().getName()+this.name+”生产啦.”);

}

}

class Test

{

public static void main(Strting[] args)

{

A a =new A(“线程1”);\

  • start();

要启动多少个线程,就创建多少个对象.并start.

}

}

方式二:

与继承最大的区别在于,实现的Runnable里没有start方法,但Thread类里有个方法可以接收Runnable类型对象.并用用start()方法启动这个对象.里的run方法

class B implments Runnable

{

public run{具体代码实现}

}

class Test

{

public static void main(Strting[] args)

{

B a =new B();

Thread t = new Thread(a);

t.start();

要启动多少个线程,就创建多少个对象.并start.

}

}

4.    什么时候用?

当一个程序里的多个功能关系并是很紧密,也就是说没有先执行哪个才能执行哪个时,我们可以让里面的各个功能模块独立线程,这样要使用的时候就可以多线程,并同时运行.

5.    有什么特点?

1,平时多用实现方法创建对程,因为比较接口可以任意实现,没有限制,如果是继承,那么执行一个线程,便要创建一个这个类的对象,那么就又初始化了一次,这样不利于操作同一数据库.除非用静态数据让其与所有对象共享.

  • 多线程里各线程执行是随机的,都是在抢夺cpu执行权.
  • 线程运行时以run开始,以run方法运行完结束.中途如果被其它线程抢夺cpu执行权,那么会进入临时阻塞状态.直到抢回来后,运行完后再销毁.

二、多线程同步

1.    什么是同步?

同步,(关键字是synchrownized,)就是其修饰的一个代码块,或方法,里只能,够有一个线程在运行

2.    有什么用?

当我们用多线程操作同一数据时,由于线程执行的的不确定性,有可能会出现多个线程重复操作同一数据,比如每次生产一个产品就要出库一个产品,如果线程在生产时暂停了,那么进来一个新线程,同时其又启动了,这时就会产生两个产品,而没有出库.这就产生了安全隐患,如果.

用了同步,那么外面的线程只能等里面的线程执行完后,才能进来,去执行,这就避免了这个情况的产生.

3.    怎么用?

snychronized一般与方法wait() 等待 notify()  唤醒最先等待的那个线程  notifyAll()唤醒所有 ,这三个方法都在Object类中,而Object是所有类的超类.

wait()方法会抛出一个异常,所以要用到try({}catch(){};

格式:

修饰方法:在返回值前加snychronized

修饰代码:snychronized(对象){同步代码}

这个对象可以随便一个,有两个要注意,本类名.class,this 但是如果要和方法上的为同一个,只能用this.

1.5以后的替换用法以:Lock

在snychronized体系中,等待唤醒其是一种普及操作,notify  与  wait(),没有具体联系,是独立的,只与线程偶合性高,唤醒是看哪个线程先等待, 由线程属性决定

而Lock,体系中,把wait()  notify()  notifyAll()封装为一个Condition对象,(一个Lock可以对应多个Condition对象,)那么同时等待与唤醒就有了对应关系,就是说我的等待只能我唤醒,其就具有了从属关系,每当唤醒与我同一个对象里的等待,与线程等待先后没有关系,那么便可以通过等待与唤醒放置位置的不同,灵活的控制不同线程的等待与唤醒

使用方法:

  • 要先导包,因为其不在lang包中,import java.util.concurrent.locks.*;
  • 创建一个把锁:Lock 锁名 = new Lock();
  • 创建condition对象 Condition c1 =锁名.newCondition();

Condition c2=锁名.newCondition();…..还可以有很多….

换成三个方法:await()   signal()  signalAll()

这里要注意,这个方法直接返回一个与当前创建的锁Lock关联的Condition对象.不然加锁就没意义,只能锁这个锁返回的condition对象,这是Lock与synchronized(隐式锁机制)最大的区别.synchronized对所有等待唤醒起作用且如何操作我们不知道

  • 那么使用就是

在要锁的代码最开始加:锁名.lock();

要实现的加锁的代码,[放入等待:里面具体放哪个看自已需要:如比:放try{c1.await()}catch(Exception e){}

…….

…….

唤醒:c2.signal();  这个也是自已控制

最后:

finally

{锁名.unlock();}….释放锁一定要执行.

这样我们唤醒只会唤醒自已的等待.

4.    什么时候用?

当需要控制流程,让线程按我们的需求操作共享数据时,这个时候就用同步,也就是线程间需要通信

5.    有什么特点?

注意:notify 与notifyAll能唤醒的都是同一把锁对象所关联的wait,也就是一把锁synchronized是对应同其一组的wait notifyAll等

如果同步synchronized存在于非静态方法上,那么在代码块上表示同一锁就是this,,代表本类对象

如果,存在于静态方法中,那么在代码上表示同一把锁的对象就是本类名.class

类名.class是返回本类的class对象

多线程里的锁,也叫监视器.

被锁同步的方法里或代码内,只能允许一个线程运行.其它的要么冻结,要么阻塞

线程中两个类似功能的wait()与sleep(时间),

区别:

  • sleep一定要放时间,而wait可以没有
  • sleep可以放于任何位置,而wait只能放于同步中
  • sleep只是释放cpu执行权,而没有释放锁,但是wait锁也放了,cpu执行权也放了.

Ø  第十三天

一.死锁

死锁产生的原因是同步中嵌套了不同的锁,另一个地方也有两个锁,且顺序相反,因为锁只能是一个线程用,那么这样就容易产生一种情况,在另一个地方需要这个锁,而这里却占用了,而这里需要的锁,在另一个地方又占用了

举例:

public class DeadLock

{

public static void main(String[] args)

{

//这里建立线程

Shou r =new Shou();

Thread  t =new Thread(r);

Thread  t1 =new Thread(r);

t.start();

try{Thread.sleep(10);}catch(Exception e){}//让线程等待一下,这样就更容易停在那个位置

r.flag=false;//让线程在两个同步块中来回切换

t1.start();

}

}

class Shou implements Runnable

{

private int a =1000;

Object obj = new Object();

boolean flag = true;

public  void run()

{

if(flag)

{

while(a>0)//循环才能让产生死锁的概率产生效果大大提升,不然一次执行完了就不会发生

{

synchronized(obj)

{

//死锁时一个线程在这里,它有obj的锁,需要本类的锁,与下面相反

sell();

}

}

}

else

{

while(a>0)//两个同步块都要循环

sell();

}

}

public synchronized void sell()

{

//死锁时一个线程在这里,它有本类的锁,需要obj锁,与上面相反

synchronized(obj)

{

System.out.println(Thread.currentThread().getName()+”:  “+(a–));

}

}

}

二.线程之间通讯之生产者消费者

需要生产一个,消费一个,这样就可让生产一个后后让关闭线程入口.

实现方式: 在生产代码入口放一个条件式等待,默认为假,当生产完成后,改为真,那么所有执行到这里的线程都要停止,也就是意味着,关闭入口了同时唤醒在消费入口等待的线程.

然后再在消费入口放一个条件等待,这个必须与生产相反默认为假,这样生产等待后才能消费,然后消费完后,让条件语句改变,这样就可以实现消费完后线程等待,同时唤醒在生产入口等待的线程.

这里就有两种方式:

snychronized模式

class Resource

{

private String name;

private int count = 1;

private boolean flag = false;

//  t1    t2

public synchronized void set(String name)

{

while(flag)如果不用while,那么唤醒多个线程后,其中一个线程生产完一个后,原本因该停,但是另外的线程由于不用再判断条件,所以直接又生产了,用了循环,每次线程醒来都要再判断避免了这种情况的发生.

try{this.wait();}catch(Exception e){}//t1(放弃资格)  t2(获取资格)

this.name = name+”–“+count++;

System.out.println(Thread.currentThread().getName()+”…生产者..”+this.name);

flag = true;

this.notifyAll();

}

//  t3   t4

public synchronized void out()

{

while(!flag)

try{wait();}catch(Exception e){}//t3(放弃资格) t4(放弃资格)

System.out.println(Thread.currentThread().getName()+”…消费者………”+this.name);

flag = false;

this.notifyAll();

}

}

class Producer implements Runnable

{

private Resource res;

Producer(Resource res)

{

this.res = res;

}

public void run()

{

while(true)

{

res.set(“+商品+”);

}

}

}

class Consumer implements Runnable

{

private Resource res;

Consumer(Resource res)

{

this.res = res;

}

public void run()

{

while(true)

{

res.out();

}

}

}

Lock模式  区别参照线程同步

class Resource

{

private String name;

private int count = 1;

private boolean flag = false;

//  t1    t2

private Lock lock = new ReentrantLock();

private Condition condition_pro = lock.newCondition();

private Condition condition_con = lock.newCondition();

public  void set(String name)throws InterruptedException

{

lock.lock();

try

{

while(flag)

condition_pro.await();//t1,t2

this.name = name+”–“+count++;

System.out.println(Thread.currentThread().getName()+”…生产者..”+this.name);

flag = true;

condition_con.signal();

}

finally

{

lock.unlock();//释放锁的动作一定要执行。

}

}

//  t3   t4

public  void out()throws InterruptedException

{

lock.lock();

try

{

while(!flag)

condition_con.await();

System.out.println(Thread.currentThread().getName()+”…消费者………”+this.name);

flag = false;

condition_pro.signal();

}

finally

{

lock.unlock();

}

}

}

class Producer implements Runnable

{

private Resource res;

Producer(Resource res)

{

this.res = res;

}

public void run()

{

while(true)

{

try

{

res.set(“+商品+”);

}

catch (InterruptedException e)

{

}

}

}

}

class Consumer implements Runnable

{

private Resource res;

Consumer(Resource res)

{

this.res = res;

}

public void run()

{

while(true)

{

try

{

res.out();

}

catch (InterruptedException e)

{

}

}

}

}

三.中断线程

stop方法,已过时:用于强行中止线程.

现在如果要让线程正常中断,只需要让run方法结束,其结束了,线程必然中断,

两种方法:

  • 一般而言,线程中都会定义循环,那么只要线程和循环结束,线程也就中止,如何让循环结束,那么就是定义标记,比如原来循环条件是true,现在改为false,就会让线程无法执行.
  • 如果线程被等待了,也就是冻结了,其又无法被notify 或 signal等唤醒,那么这个时候就要用到一个方法叫:interrupt(),

1interrupt(),有什么用?

可以让线程从冻结强制恢复到正常运行状态,记住不是中止线程,其没这个功能.

这样主要是让其去判断标记,一般与改变标记方法放在一块,从而达到记线程去判断标记中止run,线程自然中止了.

怎么用?

格式:

因为其中Thread类的方法,所以只要是Thread及其子类的对象都可以打点调用这个方法.

对象名.interrupt() 注意:用这个会抛出一个异常,所以要抛或try [抛一个InterruptedException]

interrupted()是测试调用其的线程是否中断,中断,返回一个true,否则返回一个false

什么时候用?

当你想让线程中段停止状态,而线程又无法通过正常的途径,比如,signal notify方法,这个时候你就要用到interrupt方法.

有什么特点?

这个方法会抛异常,要注意,

这个方法一般用与改变标记方法一起用.

例如:

for(int x=0; ;x++)

{

if(x==50)

{

st.setFlag();改变标记.

t1.interrupt();//t1将它的冻结状态强制结束。

t2.interrupt();//中断方法。其实不是中断线程

四.线程一些常用方法:

setDaemon(boolean):

将线程标记为后台线程,后台线程和前台线程一样,开启,一样抢执行权运行,当参数boolean为true时标记为守护线程.

必须在线程启动前标记,也就是先t.setDaermon(true); 然后再t.start();  —t代表一个线程

只有在结束时,有区别,当前台线程都运行结束后,后台线程会自动结束(不管后台线程是否运行结束,当然也可以后台线程先结束,前台线程还继续.)。且当现有进程都为守护线程时,java虚拟机退出,.程序结束

join():

什么意思?等待该线程结束。当A线程执行到了B的.join方法时,A就会处于冻结状态。

注意:join处于哪个线程中,就对哪个线程起作用.

A什么时候运行呢?当B运行结束后,A就会具备运行资格,继续运行。

用于:加入线程,可以完成对某个线程的临时加入执行。

Priority() 优先级  优先级1—10

获得线程的优先级:线程名.getPriority()

设置线程的优先级:线程名.setPriority(1~10)

yield()方法 让线程的优先级相对平均一些

格式:Thread.yield();

Ø  第十四天: String类

一、String类

1.    是什么?

字符串就是一个类,只不过有点特殊,因为其一旦初始化,就是一个常量,那么其值是不改变的,但是引用的指向可以改变.而且其中包含各种对字符串操作的方法.创建一个字符串,就相当于创建了一个对象,其就包含所有的方法.

2.    有什么用?

我把在程序中决大多数输入,是以字符串的形式输入的,而且程序最终在反馈出的结果也是字符串表现式,所以中我们最常用的, String类里面提供很多对字符串操作的方法,主要有三大类:获取,判断,转换.

3.    怎么用?

|–常见用构造函数:

四类,1.空参, 2. 由一个char型数组或char[]给定区间的(由哪里开始,总共多少个)得到字符串

由byte[] 或int[]的\或给定区间(由哪里开始,共多少个)的ASCII来组成字符串.

3.由字符串,构造对象.

  • public String()—-得到一个空的字符串,记住不是null,而是 “”
  • public String(char[] ch)——得到一个char型数组里元素的字符串

例:

char [] c ={‘h’,’g’,’r’,’e’,’d’};

String s = new String(c);

System.out.println(s);//结果是:hgred

  • public String(char[] ch,int offset, int count)–用于得到从char数组offset下标开始,count个元素的字符串

例:

char [] c ={‘h’,’g’,’r’,’e’,’d’};

String s = new String(c,1,2);

System.out.println(s);//结果是:gr

  • public String(byte[] b)–把byte型数组里的元素当ASCII码值,用其对应的字符来构造字符串.

例:

byte [] c ={65,66,67,68,69};

String s = new String(c);

System.out.println(s);//结果是:ABCDE

  • public String(byte[] b, int offset,int count)–获取一个byte型数组第offset下标开始的,总共count个元素的ASCII码值对应的字符,构建字符串

例:

byte [] c ={65,66,67,68,69};

String s = new String(c,2,3);

System.out.println(s);//结果是:CDE

  • public String(int[] i,int offset , int count)–获取一个int型数组元素当ASCII码值对应的字符的,从offset下标开始总共count个字符组成的字符串

例:

int[] c ={65,66,67,68,69};

String s = new String(c,2,3);

System.out.println(s);//结果是:CDE

  • public String(String s)–获取一个字符串对象s 值构来造字符串

例:

String s1 =”abc”;

String s = new String(“abc”);

System.out.println(s);//结果是:abc

获取方法:

|–四个获取:

1.获取有四种:获取字符串长度,length()

2.通过索引获取字符串的字符.charAt(int i)

3.正向或反向获取给定字符或字符串的索引,可以从一个索引开始:indexOf(),lastIindexOf(),如果后面加了int参数,则表明从第几个索引开始找.

4.获取从某一索引开始或给定索引区间的字符串.substring(int IndexStart); substring(int Start, int  end);

  1.  注意:这个也常用:String[] strings = url.split(“/”);String[] strings = url.split(“/”);
  2. public int length();获取长度

例:

String s1 =”abc”;

int s = s1.length();

System.out.println(s);//结果是:3

  1. public char charAt(int i);通过索引获取字符串中的字符

String s = “abc”

char x = charAt(1);===结果是b

  1. public int indexOf(int code);查找字符存在的位置:注意:code表示字符的ASCII码值.

0位开始寻找字符,找到则返回其索引,找不到则返回-1

很多形式,重载,获取字符串的某个字符所处的位置,即索引。

String s1 =”abcb”;

nt s = s1.indexOf(‘b’);这里可以写’b’是因为默认把它转换成其int 类型的ASCII码值,

System.out.println(s);//结果是:1

public int indexof(int code , int fromIndex )

从索引fromIndex开始寻找字符,找到则返回其索引,找不到则返回-1.

String s1 =”abcb”;

int s = s1.indexOf(‘b’,2);

System.out.println(s);//结果是:3

public int indexof(String s )查找字符串存在的位置

从索引fromIndex开始寻找字符串,找到则返回其索引,找不到则返回-1.

String s1 =”abcbcd”;

int s = s1.indexOf(“bc”,2);

System.out.println(s);//结果是:1

public int indexof(String s, int fromIndex )

从索引fromIndex开始寻找字符串,找到则返回其索引,找不到则返回-1.

String s1 =”abcbcd”;

int s = s1.indexOf(“bc”,2);

System.out.println(s);//结果是:3

  1. public int lastIndexofindexOf一样的原理,只不过从后面开始找.

注意:虽然是从后面开始找,但不是把字符也反过来找.也就是反向查找

例:         String s1 =”abcbcb”;

int s = s1.lastIndexOf(“bc”);

System.out.println(s);//结果是:3不是0

  1. public String substring (int index)

这是从index索引(包括start),开始直到末尾截取字符

public String substring (int start, int end )

而这是从索引start 开始(包括start),到索引end结束,(不包括end)

 

concat方法

+的效果一样:

String s = “abc”;

String s1 = “def”;

String s2 = “1234”;

String s3 = s.concat(s1).concat(s2);==s+s1+s2;

判断方法:

比较,接收的都在后面当参数.比如给定字符串,s.contains(给定字符串s1)那么就是判断s中是否包含s1

有四个:

判断两个字符串内容是否相等(一个不区分大小写)equals 

判断这个字符串中是否包含给定字符串contains

判断两个字符的前缀或后缀是否相等 startWith endWith

判断字符串是否为空boolean isEmpty()

public boolean equals(Object obj)

其对Object方法重写了,也就是比内容不一样,比的是实际内容,只要非空情况下相等,就为true

Boolean equalsIgnoreCase(String  s);

s.equalsIgnoreCase(“”)

不区分大小写比较内容,,只能是字符串

Boolean contains(String s)

判断字符串是否包含给定字符

Boolean startWith(String  s);

判断是否包含给定字符字符前缀

Boolean endwith(String  s);

判断是否包含给定字符字符后缀

转换方法:

四大转换:

  • 由一个字符串得到一个byte[]—getBytes()char[] –toCharArray

2.由一个char[] 得到一个字符串,与构造方法功能一样,也可指定起始位置和长度,区别在于这个是静态的,可以直接用类名调.String.copyVolueOf(char[]);

3.字符串大小写切换:s.toLowerCase();转小写  s.toUpperCase();转大写

4.将基本数据类型, char[] ,对象(就这三类) 转换成字符串 String volueOf(各种类型) 这个也是静态方法.

 

 

String toLowerCase();转成小写

String toUpperCase();转成大写

Byte[] getBytes();

Char[] getChar();字符转成数组。

其它常用方法:

1.字符或字符串替换eplace()

2.根据给定字符切割字符串成字符串数组s.split()

3.去除字符串首尾空白.trim();

  1. public int compareTo(String s) 比较字符串unicode

主要用于给文件排序

比较两个字符串的unicode码,从头开始比较,如果出现不一样

,           那么将这两个unicode码做减法运算的结果返回

其实就是用调用方法的对象-参数对象 得到的值.

如果相等返回0

如果大于返回正数

如果小于返回负数

String replace();进行字符或字符串的替换。

public String replace(char oldChar,char newChar)

根据s将字符串分割成几部分,每一部分作用String数组的一个元素存在,将这个String数组返回

public String[] split(String s)

String s=”abcabcabcab”;

String[] st=s.split(“c”);结果是:ab ,ab,ab,ab

Trim();去除前后空白。怎么用?

public String trim()

例:

String s=”   a b c   “;

String ss=s.trim();

System.out.println(ss);结果是abc

 

4.    什么时候用?

对字符串操作时用.

5.    有什么特点?

final修饰,不可继承:public final class String

1.String s = “ddd”与String s1 =new String(“ddd”);

s==s1为false,但 s.equals(s1)却为真,因为equals方法是从Object继承下来的,并对其进行了重写.其只要两个字符串非null情况下,的实际内容一样,就为true

  • String s = “dd”+”d”与String s1 =”dd”,String s2 = “d” s3=s1+s2 与s4 = “ddd”

那么s ==s3 为false 因为在内存中开辟了新空间 s==s4为true .因为字符串相加,就直接相连了,而两个值一样,虽然引用名不一样,但其会先在字符串区查找是否有一样的值,有的话就直接把地址值赋值给了不同的引用名

以后我们学习的类很多,要掌握的方法也很多,那么我们在掌握方法 时

1.方法的作用,与怎样调用 这个方法

2.方法的参数的作用 与类型

3.方法的返回值的作用 与类型

Ø  第十五天

一、StringBuffer类

1.    是什么?

是final修饰的类,是一个字符串缓冲区类,可变的字符串.

2.    有什么用?

可以高效进行字符串连接,并进行增删改查操作

3.    怎么用?

构造函数:

1.空参代表初始一个为16字符的缓冲区

2.参数为String:代表一个有初始值的缓冲区

常用独有方法:String的方法基本都有

  • :append(所有基本类型,char[] ,对象) 追加累加.这个有一个特点,加完后直接成了一个StringBuffer对象,则其又可以调用append方法,那么就可以成一个方法链

例:

StringBuffer sb=new StringBuffer();

sb.append(34).append(“abc”);结果是34abc

2.1.:delete(int start , int end) 删除指定索引区间字符串,包括start不包括end

2.2 deleteCharAt(int index)  删除指定位置字符

3.1:public StringBuffer insert(int index,类型 obj)  将指定对象插入指定位置

3.2:public void setCharAt(int index,char c)将指定的字符替换指定索引处的字符

3.3 public StringBuffer replace(int start,int end,String str)替换指定索引区间的字符串

3.4,public StringBuffer reverse() 反转字符串

3.5.public String substring(int start int end),这个end可以没有

3.6:public String toString()返回此字符串缓冲区的字符串表现形式.

4.1:public int length() 查长度

4.2public char charAt(int index),查指定位置字符

4.3 public int indexOf(String s ,int index)查指定字符串的索引lastIndexOf 反查,没有返回-1

4.    什么时候用?

当我们要对字符串进行较复杂操作时,用这个,这个时候StringBuffer比String在灵活的多.也高效的多,所以这个时候用StringBuffer

5.    有什么特点?

StringBuffer 与StringBuilder区别

1.5版以后出现了StringBuilder()

StringBuffer是线程安全的,可让一个线程操作,而StringBuilder可以让多个线程操作,其效率要高,但是有安全隐患.

与String类用法很多相似之处

不同之处:

String的值不可以改变,但是StringBuffer可以

StringBuffer在做大量字符串链接操作要比String高效的多

二、基本数据类型包装类

1.    是什么?

就是每个基本数据类型包装成了一类,那么其就具有了类的特性,

byte—byte

short—Short

int——integer

long—–Long

float—–Float

double —Double

char—-character

boolean —-Boolean

2.    有什么用?

主要用于字符串和基本数据类型间的相互转换

因为其可以将一个基本类型数据转换成对象.

3.    怎么用?

以integer举例

构造方法:

public Integer(int value)或(String s)将一个数字或字符串

转换成integer对象

常用方法:

  • 将字符串转成数字:static parseInt(String s , int n);n不写时默认是10进制,写了就是以所写进制转换.
  • 将数字转换成字符toString( int i)

String s = “110”;如果这里不是数字会抛一个运行时异常.

// int i=Integer.parseInt(s); //默认s作为10进制分析.

int i = Integer.parseInt(s,2);

String a =Integer.toString(i);

  • 将包装类里的数字得到:int a =Integer对象.vintalue();
  • .将int值转换成不同进制,以字符串形式返回

4.1  public static  String toBinaryString(int i)   二进制

4.2  public static  String toOctalString(int i)    八进制

4.3  public static  String toHexString(int i)      十六进制

4.    什么时候用?

大部分情况是当要将字符串转换成基本数据类型时用.

5.    有什么特点:

转换都会抛运行时异常,如果没处理成功的话.

Ø  第十六天 集合

一、Collection集合接口

各种集合的什么时候使用

Collection

如果只是存一个值,用Collection

List —->有顺序,可重复

ArrayList ——>用的比较多  查找时比较高

LinkedList——>可以方便操作头尾元素,在插入或修改效率比较高

Vector—也是数组实现,但是每次递增100%.线程安全,插入时效率比较高.

Set——>无顺序,不可重复

HashSet—->无顺序,不可重复  采用hash表来维护唯一性

LinkedHashSet 可以让添加时的顺序与取出时的顺序一致

TreeSet—-> 二叉树 有顺序,不可重复   TreeSet有顺序,效率比较低

Map

如果存储的是关系,key-value用Map

HashMap—hash表实现    比较多 线程不安全

LinkedHashMap 可以让添加时的顺序与取出时的顺序一致

Hashtable–hash实现 不可以有null键和null值 线程安全

|—-Properties 可以与流结合

TreeMap—二叉树  用key来进行排序

1.    是什么?

Collection是集合层次中的根接口.其含有集合都具备的抽象方法.其实现类

2.    有什么用?

其实现类叫集合,为一个容器,里面可以装不同的对象,并对其进行增删改查的操作

3.    怎么用?

其本身这些方法是不能用的,但是其实现类实现了就都可以用了,这个叫共有方法

增:增加一个对象或集合,增加成功返回true

1.public boolean add(Object obj)   向集合中添加一个元素obj

2.public boolean addAll(Collection c)  向集合中添加一堆元素  c

改:: 删除某个元素,或删除所有元素,或将一部分元素删除.

public void clear() 清空集合

.public boolean remove(Object obj)

将集合中元素obj删除,如果删除成功,返回true.一次只能删除一个.

public boolean removeAll(Collect c) 将集合中与c集合中相同的元素删除.

查:查询长度,交集,元素是否相同,是否是子集,是否是空集合.

public boolean retainAll(Collection c) 求集合的交集,

public int size(); 得到集合中元素的个数

public boolean contains(Object obj)

判断集合中是否有与obj相同的元素.这里面的相同是equals

public boolean containsAll(Collection c)

判断集合c是否是当前集合的子集.

public boolean isEmpty()

判断集合中是否有元素.如<A HREF=”Demo1.java”></A>果size为0,代表空,返回true。

Object[] toArray()返回包含此 collection 中所有元素的数组。

4.    什么时候用?

当需要对多个对象进行操作时,就要用到集合

5.    有什么特点?

集合只能放对象

集合分为两种,一种有序可重复,一中无序不可重复.

二、Iterator迭代器—重点

1.    是什么?

迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。迭代器修改了常规指针的接口,所谓迭代器是一种概念上的抽象:那些行为上像迭代器的东西都可以叫做迭代器。然而迭代器有很多不同的能力,它可以把抽象容器和通用算法有机的统一起来。

2.     有什么用?

迭代器提供一些基本操作符:*、++、==、!=、=。这些操作和C/C++“操作array元素”时的指针接口一致。不同之处在于,迭代器是个所谓的智能指针,具有遍历复杂数据结构的能力。其下层运行机制取决于其所遍历的数据结构。因此,每一种容器型别都必须提供自己的迭代器。事实上每一种容器都将其迭代器以嵌套的方式定义于内部。因此各种迭代器的接口相同,型号却不同。这直接导出了泛型程序设计的概念:所有操作行为都使用相同接口,虽然它们的型别不同。

3.    怎么用?

Iterator 迭代器名 = 集合名.iterator();—–得到一本集合的迭代器对象,

然后用这个对象调用Iterator接口中定义的方法

迭代器名.hasNext()…..迭代器名.next()…..迭代器名.remove()…..

来实现:

1.public boolean hasNext()  判断是否有元素进行迭代,没有返回false,一般用于定义条件标记

2.public Object next();      取到下一个元素

3.public void remove();      删除元素

4.    什么时候用?

当需要对集合里的元素进行遍历或移除操作时

5.    有什么特点?

public Iterator iterator() 得到集合的迭代器.

迭代器模式。Iterator对已集合类中的任何一个实现类,都可以返回这样一个Iterator对象。就和循环一样,好处是可以适用于任何一个类,而且实际上java对它进行了优化,比直接用index访问快一点(这一点没法考证,别人都这样说)。不过呢,有一点很好,就是用起来确实很好用,加上泛型就更好用啦。比如说这样一个例子ArrayList< String > arr = new ArrayList< String >();Iterator it = arr.iterator();迭代的时候可以这样while( it .hasNext() ){ //做一些处理,比如 System.out.print( it.next );}配合上泛型,一个好处是it.next()可以不用类型转换。以前用的时候是Object,还要自己转,我感觉,Iterator和泛型简直就是绝配哈。

三、List集合(接口)

1.    是什么?

是有序的 collection(也称为序列或集合)的接口,其实现类是ArrayList。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。

2.    有什么用?

可以装一系列可重复的对象,并可以对里面的对象对行增删改查的操作.

3.    怎么用?

:  

public void add(int index,Object obj)

将obj添加到集合的index位置

:

.public Object remove(int index)

删除集合中索引为index这个元素,返回值就是删除的这个元素.

:

5.public Object set(int index,Object obj)

将集合中index位置上的元素用obj替换,返回的是被替换掉的元素

::

public Object get(int index);

得到集合中指定位置上的元素

public int indexOf(Object obj)

得到集合中obj第一次出现的索引值,如果没有返回-1

4.    什么时候用?

当需要操作一系列可能有重复的对象时用

5.    有什么特点?

与 set 不同,列表通常允许重复的元素。更确切地讲,列表通常允许满足 e1.equals(e2) 的元素对 e1 和 e2,并且如果列表本身允许 null 元素的话,通常它们允许多个 null 元素。

Ø  第十七天

一、ListIterator接口

1.    是什么?

是Iterator(迭代器)接口的一个子接口

2.    有什么用?

作用和Iterator迭代器一样,本个功能.判断集合里还有没有元素,取出一个元素,移除一个元素

可以遍历出集合所有元素

3.    怎么用?

ListIterator 迭代名 = 集合名.listItetator();

迭代器名.hasNext()…..迭代器名.next()…..迭代器名.remove()…..

4.    什么时候用?

当你想在用迭代器时,同时又想用集合自带方法对集合进行修改时用.

5.    有什么特点?

与Itrerator区别在于,Iterator在操作集合时,不允许add(object obj) ,set(int index,Object obj)两个增加修改方法运行,但可以用list.remove(obj);

如果使用Collection中的iterator方法得到迭代器,

如果要删除集合中的对象,建议使用迭代器中的remove方法.

二、ArrayList类

1.    是什么?

是List接口的一个实现类,其有List的特点,即有序且可重复.并允许包括 null 在内的所有元素。

2.    有什么用?

可以装一系列可重复的对象,并可以对里面的对象对行增删改查的操作.

3.    怎么用?

:  

public void add(int index,Object obj)

将obj添加到集合的index位置

:

.public Object remove(int index)

删除集合中索引为index这个元素,返回值就是删除的这个元素.

:

5.public Object set(int index,Object obj)

将集合中index位置上的元素用obj替换,返回的是被替换掉的元素

::

public Object get(int index);

得到集合中指定位置上的元素

public int indexOf(Object obj)

得到集合中obj第一次出现的索引值,如果没有返回-1

4.    什么时候用?

当需要操作一系列可能有重复的对象时用

5.    有什么特点?

其底层实现方式是数组实现的实现了所有可选列表操作,并允许包括 null 在内的所有元素。

低层用数组的实现,它的特点是在进行get操作效率比较高。

但是由于是数组实现,每一次在add后,都需要重新创建数组,

所有在add操作性能比较低。

ArrayList与Vector类区别

1.ArrayList是异步的,线程不安全的。Vector是同步的,线程安全的.

2.ArrayList每一次增长 50%

三、List接口下的LinkedList

1.    是什么?

LinkedList 是List 接口下的一个的链接列表实现类,。其底层是以链表的形式实现的.

2.    有什么用?

其具体实现了List的所有功能,同时具有自已特有功能,其允许所有元素(包括 null)。

在列表的开头及结尾 get、remove 和 insert 元素提供了统一的操作方法。

3.    怎么用?

建立对象

List l = new LinkedList();

特有方法:

在开头或结尾增加元素

addFirst()

addLast()

在jdk1.6后替代方法

offerFirst();

offerLast();

在开头和结尾或取元素

getFirst()

getLast();

如果集合为空,在使用上面两个方法时会抛出NoSuchElementException

在jdk1.6后替代方法

peekFirst();

peekLast();

如果集合为空,在使用上面两个方法时,会得到null

移除开头和结尾的元素

Object removeFirst()

Object removeLast()

返回的是移除的元素

如果集合为空,在使用上面两个方法时会抛出NoSuchElementException

在jdk1.6后替代方法

pollFirst()

PollLast()

4.    什么时候用?

当需要对集合首尾进行频繁操作时,这个时候用.

5.    有什么特点?

1.执行add 操作时,因为ArrayList是数组实现,每添加一次,都会产生新的数组对象,效率比较低。LinkedList在执行add操作时,要比ArrayList性能高.

2.在执行get操作时,ArrayList是数组实现,可以理解连续内在空间,所以性能比较高。

LinkedList是链表实现,每一个中都保存了前一个的地址,在取出时效率低。

在增强for循环里不可以对元素进行修改.

四、Set集合–之HashSet

1.    什么是HashSet?

HashSet是set集合的一个实现类,由哈希表(实际上是一个 HashMap 实例)支持。其不可以有重复的元素.

而Set是一个接口,可以理解为一个不包含重复元素的 collection。更确切地讲,set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素。

2.    有什么用?

可以用来作为一系列不重复元素的容器,并对里面的元素进行操作

3.    怎么用?

:

boolean add(E e)

如果此 set 中尚未包含指定元素,则添加指定元素。

注意:由于HashSet往里面添加元素的时候,是先比较hashCode方法,不同,便直接认为其是不同,元素,直接添加,可实际往往很多内容相同的元素hashCode是不同的.这样便不能实现效果.

所以在添加元素时,一般要对对象进行hashCode方法重写,让其根据每个对象内容来生成hashCode,同时也重写equals以hashCode比较完后,进行第二次确认.

例:

int id;

String name;

public int hashCode(){  //重写hashCode方法  通过对象比较的属性来全成hashCode值.

final int num=13;

return num+id+name.hashCode();

}

删改:

void clear()

从此 set 中移除所有元素。

boolean remove(Object o)

如果指定元素存在于此 set 中,则将其移除。

:

boolean contains(Object o)

如果此 set 包含指定元素,则返回 true。

boolean isEmpty()

如果此 set 不包含任何元素,则返回 true。

Iterator<E> iterator()

返回对此 set 中元素进行迭代的迭代器。

 int size()

返回此 set 中的元素的数量(set 的容量)。

4.    什么时候用?

当需要将一系列不重复对象装入集合,进行相应的操作时,用HashCode.

5.    有什么特点?

1,不可重复,无序的

2,HashSet判断集合中元素是否重复的特点:

第一件事

做的是判断两个元素的哈希值是否相同,如果相同,代表这两个元素

可能是同一个元素.去执行第二件事。如果两个对象的哈希值不同,

HashSet集合认为这两个对象是不同的对象,不用判断equals,直接添加。

第二件事

在去进行equals比较。如果equals也返回true,

那么hashSet认为这两个元素重复,不可添加第二元素.

是否重复的元素的一个初始条件,两个对象如果hashCode一样,那么才可以判断是否

重复,通过equals方法判断。

如果两个对象hashCode不一样,就认为这两个对象是不同的对象,不会判断equals

如果在hashCode方法中返回一个常量,但是效率下降,每一次操作都需要进行equals  比较.所以为了提高效率,我们在重写hashCode时利用对象的属性获得hashCode

五、重写hashcode值和equals

应用于hashSet

final int NUM = 17;//用质数(只能被子已和1整除)

public int hashCode() {

return name.hashCode() + age * NUM;

}

public boolean equals(Object obj) {

// 为了程序提高效率

if (obj == this) {

return true;

}

// 提高程序的健壮性

if (!(obj instanceof Student)) {

return false;

}

// 向下转型

Student s = (Student) obj;

return this.name.equals(s.name) && this.age == s.age;

Ø  第十八天

一、TreeSet集合类

1.    是什么?

set的一个实现类,其以默认以自然顺序排序

2.    有什么用?

TreeSet:使用元素的自然顺序对元素进行排序, 或者根据创建 set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。

3.    怎么用?

我们将Human对象装入TreeSet集合,TreeSet要求元素有自然顺序,

我们可以让Human类的自然是按照年龄来排序.

具体过程

1.Human类实现Comparable接口

2.在Human类中重写接口中的compareTo方法,在该方法中进行年龄的比较.

public int compareTo(Object obj)

TreeSet集合中的元素也是不重复的,它怎样保证元素的不重复,

是通过compareTo方法的返回值来判断的。如果返回0代表元素是重复

TreeSet的实现是通过二叉数实现的.最小的在左边,大的在右边

特点:

默认自然顺序排序,可重写自然排序方法.或重写比较器方法.

二、Comparable(自然顺序)与Comparator(比较器接口)

怎么用?

基本类型  它们的比较就是比较值.

引用类型  比较大小.  自定义类比较大小

只能参赛类中定义的属性进行比较.

String类它已经实现了自己的自然顺序,它们比较的码值.

class HumanComparateByName implements Comparator

{

//o1代表的是TreeSet中要添加的元素   o2代表的是集合中存在的元素

public int compare(Object o1,Object o2){ //Object引用指向的真正类型应该是Human

Human h1=(Human)o1;

Human h2=(Human)o2;

return h1.name.compareTo(h2.name); //调用的是String类中的实现的Comparable接口中的compareTo方法

}

}

//当前Human类有自然顺序,是按照年龄进行比较

class Human implements Comparable{

int age;

String name;

public Human(int age,String name){

this.age=age;

this.name=name;

}

public String toString(){

return name+”  “+age;

}

public int compareTo(Object obj){

Human h=(Human)obj;

int value=new Integer(this.age).compareTo(new Integer(h.age)); //对象操作

return value==0?(this.name.compareTo(h.name)):value;

}增强

}

三、LinkedHashSet

是HashSet子类

LinkedHashSet特点是:

此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序(插入顺序)进行迭代。

简单说就是添加的顺序与迭代出的顺序一致

*/

import java.util.*;

class Demo4

{

public static void main(String[] args)

{

LinkedHashSet lhs=new LinkedHashSet();

lhs.add(“abc”);

lhs.add(“123”);

lhs.add(“def”);

lhs.add(“kkk”);

for(Iterator it=lhs.iterator();it.hasNext();){

System.out.pritnln(it.next());

}

}

}

1.ArrayList   ——->数组   可重复 ,有顺序(加入的顺序与取出顺序一致)

2.LinkedList———>链表   可以方便操作头尾元素

3.HashSet————>HashMap 依靠hash表   不重复,无顺序

4.TreeSet————>二叉数   不重复,有顺序(1.按照自然顺序2,按照比较器)

四、泛型

是什么?

java中的泛型 jdk1.5以后出现的.

在以前操作集合时,取出集合元素要判断其类型,很麻烦,并且有可能出现ClassCastException

有什么作用?

<类型>其实就是用来限定类型的.

通过泛型我们将在运行时有可能出现的异常,在编译就进行检查

使用泛型它限定了集合中元素的类型,但是我们在操作集合元素时更方便了。

在api中如果看到某个类后面<>代表这个类是可以用泛型进行限定的.

怎么用?

List<String> list=new ArrayList<String>(); //当前集合中的元素已经限定

list.add(“abc”);

list.add(“123”);

list.add(“new Thread()”);

//使用迭代器将集合中的元素迭代出来

List集合,通过get方法得到的元素类型全是Object

Iterator 的next方法得到的元素也是Object类型.

for(Iterator<String> it=list.iterator();it.hasNext();){

String s=it.next();

—–

//?是一个通配符   泛型中的一个可以匹配任何类型.

//作用是将集合中的元素显示出来

public static void show(Collection<?> c){

for(Iterator<?> it=c.iterator();it.hasNext();){

Object obj=it.next();

System.out.println(obj);

}

//自定义泛型类

class Tools<A>

{

private A obj;

public void set(A obj){

this.obj=obj;

}

public A get(){

return obj;

}

}

//对于类方法来说,我们在使用时要注意,泛型要定义在static后面.

//在类方法中不可以直接使用在类上定义的泛型

public static <B> void print(B b){

System.out.println(b);

}

Ø  第十九天

一、map集合

1.    是什么?

将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。

也就是说:可以是[a-1,b-1,c-1],但不可以是[1-a,1-b,-1-c]

Map框架

—HashMap 底层采用hash表来实现. 可以使用null值null键,异步

—-LinkedHashMap 简单说这个map保证了存入的顺序与取出顺序一致

—Hashtable 底层采用hash表来实现 不可以使用null值,null键 ,同步

—-Properties 它采用配置文件方式来映射key value。在IO操作中可以使用.

—TreeMap

TreeMap也是采用二叉树来实现。它是根据key进行排序

2.    有什么用?

3.    怎么用?

public static void main(String[] args)

{

//建立对象

Map<Integer,String> map=new HashMap<Integer,String>();

//添加元素

map.put(1,”abc”);

map.put(11,”def”);

map.put(21,”klm”);

Map类提供了一个称为entrySet()的方法,这个方法返回一个Map.Entry实例化后的对象集。接着,Map.Entry类提供了一个getKey()方法和一个getValue()方法,因此,上面的代码可以被组织得更符合逻辑。          

获得元素:

Set<Map.Entry<Integer,String>> set=map.entrySet(); //存的值的类型是Map.Entry

//获得迭代器

Iterator<Map.Entry<Integer,String>>  it=set.iterator();

//遍历出元素

// 遍历

// 第一种

Set<String> set = hm.keySet();

for (Object obj:set )

{

String key =(String)obj;

Teacher t = hm.get(key);

System.out.println(key + “***” + t.getName() + “***” + t.getAge());

}

System.out.println(“***********************************************”);

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

while (it.hasNext()) {

String key = it.next();

Teacher t = hm.get(key);

System.out.println(key + “***” + t.getName() + “***” + t.getAge());

}

System.out.println(“***********************************************”);

// 第二种

Set<Entry<String, Teacher>> entrySet = hm.entrySet();

Iterator<Entry<String, Teacher>> itEntry = entrySet.iterator();

while (itEntry.hasNext()) {

Map.Entry<String, Teacher> me = itEntry.next();

String key = me.getKey();

Teacher t = me.getValue();

System.out.println(key + “***” + t.getName() + “***” + t.getAge());

}

——————————————–

while(it.hasNext()){

Map.Entry<Integer,String> me=it.next();

int key=me.getKey();

String value=me.getValue();

System.out.println(“Key:”+key+”  value:”+value);

}

查询

map.values():获取映射的值的集合Collection

map.size()或取集合的长度

keySet()获得映射的集合set

map.get(1)获得1所映射的值

删:

map. remove(Object key)

如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。返回删除的值.

map.clear();全部清除

4.    什么时候用?

当虽要有一一对应的关系的对象所组成的集合的时候用.

5.    有什么特点?

Map集合必须掌握的东西

1.怎样存储 put(Object key,Object value)

2.怎样取得  间接使用迭代器

2.1 keySet —–>得到key的Set集合

2.2 entrySet—->得到的key,Value的关系映射图 Map.Entry类型.

如果要使用map集合中在存入时与取出时顺序一致可以使用:LinkedHashMap

 

TreeMap 根据集合中key的自然顺序来排序

二、Collections工具类

1.    是什么?

它是Collection的操作类,这个类中的方法全是static

我们可以将其理解成Collection的一个工具类

2.    有什么用?

对Collection类集合提供快速操作

3.    怎么用?

  1. int binarySearch(List list,Object key) 只对list集合有效

在集合中查找key的索引

如果不存在,返回的是(-(插入点)-1)

排序

  1. void sort(List list) 按照list集合中的自然顺序排序 .
  2. void sort(List list,Comparator c) 按照给定的比较器,对集合听元素进行排序
  3. void reverse(List list) 将list集合中的元素反转换

5.Comparater reverseOrder() 它是返回自然顺序

6.static void swap(List<?> list, int i, int j)

在指定列表的指定位置处交换元素。

7.synchronizedList():能解决线程不安全,并保证一定的高效,将非同步的集合转成同步集合。

应用举例:

List<Book> list=new ArrayList<Book>();

list.add(new Book(2,”thinking in c++”,”tom”,89.9));

list.add(new Book(1,”thinking in java”,”tom”,89.7));

list.add(new Book(3,”thinking in ruby”,”tom”,49.9));

Collections.sort(list,Collections.reverseOrder());

//list集合中元素现在有自然顺序,第二参数的作用是//反转原来的自然顺序

Collections.sort(list);//list集合中元素的自然顺序

//Collections.sort(list,new BookComparator()); //list集合中的元素按照比较器指定方式排序

//使用比较器  价格

class BookComparator implements Comparator<Book>

{

public int compare(Book b1,Book b2){

if(b1.price-b2.price>0){

return 1;

}else if(b1.price-b2.price<0){

return -1;

}else{

return 0;

}

}

}

//让Book类有自然顺序  id

class Book implements Comparable<Book>

{

int id;

String name;

String author;

double price;

Book(int id,String name,String author,double price){

this.id=id;

this.name=name;

this.author=author;

this.price=price;

}

public int compareTo(Book b){

return this.id-b.id;

}

public String toString(){

return “ID:”+id+”  NAME:”+name+”  AUTHOR:”+author+”  PRICE:”+price;

}

}

4.    什么时候用?

对Collection快速操用时使用

5.    有什么特点?

这个类中的方法全是static,

|–collection和collections的区别:

  • collections是集合框架中的一个工具类,里面提供了操作较多的对集合进行操作的方法,比如说synchronizedList、binarySeach()等。它还可以把非同的的变成同步的,也就说把不安全的变成安全的。
  • Collection同样是集合框架中的一个工具类,单列集合、顶层接口、定义了单列集合的顶层方法、增删改查,有两个子接口list、set,这样两个子接口下面各有两个常用的子类:list有arrayList、linkedlist,set有hashSet、treeSet。(自己还可以扩展、越多越好)

三、Arrays(数组)工具类

1.具体用法:

Arrays 数组的操作类,它提供了对数组的操作

static void sort(Xxx[]  a)

对指定的Xxx[] 型数组按数字升序进行排序。

static int binarySearch(Xxx[] a, Xxx xxx)

使用二分搜索法来搜索指定的Xxx型数组,以获得指定的值。

static Xxx[]  copyOfRange(Xxx[] original, int from, int to)

将指定数组的指定范围复制到一个新数组。

1.static Xxx[] copyOf(Xxx[] arr,int length)

将arr数组中length长度的元素copy到新数组中, 返回值就是得到的新数组.

2.static String toString(Xxx[] arr)

将arr数组中的元素以字符串形式显示出来

3.static void fill(Xxx[] arr,Xxx a)

将a填充到数组中,简单说arr数组中元素的值全是a

2.数组与集合之间的转换

Arrays类  数组的操作类

static List asList(T… t); 将一个数组转换成List集合

集合的操作更丰富,我们转换成以后,可以使用集合中提供的方法来操作数组.

String[] arr={“abc”,”def”,”kkk”}

List<String> list=Arrays.asList(arr); //将一个数组转换成了List集合

list.add(“wolf”);// java.lang.UnsupportedOperationException

当前list是用数组得到的,数组是定长的,不可以改变长度,

所以不支持。

不能改变集合的长度.

3.Arrays.asList(数组)转换特点:

如果数组中的元素是引用类型,那么当转换成List集合后,数组中的元素就是集合中的元素

如果数组中的元素是基本类型,那么当转换成List集合后,会将数组做为集合的元素存储到集合中.

4.集合转换成数组

List

Collection中方法

<T> T[] toArray(T[] a)

作用是将一个集合转换成数组

Integer[] st=list.toArray(new Integer[list.size()]);

//如果参数数组的长度比集合size小,那么得到的数组长度为集合的size

//如果参数数组的长度比集合size大,那么得到的数组长度为参数数组的长度.

//在使用时,我们定义list.size最合适

5.        集合转换成数组作用

如果当前集合内容需要被人访问,但是我还不想让其直接访问集合,可以将其

转换成数组返回。因为数组长度为定长,在使用时,就不能改变长度。

四、增强for循环

foreach语句

Collection实现了这个接口Iterable

实现这个接口允许对象成为 “foreach” 语句的目标。

格式

for(元素类型 变量名:Collection或数组){}

int[][] arr={{1,2,3},{4,5,6}};

for(int[] a:arr){

for(int n:a){

System.out.print(n+”  “);

}

System.out.println();

}

}

五、     静态导入

jdk1.5新特性

虽然简化了书写,但是不方便阅读.

import static java.util.Collections.*; //*代表的是Collections中的所有方法

//在当前类中所使用的Collections中的static方法直接可以使用方法名.

import static java.util.Arrays.*;

List<Integer> list=new ArrayList<Integer>();

在用的时候就可以直接sort(list),而不用Collections.sort(list);

但是如果与里面的方法有冲突,就必须有::

String[] s=new String[]{“a”,”b”,”c”};

sort(s);

System.out.println(Arrays.toString(s));//与Object中的toString方法冲突

六、方法的可变参数

相当于数组,但是在调用时,可以一次传递多个参数.

如果使用这种可变参数,那么它后面不可以在定义参数,

前面可以.

public static void show3(int…  a){

System.out.println(“可变参数”);

for(int n:a){

System.out.println(n);

}

}

七、System类

static Properties getProperties()

确定当前的系统属性。

static String getProperty(String key)

获取指定键指示的系统属性。

Properties p=System.getProperties();

Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。

Set set=p.keySet();

for(Iterator<String> it=set.iterator();it.hasNext();){

String key=it.next();

System.out.println(“KEY:”+key+”  VALUE:”+p.get(key));

}

String myProperty=System.getProperty(“filePath”);

System.out.println(myProperty);

八、Runtime类

每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。可以通过 getRuntime 方法获取当前运行时。

应用程序不能创建自己的 Runtime 类实例。

这个类对外公开构造方法,类中方法还是实例方法.

对于这样的类一般在其类都会提供一个公共的静态的获得当前类实例的方法.

1.public static Runtime getRuntime()得到一个Runtime实例.

  1. Process exec(String p)在单独的进程中执行指定的字符串命令。

2.1 Process相当于一个进程,我们可以调用这个进程相关操作。如果destroy。

Process exec(String command, String[] envp, File dir)

在有指定环境和工作目录的独立进程中执行指定的字符串命令。

 void exit(int status)

通过启动虚拟机的关闭序列,终止当前正在运行的 Java 虚拟机。

 long freeMemory()

返回 Java 虚拟机中的空闲内存量。

void gc()

运行垃圾回收器。

static Runtime getRuntime()

 

返回与当前 Java 应用程序相关的运行时对象。

void halt(int status)

强行终止目前正在运行的 Java 虚拟机。

九、Math 数学类

Math 类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。

  1. abs求绝对值
  2. round 四舍五入
  3. random() 得到0-1之间的一个随机数,不包含1

jdk1.5之后有了Random类.

  1. pow(double a,double b) 得到a的b次方
  2. floor(double a) 得到比a小的数中最大的整数
  3. ceil(double a) 得到比a大的数中最小的整数
  4. sqrt(double a) 得到a的平方根

十、Date  时间日期类

java.util.Date

构造方法

1.new Date(); 得到系统当前时间

2.new Date(long m); 用m来构造一个时间

实例方法

1.long getTime() 得到基准时间到Date对象表示的时间点所经过的毫秒值

2.void setTime(long l); 设置Date对象的毫秒值

3.String toString()

把此 Date 对象转换为以下形式的 String: dow mon dd hh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat)。

*/

import java.util.*;

class Demo14

{

public static void main(String[] args)

{

Date date=new Date(1234567890000L)

System.out.println(date);

Date date=new Date();

date.setTime(1234567890000L);

System.out.println(date.getTime());

//得到昨天这个时间.

Date date=new Date();//当前时间

Date yestoday=new Date(date.getTime()-24*60*60*1000);

System.out.println(date.after(yestoday));

System.out.println(date.before(yestoday))

//System.out.println(yestoday);

}

}

十一、DateFormat 时间日期格式化类

DateFormat是一个抽象类,作用是用来格式化日间与日期的.

作用:

              1.可以将Date格式化成指定样式的字符串

              2.可以将一个字符串分析成日期

用其子类

我们一般使用时都用SimpleDateFormat类

1.String format(Date date) 将一个Date格式化成String 用默认的模式和默认语言环境的日期格式符号构造 SimpleDateFormat

import java.util.*;

import java.text.*;

class Demo15

{

public static void main(String[] args)

{

//默认模式

DateFormat df=new SimpleDateFormat();

String s=df.format(date);

System.out.println(s);

//自定义模式  要参数模式定义字母,这些字母有特定意义

DateFormat df=new SimpleDateFormat(“yyyy年MM月dd日 hh时mm分ss秒”);

String s=df.format(date);

System.out.println(s);

}

}

1.static DateFormat getDateInstance();这个方法得到的是DateFormat对象. 真实对象还是子类对象.

得到的是一个日期的格式化器,只能格式化出年月日

2.static DateFormat getDateTimeInstance();

得到的是一个日期日间的格式化器,只能格式化出年月日小时分钟

*/

import java.util.*;

import java.text.*;

class Demo16

{

public static void main(String[] args)

{

DateFormat df=DateFormat.getDateInstance(DateFormat.LONG)

System.out.println(df.format(new Date()));

DateFormat df=DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);

System.out.println(df.format(new Date()));

}

}

3..Date parse(String s)

       将s字符串分析成一个Date对象.

在分析字符串成为Date时,一定要注意当前DateForamt所采用的模式要与要分析的字符串匹配,这样才可以分析成功,要不会抛出ParseException异常

import java.util.*;

import java.text.*;

class Demo17

{

public static void main(String[] args) throws Exception

{

String s=”2012/10/10″;

//DateFormat df=DateFormat.getDateInstance();

DateFormat df=new SimpleDateFormat(“yyyy/MM/dd”);

Date date=df.parse(s);

System.out.println(date);

}

十二、集合总结:

1:集合框架

用任意的集合对象,可以存储自定义对象即可。可以遍历出来。

Collection

|–List

|–ArrayList

|–Vector

|–LinkedList

|–Set

|–HashSet

|–LinkedHashSet

|–TreeSet

Map(key,value)

|–HahsMap

|–LinkedHashMap

|–Hashtable

|–Properties 这个类可以和io结合使用。

|–TreeMap

Iterator:迭代器接口

比较器接口 主要用于TreeSet

Comparable 让元素本身具备比较性

Comparator 让集合具备比较性

      简述ArrayList、Vector、LinkedList之间的区别?

ArrayList与Vector底层都是通过数组实现的,但是区别在于ArrayList每增加一值后,长度递增50%,查询速度快,增删慢.

而Vector长度初始是固定的,每超过长度后,就会创建一个两倍长度的新数组,且是线程安全的,但效率较低

而对于LinkedList,其底层是通过链表实现的,其有自已的独的方法,找数据比较快,addFirst(E e)将指定元素插入此列表的开头,

addLast(E e) 将指定元素添加到此列表的结尾。

Collection和Map之间的区别?

Collection每个位置只存储一个值,而Map是存储一对有关系的值

HashSet和TreeSet之间的区别?

HashSet无序且不可重复的集合,可以通过重写hashcode值和equals方法来维护其元素的唯一性,通过hashcode表实现

final int NUM = 17;//用质数(只能被子已和1整除)

public int hashCode() {

return name.hashCode() + age * NUM;

}

public boolean equals(Object obj) {

// 为了程序提高效率

if (obj == this) {

return true;

}

// 提高程序的健壮性

if (!(obj instanceof Student)) {

return false;

}

// 向下转型

Student s = (Student) obj;

return this.name.equals(s.name) && this.age == s.age;

}

而TreeSet是有序的不可重复的通过二叉数实现的集合,通过元素的自然顺序排序,可以通过重建比较器或重新定义,自然顺序来实现元素的存储.

Collection和Collections的区别?

Collection是集合系的父接口,而Collections是对所有Collection集合的工具类.

Hashtable和HashMap之间的区别?

Hashtable不允许有null键和null值,HashMap可以有.

Ø  第二十天 IO流

一、1.Calendar抽象类

1.    是什么?

是一个操作日期中的年,月,日,时,分,秒这样的单独数据的抽象类

2.    有什么用?

获取日期中的年,月,日,时,分,秒这样的单独数据

3.    怎么用?

通过Calendar.getInstance()获取一个子类对象。

例如:

public class CalendarDemo {

public static void main(String[] args) {

// 创建Calendar的子类对象

Calendar c = Calendar.getInstance(); // 获取到的是子类的实例 多态

// 直接打印对象名,其实是调用了对象的toString方法。

// getClass().getName() + ‘@’ + Integer.toHexString(hashCode())

// System.out.println(c);

System.out.println(“现在的时间是:” + c.get(Calendar.YEAR) + “年”

+ (c.get(Calendar.MONTH) + 1) + “月” + c.get(Calendar.DATE)

+ “日” + c.get(Calendar.HOUR) + “时” + c.get(Calendar.MINUTE)

+ “分” + c.get(Calendar.SECOND) + “秒”);

//getDays(2012);

getDays(2002);

}

// 获取任意一年的二月份有多少天

public static void getDays(int year) {

// 获取日历类的子类对象

Calendar c = Calendar.getInstance();

// set方法 设置年,月,日

c.set(year, 2, 1); // 设置某一年的3月1日

// 怎么着让这个日期减1天呢

c.add(Calendar.DATE, -1);

System.out.println(“现在的时间是:” + c.get(Calendar.YEAR) + “年”

+ (c.get(Calendar.MONTH) + 1) + “月” + c.get(Calendar.DATE)

+ “日” + c.get(Calendar.HOUR) + “时” + c.get(Calendar.MINUTE)

+ “分” + c.get(Calendar.SECOND) + “秒”);

4.    什么时候用?

如果想获取日期中的年,月,日,时,分,秒这样的单独数据的时候

5.    有什么特点?

其是一个抽象类,但是其提供一个静态方法获取其子类的对象

Calendar c = Calendar.getInstance();

十三、File类

1.    是什么?

是文件和目录路径名的抽象表示形式。用户界面和操作系统使用与系统相关的路径名字符串 来命名文件和目录。此类呈现分层路径名的一个抽象的、与系统无关的视图。

2.    有什么用?

对文件和文件夹都是用File对象进行封装的

可以让java对文件或文件夹进行获取,创建,删除,获取和判断操作

3.    怎么用?

A:构造方法

**File file = new File(“c:\\it.txt”); 绝对路径

**File file = new File(“it.txt”); 相对路径

**File file = new File(“c:\\”,”it.txt”);

**File file = new File(“c:\\”);

File file2 = new File(file,”it.txt”);

B:绝对路径和相对路径(重点)

绝对路径是从盘符开始的路径。c:\\it.txt

(3)File类常用功能(重点)

A:创建功能

**创建文件 createNewFile();

**创建文件夹 mkdir(),mkdirs(); 后者可以创建多级目录

B:删除功能

**删除文件和文件夹 delete()

注意:删除的目录中如果有内容(文件或者文件夹),那么必须首先删除内容。

C:判断功能

**exists() 判断文件或者文件夹是否存在

**isDirectory 判断是否是目录(重点)

**isFile 判断是否是文件(重点)

**isAbsolute 判断是否是绝对路径

**canRead 判断File实例是否可读

**canWrite 判断File实例是否可写

**isHidden 判断File实例是否是隐藏内容

D:基本获取功能

**getAbsolutePath 获取File实例的绝对路径

**getPath 获取File实例的相对路径

**getName 获取File实例的名称

**length 获取File实例的大小。单位是字节

**lastModified 获取File实例的最后修改时间。单位毫秒

E:重要的获取功能(重点)

**File[] static listRoots 获取硬盘的所有盘符集合

**String[] list 获取指定目录下所有文件和文件夹的名称的字符串数组

String[] list(new FilenameFilter) 文件名称过滤器

**File[] listFiles 获取指定目录下所有文件和文件夹的File对象的数组

File[] listFiles(new FilenameFilter) 文件名称过滤器

(4)重点代码:

获取指定目录下以某个后缀结尾的所有文件的名称

两种方式:

第一种:匿名对象

第二种:匿名内部类

匿名内部类的格式:

new 类名或者接口名(){

//重写或者实现方法

}

String[] strArray = file.list(new 类名或者接口名(){

//重写或者实现方法

});

public static void main(String[] args){

File file = new File(“c:\\”);

String[] strArray = file.list(new FilenameFilter(){

@Override

public boolean accept(File dir,String name)

{

return name.endsWith(“.java”);

}

});

for(String str : StrArray){

System.out.println(str);

}

}

4.    什么时候用?

对文件或文件夹进行获取,创建,删除,获取和判断操作

5.    有什么特点?

构造函数的参数是:字符串表现形式,””

十四、递归

1.    是什么?

  • 方法定义中调用方法本身的现象叫做递归
  • 有什么用?

2.    怎么用?

(4)如何使用递归:

A:递归的出口

B:递归的表达式

3.    什么时候用?

(3)案例

A:求阶乘

/**

* 5! = 5*4!

*          5*4*3!

*          5*4*3*2!

*          5*4*3*2*1!

* 你知道的1!=1

*

* 你只要知道:

* 递归的出口:1!=1

* 递归的式子:n! = n*(n-1)!

*/

public static int getTotal(int m){  //m=5

if(m==1){

return 1;

}

else{

return m*getTotal(m-1);

/*

* 5*getTotal(4) 24

*    4*getTotal(3) 6

*      3*getTotal(2) 2

*           2*getTotal(1) 1

*/

B:求斐波纳契数列的第二十项的值

斐波纳契数列:

* 1,1,2,3,5,8,13,21…

*

* 分析数列规律:

*          第一项和第二项是1。

*          从第三项开始:每一项是前两项之和。

*

public class DiGuiDemo2 {

public static void main(String[] args) {

//定义数组来实现

int[] arr = new int[20];

arr[0] = 1;

arr[1] = 1;

for(int x=2; x<arr.length; x++){

arr[x] = arr[x-1]+arr[x-2];

}

System.out.println(“斐波纳契数列的第二十项的值是:”+arr[19]);

//不用数组做

int a = 1;

int b = 1;

for(int x=0; x<18; x++){

//用一个临时变量存储a的值

int temp = a;

a = b;

b = temp + b;

}

System.out.println(“斐波纳契数列的第二十项的值是:”+b);

//用递归做

System.out.println(“斐波纳契数列的第二十项的值是:”+getFib(20));

}

/**

* 递归的出口:第一项和第二项的值都是1  a b

* 递归的表达式:第三项开始:是前两项之和 a+b

*/

public static int getFib(int m){

if(m==1 || m==2){

return 1;

}

else{

return getFib(m-1)+getFib(m-2);

}

}

4.    有什么特点?

(2)递归的注意事项

A:递归次数不要太多

B:递归必须有出口

Ø  第二十一天

一、字符流的写入 FileWriter

1.    是什么?

是抽象类Writer的子类,用于向指定文件写入字符流

2.    有什么用?

向指定文件写入字符

3.    怎么用?

FileWriter

A:构造方法

FileWriter(File file)

根据给定的 File 对象构造一个 FileWriter 对象。

FileWriter(File file, boolean append)

根据给定的 File 对象构造一个 FileWriter 对象。

FileWriter(FileDescriptor fd)

构造与某个文件描述符相关联的 FileWriter 对象。

FileWriter(String fileName)

根据给定的文件名构造一个 FileWriter 对象。

FileWriter(String fileName, boolean append)

根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。

File file = new File(“pw.txt”);

FileWriter fw = new FileWriter(file);

FileWriter fw = new FileWriter(new File(“pw.txt”));

FileWriter fw = new FileWriter(“pw.txt”);

B:步骤

创建文件对象,指定写入的文件目录

调用write方法写入数据

关闭资源

FileWriter fw = new FileWriter(“fw.txt”);

fw.write(“haha”);

fw.flush();.一定要记得刷

fw.close();

标准代码事例:

import java.io.FileWriter;

import java.io.IOException;

public class Test4 {

public static void main(String[] args) {

FileWriter flr = null;

String s = “写入字符”;

try {

flr = new FileWriter(“fada.txt”);

// 方式一:直接写入字符串

flr.write(s);

// 方式二:写入char型数组

char[] ch = s.toCharArray();

flr.write(ch);

// 方式三:写入数字,结果是其ASCII码值

flr.write(110);

flr.flush();

} catch (IOException e) {

e.printStackTrace();

}finally{

if (flr!=null) {

try {

flr.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

}

4.    什么时候用?

当需要向文件中写入字符的时候

5.    有什么特点?

wrtie完后,一定要刷,flush 里面的fileName如果没有,会自已创建

fw.write(ch,0,i);为了防止写出空格,因为reader(ch)是每次读取的是一个数组,返回是当时写入的字符数目int 所以在writer时,要给定长度

这个可以写一次,刷一次,也可写多次刷一次,关健看每次写入的大小,如果大的话,就刷多几次

避免过份耗内存.

最后一定要close(),关闭以释放资源

如果追加数据,怎么办?FileWriter fw = new FileWriter(“it.txt”,true);

有true就不会覆盖,不加默认覆盖

如果让数据可以换行,怎么办?fw.write(“\r\n”);

window的换行是:\r\n

*           linux的换行是:\n

C:flush和close的区别?

flush只刷新数据

close先刷新数据,后关闭资源

D:流为什么一定要关闭?

流对象的关闭,其实做了两件事情.

第一:告诉jvm本身流对象是垃圾了,

第二:告诉系统可以释放创建流对象时候使用的资源。

二、字符流的读取 FileReader

1.    是什么?

是io包下抽象类Reader的一个子类

2.    有什么用?

用于从文件中读取字符

3.    怎么用?

构造方法

FileReader(File file)

在给定从中读取数据的 File 的情况下创建一个新 FileReader。

FileReader(FileDescriptor fd)

在给定从中读取数据的 FileDescriptor 的情况下创建一个新 FileReader。

FileReader(String fileName)

在给定从中读取数据的文件名的情况下创建一个新 FileReader。

A:读取方式一

FileReader fr = new FileReader(“it.txt”);

int ch = 0;

while((ch=fr.read())!=-1)

{

System.out.print((char)ch);

}

fr.close();

B:读取方式二

FileReader fr = new FileReader(“it.txt”);

char[] chs = new char[1024];

int len = 0;

while((len=fr.read(chs))!=-1)

{

System.out.print(new String(chs,0,len));

}

fr.close();

C.文件的复制

把某个地方的文件复制到另外一个地方去。

源文件:a.txt — FileReader

目标文件:b.txt — FileWriter

FileReader fr = new FileReader(“a.txt”);

FileWriter fw = new FileWriter(“b.txt”);

char[] chs = new char[1024];

int len  = 0;

while((len=fr.read(chs))!=-1)

{

fw.write(chs,0,len);

fw.flush();

}

fw.close();

fr.close();

标准代码写法:

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.IOException;

public class Test5 {

public static void main(String[] args) {

// 获取文件

FileReader fr = null;

try {

fr = new FileReader(“总结.txt”);

int i = 0;

// 方法一:一个字符一个字符读

while ((i = fr.read()) != -1) {

System.out.print((char) i);

}

// 方式二:一次把字符写满到一个字符数组中,如果写完了,返回-1

char[] ch = new char[1024];

while ((i = fr.read(ch)) != -1) {

System.out.print(new String(ch, 0, i));

}

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} finally {

if (fr != null) {

try {

fr.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

}

4.    什么时候用?

当需要对文件里的字符进行读取时

5.    有什么特点?

不管读还是写,都要关闭流!

读取的时候有两种方式:一种是一个字符一个字符读,这个时候返回的是ASCII,所以要强转

二是字符数组的方式读,也就是一次一个char数组

那么我们定义数组长度就显得尤为重要了,不然容易乱码,所以一般定义为char[1024].也就是1KB

三、字符写入缓冲流BufferedWrite

1.    是什么?

是FileWriter的子类,是可以高效写入字符文件的便捷类此类的构造方法假定默认字符编码和默认字节缓冲区大小都是可接受的。要自己指定这些值,可以先在 FileOutputStream 上构造一个 OutputStreamWriter。

2.    有什么用?

可以高效写入字符文件。

3.    怎么用?

public static void main(String[] args) throws IOException {

//创建对象

BufferedWriter bw= new BufferedWriter(new FileWriter(“dandan.txt”));

//给定要写入的字符

String s = “fadadfafaf”;

//定一个写入次数

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

bw.write(s);

bw.newLine();

}

bw.close();

}

}

4.    什么时候用?

当也要写入较多的字符时,可以用这个,比较高效

5.    有什么特点?

有自带的缓冲区,写入速度快 会抛异常

四、字符读取缓冲流BufferedReader

1.    是什么?

是FileReader的子类,叫字符缓冲流

用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的。

2.    有什么用?

对文件里的字符读出并缓存至自有缓冲区,还可以一行一行读取

3.    怎么用?

关健方法: readLine

public String readLine()

throws IOException读取一个文本行。通过下列字符之一即可认为某行已终止:换行 (‘\n’)、回车 (‘\r’) 或回车后直接跟着换行。

返回:

包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null

抛出:

IOException – 如果发生 I/O 错误

public static void main(String[] args) throws IOException {

BufferedReader br = new BufferedReader(new FileReader(“总结.txt”));

// 方式一:

//    int i = 0;

//    while ((i = br.read()) != -1) {

//       System.out.print((char) i);

//    }

//    // 方式二:每次读出到一个字符数组

//    char[] ch = new char[1024];

//    while ((i = br.read(ch)) != -1) {

//       System.out.println(new String(ch, 0, i));

//    }

//方式三:每次读一行

String s;

while((s=br.readLine())!=null){

System.out.println(s);

}

br.close();

}

4.    什么时候用?

读取比较多的字符文件时,

5.    有什么特点?

一次可读入一行,效率比一次读一个字符数组高,因为有自带的缓冲区.

其是用FileReader来构造,不是文件名称

为什么readLine()要加newLine?

因为readLine()是以分割符为基点

 

五、LineNumberReader用法

1.    是什么?

是BufferedReader的子类,

2.    有什么用?

可以在读取的时候,加上行号

3.    怎么用?

//与BufferedReader相同用法,也是只能用FileReader来构造,并且继承BufferedReader所有方法,比如:readLine()

public static void main(String[] args) throws IOException {

BufferedWriter bw = new BufferedWriter(new FileWriter(“dandan.txt”));

LineNumberReader lr = new LineNumberReader(new FileReader(“总结.txt”));

String s =null;

while((s=lr.readLine())!=null) {//读取

bw.write(lr.getLineNumber()+”:”+s);//获取行号写入

bw.newLine();//换行

}

bw.close();

lr.close();

}

}

Ø  第二十二天

(一)字符流与字节流框架与转换

字符流读—-Reader(抽象父类)—-FileReader(字符源)—–BufferedReader(字符源)

 |—-转换流(字节转成字符):InputStreamReader(字节源)

字节流读-–InputStream(抽象父类)–FileInputStream(字节源)

读是由bw—写入到System.in

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

读的方式一:一个字节或一个字符的读

int i=0;

while(i=流名.read()!=-1)

i=读出来的数据

读的方式二:一个字节数组或一个字符读

int i=0;byte[] bye = new byte[1024];char[] ch = new char[1024];

while(i=流名.read(数组)!=-1)

数组=读出来的数据

读的方式三:一个字符串一个字符串的读:

String s=null;

while(s=流名.readline()!=null){

s=一行字符

}

字符流写—–Writer(抽象父类)—-FileWriter(字符源)——–BufferedWriter(字符源)

|—-转换流(字节符转成字节):OutputStreamReader(字节源)

字符流写—-OutputStrem(抽象父类)—FileOutputStream(字节源)

写是由bw—写入到System.out

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

写的方式一:一个字节或一个字符的写

流名称.write((char)读出的单个字符或字节)

流名称..flush()

写的方式二:一个字节数组或一个字符写

流名称.write(读出来的数组,0,每次读出的长度)

流名称..flush()

数组=写的方式三:一个字符串一个字符串的写

流名称.write(读出来的字符串)

流名称.newline();换行

流名称..flush()

(二)字节流读写数据(重点)

字节流写数据也不用刷.

Reader Writer — FileReader,FileWriter — BufferedReader,BufferedWriter

InputStream OutputStream

— FileInputStream,FileOutputStream

— BufferedInputStream,BufferedOutputStream

(1)字节流写入数据

FileOutputStream fos = new FileOutputStream(“fos.txt”);

byte[] bys = “abcdefg”.getBytes();

fos.write(bys);

fos.close();

(2)字节流读取数据

//第一种

FileInputStream fis = new FileInputStream(“fos.txt”);

int by = 0;

while((by=fis.read())!=-1)

{

sop((char)by);

}

fis.close();

//第二种

FileInputStream fis = new FileInputStream(“fos.txt”);

byte[] bys = new byte[1024];

int len = 0;

while((len=fis.read(bys))!=-1)

{

sop(new String(bys,0,len));

}

fis.close();

(3)用字节流读写文本文件(重点代码)

FileInputStream fis = new FileInputStream(“fis.txt”);

FileOutputStream fos = new FileOutputStream(“fos.txt”);

byte[] bys = new byte[1024];

int len = 0;

while((len=fis.read(bys))!=-1)

{

fos.write(bys,0,len);

}

fos.close();

fis.close();

(4)用字节流复制图片 和第(3)类似。

(三) 用字节缓冲流读写数据

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(“bis.txt”));

BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(“bos.txt”));

byte[] bys = new byte[1024];

int len = 0;

while((len=bis.read(bys))!=-1)

{

bos.write(bys,0,len);

bos.flush();

}

bos.close();

bis.close();

(6)用字节流复制MP3(重点) 今天必须练习。

(7)从键盘录入数据,通过System.out.println()打印到控制台。

(8)从键盘录入数据,并写入到一个文件中。

InputStream is = System.in;

我们就开始自己想办法,一次读取一行的输入。

写好后,想想好像这种代码我们前面写过。

我们可以直接读取一行。

不能直接用,为什么?

因为我们前面使用的是BufferedReader的方法。它是一个字符流。

而我们现在的键盘录入是一个字节流。

所以,我们考虑字节流和字符流是否能够转换。

(四) 转换流

InputStreamReader: 从字节流 — 转换流 — 字符缓冲流

字节流:InputStream is = System.in;

转换流:InputStreamReader isr = new InputStreamReader(is);

缓冲流:BufferedReader br = new BufferedReader(isr);

其实上面三句代码我们一般会如下写:

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

OutputStreamWriter:从字符流  — 转换流 — 字节流

缓冲流:BufferedWriter bw = new BufferedWriter(osw);

转换流:OutputStreamWriter osw = new OutputStreamWriter(os);

字节流:OutputStream os = System.out;

三句话合并:

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

(10)从控制台录入数据,写入到一个文本文件中

// 为了方便从键盘录入读取,也就是说想一次读取一行。我们使用转换流

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

// 往目标写

BufferedWriter bw = new BufferedWriter(new FileWriter(“demo.txt”));

String line = null;

while ((line = br.readLine()) != null) {

if (“over”.equals(line)) {

break;

}

bw.write(line);

bw.newLine();

bw.flush();

}

bw.close();

br.close();

(11)把一个文本文件的内容输出到控制台

// 指定源

BufferedReader br = new BufferedReader(new FileReader(“demo.txt”));

// 指定目标

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(

System.out));

String line = null;

while ((line = br.readLine()) != null) {

bw.write(line);

bw.newLine();

bw.flush();

}

bw.close();

br.close();

(五) 流的操作规律:

A:明确数据源和目的地

数据源:InputStream,Reader

目的地:OutputStream,Writer

B:明确数据源和目的地是否是文本文件

是:

数据源:Reader

目的地:Writer

不是:

数据源:InputStream

目的地:OutputStream

不知道,用字节流。

C:明确操作设备

数据源:键盘录入(System.in),内存,硬盘文件

目的地:控制台(System.out),内存,硬盘文件

可能为了方便操作,使用到转换流和缓冲流。

InputStreamReader isr = new InputStreamReader(System.in);

OutputStreamWriter osw = new OutputStreamWriter(System.out);

D:明确是否需要高效

是:

就使用带Buffered的类

不是:

不使用带Buffered的类

(13)用流的操作规律分析四种操作并完成作业。

Ø  第二十三天:

一、打印流:

1.    是什么?

打印流就是javaIO中为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。包括打印字符流PrintWrite,(是Writer的子类)和打印字节流:PrintStream(是FileOutputStream的子类)

2.    有什么用?

其除了有父类所有方法外.还可以很方便向设备输出字符或字节,可以自动换行,且不用启用刷新,

3.    怎么用?

字符打印流

格式:

创建一个对象

构造方法有:

PrintWriter(File file) —可以直接用需要写入的文件对象构造对象.

使用指定文件创建不具有自动行刷新的新 PrintWriter。

PrintWriter(OutputStream out) —–直接用流构造

根据现有的 OutputStream 创建不带自动行刷新的新 PrintWriter。

PrintWriter(OutputStream out, boolean autoFlush)

通过现有的 OutputStream 创建新的 PrintWriter。

PrintWriter(String fileName) 直接用文件的字符串构造

创建具有指定文件名称且不带自动行刷新的新 PrintWriter。

PrintWriter(Writer out) 直接用写入流构造

创建不带自动行刷新的新 PrintWriter。

PrintWriter(Writer out, boolean autoFlush)

创建新 PrintWriter。

//特有方式用法,直接写入,换行,不自动刷新

PrintWriter pw = new PrintWriter(new FileWriter(“pw.txt”), true);

pw.println(“haha”);

pw.println(“hehe”);

pw.println(“xixi”);

pw.close();

}

PrintWriter pw = new PrintWriter(“pw.txt”);

//需要手动刷新的三种方式.

pw.println(“hehe”);

pw.println(“xixi”);

pw.flush();

pw.close();

//方式二:

pw.print(100);

pw.print(“haha”);

pw.print(23.5);

pw.flush();

pw.close();

}

//方式三:

pw.write(“haha\r\n”);

pw.write(“hehe\r\n”);

pw.flush();

pw.close();

}

}

字节流一样,只不过字节流什么时候都不需要刷新

4.    什么时候用?

当需要输出到设备时,可以方便使用

5.    有什么特点?

有自有方法,自动换行,自动刷新,可以直接操作字符流,字节流,文件,对象,及文件名,扩展性强.

二、对象流

1.    是什么?

是可以对对象进行读取与写入文件的流

ObjectOutputStream:writeObject(Object obj)

* ObjectInputStrem: Object readObject()

2.    有什么用?

对象的读写流:其实就是把对象按照流的方式进行写入和取出

*

*

*

3.    怎么用?

ObjectOutputStream(OutputStream out)

创建写入指定 OutputStream 的 ObjectOutputStream。

写入与读取方法与字节流无区别

只不过如果一个对象要可bei读取,必须实现序列化接口Serializable

//给要写入的对象实现序列化

public class Person implements Serializable {

// 手动给定序列号值

private static final long serialVersionUID = -3124753242215610223L;

private String name;

//private int age;

int age;

//写入对象

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(“obj.txt”));

Person p = new Person(“卡卡”, 20);

oos.writeObject(p);

oos.close();

}

//读取对象

ObjectInputStream ois = new ObjectInputStream(new FileInputStream(

“obj.txt”));

Object obj = ois.readObject();

ois.close();

//操作读取的对象

Person p = (Person) obj;

System.out.println(p.getName() + “***” + p.getAge());

4.    什么时候用?

当虽要对对象进行长期保存时,可以用

序列化和反序列化。就是一些程序里的保存进度、或记住密码之类的,用的就是这个你序列化的时候就保存成文件,然后在次启动的时候就可以用反序列化给还原。

序列化:将对象转化成流的过程称为序列化

反序列化:将流转化成对象的过程称之为反序列化

5.    有什么特点?

只能接收字节流构造对象

一个对象向通过对象流操作,那么这个对象必须实现序列化接口。Serializable

* 其实你可以这是一个标记,标记着这个类可以被对象流操作。

protected  ObjectOutputStream()

为完全重新实现 ObjectOutputStream 的子类提供一种方法,让它不必分配仅由 ObjectOutputStream 的实现使用的私有数据。

三、properties集合

1.    是什么?

是Map下的实现类Hashtable(不允许有null值和null键)下的一个子类.

1.    有什么用?

有Map集合的特性,并可以与IO流结合操用,并有自已独有的特性,

可以直接将集合的值写入流中的文件list 和store

可以直接将文件里的值读出.用load

2.    怎么用?

//自己特有的方式添加和获取。键和值都是字符串

setProperty与getProperty

Properties prop = new Properties();

prop.setProperty(“it002”, “abc1”);

//获得键的集合

Set<String> set = prop.stringPropertyNames();

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

//迭代出元素.

while (it.hasNext()) {

String key = it.next();

String value = prop.getProperty(key);

System.out.println(key + “***” + value);

}

//Map的公有方式添加和获取:put与get

prop.put(“it002”, “abc1”);

Set set = prop.keySet();

Iterator it = set.iterator();

while (it.hasNext()) {

String key = (String) it.next();

String value = (String) prop.get(key);

System.out.println(key + “***” + value);

}

}

//

// 获取到系统属性

Properties prop = System.getProperties();

// 遍历 让系统属性在控制台显示,太麻烦了。

// Set<String> set = prop.stringPropertyNames();

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

// while (it.hasNext()) {

// String key = it.next();

// String value = prop.getProperty(key);

// System.out.println(key + “=” + value);

// }

//使用Properties的特有方法list。通过list方法,可以直接将Properties值显示在控制台

prop.list(System.out);

// 写入到文件中方法一: 麻烦

PrintWriter fw = new PrintWriter(“prop.txt”);

prop.list(fw);

fw.flush();

fw.close();

//写入到文件中方法二:简单

//prop.list(new PrintStream(“prop.txt”));

将文件信息读入到

Properties prop = new Properties();

FileInputStream fis = new FileInputStream(“load.txt”);

prop.load(fis);

fis.close();

3.    什么时候用?

当虽要将运行数据存于文件中,每次程都可以读出中的数据

4.    有什么特点?

如果要用自已的特有方法只能存字符串健值对.

四、 编码与解码

1.    是什么?

是将字节存入和读取和方式

2.    有什么用?

也就是我们写入数据必须有对应的编码

而到时候我们读数据出来就要用当时存的解码方式

3.    怎么用?

(1)在IO流中,指定编码的需要使用转换流。

下面的三句话效果一致:

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(“a.txt”),”GBK”);

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(“a.txt”));

FileWriter fw =  new FileWriter(“a.txt”);

字符流 = 字节流+编码表

用哪种编码写数据,就用哪种编码读取数据。

(2)字符串的编码问题

编码:字符串 — 字节数组

解码:字节数组 — 字符串

GBK和UTF-8编码解码出问题的情况。

4.    什么时候用?

当需要指定编码的需要使用转换流。

5.    有什么特点?

如果写入编码与定出编码不一样,就会乱码

Ø  第二十四天

一、GUI可视化编程

1.    是什么?

就是让界面可视,点击触发事件

2.    有什么用?

让java程序用一个窗口界面直观的表示所操作的动作和结果

3.    怎么用?

格式:步骤

建立窗口—建立各种组件(菜单,文本框,文本域)—–添加各种组件—-给各种组件添加监听器—–给组件添加事件处理

private Frame f;

private TextField tf;

private Button bt, bt1;

private TextArea ta;

private MenuBar mb;

private Menu m, m1;

private MenuItem mi,mi1,mi2,mi3,mi4;

public MyFormat() {

init();

}

private void init() {

// 建立一个窗口

f = new Frame();

//设置窗口名称

f.setTitle(“不会回来”);

// 设大小位置

f.setBounds(400, 300, 400, 300);

// 设制布局–流式布局

f.setLayout(new FlowLayout());

//建立一个文本框

tf = new TextField(20);

//建立一个按键

bt = new Button(“输入”);

//再建立一个按键

bt1 = new Button(“打印”);

//建立一个文本域

ta = new TextArea(10, 40);

//建立一个菜单栏

mb = new MenuBar();

//建立一个菜单

m = new Menu(“文件”);

//再建立一个菜单

m1 = new Menu(“更改标题”);

//建立菜单项

mi = new MenuItem(“退出系统”);

mi1 = new MenuItem(“记事本”);

mi2 = new MenuItem(“好好学习”);

mi3 = new MenuItem(“天天向上”);

mi4 = new MenuItem(“恢复标题”);

//将菜单栏添加到窗口上

f.setMenuBar(mb);

//将菜单添加至菜单栏

mb.add(m);

//再将菜单项添加至菜单m

m.add(m1);

m.add(mi);

m.add(mi1);

//再给m1添加菜单项

m1.add(mi2);

m1.add(mi3);

m1.add(mi4);

//给窗口添加文本框

f.add(tf);

//给窗口添加按钮

f.add(bt);

f.add(bt1);

//给窗口添加文本域

f.add(ta);

//建立监听方法

myEvent();

//让窗口可见

f.setVisible(true);

}

private void myEvent(){

//给窗口添加关闭事件

f.addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) {

System.exit(0);

}

});

//给菜单项mi添加事件

mi.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

System.exit(0);

}

});

//给菜单项添加事件

mi1.addActionListener(new ActionListener() {

//给mi2建立事件

public void actionPerformed(ActionEvent e) {

Runtime r =Runtime.getRuntime();

try {

r.exec(“notepad”);

f.setVisible(false);

System.exit(0);

} catch (IOException e1) {

e1.printStackTrace();

}

}

});

//给文本框添加事件

bt.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

//让文本框写入到文件中

PrintWriter pw =null;

try {

pw = new PrintWriter(new FileWriter(“Frame.txt”,true),true);

pw.println(tf.getText());

} catch (IOException e1) {

e1.printStackTrace();

}finally{

if (pw!=null) {

pw.close();

//写完之后清空文本框

tf.setText(“”);

}

}

}

});

//设立文本域事件

bt1.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent e) {

//让文本域据接收数据

//写前之清空文本框

ta.setText(“”);

BufferedReader br=null;

try {

br= new BufferedReader(new FileReader(“Frame.txt”));

try {

String s=null;

System.out.println(s);

while ((s=br.readLine())!=null) {

ta.append(s+”\t\n”);

}

} catch (IOException e1) {

e1.printStackTrace();

}

} catch (FileNotFoundException e1) {

e1.printStackTrace();

}finally{

if (br!=null) {

try {

br.close();

} catch (IOException e1) {

e1.printStackTrace();

}

}

}

}

});

}

}

4.    什么时候用?

5.    有什么特点?

二、枚举

1.    什么是枚举?

枚举就是一个特殊的类,

2.    有什么用?

3.    怎么用?

4.    什么时候用?

5.    有什么特点?

Ø  第二十五天 网络编程

1.    什么是网络编程?

就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换。

2.    有什么作用?

可以计算机之间相互通信,并进行数据传输

3.    怎么用?

InetAddress类的使用:

没有构造方法,但可以通过getLocalHost etByName 获取对象

要掌握的功能

获取本地主机:getLocalHost

InetAddress address =InetAddress.getLocalHost();

获取任意指定主机:getByName

InetAddress address = InetAddress.getByName(“fada-PC”);

主机Ip地址:getHostAddress

String ip = address.getHostAddress();

主机名:getHostName

String name = address.getHostName();

UDP传输:

格式步骤:

DatagramSocket与DatagramPacket

建立发送端,接收端。

建立数据包。

调用Socket的发送接收方法。

关闭Socket。

发送端与接收端是两个独立的运行程序。

做一个发送端:

//建立发送端

DatagramSocket ds = new DatagramSocket();

//建立字节输入流并用转换流转换成一个字符缓冲

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

//把字符流中的数据读出

String s =null;

while((s=br.readLine())!=null){

if(“886”.equals(s)){

byte[] bye = s.getBytes();

//把字符流读出的数据存在数据包中 建立数据包

break;

}

byte[] bye = s.getBytes();

//把字符流读出的数据存在数据包中建立数据包

DatagramPacket dp = new DatagramPacket(bye,bye.length,InetAddress.getByName(“fada-pc”),11118);

//把数据包发送出去

ds.send(dp);

}

//关闭资源

ds.close();

br.close();

接收端:

//给定建立接收端

DatagramSocket ds = new DatagramSocket(11118);

//建立一个给定容量的数据包

while(true){

byte[] bye =new byte[1024];

DatagramPacket dp = new DatagramPacket(bye,bye.length);

//将数据包加载到缓存中

ds.receive(dp);

//解析数据包中的IP

String ip = dp.getAddress().getHostAddress();

//解析数据包中的数组接收的内容

String text = new String(bye,0,dp.getLength());

System.out.println(ip+”***”+text);

}

TCP传输

①使用Socket和ServerSocket,

②建立客户端和服务器端,

③建立连接后,通过Socket中的IO流进行数据的传输

④关闭socket

客户端与服务器端也是两个独立的应用程序。

a.TCP协议的客户端

思路:

1:建立客户端的Socket服务,并明确要连接的服务器。

2:如果连接建立成功,就表明,已经建立了数据传输的通道.就可以在该通道通过IO进行数据的读取和写入.

该通道称为Socket流,Socket流中既有读取流,也有写入流.

3:通过Socket对象的方法,可以获取这两个流

4:通过流的对象可以对数据进行传输

5:如果传输数据完毕,关闭资源

代码:

Socket s = new Socket(“192.168.1.34”, 10010);

OutputStream os = s.getOutputStream();

os.write(“Hello,Tcp,I am coming”.getBytes());

s.close();

b.TCP协议的服务器端

思路:

1:建立服务器端的socket服务,需要一个端口

2:服务端没有直接流的操作,而是通过accept方法获取客户端对象,在通过获取到的客户端对象的流和客户端进行通信

3:通过客户端的获取流对象的方法,读取数据或者写入数据

4:如果服务完成,需要关闭客户端,然后关闭服务器,但是,一般会关闭客户端,不会关闭服务器,因为服务端是一直提供服务的

代码:

ServerSocket ss = new ServerSocket(10010);

Socket s = ss.accept();

String ip = s.getInetAddress().getHostAddress();

System.out.println(“客户端的ip:”+ip + “*连接上”);

InputStream is = s.getInputStream();

byte[] bys = new byte[1024];

int len = is.read(bys);

String text = new String(bys, 0, len);

System.out.println(text);

ss.close();

c.TCP协议的程序服务器给客户端一个反馈

客户端和服务器端在原有的基础上添加反馈,接收端的部分写到客户端下边,客户端的部分写到接收端下边

d.一个大写的转换服务器

客户端代码:

Socket s = new Socket(“192.168.1.34”, 10086);

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

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

BufferedReader brServer = new BufferedReader(new InputStreamReader(s.getInputStream()));

String line = null;

while ((line = br.readLine()) != null) {

if (“over”.equals(line)) {

break;

}

bw.write(line+”\r\n”);

bw.flush();

String serverText = brServer.readLine();

System.out.println(“server:” + serverText);

}

br.close();

s.close();

注意:

1.字符流是有缓冲区的,每次数据写入后,需要刷新缓冲区。

2.这样操作后发现还是不行,那么还有什么原因呢?

3.考虑readLine的特点。一次读取一行。但是不要忽略它的结束条件是:\r\n

服务器代码:

ServerSocket ss = new ServerSocket(10086);

Socket s = ss.accept();

BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

String line = null;

while ((line = br.readLine()) != null) {

System.out.println(line);

bw.write(line.toUpperCase()+”\r\n”);

bw.flush();

}

ss.close();

e.用PrintWriter改写转换服务器

注意println和true的使用

4.    什么时候用?

计算机间需要进行数据传输时

5.    有什么特点?

网络通信三要素

IP地址:InetAddress :网络中设备的标识,不易记忆,可用主机名

端口号 :用于标识进程的逻辑地址,不同进程的标识

物理端口 网卡口

逻辑端口 我们指的就是逻辑端口

A:每个网络程序都会至少有一个逻辑端口

B:用于标识进程的逻辑地址,不同进程的标识

C:有效端口:0~65535,其中0~1024系统使用或保留端口。自已定义一般在1万以上

通过360可以查看端口号

传输协议:通讯的规则 —常见协议:TCP,UDP

UDP

将数据源和目的封装成数据包中,不需要建立连接;每个数据报的大小在限制在64k;因无连接,是不可靠协议;不需要建立连接,速度快

TCP

建立连接,形成传输数据的通道;在连接中进行大数据量传输;通过三次握手完成连接,是可靠协议;必须建立连接,效率会稍低

Socket

用于描述IP地址和端口,是一个通信链的句柄。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。

Socket就是为网络编程提供的一种机制;通信的两端都有Socket;网络通信其实就是Socket间的通信;数据在两个Socket间通过IO传输。

Ø  第二十六天: 正则

一、正则表达式:

1.    是什么?

是符合一定规则的字符串表达式。有特殊应用场景。

2.    有什么用?

常用功能就是可以对字符串进行匹配,给其设定某种规则,符合一种规范,比如qq号,邮箱,电话号码,另外还可以根据其规则结合字符串操作的方法对字符串进行切割,替换,和获取.以实现特定的要求.

3.    怎么用?

正则表达式的规则

A:特殊字符

\\:反斜线

\r:回车

\n:换行

B:字符类

[abc]:a,b或者c的任意一个。

[^abc]:除了a,b,c以外的字符。

[a-zA-Z]:包括了26个英文字母。

[0-9]:包括了0-9这个10个数字字符。

C:预定义字符类

.      任意字符

\d    数字[0-9]

\D    非数字[^0-9]

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

\W   非单词字符:[^\w]

D:边界匹配器

^     行的开头

$     行的结尾

\b    单词边界

E:Greedy 数量词

x?    0次或1次

x*    0次或多次

x+   1次或多次

x{n} 恰好n次

x{n,} 至少n次

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

按照这些规则,能够读懂别人的正则表达式即可。

简单的常见最好会写。

(3)正则的功能

A:匹配功能

String类下的matches

B:切割功能

String类下的split

C:替换功能

String类下的replaceAll

D:获取功能

Pattern类和Matcher类。

基本模式:

String regex = “规则”;

Pattern p = Pattern.compile(regex);

Matcher m = p.matcher(要获取的字符串);

m.find():判断是否有满足条件的数据

m.group():取出满足条件的数据

4.    什么时候用?

当需要对一些字符串按按照给定的规则匹配,获取,切割,和替换时.

5.    有什么特点?

只能对字符串操作

常与字符串的方法相结合

二、URL类和URLConnection类 了解

(1)URL类的使用

可以对地址栏信息进行封装,单独获取每个部分信息。

(2)URLConnection类的使用

可以从网页中获取数据

三、JAVA反射机制:

何为反射?

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

反射有什么作用?

反射可以在我们运行时,加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields(成员属性)设值、或唤起其methods成员方法。

反射可以程序运行时,改变程序结构或变量类型,比如为一个Integer集合添加String元素

也可以改变或获取成员属性(字段),获取构造方法,获取并调用成员方法,

反射怎么用?

1.       获取字节码对象的三种方法:

获取字节码对象的方式一:

* 1,Object类中的getClass()方法的。

* 想要用这种方式,必须要明确具体的类,并创建对象。

* 缺点:不够简单

public static void getClassObject_1(){

Person p = new Person();

Class clazz = p.getClass();

方式二:

* 2,任何数据类型都具备一个静态的属性.class来获取其对应的Class对象。

* 相对简单,但是还是要明确用到类中的静态成员。

* 缺点:不够扩展。

public static void getClassObject_2() {

Class clazz = Person.class;

方式三:最常用

        * 只要通过给定的类的 字符串名称就可以获取该类,更为扩展。

        * 可是用Class类中的方法完成。

        * 该方法就是forName.

        * 这种方式只要有名称即可,可以将名称写在配置文件中,同时给定一个引用名,用forName与引用名关联,到时候对象名有更改,那么只需要修改引用所对应的类名字符串就可以.  更为方便,扩展性更强。

String className = “cn.itcast.bean.Person”;(这里要注意:是包名.类名的字符串表现形式,这与导不导包没有关系)

              Class clazz = Class.forName(className);

2.       获取构造方法得到对象

关健字:Construtor

获取对象方法.newInstance

1.当只需要获得无参构造成的对象时

String name = “cn.itcast.bean.Person”;

//找寻该名称类文件,并加载进内存,并产生Class对象。

Class clazz = Class.forName(name);

//如何产生该类的对象呢?

Object obj  = clazz.newInstance();

2.当想获取有参构造的对象.

String name = “cn.itcast.bean.Person”;

//找寻该名称类文件,并加载进内存,并产生Class对象。

Class clazz = Class.forName(name);

//获取到了指定的构造函数对象。

Constructor constructor = clazz.getConstructor(String.class,int.class);(这里传构造方法参数类型的字节码对象)

这里可以用可变参数,也就是用一个数组也可实现:

或:Constructor constructor = clazz.getConstructor(new Class[]{String.class,int.class});

//通过该构造器对象的newInstance方法进行对象的初始化。

Object obj = constructor.newInstance(“小明”,38);(直接传构造方法参数)

或:Object obj = constructor.newInstance(Object[]{“小明”,38});(直接传构造方法参数)

Constructor[] constructor = clazz.getConstructors();

这是获取包含所有按由上至下的构造方法的,一个数组

3.       获取和改变成员属性(字段)

这有两种,

一是公共(public )字段:Field field = null;//clazz.getField(“age”);//只能获取公有的,

二是非公共字段:

Class clazz = Class.forName(“cn.itcast.bean.Person”);

field = clazz.getDeclaredField(“age”);//只获取本类,但包含私有。

//对私有字段的访问取消权限检查。暴力访问。

field.setAccessible(true);

Object obj = clazz.newInstance();

field.set(obj, 89);(里面的参数是,对象+想要设制的值)

Object o = field.get(obj);获得改字段的

4.       获取和运行成员方法

Class clazz = Class.forName(“cn.itcast.bean.Person”);

Method method = clazz.getMethod(“paramMethod”, String.class,int.class);

参数(方法名字符串表现形式,方法参数1的字节码对象1,方法参数2的字节码对象)

Object obj = clazz.newInstance();

method.invoke(obj, “小强”,89);(本类对象,方法参数1,方法参数二)

Method[] methods  = clazz.getMethods();//获取的都是公有的方法的数组。

返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。

Method[] methods = clazz.getDeclaredMethods();//只获取本类中所有方法,包含私有的数组。

返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。

运行方法:

反射什么时候用?

经典的就是xml或者properties里面写上了配置,然后在Java类里面解析xml或properties里面的内容,得到一个字符串,然后用反射,根据这个字符串获得某个类的实例,这样就可以动态配置一些东西,不用每一次都要在代码里面去new或者做其他的事情,以后要改的话直接改配置文件,代码维护起来就很方便了,同时有时候要适应某些需求,Java类里面不一定能直接调用另外的方法,这时候也可以通过反射机制来实现。

总的来说,自己写的很少,具体什么时候要用那要看需求,楼上说得对,无非就是根据一个String来得到你要的实体对象,然后调用它原来的东西。但是如果是要自己写框架的话,那就会用得比较多了。

反射有什么特点?

Ø  第二十七天–html

一、html

1.    是什么?

超文本标记语言,即HTML(Hypertext Markup Language),是用于描述网页文档的一种标记语言,

2.    有什么用?

HTML是一种规范,一种标准,它通过标记符号来标记要显示的网页中的各个部分。网页文件本身是一种文本文件,通过在文本文件中添加标记符,进行数据的封装,定义标签.进行属性的定义,可以告诉浏览器如何显示其中的内容(如:文字如何处理,画面如何安排,图片如何显示等)。

3.    怎么用?

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN” “http://www.w3.org/TR/html4/strict.dtd”>

<!–这个只是告诉浏览器应该执行W3C的那一种标准检查。 –>

<html>

<head>

<meta http-equiv=”Content-Type” content=”text/html; charset=GBK”>

<!–meta:这将告诉浏览器准备接受一个 HTML 文档。使用带有 http-equiv 属性的 <meta> 标签时,

服务器将把名称/值对添加到发送给浏览器的内容头部。content:内容   charset编码类型 –>

<title>这是网页的标题</title>

<!–注释是这样写的,head里一般写入css的调用与属性–>

</head>

<body>

<!–任何信息没有用标识都是不能处理的,也是没有任何格式的–>

<!–html语言最关健的就是给数据定义标签,然后给出相应的操作

常用的标签:

1.颜色字体标签<font >

–>

<font color=”red” size=”4″>字体颜色标签</font>

<fieldset>

<legend>legend标签为 fieldset 元素定义标题。</legend>

<font color=”bule”>fieldse标签将表单内容的一部分打包,生成一组相关表单的字段。

当一组表单元素放到 fieldset标签内时,浏览器会以特殊方式来显示它们,它们可能有特殊的边界、3D 效果,或者甚至可创建一个子表单来处理这些元素。

fieldset标签没有必需的或唯一的属性。</font>

<form action=”http://192.168.1.253:9090″ method=”get”>

<!–action表示将form表单里的数据存入, 以上网站服务器,并用是get方式–>

<table border=”2″ bordercolor=”blue” cellpadding=”10″ cellspacing=”0″ width=”600px”>

<!–table 边界宽度=”2″ 边界颜色=”blue” 单元格边距=”10″ 单元格间距=”0″ 宽=”600px”–>

<caption>定义表格名称</caption>

<tr>

<th  colspan=”2″> colspan表示占有多少列 th表头标签</th>

</tr>

<tr><th  colspan=”2″> <a href=”http://www.baidu.com” >百度超链接</a></th></tr>

<tr>

<td>tr:行标签:定义一行的内容. </td>

<td>td:单元格标签:加载行标签的里面。可以简单理解为,先有行,在行中在加入单元格。</td>

</tr>

<tr>

<td>用户名称:</td>

<td>

<input type=”text” name=”user” />

</td>

</tr>

<tr>

<td>输入密码:</td>

<td>

<input type=”password” name=”psw” />

</td>

</tr>

<tr>

<td>确认密码:</td>

<td>

<input type=”password” name=”repsw” />

</td>

</tr>

<tr>

<td>单选:</td>

<td>

<input type=”radio” name=’sex’ value=”nan”/>男

<input type=”radio” name=’sex’ value=”nv”/>女

</td>

</tr>

<tr>

<td>多选框:</td>

<td>

<input type=”checkbox” name=”tech” value=”java”/>JAVA

<input type=”checkbox” name=”tech” value=”html”/>HTML

<input type=”checkbox” name=”tech” value=”css”/>CSS

</td>

</tr>

<tr>

<td>下拉菜单:</td>

<td>

<select name=”country”>

<option value=”none”>–选择国家–</option>

<option value=”cn” selected=”selected”>中国</option>

<option value=”usa”>美国</option>

<option value=”en”>英国</option>

</select>

</td>

</tr>

<tr>

<td>

文本域:

</td>

<td>

<textarea name=”说明” cols=”30″ rows=3″”></textarea>

</td>

</tr>

<tr>

<th colspan=”2″>

<input type=”submit” value=”提交数据” />

<input type=”reset” value=”清除数据” />

</th>

</tr>

</table>

</form>

</fieldset>

</body>

</html>

4.    什么时候用?

做网页的时候用

5.    有什么特点?

浏览器按顺序阅读网页文件,然后根据标记符解释和显示其标记的内容,对书写出错的标记将不指出其错误,且不停止其解释执行过程,编制者只能通过显示效果来分析出错原因和出错部位。

对于不同的浏览器,对同一标记符可能会有不完全相同的解释

超文本标记语言(15张),因而可能会有不同的显示效果。

HTML文档制作不是很复杂,且功能强大,支持不同数据格式的文件镶入,这也是WWW盛行的原因之一,其主要特点如下:

1 简易性,HTML版本升级采用超集方式,从而更加灵活方便。

2 可扩展性,HTML语言的广泛应用带来了加强功能,增加标识符等要求,HTML采取子类元素的方式,为系统扩展带来保证。

3 平台无关性。虽然PC机大行其道,但使用MAC等其他机器的大有人在,HTML可以使用在广泛的平台上,这也是WWW盛行的另一个原因。

禅意花园

二、html网页数据提交

1.    域名解析原理

访问网站链接的网址所进行的过程

访问网站就是通过访问一台服务器的IP来访问服务器里的数据,网站名称只是为了方便记忆,最终要访问主机要先通过本地Hosts解析出这个网址对应的IP..如果hosts里没有找到,则通过DNS域名解析服务去解析网址,然后返回IP,然后通过IP去访问主机.服务器.

如果本地(C:\Windows\System32\drivers\etc)  host配制了网址,那么就算是错的,也不会去DNS域名解析服务器上解析网址,这个技巧可以用来防垃圾网站 在hosts上给配一个错误IP就可以

2.    html网页数据提交的两种方式get 与post

<!–

http协议的请求消息头。

get提交方式。

地址栏:http://192.168.1.253:9090/?user=abc&psw=12&repsw=12&sex=nan&tech=java&country=cn

GET /?user=abc&psw=12&repsw=12&sex=nan&tech=java&tech=css&country=cn HTTP/1.1 // 请求行 :请求方式 请求的资源路径  协议的版本

请求消息中的键值对。

Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/xaml+xml, application/x-ms-xbap, application/x-ms-application, */*

Accept-Language: zh-cn,zu;q=0.5

Accept-Encoding: gzip, deflate

User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.2; .NET4.0C)

Host: 192.168.1.253:9090

Connection: Keep-Alive

空行 用于区分消息头和消息体。

请求体

post提交方式:

地址栏:http://192.168.1.253:9090/

POST / HTTP/1.1

Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/xaml+xml, application/x-ms-xbap, application/x-ms-application, */*

Accept-Language: zh-cn,zu;q=0.5

Content-Type: application/x-www-form-urlencoded

Accept-Encoding: gzip, deflate

User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.2; .NET4.0C)

Host: 192.168.1.253:9090

Content-Length: 54

Connection: Keep-Alive

Cache-Control: no-cache

//空行

user=abcd&psw=11&repsw=11&sex=nv&tech=html&country=usa

3.    GET和POST的区别?

1,

GET提交将数据显示到地址栏。

POST提交不会将数据显示在地址栏。

2,

GET提交对于敏感信息不安全。

POST提交对于敏感信息安全。

3,

GET提交提交的数据对于大体积数据是不适合的。因为地址栏存储的数据是有限的。

POST提交适合大体积数据的提交。

4,

GET提交将提交的信息封装到了请求行。

POST提交将提交的信息封装到了请求体。

对于服务器端接收端到客户端的提交的中文的数据时,GET提交解码较为麻烦。POST提交较为简单。因为对请求体解码直接通过服务器(tomcat)直接通过一个方法就可以完成。

综上所述:在进行表单提交时,建议使用post提交。

和服务器端交互的方式:

1,地址栏输入地址。get

2,超链接。get

3,表单提交。get post

如果在客户端进行了增强型的校验(必须所有组件内容都填写正确,才可以提交,否则,提交按钮无法提交数据)

问题:服务端收到数据后,还用对数据进行校验吗?

需要,因为安全性。服务端要再一次对数据进行校验。

如果服务端进行了增强型校验,客户端还需要校验吗?

需要,为了增强用户体验,也为了减轻服务器端压力。

Ø  二十八天–ccs

1.    是什么?

CSS是层叠样式表(Cascading Style Sheets)用来定义网页的现实效果。

2.    有什么用?

对html封装的网页数据进行版式和样式的定义.

可以解决html代码对样式定义的重复,提高了后期样式代码的可维护性,并增强了网页的现实效果功能。简单一句话:CSS将网页内容和显示样式进行分离,提高了显示功能。

3.    怎么用?

步骤:

先封装代码

三种方式: p: 封装后成行里的一部分信息  div :封装后成一行就是会自动换行  span:封装后成了一段(前后都空一行) 

三种标识

1:html 直接用div p span 标记操作

标记:

<div >演示div区域二</div>

引用:

div{

color:red;

}

  • class

标记:

<div class=”hehe” >演示div区域二</div>

<span class=”haha”>演示span<b>区域</b>一</span>

引用:

div.haha{

color:red;

}

span.haha{

color:red;

}

/*对名称为haha的类的标签进行样式操作:前面加点.

. haha{

color:red;

}

第三种:id 这个要确保唯一性,可以被Jsp识别

标记:

<div id=”xixi” >演示div区域二</div>

引用:

#xixi{

color:blue;

}

合并操作:

div b,.hehe,#xixi{

color:red;

}

csshtml结合通过四种方式 格式如下:

1.   style属性方式:

利用标签中style属性来改变每个标签的显示样式。

例:

<p style=”background-color:#FF0000; color:#FFFFFF”>

p标签段落内容。

</p>

该方式比较灵活,但是对于多个相同标签的同一样式定义比较麻烦,适合局部修改。

2.   style标签方式:(内嵌方式)

在head标签中加入style标签,对多个标签进行统一修改。

<head>

<style type=”text/css”>

p { color:#FF0000;}

</style>

</head>

该方式可以对单个页面的样式进行统一设置,但对于局部不够灵活。

3.   导入方式:

前提是已经存在一个定义好的CSS文件。网页的一部分样式需要用到,那么就用到这种方式。

例:
<style type=”text/css”>

@import url(css_3.css);

注:css里还可以定义:@import url包 在css文件里直接写义

    @import url(div.css);

@import url(span.css);

@import url(p.css);

div { color:#FF0000;}

</style>

注:url括号后面必须要用分号结束。如果导入进来的样式与本页面定义的样式重复,以本页定义样式为准。

4.   链接方式:

通过head标签中link标签来实现,前提也是先要有一个已定好的CSS文件。

例:

<link rel=”stylesheet” type=”text/css” href=”css_3.css” media=”screen” />

注:可以通过多个link标签链接进来多个CSS文件。重复样式以最后链接进来的CSS样式为准。

  1. 伪元素选择器

其实就在html中预先定义好的一些选择器。称为伪元素。是因为CSS的术语。

格式:标签名:伪元素。类名   标签名。类名:伪元素。都可以。

a:link  超链接未点击状态。

a:visited 被访问后的状态。

a:hover 光标移到超链接上的状态(未点击)。

a:active 点击超链接时的状态。

使用顺序 L – V – H – A

p:first-line 段落的第一行文本。

p:first-letter 段落中的第一个字母。

:focus 具有焦点的元素。IE6浏览器不支持,在FireFox中可以看到效果。

4.    什么时候用?

制作网页时需要给出复杂的特效时.

5.    有什么特点?

样式优先级:

由上到下,由外到内。优先级由低到高。

总结CSS代码格式

选择器名称 { 属性名:属性值;属性名:属性值;…….}

属性与属性之间用 分号 隔开

属性与属性值直接按用 冒号 连接

如果一个属性有多个值的话,那么多个值用 空格 隔开。

Ø  第二十九天–javaScript

1.    是什么?

JavaScript是基于对象和事件驱动(事件驱使其动态)的脚本语言.

2.    有什么作用?

负责提供具备逻辑性的编程语言内容,控制页面的行为。

3.    怎么用?

在html运用:

格式1:前面加<script type=”text/javascript” >

javaScript内容

</script>

格式二:直接导入一个js文件,如:<script type=”text/javascript” src=”jsfiles/hello.js”></script>

javaScript的基本语法

基本要素:

关键字:有特殊意义的单词

标识符:用于标识数据的符号,比如和序的自定义名称 变量名

变量:用于储存常量的内存空间,当储存的数据不确定时,用变量

运算符:用于数据运算的符号

语句:用于控制程序的运行流程(判断与选择语句没有区别)

数组:是一个储存数据的容器,并可以对里面的数据进行操作

函数:一段独立的代码,用于表示一个功能.提高代码复用性

变量:是弱类型,所以其没有数据类型的区分,所有的都用一种var

如:var  x= “123” var x=1 var  x=true等…

显示数据的两种方式:

alert(“x”+x)—–弹出一个窗口

document.write(“x”=x);—–直接在网页区域显示

如何显示隐式数据类型:

//typeof。获取数据的隐式类型。

document.write(“abc:”+typeof(“abc”)+”<br/>”);//string

document.write(“123:”+typeof(123)+”<br/>”);//number

语句:

* 1,判断结构。if

* 2,选择结构。switch

* 3,循环结构。while, do while ,for

==============================================

//判断结构。

var x = 3;

if(4==x){//在判断时,建议将常量放左边

document.write(“yes”);

}else{

document.write(“no”);

}

//                   ==============================================

//选择结构。

var str = “abcd”;

switch(str){

case “cc”:

document.write(“a”);

break;

case “abc”:

document.write(“b”);

break;

default:

document.write(“c”);

}

==============================================

//循环结构。

//                   while ,do while(无论条件是否满足,循环体至少执行一次), for

/*

var x = 1;

while(x<3)

{

alert(“x=”+x);

x++;

}

——————————

for(var x=0; x<3; x++){

document.write(“x=”+x+”<br/>”);

}

//                   var x = 9;

document.write(“x===”+x);么时候用?

/*

数组:

*

* 定义格式:var arr = [];//创建一个元素个数为0的数组。

* 特点:

* 1,数组长度可变。

* 2,数组元素的类型可以任意。

  • 不一定每个元素都要赋值,

如可以:var arr=[2,3]   再定义一个arr[2]=”abc” 那么结果是:2,3,nofield,”abc”,

*

* 格式二:var arr = new Array(4,6);

*/

函数:

/*

* js中的函数

*

* 定义函数无外乎围绕两点:

* 1,明确该功能的参与运算的未知内容。明确参数列表。

* 2,明确该功能的结果。明确返回值。

*

* 格式:通过关键字function 来定义。

*

* function 函数名(参数列表)

* {

*     函数体;

*     return 返回值;

* }

*

*

*/

注意几点:

1.只与函数名有关系,参数不作区分

2.参数不需要有类型,直接跟一个数组形式存在

3.不管参数有没有,都可以传参数,以数组形式存在的,这个数组名字叫做:arguments.

只是说为了阅读和使用方便,定义了几个参数,就传入几个实参。

function show(a,b){

for (var x = 0; x < arguments.length; x++) {

document.write(arguments[x]+”<br/>”);}

4.函数的参数或者函数内定义的变量,只在函数内有效,称为局部变量。

5.函数名后面写括号,是在调用这个函数。不写括号,是在使用这个函数引用。

6.函数的其他定义方式。

1,动态函数。该函数特点,参数列表,和函数体都是动态指定。

var add = new Function(“x,y”,”var sum; sum=x+y; return sum;”);// 根据Function类,通过new产生一个函数对象

2,匿名函数。有什么特点?匿名函数。 就是一种简写格式。

var method = function(){

alert(“func run”);

}

javaScript常用方法:
  • 数组://加入分隔符join(),默认,;排序sort();
  • String:如下事例:

var str = ‘abcde’;

alert(str.bold());

writePageln(str.bold());

writePageln(str.fontcolor(“red”));

writePageln(str.link(“http://www.sina.com.cn”));

writePageln(str.substr(1,4));//bcde

writePageln(str.substring(1,4));//bcd

  • Date:

ar year = date.getFullYear();

var month = getValue(date.getMonth()+1);

var day = getValue(date.getDate());

var week = getWeek(date.getDay());

//获取两个时间点之间相隔多少天.

var  str_date = ’01/12/1988′;

var  str1_date = ‘9/30/2012’;

//先获取多少毫秒

var value = Date.parse(str1_date)-Date.parse(str_date);//将日期字符串转成日期对象。

var day=value/3600/24/1000;

document.write(value+”<br/>”);

var  str_date = ‘7/26/2006’;

var value = Date.parse(str_date);//将日期字符串转成日期对象。

writePageln(“value=”+new Date(value).toLocaleString());

  • Math:

var num1 = Math.ceil(13.56);

var num2 = Math.floor(13.56);

writePageln(“num1=”+num1);

writePageln(“num2=”+num2);

for(varx=0;x<10;x++){        writePageln(Math.ceil(Math.random()*10));

writePageln(parseInt(Math.random()*6+1));

}

javaScript对象的创建:

是什么?

本质上就是封装,因为js是基于对象的,所以相当于把一个一个的小对象,封装在一个方法中.然后把这个方法当作一个对象,然后,再往里面添加方法,或属性对象.

怎么用?

格式:

先建立一个方法 描述一个事物

//描述人。Person

function Person(){//相当于构造器。

alert(“person run”);

}

再创建对象.

//创建Person对象。

var p = new Person();

给对象添加属性

p.name = “lisi”;//p这个对象就具备了一个属性名为name,值为lisi。

p.age = 32;

给对象添加方法

p.show = function(){

alert(this.name+”…..”+this.age);

}

//调用方法

p.show();

也可以实现get set的封装:

如下:

function Person(name,age){

this.name=name;

this.age=age;

this.show = function(){

alert(this.name+”……..”+this.age);

}

this.setName = function(name){

this.name = name;

}

this.getName = function(){

return this.name;

}

}

Ø  第三十天:–DOM与BOM

1.    是什么?

DOM: Document Object Model 文档对象模型

文档:标记型文档,html,xml等。

对象:就是一个封装体,这里指的就是将文档封装成了对象。

模型:就是一个共性的内容具体表现。

2.    有什么用?

DOM技术的作用:就是将标记型文档以及文档中的所有内容封装成了对象。

并在对象中定义了更多的属性和行为,便于操作这些对象.

可以对节点进行各种操作 增删改查。 弊端:如果标记型文档较大,效率低。

DOM技术是一种底层技术,只要应用软件中内置了可以DOM技术的解析引擎,

就是可以通过DOM的方式对标记型文档进行解析。

浏览器中就内置了DOM解析引擎。

3.    怎么用?

DOM技术如何对标记型文档解析的呢?

将一个标记型文档解析成一个dom树,将文档中的内容解析成树中的节点。

document

|–html

|–head

|–meta

|–title

|–body

|–div

|–文本

|–table

|–tbody

|–tr

|–td

|–a

|–form

|–input

|–select

4.    什么时候用?

负责将文档以及文档中的所有内容封装成对象,并提供了属性和行为,便于对对象的操作。

5.    有什么特点?

DOM解析:好处:可以对节点进行各种操作 增删改查。 弊端:如果标记型文档较大,效率低。

SAX解析:基于事件驱动。好处:速度快。弊端:只能获取数据,不能对节点进行修改等其他操作。

DOM发展等级:

level_1: 将html文档封装成了对象。

level_2: 在1的基础上进行升级,加入了名称空间支持等。

level_3: 将xml文档封装成了对象。

DHTML:动态的HTML。多项技术的综合体简称。

包含着:html css  javascript dom。

HTML:       负责提供标签,对数据进行封装(标示)

CSS:      负责提供丰富的样式,对数据进行显示效果的定义。

DOM:    负责将文档以及文档中的所有内容封装成对象,并提供了属性和行为,便于对对象的操作。

JS:         负责提供具备逻辑性的编程语言内容,控制页面的行为。

BOM

是什么?

BOM:Browser Object Model 浏览器对象模型。

将浏览器窗口封装了对象。 以及浏览器中包含的内容也封装成了对象。

比如:地址栏,状态栏,历史记录,浏览器的特有信息。

window

|–history

|–location

|–document

|–navigator

Ø  第三十一天: DHTML编程事例

一、DHTML应用

1.    DHML是什么?

DHTML是指动态的HTML。是多项技术的综合体简称。包含着:html  css  javascript dom。

2.    有什么用?

可以让HTML实现动态效果,从而实现与用户更好的交互.

3.    怎么用?

DHTML编程思想:

  • 首先使用HTML标签对数据进行封装,定义数据的位置.
  • 接下来,用CSS定义数据的初始化样式.
  • 最后实现动态效果:
  • 明确事件源:也就是操作哪个标签以获得效果
  • 明确事件动作,:也就是通过什么动作让这个事件发生.
  • 明确事件的处理方式:

这里就要用到JavaScript和DOM, 用DOM获取网页节点,并应用节点的属性和行为,然后用javaScript来对操用各个对象的行为及维护各个对象的关系.

事例一:新闻字体的大小调整。

<html>

<head>

<meta http-equiv=”Content-Type” content=”text/html; charset=GBK”>

<title>Untitled Document</title>

<style type=”text/css”>

/*

伪元素选择器,是html预定好的一些选择器.

*/

a:link,a:visited{

/*设定超链接点击前和点击后的颜色为一样*/

color:#a4d1f7;

/*取消下划线*/

text-decoration:none;

}

/*设定光标移动到超链接上的颜色状态*/

a:hover{

color:#fa8316;

}

/* 用id选择器设定div文本的格式*/

#newstext{

/*设制区域离上面标签的距离*/

margin-top:20px;

/*设制一个div的外框线条粗细和颜色*/

border:solid 3px #0080ff;

/*设制一个div的外框的宽度*/

width:550px;

/*设制一个div内容的页边距*/

padding:10px;

}

</style>

</head>

<body>

<h2>这是新闻标题</h2>

//定义javaScript 方法一:直接通过传参改变属性

<script type=”text/javascript”>

//改变新闻文字的字体大小。

function changeFont(size,clr){

//1,获取被处理的新闻文字div节点。

var newsTextNode = document.getElementById(“newstext”);

//用div节点去调用其style属性节点并调用其样式对象属性:字体大小

newsTextNode.style.fontSize = size+”px”;

//用div节点去调用其style属性节点并调用其样式对象属性:字体格式

newsTextNode.style.color = clr;

}

</script>

<a href=”javascript:void(0)” onclick=”changeFont(’24’,’green’)”>大字体</a>

<a href=”javascript:void(0)” onclick=”changeFont(’16’,’black’)”>中字体</a>

<a href=”javascript:void(0)” onclick=”changeFont(’12’,’red’)”>小字体</a>

javaScript方法二:将样式进行CSS封装成参数传入.

<head>

<style type=”text/css”>

/*定义一些风格*/

/*.开头是就是class属性*/

.max{

font-size:24px;

color:#81f02f;

}

.min{

font-size:12px;

color:#fa590c;

}

.norm{

font-size:16px;

color:#000000;

}

</style>

</head>

<script type=”text/javascript”>

//改变新闻字体风格。通过className进行风格切换。

function changeFont(styleName){

var newsTextNode = document.getElementById(“newstext”);

//通过div对象的属性className获取对象的类

newsTextNode.className = styleName;

}

</script>

<a href=”javascript:void(0)” onclick=”changeFont(‘max’)”>大字体</a>

<a href=”javascript:void(0)” onclick=”changeFont(‘norm’)”>中字体</a>

<a href=”javascript:void(0)” onclick=”changeFont(‘min’)”>小字体</a>

<div id=”newstext”>

这是新闻内容这是新闻内容这是新闻内容这是新闻内容这是新闻内容<br/>

这是新闻内容这是新闻内容这是新闻内容这是新闻内容这是新闻内容<br/

</div>

</body>

</html>

事例二:列表标签的展开闭合

<style type=”text/css”>

//让dd标签不缩进

dl dd{

margin:0px;

}

dl{

//设置默认属性

height:16px;

overflow: hidden;

}

.open{

overflow:visible;

}

.close{

overflow: hidden;

}

</style>

</head>

<body>

<script type=”text/javascript”>

展开闭合切换方法一:

var b= true;

function list(node){

var dlNode=node.parentNode;

if(b){

dlNode.style.overflow=”visible”;

b=false;

}else{

dlNode.style.overflow=”hidden”;

b=true;

}

}

展开闭合切换方法二:

function list2(node){

var dlNode=node.parentNode;

if(dlNode.className==”open”){

dlNode.className=”close”;

}else{

dlNode.className=”open”;

}

}

</script>

<dl>

<dt onclick=”list(this)”>体育新闻</dt>

<dd>足球新闻</dd>

<dd>篮球新闻</dd>

<dd>网球新闻</dd>

<dd>排球新闻</dd>

</dl>

<dl>

<dt onclick=”list2(this)”>财经新闻</dt>

<dd>股票新闻</dd>

<dd>基金新闻</dd>

<dd>理财新闻</dd>

<dd>黄金新闻</dd>

</dl>

</body>

</html>

4.    什么时候用?

只要做网页,需要有交互与动态就会用到

5.    有什么特点?

这个技术方法最重要

Ø  第三十二天–DHML综合运用与javaScript表单校验

一、DHML综合运用

<style type=”text/css”>

1.    //设定表格:css样式

table,table td,table th{

/*设定表格外框,solid是实线*/

border:#0080ff 1px solid;

width:500px;

padding:5px;

}

table th{

background-color:#4fceee;

}

.one{

background-color:#12e99d;

}

.two{

background-color:#f5e947;

}

.over{

background-color:#5c73ef;

}

</style>

<script type=”text/javascript”>

var name;

2.    //行颜色间隔显示。

function trColor(){

//1,获取表格节点。

var tabNode = document.getElementById(“mailtable”);

//2,获取表格中所有行节点。

var trs = tabNode.rows;

//3,遍历所有需要加上间隔颜色背景的行节点。

for(var x=1; x<trs.length-1; x++){

//进行奇偶判断。

if(x%2==1){

trs[x].className = “one”;

}else{

trs[x].className = “two”;

}

3.    //给每一个行加载两个事件,用于完成高亮效果。

trs[x].onmouseover = function(){

name = this.className;

this.className = “over”;

}

trs[x].onmouseout = function(){

this.className = name;

}

}

}

onload = function(){

trColor();

}

4.    //完成复选框的全选动作。

function checkAll(node){

//1,获取当前的allmail的复选框的状态。通过this进行传入,当前的allmail节点

//2,获取所有的mail节点。

var mailNodes = document.getElementsByName(“mail”);

//3,遍历该mail节点。

for(var x=0; x<mailNodes.length; x++){

//将当前allmail节点的checked状态赋值给所有的mail节点checked。

mailNodes[x].checked = node.checked;

}

}

5.    //完成通过按钮选取mail的动作。

function checkAllByBut(num){

//1,获取所有的mail节点。

var mailNodes = document.getElementsByName(“mail”);

//2,遍历该mail节点。

for(var x=0; x<mailNodes.length; x++){

//判断是哪个按钮。

if(num>1){

mailNodes[x].checked = !mailNodes[x].checked;

}else{

//数字0是false 1就是true。

mailNodes[x].checked = num;

}

}

}

6.    //通过按钮将所选的邮件删除。

function deleteMail(){

if(confirm(“你真的要删除所选邮件吗?”)){

//1,获取所有mail节点。

var mailNodes = document.getElementsByName(“mail”);

//2,遍历这些节点明确哪些是被选中的mail节点。

for (var x = 0; x < mailNodes.length; x++) {

if(mailNodes[x].checked){

//咋删?应该是删除该复选框所在的行节点。

//获取行节点。当前的复选框节点的父节点的父节点。因为mail节点代表的是input=checkbox的节点

var trNode = mailNodes[x].parentNode.parentNode;

//                      alert(trNode.nodeName);

trNode.parentNode.removeChild(trNode);

x–;

}

}

}

trColor();

}

</script>

</head>

<body>

<table id=”mailtable”>

<tr>

<th><input type=”checkbox” name=”allmail” onclick=”checkAll(this)” />全选</th>

<th>发件人</th>

<th>邮件内容</th>

<th>附件信息</th>

</tr>

<tr>

<td><input type=”checkbox” name=”mail” /></td>

<td>张三1</td>

<td>一封邮件</td>

<td>没有附件</td>

</tr>

<tr>

<td><input type=”checkbox” name=”mail” /></td>

<td>张三2</td>

<td>一封邮件</td>

<td>没有附件</td>

</tr>

<tr>

<td><input type=”checkbox” name=”mail” /></td>

<td>张三3</td>

<td>一封邮件</td>

<td>没有附件</td>

</tr>

<tr>

<th>

<input type=”checkbox” name=”allmail” onclick=”checkAll(this)” />全选</th>

<th colspan=”3″><input type=”button” value=”全选” onclick=”checkAllByBut(1)”/>

<input type=”button” value=”取消全选” onclick=”checkAllByBut(0)” />

<input type=”button” value=”反选” onclick=”checkAllByBut(2)” />

<input type=”button” value=”删除所选邮件” onclick=”deleteMail()”/>

</th>

</tr>

</table>

</body>

</html>

二、javaScript表单校验

<body>

<script type=”text/javascript” >

1.    js表单校验步骤:

* 1,明确事件:onblur:失去焦点。

* 2,明确提示信息的显示方式。在节点旁边进行信息提示。

* 3,校验规则,为了方便于对字符串的判断,可以使用js中的正则表达式。

* 4,表单提交事件的处理。

* 5,确认密码的校验。

*/

var flag;

2.    封装一个校验方法:

function check(name, spanId, reg, okinfo, errinfo){

var val = document.getElementsByName(name)[0].value;

var spanNode = document.getElementById(spanId);

if (reg.test(val)) {

spanNode.innerHTML = okinfo.fontcolor(“green”);

flag = true;

}

else {

spanNode.innerHTML = errinfo.fontcolor(“red”);

flag = false;

}

return flag;

}

3.    //让用户名一开始就获取焦点:

function getfocus(){

var val=document.getElementsByName(“user”)[0];

val.focus();

}

onload=getfocus;

4.     //校验用户名

function checkUser(){

/*未提取方法前的做法

var val=document.getElementsByName(“user”)[0].value;

var spanNode=document.getElementById(“userspan”);

var reg=new RegExp(“^[a-zA-Z]{4}$”,”i”);

if(reg.test(val)){

spanNode.innerHTML=”用户名正确”.fontcolor(“green”);

}else{

spanNode.innerHTML=”用户名错误”.fontcolor(“red”);

}*/

//提取方法后的做法

var reg = new RegExp(“^[a-zA-Z]{4}$”, “i”);

return check(“user”, “userspan”, reg, “用户名正确”, “用户名错误”)

}

5.    //校验密码是否正确

function checkPsw(){

var reg = new RegExp(“^[a-z0-9]{4}$”, “i”);

return check(“psw”, “pswspan”, reg, “密码正确”, “密码错误”);

checkRepsw();

}

6.    //校验密码是否一致

function checkRepsw(){

var val = document.getElementsByName(“psw”)[0].value;

var val1 = document.getElementsByName(“repsw”)[0].value;

var spanNode = document.getElementById(“repswspan”);

if (val == val1) {

spanNode.innerHTML = “密码一致”.fontcolor(“green”);

return true;

}

else {

spanNode.innerHTML = “密码不一致”.fontcolor(“red”);

return false;

}

}

7.     //校验总表单并提交.

function checkForm(){

8.  //设定性别按钮必须选择,不然不允许提交数据.

var sexNode=document.getElementsByName(“sex”)[0].checked;

if (checkUser() && checkPsw() && checkRepsw()&&sexNode) {

return true;

}

else {

return false;

}

}

9.  // 校验总表单是否正确并提交的另一种方法

//即不通过submit控件,而是通过任何标签.

function mySubmit(){

//设定性别按钮必须选择,不然不允许提交数据.

var sexNode=document.getElementsByName(“sex”)[0].checked;

//获取form节点

var formNode = document.getElementById(“formid”);

if (checkUser() && checkPsw() && checkRepsw()) {

formNode.submit();

}

}

</script>

10.     <!–表单标签设置。 –>

<form id=”formid” onsubmit=”return checkForm()”>

用户名称:<input type=”text” name=”user” onblur=”checkUser()”/>

<span id=”userspan”></span>

<br/>

<!–这里为了便于看到结果,用明文密码*/–>

输入密码:<input type=”text” name=”psw” onblur=”checkPsw()”/>

<span id=”pswspan”></span>

<br/>

确认密码:<input type=”text” name=”repsw” onblur=”checkRepsw()”/>

<span id=”repswspan”></span>

<br/>

性别:<input type=”radio” name=”sex” value=”nan”>男

<input type=”radio” name=”sex” value=”nv”>女

<br/>

<input type=”submit” value=”提交数据” />

<input type=”button” value=”另一种提交方式” onclick=”mySubmit()”/>

</form>

</body>

三、DHTML总结:

一、首先就是要用html给数据封装标签

步骤:

  • 明确是要封装什么类型的标签:字体,列表还是表格 表单 图像或其它…….
  • 有标签名后,就要定义需要的具体属性
  • 最后就是明确事件,这个标签虽不虽要发生事件,要发生是哪一种事件…

二、封装好标签后,就是要用CSS给标签定义一些所需的样式:

步骤:

  • 明确用什么选择器
  • 从上到下,从整体到局部.
  • 不求会写,但求会改

三、用DOM获得对象,用javaScript进行效果的封装

步骤:

  • 事件源:要先明确是要操作哪个标签对象的事件.
  • 事件:明确那个标签是要操作一个什么事件:点击,悬停,焦点等等….
  • 事件要处理的标签对象是什么:比如通过点击让一个段落标签封装的文字作改变..等等..
  • 用javaScript定义事件的内容(方法):比如:你是要让处理的标签变色呢,还是要让处理的标签实现数据校验等等….
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇