JavaSE笔记

一、 初识Java编程

1、 Java开发环境

JDK Java开发工具

JVM Java虚拟机

JRE Java运行环境

2、实现第一个hello world

public class Hello{ public static void main(String[] args){ System.out.println("hello man!"); } }

执行代码:

(1) 在命令窗体输入: javac 文件名.java

(2) 输入:java 文件名

注意:

(1) 类名和文件名要保持一致;

(2) Java源代码中的所有标点符号使用英文输入法状态输入;

(3) Java源代码是区分大小写;

(4) 类名默认都使用大写;

3、Java运行原理

4、变量的声明

声明语法:

数据类型 变量名 ;

赋值:

变量名 = 值;

示例:

public class Hello{ public static void main(String[] args){ //声明整数类型的a,在内存中创建这个变量 int a; double b; double c; //给变量赋值 a = 1; b = 2; System.out.println(a/b); } }

5、标识符

(1) 标识符是用于类名、变量名、方法名、对象名、数组名等的命名;

(2) 可以使用英文、数字、下划线_、$符号;

(3) 不能以数字开头;

(4) 不能使用Java关键字或保留字;

(5) 区分大小写;

6、注意事项

(1)当声明的类使用public关键字修饰时,源文件名必须和类名保持一致;

(2)一个.java源文件中可以声明多个类,但是只能有一个public修饰的类,文件名要和public修饰的类名保持一致;

(3)类中可以继续声明类,称为内部类;

6、eclipse的使用

6.1 默认界面效果

6.2 创建项目

(1)在包资源管理器中点右键,选择:

(2)在src目录上右键,新建package,包的命名规范:

域名的倒置,例如:www.baidu.com 包名 com.baidu.www

(3)在当前包下,新建Class

(4)修改字体

7、注释

7.1 单行注释

语法:

//这一行是注释

7.2 多行注释

/*

* 多行注释

* 多行注释

*/

7.3 文档注释

/**

* 这是一个测试的类

* @author

*

*/

练习

声明两个变量,例如:

int a,b; a = 1; b = 2;

把变量a和变量b的值交换。

答案:

int a,b,c; a = 1; b = 2; c = a; a = b; b = c; System.out.println("a="+a);//+ 是拼接的意思 System.out.println("b="+b);

二、Java的基本数据类型

Java的基本数据类型有4类8种,

类型分别为:整数型、浮点型、字符型、布尔型;

其中整数型有4种,字节型byte、短整型short、整数型int、长整型long;

浮点型有2种:单精度float、双精度double;

字符型char;

布尔型boolean

1、整数型

整数型取值范围:

System.out.println("字节类型byte取值范围:"); System.out.println(Byte.SIZE+"位"); System.out.println("byte最大:"+Byte.MAX_VALUE); System.out.println("byte最小:"+Byte.MIN_VALUE); System.out.println("短整型short取值范围:"); System.out.println(Short.SIZE+"位"); System.out.println("Short最大:"+Short.MAX_VALUE); System.out.println("Short最小:"+Short.MIN_VALUE); System.out.println("整数型int取值范围:"); System.out.println(Integer.SIZE+"位"); System.out.println("int最大:"+Integer.MAX_VALUE); System.out.println("int最小:"+Integer.MIN_VALUE); System.out.println("长整型long取值范围:"); System.out.println(Long.SIZE+"位"); System.out.println("long最大:"+Long.MAX_VALUE); System.out.println("long最小:"+Long.MIN_VALUE);

2、浮点型

整数型取值范围:

System.out.println("单精度浮点型float取值范围:"); System.out.println(Float.SIZE+"位"); System.out.println("float最大:"+Float.MAX_VALUE); System.out.println("float最小:"+Float.MIN_VALUE); System.out.println("双精度浮点型double取值范围:"); System.out.println(Double.SIZE+"位"); System.out.println("double最大:"+Double.MAX_VALUE); System.out.println("double最小:"+Double.MIN_VALUE);

3、字符型

char类型是一个单一的16位Unicode字符,在Java底层是以整数型进行运算;

最大值:char d = '\uffff';

最小值:char c = '\u0000';

4、布尔型

boolean表示逻辑运算的结果,值为true或false

boolean a = true;//真

boolean b = false;//假

5、数据类型转换

5.1 自动类型转换

int a = 1; long b = a;//小类型转大类型,自动类型转换

5.2、强制类型转换

int a = 127; byte b =(byte) a;//大类型转小类型,需要强制类型转换

练习

把123.456789,使用当前所学的知识,计算四舍五入保留2位小数的结果。

答案:

double d = 123.456789;//保留2位小数 System.out.println((int) (d*100+0.5)/100.0);

三、运算符

1、算术运算符

重点掌握:取模(%)、自增自减(++a,a++)

示例代码:

int a = 1; a++;// 自身增加1 , a = a; a=a+1 ++a;// 自身增加1, a = a+1 ; a = a System.out.println(a++); // 在打印的时候,执行的是a = a,所以打印的结果为1 ,打印结束后 a = a+1; System.out.println(a); System.out.println(++a); // 在打印的时候同时执行了 a = a + 1,所以结果为2,打印结束后又执行了 a=a; System.out.println(a);

2、关系运算符(条件运算)

3、赋值运算

4、逻辑运算符

5、位运算

代码示例:

// boolean a = 1>2; // false // boolean b = 1==1;// true // // System.out.println(a & b);//短路与 // System.out.println(a | b);//短路或 // int a = 3;// 转为二进制:11 // int b = 2;// 转为二进制:10 char a = 'a';// 97 --> 1100001 char b = 'b';// 98 --> 1100010 // 1100000 --> 96 // 1100011 --> 99 // 0000011 --> 3 System.out.println(a & b);// & 表示对应位都为1,结果为1,否则为0 System.out.println(a | b);// | 表示对应位都为0,结果为0,否则为1 System.out.println(a ^ b);// ^ 表示对应位相同,结果为0,否则为1

异或(^)作为逻辑运算符时,符号两边相同时返回false,两边不同时返回true;

6、条件运算符

语法:

变量类型 变量名 = 条件 ? A : B ;

解读:

声明一个变量,当条件为true时,当前变量的值为A,当条件为false时,当前变量的值为B;

代码示例:

int a = false ? 1 : 0; System.out.println(a);

int week = 6; String s = (week>=1 && week<=5) ? "去上课":"去LOL"; System.out.println(s);

四、流程控制

1、分支语句

1.1 if-else-if

语法:

if(条件){

当条件为true时,执行大括号内的代码

}else if(条件){

}

补充:

//实例化扫描仪对象 Scanner sc = new Scanner(System.in); System.out.println("请输入第一个值:"); int a = sc.nextInt(); System.out.println("请输入第二个值:"); int b = sc.nextInt(); System.out.println("求和结果:"+(a+b)); // String s = sc.next(); // System.out.println(s); // double d = sc.nextDouble();

1.2 switch语句

概念:

switch 语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支。

语法:

switch( 变量 ){

case 值1:

break;

case 值2:

break;

default:

}

当程序执行到break关键字时,跳出当前的switch语句;

注意事项:

  • switch 语句中的变量类型可以是: byte、short、int 或者 char。从 Java SE 7 开始,switch 支持字符串类型了,同时 case 标签必须为字符串常量或字面量。
  • switch 语句可以拥有多个 case 语句。每个 case 后面跟一个要比较的值和冒号。
  • case 语句中的值的数据类型必须与变量的数据类型相同,而且只能是常量或者字面常量。
  • 当变量的值与 case 语句的值相等时,那么 case 语句之后的语句开始执行,直到 break 语句出现才会跳出 switch 语句。
  • 当遇到 break 语句时,switch 语句终止。程序跳转到 switch 语句后面的语句执行。case 语句不必须要包含 break 语句。如果没有 break 语句出现,程序会继续执行下一条 case 语句,直到出现 break 语句。
  • switch 语句可以包含一个 default 分支,该分支必须是 switch 语句的最后一个分支。default 在没有 case 语句的值和变量值相等的时候执行。default 分支不需要 break 语句。

2、循环语句

2.1 while循环

语法:

while(条件){

当条件为true时,执行循环体内的代码;

}

备注:

满足循环的三个条件:初始化变量、关系运算、迭代

2.2 do-while循环

语法:

do{

}while(条件);

备注:与while循环的区别是,当条件为false时,也会被执行一次。

2.3 for循环

语法:

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

}

2.4 嵌套for循环

2.4.1 打印直角三角形

for(int i = 1 ; i < 10 ; i++){ for(int j = 1 ; j <= i ; j++){ System.out.print("* "); } System.out.println(); }

for(int i = 1 ; i < 10 ; i++){ for(int j = 1 ; j <=(10-i) ; j++){ System.out.print("* "); } System.out.println(); }

2.4.2 打印乘法口诀

for(int i = 1 ; i < 10 ; i++){ for(int j = 1 ; j <=i ; j++){ System.out.print(j+"×"+i+"="+(i*j)+"\t"); } System.out.println(); }

for(int i = 1 ; i < 10 ; i++){ for(int j = 1 ; j <=(10-i) ; j++){ System.out.print(i+"×"+j+"="+(i*j)+"\t"); } System.out.println(); }

for(int i = 1 ; i < 10 ; i++){ for(int j = 1 ; j < i ; j++){ System.out.print("\t"); } for(int j = i ; j < 10 ; j++){ System.out.print(i+"×"+j+"="+(i*j)+"\t"); } System.out.println(); }

for(int i = 1 ; i < 10 ; i++){ for(int j = 1 ; j < 10-i ; j++){ System.out.print("\t"); } for(int j = 1 ; j <=i ; j++){ System.out.print(j+"×"+i+"="+(i*j)+"\t"); } System.out.println(); }

2.5 循环控制

2.5.1 break语句

break 可以用于所有的循环语句或者 switch 语句中,用来跳出整个语句块。

break 跳出该关键字所在的循环,并且继续执行该循环下面的语句。

2.5.2 continue语句

continue 适用于任何循环控制结构中。作用是让程序立刻跳转到下一次循环的迭代。

在 for 循环中,continue 语句使程序立即跳转到更新语句。

在 while 或者 do…while 循环中,程序立即跳转到布尔表达式的判断语句。

2.6 标签的使用

语法:

标签名 :

使用:

break 标签名; 或

continue 标签名;

示例:

a: for (int i = 1; i <= 10; i++) { System.out.println("i="+i); b: for (int j = 1; j <= 10; j++) { if(j==5){ // continue a; break a; } System.out.println("j="+j); } }

注意:

标签名的语法规则要遵循标识符的语法要求;

break 标签名 : 跳出该标签名后面的循环;

continue 标签名: 跳过该标签名的本次循环,继续进行下次迭代;

补充(随机数)

生成随机数(2位)

Random ran = new Random(); int i = ran.nextInt(90)+10; // 随机的结果为 [0,90)+10 = [10,99] System.out.println(i);

五、数组

1、数组的声明

(1)语法:

类型[] 数组名 = new 类型[长度];

示例:

int[] array = new int[10];

(2)语法:

类型[] 数组名 = {值,值,……};

示例:

int[] array2 = {1,2,3,4,5,6,7,8,9,10};

(3)语法:

类型[] 数组名 = new 类型[]{值,值……};

示例:

int[] array3 = new int[]{1,2,3,4,5,6,7,8};

数组通过下标来赋值和取值,例如:

array[0] = 1;

System.out.println(array[0]);

下标的范围是从0开始,到数组的长度-1;

2、数组的遍历

示例:

int[] array = {10,12,32,45,57,68,79,80,90,100,200,300}; //数组的遍历 for(int i = 0 ; i < array.length ; i++){ System.out.println(array[i]); }

增强for循环:

语法:

for(数组类型 变量名 : 数组名){

System.out.println(变量名);

}

示例:

int[] a = {1,2,3,4,5,6}; //增强for循环 for(int i : a){ System.out.println(i); }

3、数组排序

3.1 冒泡排序

从后往前依次确定元素,相邻的两个元素比较,互换位置;

int[] a = {3,7,9,1,5}; for(int i = 1 ; i < a.length ; i++){ for(int j = 0 ; j < a.length - i; j++){ if(a[j] < a[j+1]){ int temp = a[j]; a[j] = a[j+1]; a[j+1] = temp; } } }

3.2 选择排序

从前往后确定元素,让未确定的第一个数依次和后面的比较,互换位置;

int[] a = { 3, 7, 9, 1, 5 }; for (int i = 0; i < a.length - 1; i++) { for (int j = i + 1; j < a.length ; j++) { if (a[i] < a[j]) { int temp = a[i]; a[i] = a[j]; a[j] = temp; } } }

4、二维数组

示例:

int[] a = {1,2,3,4,5,20}; int[] b = {6,7,8,9,10}; int[] c = {11,12,13,14,15,16,17,18}; //二维数组 int[][] array = {a,b,c}; //遍历array for(int i = 0 ; i < array.length ; i++){ for(int j = 0 ; j < array[i].length; j++){ System.out.print(array[i][j]+" "); } System.out.println(); }

六、方法

1、方法的声明

语法:

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

要执行的代码

}

示例:

//自定义方法 public static void print(){ System.out.println("hello"); }

1.1 static关键字

用法:

  • 当使用static关键字修饰方法时,该方法称为静态方法,即类的方法;
  • 如果没有使用static关键字修饰,该方法为普通方法(实例方法),即对象的方法;
  • 静态方法中,只能直接调用静态方法;
  • 实例方法中,可以直接调用静态方法,也可以直接调用实例方法;
  • 静态方法中如果要调用实例方法,必须先实例化对象,使用对象名调用;

补充:

实例化对象语法:

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

1.2 void关键字

  • 当方法没有任何返回值时,方法声明语句中使用void关键字;
  • 当方法有返回值时,返回值是什么数据类型,就声明为什么类型;

1.3 参数

语法:

  • 在方法名后面的括号中声明;
  • 参数的个数为大于等于0;
  • 写法:方法名(类型 变量名,类型 变量名,……){}
  • 参数是当前方法的局部变量,是一种特殊的局部变量;
  • 参数的赋值过程,是在调用该方法时完成的;
  • 当有多个参数,调用该方法时,依次按照括号中的顺序为参数赋值;
  • 参数的类型可以为Java的任何数据类型;

2、使用方法的好处

(1)提高代码的复用性,减少代码量;

(2)把某个功能封装到一个方法中,便于协作开发;

(3)便于代码集中管理;

(4)提现了面向对象的思想;

3、方法重载

概念:重载(overloading) 是在一个类里面,方法名字相同,而参数不同。与返回值类型、访问修饰符无关。

规则:

(1) 参数的类型不同;

(2) 参数个数不同;

(3) 参数的顺序不同;

七、面向对象

万物皆对象

描述一个物质都可以通过两方面说明:数据模型(属性)、行为模型(行为)。

在Java编程中,我们使用成员变量表示数据模型,用成员方法表示行为模型。

使用类表示某些具有相同属性和行为的事物。

以动物为例:

1、构造方法

语法:

[访问修饰符] 类名(){

}

注意:

当类中没有显式的构造方法,实例化该类的对象时,程序会自动创建一个公开的无参构造方法;

如果类中有显示的构造方法,程序就不会创建无参构造;

构造方法,一般是用于为成员属性赋初始化值;

2、变量

2.1 局部变量

  • 声明在构造方法、静态方法、实例方法、代码块中的变量,都是局部变量;
  • 不能使用static和访问修饰符修饰;
  • 可以使用final修饰,即为常量,不必在声明语句中赋值;
  • 当执行局部变量所在的方法或代码块时,才有机会被创建,在方法或代码块执行结束后被自动销毁;
  • 局部变量在内存的栈区分配;
  • 局部变量在使用之前必须要先赋值;
  • 声明在所有方法体和代码块之外,并且没有使用static修饰的变量,叫做实例变量;
  • 可以使用访问修饰符和final修饰;
  • 使用final修饰时,一定要赋值;
  • 实例变量是在对象被创建时创建,对象被销毁时销毁;
  • 作用域范围在整个类中;
  • 声明在所有方法体和代码块之外,并且使用static修饰的变量;
  • 可以使用访问修饰符修饰;
  • 一般配合final使用,即public static fianl,标识符使用大写;
  • 类变量被分配在静态存储区,是被所有该类的对象共享数据;
  • 类变量是在程序开始时被创建,程序结束时销毁;

2.2 实例变量

2.3 类的变量

3、访问修饰符

访问修饰符是用来控制其他类对该类的类、实例变量、构造方法、实例方法的访问权限。Java的访问权限有4种:

public 公开的

protected 受保护的

默认的,没有任何关键字来表示

private 私有的

修饰符

当前类

同包的类

同包的子类

异包

异包的子类

public

protected

×

×

默认的

×

×

private

×

×

×

×

4、this关键字

this指当前对象,用法:

  • 当局部变量名和实例变量名同名时,使用this.变量名来表示实例变量;
  • this()表示当前类的构造方法,只能在构造方法中使用该写法,并且是写在构造方法内的第一行。

5、封装

私有的属性,公开的方法。

封装的步骤:

声明私有(private)的属性;

声明公开(public)的geter和seter方法;

6、继承

Java中的继承是单继承,可以实现多层继承,继承的关键字extends

语法:

public class Son extends Father{

}

规则:

  • 子类继承父类非私有的所有属性和方法,不能继承父类的构造方法;
  • 实例化子类对象的步骤:先执行父类的构造方法,再执行子类的构造方法;

重写定义:

  • 子类重新声明从父类继承来的方法,称为方法重写;
  • 方法重写时,方法的声明部分要和父类保持一致(返回值类型,方法名,参数);
  • 重写方法的访问权限要大于等于父类中方法的访问权限;
  • 子类重写父类方法,子类对象调用的是子类中重写后的方法;
  • 使用static修饰的方法不能被重写,但是可以被子类重写声明;
  • 不同包的子类可以重写父类中protected修饰的方法,但是不能以继承的形式,用子类对象直接调用父类的该方法;

Final关键字:

  • 当final修饰类时,当前类不能被继承;
  • 当final修饰方法时,该方法不能被重写;
  • 当final修饰变量时,变量的值不能被修改,即为常量;

7、多态

实现的必要条件:

  • 继承
  • 重写
  • 父类引用指向子类对象

instanceof关键字:

语法:

if (对象名 instanceof 类名) {

类型转换代码;

}

实例:

Animal cat = new Cat(); if (cat instanceof Cat) {//返回结果为boolean类型 Cat c = (Cat) cat; c.eat(); }else{ System.out.println("类型不匹配"); }

8、抽象类

抽象类语法:

public abstract class Demo {

}

抽象方法语法:

public abstract void abc();

规则:

含有抽象方法的类,一定是抽象类;

  • 抽象类中可以声明成员变量、常量、成员方法、抽象方法,抽象类中不一定要有抽象方法;
  • 抽象类不能被实例化;
  • 抽象类可以被继承;
  • 可以通过两种方式获得抽象类对象:父类引用指向子类对象、匿名内部类;
  • 子类必须重写抽象父类的所有抽象方法,或者是把子类也定义为抽象类;
  • 如果一个类继承的抽象父类还有上级抽象父类,那么子类中需要要重写所有抽象父类的所有抽象方法;
  • 抽象类也可以继承非抽象类,同时继承了父类的所有非私有的属性和方法;

9、接口

语法:

public interface ITest {

}

规则:

  • 接口使用interface关键字修饰;
  • 接口是一个完全抽象的抽象类;
  • 接口中没有构造方法;
  • 接口不能被实例化对象;
  • 接口中可以声明静态常量、抽象方法、静态方法;
  • 接口中不能声明实例方法,声明抽象方法时,不能使用static关键字修饰;
  • 声明接口语句中,默认含有abstract关键字,抽象方法中也默认含有abstract关键字;
  • 接口可以被实现,使用implements关键字,一个类实现一个接口,必须重写该接口中所有的抽象方法;
  • 一个类可以实现多个接口,每个接口名用英文的逗号隔开,该类中必须重写所有已实现接口中的抽象方法;
  • 接口可以继承接口,接口与接口间是多继承关系,接口不能继承类;

10、内部类

10.1 成员内部类

成员内部类声明在类中,方法体、代码块之外。和成员变量、成员方法在同一级别。

语法:

public class Out { //成员内部类 public class Inner{ } }

实例化成员内部类:

//先实例化外部类 Out o = new Out(); //使用外部类对象,再实例化内部 Out.Inner inner = o.new Inner();

实例:

public class Out { //成员变量 public int a = 1; //成员内部类 public class Inner{ public int a = 2; //内部类的成员方法 public void print(){ //执行内部类中的实例变量a System.out.println(a); //执行外部类的实例变量a System.out.println(Out.this.a); } } }

10.2 静态内部类

声明的位置参考成员内部类。

语法:

public class Out { //静态内部类 public static class Inner{ } }

实例化静态内部的对象:

Out.Inner inner = new Out.Inner();

实例:

public class Out { public static int a = 1; public int b = 3; //静态内部类 public static class Inner{ public static int a = 2; public static void print(){ //执行静态内部的静态变量 System.out.println(a); //执行外部类的静态变量 System.out.println(Out.a); //执行外部类的实例变量 Out o = new Out(); System.out.println(o.b); } } }

10.3 局部内部类

声明在方法体或代码块内,作用域范围在方法体或代码块内。

语法:

public class Out { public void method(){ //局部内部类 class Inner{ //局部内部类的成员方法 public void print(){ System.out.println("局部内部类"); } } //实例化局部内部类 Inner inner = new Inner(); inner.print(); } }

执行局部内部类的方法:

Test类:

public static void main(String[] args) { Out o = new Out(); o.method(); }

10.4 匿名内部类

  • 声明位置同局部内部类一样,前提条件:必须继承一个类或实现一个接口,匿名内部类的声明和实例化对象是同时进行的;
  • 一般使用于获得抽象类或接口对象;

语法:

父类名/接口名 对象名 = new 父类名/接口名(){

//匿名内部类成员

};

实例:

父类

public class Father { }

匿名内部类:

public class Out { public void method(){ //匿名内部类对象 Father f = new Father(){ }; } }

八、Java常用类库

1、Object类

Object类是所有类直接或间接父类。

方法:

toString():以字符串形式返回对象的文本信息;

hashCode():返回该对象的哈希值;

getClass():返回对象的类类型;

equals(Object obj):比较两个对象是否相等

2、包装类

2.1 装箱与拆箱

实例:

byte b = 1;//基本数据类型 System.out.println(b+1); Byte b2 = new Byte(b);//包装类的对象 System.out.println(b2); Byte b3 = b;//自动装箱,把基本数据类型转为对象 System.out.println(b3+5); byte b4 = new Byte(b);//自动拆箱,把对象转为基本数据类型 System.out.println(b4+7);

2.2 Number类的常用方法

  • 构造方法;
  • valueOf();
  • toString();

2.3 Character 常用方法

  • valueOf();
  • toString();
  • isDigit():判断是否为数字
  • isLetter():判断是否为字母
  • isUpperCase():判断是否为大写字母
  • isLowerCase():判断是否为小写字母
  • isWhitespace():判断是否为空格
  • toUpperCase():转为大写字母
  • toLowerCase():转为小写字母

3、字符串操作

3.1 String类

String字符串的值不可更改。

常用方法:

  • charAt(int i):返回指定索引处的字符;
  • length():返回字符串的长度;
  • contains(CharSequence c):判断字符串中是否包含指定的字符序列;
  • startsWith(String s):判断字符串是否以指定的前缀开始;
  • endsWith(String s):判断字符串是否以指定的后缀结束;
  • indexOf(char c):返回指定字符在字符串中第一次出现的索引;
  • lastIndexOf(char c):返回指定字符在字符串中最后一次出现的索引;
  • isEmpty():当且仅当字符串长度为0时,返回true;
  • replace(char old,char new):把字符串中的old字符替换为new字符,然后返回一个新字符串;
  • split(String s):根据指定的规则拆分字符串,返回字符串数组;
  • subString(int begin,int end):按照指定的索引截取字符串,从begin(包含)开始,到end(不包含)结束;
  • toLowerCase():把字符串的英文字母全部转为小写;
  • toUpperCase():把字符串的英文字母全部转为大写;
  • trim():清除字符串前后的空白字符;
  • valueOf():把指定类型的数据转为字符串类型;
  • toCharArray():把字符串转为字符数组;

3.2 可变字符序列

StringBuffer和StringBuilder都是可变的字符序列,唯一的区别:StringBuffer是线程安全的,StringBuilder是线程不安全;

常用方法:

  • append():追加;
  • toString():把所有追加的内容以String类型返回;

4、System类

常用方法:

currentTimeMillis():获得当前时间戳,以毫秒为单位

exit(0):正常终止JVM

5、时间日期操作

5.1 时区操作(了解)

实例:

/* * 获取可用时区ID的方法 */ //获得时区对象的方法 // TimeZone t = TimeZone.getDefault(); //获取可用的所有ID String[] ids = TimeZone.getAvailableIDs(); for (String id : ids) { //获得每次遍历ID的时区对象 TimeZone tz = TimeZone.getTimeZone(id); System.out.println(id+"------>"+tz.getDisplayName()); } //根据时区ID获得时区对象 TimeZone tz = TimeZone.getTimeZone("Africa/Abidjan"); //设置时区 TimeZone.setDefault(tz); //根据时间戳获得指定日期对象 long time = 0; Date d = new Date(time); System.out.println(d);

5.2 Date类

构造方法:

  • Date():创建日期对象;
  • Date(long t):根据时间戳创建日期对象;

常用方法:

  • after(Date d):当前日期对象是否在指定日期之后;
  • before(Date d):当前日期对象是否在指定日期之前;
  • getTime():获得当前的时间戳;
  • setTime(long t):设置时间对象的具体时间为指定的时间戳;

5.3 Calendar类

实例:

//获得日历对象 Calendar c = Calendar.getInstance(); int year = c.get(Calendar.YEAR);//获得年份 System.out.println(year); int month = c.get(Calendar.MONTH);//获得月份 System.out.println(month+1); int day = c.get(Calendar.DAY_OF_MONTH);//获得月份中的日期 System.out.println(day); int week = c.get(Calendar.DAY_OF_WEEK);//星期几 System.out.println(week-1); // int s = c.get(Calendar.HOUR);//12小时制的时 int s = c.get(Calendar.HOUR_OF_DAY);//24小时制的时 System.out.println(s); int f = c.get(Calendar.MINUTE);//小时的分钟数 System.out.println(f); int m = c.get(Calendar.SECOND);//秒 System.out.println(m); int hm = c.get(Calendar.MILLISECOND);//毫秒 System.out.println(hm);

常用方法:

  • add(int field,int value):计算时间日期的偏移量;
  • getTime():获得Date类型的日期对象;
  • getTimeInMillis():获得时间戳;
  • get(int field):获得时间数据;
  • set(int field,int value):设置具体的时间;
  • set(year,month,day,hour,minute,second):通过参数直接设置具体时间;
  • setTime(Date d):把Date类型转为Calendar类型;

Calendar的子类GregorianCalendar,是格里高利日历,常用的方法:

  • isLeapYear(int year):判断指定年份是否为闰年,是闰年返回true;

5.4 日期格式化

1.格式化日期

实例:

// Date d = new Date(0); SimpleDateFormat sdf = new SimpleDateFormat("y年M月dd日 HH:mm:ss"); System.out.println(sdf.format(new Date()));

2.解析日期

实例:

Scanner sc = new Scanner(System.in); System.out.println("请输入一个日期:"); String str = sc.next(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); //把字符串类型的日期解析为Date对象 Date d = sdf.parse(str); System.out.println(d);

注意解析的模式是否正确,防止抛出解析异常

6、Math类

Math类是数学相关的操作工具类

7、Random类

获取伪随机数的类

8、Scanner类

获得用户在控制台输入的内容

9、Desktop类

使用Java程序执行本机的应用程序

执行浏览器实例:

// URI uri = new URI("http://www.baidu.com"); //获得本机对象 // Desktop d = Desktop.getDesktop(); // d.browse(uri); //简化 Desktop.getDesktop().browse(new URI("http://www.taobao.com"));

执行本地应用程序实例:

//执行本地应用程序 Desktop.getDesktop().open(new File("F:/a.txt"));

10、正则表达式

正则符号:

含义

符号

数字

[0-9] \\d

字母

[a-zA-Z]

空白字符

[ \n\t\r\f\x0B]

表示非

[^规则]

任意字符(换行除外)

. (点)

正则开始

^

正则结束

$

正则数量:

符号

含义

+

n≥1 1到多个

*

n≥0 0到多个

?

0≤ n ≤1 0或1个

{n}

n个

{n,}

n ≤ n到多个

{n,m}

n≤ num ≤m n到m个

正则逻辑:

含义

符号

分组

()

|

什么都不写

实例:

验证手机号:

//手机号是11位数字,前3位是136/130开头,后8位是随机数字 String str = "13033338880"; //规则 String gz = "^(([1][3][6])|([1][3][0]))([0-9]{8})$"; boolean rel = str.matches(gz); if(rel){ System.out.println("ok"); }else{ System.err.println("no"); }

邮箱验证:

//邮箱 zhangsan_.abc@qq.com为例,前缀:字母、数字、下划线、点、减号,@,qq/126/139/sina,com/com.cn/org/cn String str = "adf123@qq.cn"; //规则 String gz = "^([0-9a-zA-Z_.-]{3,18})" + "[@]" + "(([q]{2})|([1][2][6])|([1][3][9])|([s][i][n][a]))[.]" + "(([c][o][m])|([c][n])|([c][o][m][.][c][n]))$"; boolean rel = str.matches(gz); if(rel){ System.out.println("ok"); }else{ System.err.println("no"); }

九、集合

1、List序列

List是有序、可重复的集合;

1.1 常用方法

  • add(Object obj):添加元素;
  • add(int i,Object o):在指定位置处添加元素;
  • addAll(Collection c):把一个集合内的元素依次添加到当前集合;
  • addAll(int i,Collection c):把一个集合内的元素添加到当前集合的指定位置;
  • size():返回序列的长度;
  • get(int i):返回指定位置上的元素;
  • set(int i,Object o):修改指定位置的元素,返回被修改的原对象;
  • remove(int i):删除指定位置的元素,返回指定位置的元素;
  • remove(Object o):删除指定的对象,删除成功返回true;
  • removeAll(Collection c):从列表中移除指定集合中包含的其所有元素,删除成功返回true;
  • clear():清除集合中的所有元素;
  • contains(Object o):判断集合中是否包含指定的元素,包含返回true;
  • indexOf(Object o):返回指定元素在集合中第一次出现的下标;
  • lastIndexOf(Object o):返回指定元素在集合中最后一次出现的下标;
  • isEmpty():当且仅当集合长度为0时,返回true;
  • subList(int start,int end);截取集合,下标从start开始(包含),到end结束(不包含),返回一个新的集合;

实例:

1.2 添加

//获得List对象 List list = new ArrayList(); //依次添加 list.add("tom"); list.add("jack"); list.add("Lily"); list.add(3,"宋小宝"); List list2 = new ArrayList(); list2.add("张三"); list2.add("李四"); list2.add("王五"); // list.add(list2); // list.addAll(list2);//list集合中添加另一个集合的元素 list.addAll(2, list2);

1.3 for遍历

//使用for循环遍历 for (int i = 0; i < list.size(); i++) { Object obj = list.get(i); } //使用foreach循环遍历 for (Object obj : list) { System.out.println(obj); }

迭代器遍历:

//使用Iterator迭代器遍历 Iterator it = list.iterator(); while(it.hasNext()){ Object obj = it.next(); System.out.println(obj); }

1.4 修改

//修改 Object o = list.set(0, "汤姆");//返回被修改的对象 System.out.println(o+"被修改了");

1.5 删除

//根据下标删除 Object o = list.remove(0); System.out.println(o+"被删除了"); //根据对象删除 boolean b = list.remove("tom"); System.out.println(b); //删除指定集合中的所有元素 List list3 = new ArrayList(); list3.add("tom"); list3.add("宋小宝"); list3.add("王五"); boolean b = list.removeAll(list3); System.out.println(b);

1.6 泛型实例

Student s1 = new Student(); s1.name = "tom"; Student s2 = new Student(); s2.name = "jack"; Student s3 = new Student(); s3.name = "Lily"; Person p = new Person(); p.name = "张三"; //泛型,规定当前的集合只能存某种类型 List<Student> list = new ArrayList<Student>(); list.add(s1); list.add(s2); list.add(s3); //遍历 for (Student student : list) { System.out.println(student.name); } //使用迭代器遍历 Iterator<Student> it = list.iterator(); while(it.hasNext()){ Student s = it.next(); System.out.println(s.name); }

1.7 集合与数组的转换实例

String[] str = {"tom","jack","Lzly","rose","Ljly","1"}; //把数组转为集合 List<String> list = Arrays.asList(str); //把集合转为数组 Object[] obj = list.toArray();

1.8 集合排序实例

String[] str = {"tom","jack","Lzly","rose","Ljly","1"}; //把数组转为集合 List<String> list = Arrays.asList(str); Collections.sort(list);//自然升序 Collections.reverse(list);//将集合元素倒置 Collections.shuffle(list);//随机排序 for (String s : list) { System.out.println(s); }

1.9 使用排序算法对集合排序

List<Integer> list = new ArrayList<Integer>(); list.add(3); list.add(1); list.add(5); list.add(2); list.add(9); list.add(7); System.out.println("===========排序前=========="); for (Object object : list) { System.out.print(object+" "); } System.out.println(); System.out.println("===========排序后=========="); for(int i = 1 ; i < list.size() ; i++){ for(int j = 0 ; j < list.size() - i; j++){ int a = (int) list.get(j); int b = (int) list.get(j+1); if(a > b){ list.set(j, b); list.set(j+1, a); } } } //遍历 for (Object object : list) { System.out.print(object+" "); } System.out.println();

2、Set集合

Set是不可重复,无序的集合;

2.1 常用方法

  • add(Object o):添加元素,添加成功返回true,重复添加,返回false;
  • addAll(Collection c):把一个集合内的元素添加到当前集合;
  • contians(Object o):判断集合中是否包含指定元素,包含返回true;
  • isEmpty():当且仅当集合长度为0时,返回true;
  • iterator():返回迭代器对象,用于遍历集合;
  • remove(Object o):删除集合中的指定元素,删除成功返回true;
  • removeAll(Collection c):从列表中移除指定集合中包含的其所有元素,删除成功返回true;
  • clear():清除集合中的所有元素;
  • size():返回集合的长度;
  • toArray():把集合转为数组;

2.2 添加

//添加 Student s1 = new Student("tom"); Student s2 = new Student("jack"); Student s3 = new Student("Lily"); Student s4 = new Student("rose"); Set<Student> set = new HashSet<Student>(); set.add(s1); set.add(s2); //添加set集合 Set<Student> set2 = new HashSet<Student>(); set2.add(s3); set2.add(s4); set.addAll(set2); //添加list集合 List<Student> list = new ArrayList<Student>(); list.add(s3); list.add(s4); set.addAll(list); //添加数组 Student[] stuArray = {s3,s4}; set.addAll(Arrays.asList(stuArray));

2.3 遍历

//使用foreach遍历 for (Student stu : set) { System.out.println(stu.name); } //使用迭代器遍历 Iterator<Student> it = set.iterator(); while(it.hasNext()){ Student stu = it.next(); System.out.println(stu.name); }

2.4 修改

//可以使用间接的方式修改 boolean b = false; for (Student stu : set) { if(stu.name.equals("tom")){//找到要修改的对象 //把该对象删除 b = set.remove(stu); if(b){ break; } } } //添加要替换的新对象 set.add(new Student("汤姆"));

2.5 删除

//根据对象的属性删除,使用迭代器删除 Iterator<Student> i = set.iterator(); while(i.hasNext()){ Student stu = i.next(); if(stu.name.equals("rose")){ i.remove(); } } //删除指定对象 boolean b = set.remove(s1); System.out.println(b); //删除对个对象 Student[] stuArry = {s1,s3}; boolean b = set.removeAll(Arrays.asList(stuArry)); System.out.println(b); //清除所有元素 set.clear(); System.out.println(set.size());

3、Collection接口思维导图

4、Map集合

Map集合是一种键值对映射关系,Map中的键是唯一性的,即:键不能重复,值可以重复,一个键只能对应一个值,每个值可以有多个键;

常用方法:

  • put(K key,V value):向map集合中添加键值对,返回上一次该键对应的值,初次添加,返回null;
  • putAll(Map<k,v>):将一个Map集合添加到该Map集合中;
  • size():返回map集合中的键值对个数;
  • get(Key k):通过Key返回Value;
  • keySet():把所有的键以set集合的形式返回;
  • isEmpty():当且仅当Map集合中的个数为0时,返回true;
  • containsKey(K key):判断集合中是否包含指定的Key;
  • containsValue(V value):判断集合中是否包含指定的Value;
  • clear():清除集合中的所有键值对;
  • remove(K key):根据键删除集合中的对应键值对,返回被删除键值对的值;
  • values():返回以Collection集合的形式所有的值;
  • entrySet():把所有的键-值对,以set集合的形式返回;

添加:

Map<Integer,String> map = new HashMap<Integer,String>(); String s = map.put(1, "tom"); String s2 = map.put(2, "jack"); String s3 = map.put(3, "Lily"); String s4 = map.put(4, "Lily");

遍历:

1.使用KeySet方法遍历

//使用KeySet获得map中的所有键值对 Set<Integer> set = map.keySet(); for (Integer i : set) { String v = map.get(i); System.out.println("键:"+i+",值:"+v); }

2.使用entrySet方法遍历

//使用entrySet方法遍历 Set<Entry<Integer,String>> set = map.entrySet(); for (Entry<Integer, String> e : set) { System.out.println("键:"+e.getKey()); System.out.println("值:"+e.getValue()); }

3.使用values遍历值

//使用values方法遍历值 Collection<String> c = map.values(); Iterator<String> it = c.iterator(); while(it.hasNext()){ String v = it.next(); System.out.println("值:"+v); }

5、集合中的对象排序

实例:

Student类:

public class Student implements Comparable<Student>{ public String id; public String name; public Integer age; @Override public int compareTo(Student s) { // TODO Auto-generated method stub return id.compareTo(s.id); } }

Test类:

public static void main(String[] args) { List<Student> list = new ArrayList<Student>(); list.add(new Student("1","tom",20)); list.add(new Student("3","jack",22)); list.add(new Student("2","Lily",21)); list.add(new Student("6","hanmeimei",25)); list.add(new Student("5","Lilei",24)); //按照自然升序排序 Collections.sort(list); //反转排序 Collections.reverse(list); }

十、异常处理

1、常见的异常类

  • ArithmeticException:算术异常;
  • NullPointerException:空指针异常;
  • IndexOutOfBoundsException:下标越界异常,有两个子类,分别为:ArrayIndexOutOfBoundsException(数组下标越界)、

StringIndexOutOfBoundsException(字符串下标越界);

  • ClassCastException:类型转换异常;
  • ParseException:解析异常;
  • InputMismatchException:输入不匹配异常;

2、处理异常

2.1 使用try-catch-finally语句块捕获异常

语法:

try{ //可能会出现异常的代码,假如有异常,程序会跳转到catch语句块中 }catch(//声明要捕获的异常类){ //出现异常后要执行的代码; } finally{ //无论是否捕获到异常,始终会被执行的代码 }

Try-catch语句块可以声明多个catch语句,捕获异常的顺序是:子类在前,父类在后;

2.2 抛出异常

语法:

public void a() throws ParseException {//使用throws关键字向外抛出异常 throw new ParseException("",1);//实例化异常类,在此处抛出 }

使用throws抛出异常,该异常将会交给调用者来处理

3、自定义异常

步骤:

1) 声明一个类,继承Exception;

2) 声明自定义异常类的有参构造,将参数传给Exception的有参构造;

实例:

public class AgeBoundsException extends Exception{ //有参构造 public AgeBoundsException(String s){ super(s); } public AgeBoundsException(){ } }

4、异常链

十一、多线程

1、实现多线程

方法一:

使用Thread类实现多线程:

1) 自定义线程类,继承Thread类;

2) 重写run方法,把要执行的代码写入run方法中;

3) 实例化自定义线程类对象;

4) 调用start方法开启线程;

实例:

自定义线程类:

public class ThreadDemo1 extends Thread{ @Override public void run() { for (int f = 0; f < 1000; f++) { System.out.println("线程1:"+f); } } }

Test类:

//实例化线程类对象 ThreadDemo1 t1 = new ThreadDemo1(); t1.start();//启动线程

方法二:

使用Runnable接口实现多线程:

1) 自定义线程类,实现Runnable接口;

2) 重写run方法,把要执行的代码写入run方法中;

3) 实例化自定义线程类对象;

4) 实例化Thread类对象,把自定义线程对象传入其构造方法;

5) 使用Thread对象调用start方法,开启线程;

实例:

自定义线程类:

public class RunnableDemo1 implements Runnable{ @Override public void run() { for (int f = 0; f < 1000; f++) { System.out.println("线程1:"+f); } } }

Test类:

//实例化线程对象 RunnableDemo1 r1 = new RunnableDemo1(); RunnableDemo2 r2 = new RunnableDemo2(); //实例化Thread对象 Thread t1 = new Thread(r1); Thread t2 = new Thread(r2); //开启线程 t1.start(); t2.start();

2、线程的生命周期

3、线程控制

  • Sleep(long m):暂停当前线程多少毫秒;

@Override public void run() { for (int f = 0; f < 1000; f++) { System.out.println("线程1:"+f); if(f==500){ try { Thread.sleep(5000);//暂停当前线程3000毫秒 } catch (InterruptedException e) { e.printStackTrace(); } } } }

  • setPriority(int i):设置当前线程的优先级,范围1-10;
  • getPriority():返回当前线程的优先级;

//实例化线程对象 RunnableDemo1 r1 = new RunnableDemo1(); RunnableDemo2 r2 = new RunnableDemo2(); //实例化Thread对象 Thread t1 = new Thread(r1); Thread t2 = new Thread(r2); //设置优先级 t1.setPriority(10); t2.setPriority(1); //获得优先级 System.out.println("线程1的优先级为:"+t1.getPriority()); System.out.println("线程2的优先级为:"+t2.getPriority()); //开启线程 t1.start(); t2.start();

  • currentThread():获得当前线程对象,下面代码是用在Runnable接口的实现类中,获得当前线程对象的名称;

Thread.currentThread().getName()

如果是在Thread子类中获得当前线程对象,可以直接用this关键字;

this.getName()

  • SetName(String s):设置线程名称;
  • getName():获得线程名称;

//实例化Thread对象 Thread t1 = new Thread(r1); Thread t2 = new Thread(r2); //设置线程名称 t1.setName("线程A"); t2.setName("线程B");

4、线程同步

实例:

Bank类:

public class Bank { private double money;//余额 /** * 构造方法 * @param money 开户时存入的金额 */ public Bank(double money){ this.money = money; } /** * 取钱的方法 * @param m 要取款的金额 */ // public synchronized void getMoney(double m){//线程锁 // if(money < m){ // System.out.println("余额不足!"); // return; // } // // System.out.println(Thread.currentThread().getName()+"查看余额为"+money+"元"); // money -= m; // System.out.println(Thread.currentThread().getName()+"取款"+m+"元后,余额为"+money+"元"); // // } public void getMoney(double m){//线程锁 synchronized (this) {//this代表当前对象 if (money < m) { System.out.println("余额不足!"); return; } System.out.println(Thread.currentThread().getName() + "查看余额为" + money + "元"); money -= m; System.out.println(Thread.currentThread().getName() + "取款" + m + "元后,余额为" + money + "元"); } } }

取款线程类:

public class Qu extends Thread{ private Bank bank;//账户对象 private double money;//取款金额 public Qu(Bank bank,double money){ this.bank = bank; this.money = money; } @Override public void run() { bank.getMoney(money); } }

Test类:

public static void main(String[] args) { //创建银行账户 Bank b = new Bank(1000); //使用三种方式,在同一时间对账户取款 Qu zfb = new Qu(b,100); Qu wx = new Qu(b,100); Qu wy = new Qu(b,100); zfb.setName("支付宝"); wx.setName("微信"); wy.setName("网银"); zfb.start(); wx.start(); wy.start(); }

5、死锁

实例:

线程A:

public class A extends Thread{ private Object o1; private Object o2; public A(Object o1,Object o2){ this.o1 = o1; this.o2 = o2; } @Override public void run() { synchronized (o1) { System.out.println("线程A持有o1对象"); synchronized (o2) { System.out.println("线程A持有o1对象和o2对象"); o2.notify(); } System.out.println("线程A释放o2对象,继续持有o1对象"); } System.out.println("线程A释放o1对象和o2对象"); } }

线程B:

public class B extends Thread{ private Object o1; private Object o2; public B(Object o1,Object o2){ this.o1 = o1; this.o2 = o2; } @Override public void run() { synchronized (o2) { System.out.println("线程B持有o2对象"); try { o2.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized (o1) { System.out.println("线程B持有o1对象和o2对象"); } System.out.println("线程B释放o1对象,继续持有o2对象"); } System.out.println("线程B释放o1对象和o2对象"); } }

Test类:

public static void main(String[] args) { //创建2个对象 Object o1 = new Object(); Object o2 = new Object(); //实例化线程对象 A a = new A(o1,o2); B b = new B(o1,o2); //启动线程 a.start(); b.start(); }

十二、IO流

1、File类

常用方法:

  • exists():判断指定的目录或文件是否存在,存在返回true;
  • createNewFile():当且仅当指定文件不存在时,创建新的空文件;
  • mkdir():创建指定的目录;
  • mkdirs():创建多层级目录,包含必须的但不存的父级目录;

实例:

File f = new File("F:\\abc\\test\\demo\\hello.txt"); if(f.exists()){ System.out.println("此文件已存在"); }else{ // boolean b = f.createNewFile(); // if(b) System.out.println("文件创建成功"); boolean b = f.mkdirs(); if(b) System.out.println("目录创建成功"); }

delete():删除文件或目录,删除成功返回true;

File f = new File("F:\\temp.txt"); if(!f.exists()){//当文件不存在时,创建文件 f.createNewFile(); } for (int i = 0; i < 1000000; i++) { System.out.println(i); } f.delete();

  • getName():返回此路径下最后一个层级的文件名或目录名;
  • getParent():返回该路径表示的文件或目录的父级路径;
  • getParentFile():获得父级目录的File对象;
  • getPath():将此对象表示的路径转为字符串类型;
  • length():获得文件的大小;
  • lastModified():获取最后一次修改的时间;

实例:

//修改文件的最后操作时间 //获取指定时间的时间戳 File f = new File("F:\\hello.txt"); Calendar c = Calendar.getInstance(); c.add(Calendar.DAY_OF_MONTH, -1); long d = c.getTimeInMillis(); //修改文件 f.setLastModified(d); //时间格式化 String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(d)); System.out.println(time);

  • isDirectory():判断是否为目录;
  • isFile():判断是否为文件;
  • list():获取指定目录下的所有文件名或目录名,返回String[]类型;
  • listFiles():获取指定目录下的所有文件名或目录名,返回File[]类型;
  • renameTo(File newfile):修改该文件对象的文件名;
  • setLastModified(long time):修改文件最后一次操作的时间;
  • setWritable(boolean writable):设置文件为只读文件;

获取文件绝对路径三个方法:

  • toString();
  • getPath();
  • getAbsolutePath();

实例:

遍历指定目录下的所有文件:

public static void main(String[] args) throws IOException { File f = new File("F:\\共享"); new Demo().getFiles(f); } /** * 获取指定目录下的所有内容的绝对路径 * @param f */ public void getFiles(File f){ if(f == null){ System.out.println("不能查询空的对象"); return; } if(!f.exists()){ System.out.println("要查询的目录不存在"); return; } File[] files = f.listFiles(); for (File file : files) { if(file.isFile()){//如果该对象是文件 System.out.println(file.getPath()); } if(file.isDirectory()){//如果该对象是目录 //判断遍历出来的当前目录下是否还有内容,len=0,证明该目录下没有内容 int len = file.listFiles().length; if(len == 0){ System.err.println(file.getPath()); file.delete(); }else{ getFiles(file);//递归调用,自己调用自己 } } } }

2、RandomAccessFile

常用方法:

输入流:从硬盘文件流向内存(read)

输出流:从内存流向硬盘的文件(write)

输入流实例:

//输入流 RandomAccessFile r = new RandomAccessFile("F:\\a.txt", "rw"); byte[] arr = new byte[1024]; int len = (int) r.length(); for(int i = 0 ; i < r.length() ; i++){ r.read(arr);//使用输入流读取文件内容 } String str = new String(arr,0,len); // System.out.println(str.trim()); System.out.println(str);

输出流实例:

//输出流 RandomAccessFile w = new RandomAccessFile("F:\\a.txt", "rw"); String str = "计算机科学"; byte[] b = str.getBytes(); w.write(b);

实例:

/* * 文件复制 */ //创建流对象 RandomAccessFile r = new RandomAccessFile("F:\\abc.mp4", "rw"); RandomAccessFile w = new RandomAccessFile("E:\\abc.mp4", "rw"); //使用流传输 int i;//每次读取的字节 byte[] b = new byte[1048576]; int count = 0;//统计循环次数 while((i=r.read(b))!=-1){ //把每次读到的字节输出 w.write(b); count++; } System.out.println(count); //关闭资源 w.close(); r.close();

3、IO流

3.1 字节流

  • 字节输入流:InputStream,子类:FileInputStream

//实例化字节输入对象 FileInputStream fis = new FileInputStream("F:\\b.txt"); int count = 0; byte[] b = new byte[1024]; StringBuffer sb = new StringBuffer(); while(fis.read(b)!=-1){ String str = new String(b); sb.append(str); count++; } System.out.println(sb.toString()); System.out.println(count); //关闭资源 fis.close();

  • 字节输出流:OutputStream,子类:FileOutputStream

//创建字节输出流对象 FileOutputStream fos = new FileOutputStream("F:\\abc.txt"); String str = "许昌学院"; //把字符串转为字节数组 byte[] b = str.getBytes(); //通过流传输 fos.write(b); //关闭资源 fos.close();

3.2 字符流

  • 字符输入流:Reader,子类:InputStreamReader

//字节流对象 FileInputStream fis = new FileInputStream("F:\\abc.txt"); //实例化字符流对象 InputStreamReader isr = new InputStreamReader(fis); //每次读取1个字符 int i; while((i=isr.read())!=-1){ System.out.println((char)i); } //关闭字符流 isr.close(); fis.close();

  • 字符输出流:Writer,子类:OutputStreamWriter

//字节流对象 FileOutputStream fos = new FileOutputStream("F:\\test.txt"); //实例化字符输出流 OutputStreamWriter osw = new OutputStreamWriter(fos); //输出文本信息 // String str = "甲骨文Java"; osw.write("甲骨文Java"); //关闭资源 osw.close(); fos.close();

3.3 缓冲流

  • 缓冲输入流:BufferedReader

//字节流对象 FileInputStream fis = new FileInputStream("F:\\abc.txt"); //字符流对象 InputStreamReader isr = new InputStreamReader(fis); //缓冲输入流对象 BufferedReader br = new BufferedReader(isr); //便捷方法 // BufferedReader br = new BufferedReader(new FileReader("F:\\abc.txt")); //每次读取一行 // String s = br.readLine(); // System.out.println(s); String s; int i = 0; while((s=br.readLine())!=null){ System.out.println(s); i++; } System.out.println(i); //关闭资源 br.close(); isr.close(); fis.close();

  • 缓冲输出流:BufferedWriter

//缓冲输出流对象 BufferedWriter bw = new BufferedWriter(new FileWriter("F:\\test.txt")); //输出文本 bw.write("许昌学院\r\n甲骨文"); // bw.newLine();//行分隔符 // bw.write("甲骨文"); //关闭资源 bw.close();

3.4 序列化和反序列化(对象流)

  • 实体类:

public class Student implements Serializable{ public String name; public int age; public Student(String name, int age) { super(); this.name = name; this.age = age; } }

  • 序列化:对象输出流ObjectOutputStream

//实例化对象 Student s1 = new Student("tom",22); //把对象保存到本地,用输出流 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("F:\\mmm.aaa")); oos.writeObject(s1); oos.close();

  • 反序列化:对象输入流ObjectInputStream

//读取本地对象,使用输入流 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("F:\\mmm.aaa")); Object obj = ois.readObject(); if(obj instanceof Student){ Student stu = (Student) obj; System.out.println(stu.name+" "+stu.age); } ois.close();

十三、网络编程

1、URL类

统一资源定位符是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。

URL类实例:

//获取网络资源 URL url = new URL("http://sw.bos.baidu.com/sw-search-sp/software/1e41f08ea1bea/QQ_8.9.2.20760_setup.exe"); //打开输入流 InputStream is = url.openStream(); //获得字节输出流对象 FileOutputStream fos = new FileOutputStream("F:\\qq.exe"); double temp = 0;//统计已经下载了多少兆(M) byte[] b = new byte[20000]; int i; while((i=is.read(b))!=-1){ fos.write(b, 0, i); //把每次下载的字节累加 temp+=i; System.out.println("已经下载了:"+(temp/1024/1024)+"M"); } //关闭资源 fos.close(); is.close();

2、TCP通讯

2.1 单向单次通讯:客户端向服务器发送请求

服务器类:

//实例化服务器套接字对象 ServerSocket server = new ServerSocket(9999); System.out.println("==========服务器已启动=========="); //侦听客户端的连接 Socket socket = server.accept(); System.out.println(socket.getInetAddress()+"连接了服务器"); //接收客户端的信息 InputStream is = socket.getInputStream(); //封装为字符流 InputStreamReader isr = new InputStreamReader(is); //封装为缓冲流 BufferedReader br = new BufferedReader(isr); String mess = br.readLine(); System.out.println(mess); //关闭资源 br.close(); isr.close(); is.close(); socket.close(); server.close();

客户端类:

//实例化客户端套接字对象 Socket socket = new Socket("localhost",9999);//本地IP:127.0.0.1或localhost System.out.println("===========客户端已启动==========="); //向服务器发送信息 OutputStream os = socket.getOutputStream(); //封装为字符流 PrintWriter pw = new PrintWriter(os); pw.write("服务器,你好"); pw.flush();//刷新 //关闭资源 pw.close(); os.close(); socket.close();

2.2 双向单次通讯:客户端请求,服务器响应

服务器类:

//实例化服务器套接字对象 ServerSocket server = new ServerSocket(9999); System.out.println("==========服务器已启动=========="); //侦听客户端的连接 Socket socket = server.accept(); System.out.println(socket.getInetAddress()+"连接了服务器"); //接收客户端的信息 InputStream is = socket.getInputStream(); //封装为字符流 InputStreamReader isr = new InputStreamReader(is); //封装为缓冲流 BufferedReader br = new BufferedReader(isr); String mess = br.readLine(); System.out.println(mess); //向客户端响应 Scanner sc = new Scanner(System.in); System.out.println("向客户端发送信息:"); String message = sc.next(); OutputStream os = socket.getOutputStream(); //封装为字符流 PrintWriter pw = new PrintWriter(os); pw.write(message); pw.flush();//刷新 //关闭资源 pw.close(); os.close(); br.close(); isr.close(); is.close(); socket.close(); server.close();

客户端类:

// 实例化客户端套接字对象 Socket socket = new Socket("localhost", 9999);// 本地IP:127.0.0.1或localhost System.out.println("===========客户端已启动==========="); Scanner sc = new Scanner(System.in); System.out.println("向服务器发送信息:"); String message = sc.next(); // 向服务器发送信息 OutputStream os = socket.getOutputStream(); // 封装为字符流 PrintWriter pw = new PrintWriter(os); pw.write(message); pw.flush();// 刷新 //关闭socket中的输出流 socket.shutdownOutput(); // 接收服务器响应信息 InputStream is = socket.getInputStream(); // 封装为字符流 InputStreamReader isr = new InputStreamReader(is); // 封装为缓冲流 BufferedReader br = new BufferedReader(isr); String mess = br.readLine(); System.out.println(mess); // 关闭资源 br.close(); isr.close(); is.close(); pw.close(); os.close(); socket.close();

十四、Java的反射机制

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

  • 静态加载类:在程序编译期加载;
  • 动态加载:在程序的运行期加载;

所有类都是Class类的实例(对象),所有的属性都是Field类的实例,所有的方法都是Method类的实例。

1、类的反射

实例:

//动态加载类,Class是表示当前类的类类型 Class c = Class.forName("com.oracle.test.Demo"); IDemo d = (IDemo) c.newInstance(); d.a(); //静态加载 Demo d2 = new Demo(); d2.a();

获得Class实例的三种方法:

/** * 类的反射 */ // 方法一,通过对象获得Class类类型 Demo d = new Demo(); Class c1 = d.getClass(); // 方法二,通过类名获得Class类类型 Class c2 = Demo.class;//每个类都有一个隐含的静态属性class // 方法三,通过动态加载 Class c3 = null; try { c3 = Class.forName("com.oracle.test.Demo"); } catch (ClassNotFoundException e) { e.printStackTrace(); } // 三个对象相等 System.out.println(c1 == c2); System.out.println(c2 == c3); System.out.println(c3 == c1); // 通过Class类类型获得类的实例 Demo d1 = (Demo) c1.newInstance(); Demo d2 = (Demo) c2.newInstance(); Demo d3 = (Demo) c3.newInstance(); // 三个对象不相等 System.out.println(d1 == d2); System.out.println(d2 == d3); System.out.println(d3 == d1);

2、获取类的信息

//动态加载类,Class是表示当前类的类类型 Class c = Class.forName("com.oracle.test.Demo"); /** * 获得类的属性和方法信息 */ //获得所有的属性 // Field[] fs = c.getFields();//获得所有的公开的属性,自己的和继承父类的 Field[] fs = c.getDeclaredFields();//获得自己所有的属性,不限访问权限 for (Field f : fs) { System.out.print(f.getType()+" ");//获得属性的类型 System.out.println(f.getName());//获得属性名称 } //获得所有的方法 // Method[] ms = c.getMethods();//获得所有公开的方法,自己的和父类的 Method[] ms = c.getDeclaredMethods();//获得自己的所有方法,不限访问权限 for (Method m : ms) { System.out.print(m.getReturnType()+" ");//获得方法返回值类型 System.out.print(m.getName()+"(");//获得方法名 Class[] cs = m.getParameterTypes();//获得参数类型 for (Class cl : cs) { System.out.print(cl.getName()+","); } System.out.println(")"); }

3、方法的反射

public class Test3 { @SuppressWarnings("unchecked") public static void main(String[] args) throws Exception { /** * 方法的反射 */ //获得类的类类型 // Class c = A.class; A a = new A(); Class c = a.getClass(); //调用getMethod方法 // Method m = c.getMethod("print", String.class); // c.getMethod("print", new Class[]{int.class,int.class}); Method m = c.getMethod("print", int.class,int.class); //通过invoke方法调用对象的方法,有返回值时返回具体内容,无返回值时返回null // Object o = m.invoke(a, "hello"); // m.invoke(c.newInstance(), 2,2); Object o = m.invoke(a, 1,2); System.out.println(o); } } class A{ public void print(int i,int j){ System.out.println(i+j); } public String print(String s){ return s; } }

十五、泛型

Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。

泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

使用Java反射来解释集合的泛型:

//集合中的泛型是在编译期对代码的约束 List<String> list = new ArrayList<String>(); list.add("hello"); list.add("world"); //通过反射机制,绕过编译,往集合中添加Integer类型的值 Class c = list.getClass(); //获得add方法的对象 Method m = c.getMethod("add", Object.class); //调用add方法,添加Integer元素1 m.invoke(list, 1); //集合长度 System.out.println(list.size()); System.out.println(list); //遍历 for (String string : list) { System.out.println(string); }

1、方法的泛型

//语法:在方法返回类型前声明泛型的标识 public <E> void method(E i){ }

2、类和接口的泛型

public class Person<T extends Number> { //成员变量 private T a;//a是<T>类型的一个成员变量,T就是泛型的表现形式 //成员方法 public void setA(T a){ this.a = a; } public T getA(){ return a; } //类上声明的泛型不能作用在静态方法上 public static <E> void abc(E a){ } }

3、通配符

//类型通配符一般是使用?代替具体的类型参数 public void method(List<? extends Number> list){ }

十六、枚举

1、枚举的语法

枚举声明

public enum Color { RED,BLUE,WHITE,BLACK,GREEN; }

枚举的遍历

//使用foreach遍历枚举 for (Color c : Color.values()) { // System.out.println(c.toString()); System.out.println(c.name()); } //使用switch遍历枚举 Color c = Color.RED; switch(c){ case RED: System.out.println("红色"); break; case BLUE: System.out.println("蓝色"); break; …… }

2、常用方法

Color c = Color.BLACK; System.out.println("常量名:"+c.name());//等同toString()方法 System.out.println("序号:"+c.ordinal());//从0开始

3、自定义枚举属性和方法

public enum Color { RED("红色",1),BLUE("蓝色",2),WHITE("白色",3),BLACK("黑色",4),GREEN("绿色",5); private String name; private int id; public String getName() { return name; } public int getId() { return id; } private Color(String name, int id) { this.name = name; this.id = id; } }

4、EnumSet和EnumMap的用法

EnumSet用法

//添加 EnumSet<Color> set = EnumSet.allOf(Color.class); //遍历 for (Color c : set) { System.out.println(c.getId()+"."+c.getName()); }

EnumMap用法

//实例化EnumMap对象 EnumMap<Color, String> map = new EnumMap(Color.class); //添加 map.put(Color.RED, "红色代表热情"); map.put(Color.WHITE, "白色代表纯洁"); //遍历 Set<Color> s = map.keySet(); for (Color color : s) { String mess = map.get(color); System.out.println(mess); }

十七、注解

1、常见注解

JDK自带注解

@Override:重写

@Deprecated:过时的方法

@SuppressWarnings(“”):忽略警告

2、注解的分类

2.1 按照运行机制分

源码注解:注解只在源码中存在,编译成.class文件就不存在了;

编译时注解:注解在源码和.class文件中都存在;

运行时注解:在运行阶段还起作用,甚至会影响运行逻辑的注解;

2.2 按照来源分

JDK注解

第三方注解

自定义注解

元注解:给注解进行注解的注解

3、自定义注解

3.1 自定义注解语法

/** * 元注解 */ //注解的作用域 @Target({ElementType.METHOD,ElementType.TYPE}) //注解的生命周期 @Retention(RetentionPolicy.RUNTIME) //允许子类继承,只有用在类上时才会生效,对接口无效 @Inherited //生成javadoc时会包含注解 @Documented public @interface Test { /** * 1.成员类型是受限制的,合法的类型包括: * 原始类型及String,Class,Annotation,Enumeration; * 2.如果注解只有一个成员,则成员名必须取名为value(),在使用 * 时可以省略成员名和赋值的“=”号; * 3.注解类可以没有成员,没有成员的注解称为标识注解; */ //value(); //成员以无参无异常的方式声明 String desc(); String author(); //可以用default为成员指定一个默认值 int age() default 18; }

3.2 使用自定义注解

使用注解的语法:

@<注解名>(成员=值,成员=值,……)

实例:

@Test(desc="",author="",age=18) public void demo(){ }

4、解析注解

4.1 获得类上的注解

//获得对象类类型 Class c = Demo.class; //获得类上面的注解 boolean b = c.isAnnotationPresent(Test.class); if(b){ //获得注解对象 Test t = (Test) c.getAnnotation(Test.class); //打印注解成员的值 System.out.println(t.desc()); System.out.println(t.author()); System.out.println(t.age()); }

4.2 获得方法上的注解

//获得类中的所有方法对象 Method[] ms = c.getMethods(); for (Method m : ms) { boolean is = m.isAnnotationPresent(Test.class); if(is){ //获得方法上的注解 Test mt = m.getAnnotation(Test.class); System.out.println(mt.desc()); System.out.println(mt.author()); System.out.println(mt.age()); } }

方法二

//方法二 for (Method m : ms) { Annotation[] as = m.getAnnotations(); for (Annotation a : as) { if(a instanceof Test){ Test t = (Test) a; System.out.println(t.desc()); System.out.println(t.author()); System.out.println(t.age()); } } }

十八、配置文件操作

1、XML文件

(1)使用pull方式解析

//1.创建解析工厂对象 XmlPullParserFactory xmlFactory = XmlPullParserFactory.newInstance(); //2.获得解析器对象 XmlPullParser xmlParser = xmlFactory.newPullParser(); //3.指定资源路径 FileReader fr = new FileReader("F:\\book.xml"); xmlParser.setInput(fr); int event = xmlParser.getEventType(); while(event != END_DOCUMENT){ switch(event){ case START_DOCUMENT://文档开始 System.out.println("=====开始解析文档======"); break; case START_TAG://标签开始 String tagname = xmlParser.getName();//获得标签名称 switch(tagname){ case "name": String name = xmlParser.nextText(); System.out.println(name); break; case "jiage": String jiage = xmlParser.nextText(); System.out.println(jiage); break; case "zz": String zz = xmlParser.nextText(); System.out.println(zz); break; case "cb": String cb = xmlParser.nextText(); System.out.println(cb); break; } break; case END_TAG://标签结束 tagname = xmlParser.getName(); System.out.println("======文档解析结束======="); break; } event = xmlParser.next();//获取下一个事件 }

(2)使用pull方式写入

//1.创建解析工厂 XmlPullParserFactory xmlFactory = XmlPullParserFactory.newInstance(); //2.创建序列化对象 XmlSerializer xmls = xmlFactory.newSerializer(); //3.指定文件资源 FileWriter fw = new FileWriter("F:\\stu.xml"); xmls.setOutput(fw); xmls.startDocument("utf-8", false);//生成xml文档头信息 xmls.startTag(null, "student");//student标签开始 xmls.startTag(null, "id");//id标签开始 xmls.text("1234");//文本内容 xmls.endTag(null, "id");//id标签结束 xmls.endTag(null, "student");//student标签结束 xmls.endDocument();//文档结束

2、json文件

(1)使用gson方式解析

//1.实例化解析对象 JsonParser jp = new JsonParser(); //2.读取要解析的json文件 FileReader fr = new FileReader("F:\\stu.json"); //3.解析json文件 JsonObject jo = (JsonObject) jp.parse(fr); System.out.println("姓名:"+jo.get("name").getAsString()); System.out.println("年龄:"+jo.get("age").getAsDouble()); System.out.println("是否有车:"+jo.get("car").getAsBoolean()); //获取数组 JsonArray jarr = jo.get("hobby").getAsJsonArray(); for (int i = 0; i < jarr.size(); i++) { JsonObject j = (JsonObject)jarr.get(i); System.out.println("id:"+j.get("id").getAsString()); }

(2)写入json文件

//1.创建json对象 JsonObject jo = new JsonObject(); //2.添加键值对 jo.addProperty("name", "张三"); jo.addProperty("age", 20); jo.addProperty("car", true); JsonObject hobby1 = new JsonObject();//数组中的第1个元素 hobby1.addProperty("id", "java"); JsonObject hobby2 = new JsonObject();//数组中的第2个元素 hobby2.addProperty("id", "php"); JsonArray ja = new JsonArray();//数组对象 ja.add(hobby1); ja.add(hobby2); jo.add("hobby", ja);//把数组对象添加到json的hobby属性中 //3.保存到json文件 FileOutputStream fos = new FileOutputStream("F:\\abc.json"); fos.write(jo.toString().getBytes()); fos.close();

3、properties文件

(1)解析properties

//1.实例化properties对象 Properties prop = new Properties(); //2.获得属性文件 FileInputStream fis = new FileInputStream("F:\\stu.properties"); //3.使用属性对象的load()方法获取内容 prop.load(fis); //4.根据键获得值 String name = prop.getProperty("userName"); System.out.println(name); String pwd = prop.getProperty("pwd"); System.out.println(pwd); //5.关闭资源 fis.close();

(2)写入properties

//1.创建properties对象 Properties prop = new Properties(); //2.指定输出文件 FileOutputStream fos = new FileOutputStream("F:\\stu.properties"); //3.设置要输出的属性 prop.setProperty("userName", "java456"); prop.setProperty("pwd", "abc123"); //4.保存文件 prop.store(fos, "abc"); //5.关闭资源 fos.close();

十九、发送邮件

1、jar包下载

下载地址:http://download.csdn.net/detail/p445098355/9865646

2、代码实现

import javam.util.sendmail.MailEntity; import javam.util.sendmail.SendMailUtility; String to = "";//收件人邮箱 String from = "";//发件人邮箱 String host = "";//SMTP邮件发送服务器 String userName = "";//发件人邮箱地址 String password = "";//发件人邮箱登录密码 String title = "";//邮件的标题 String info = "";//邮件正文内容 // 实例化邮件主体信息类对象 MailEntity mail = new MailEntity(to, from, host, userName, password); // 实例化邮件发送功能类对象 SendMailUtility send = SendMailUtility.getInstance(); // 调用发送邮件方法,邮件发送成功返回true boolean rel = send.sendMessage(mail, title, info);

二十、设计模式

1、单例模式

1.1 饿汉模式

是在类加载的时机创建对象。

实例:

public class TimeUtil { //1.创建私有的构造方法 private TimeUtil(){ } //2.声明公开的静态对象属性 private static TimeUtil instance = new TimeUtil(); //3.提供公开的get方法,获得单例对象 public static TimeUtil getInstance(){ return instance; } }

1.2 懒汉模式

是在程序执行过程中需要得到一个对象时,才创建对象。

实例:

public class TimeUtil { //1.创建私有的构造方法 private TimeUtil(){ } //2.声明公开的静态对象属性 // private static TimeUtil instance = new TimeUtil(); private static TimeUtil instance ; //3.提供公开的get方法,获得单例对象 public static TimeUtil getInstance(){ if(instance==null){ instance = new TimeUtil(); } return instance; } }

1.3 区别

  • 对象创建的时机不同,一个是类加载时创建对象,另一个是在需要时创建对象;
  • 饿汉模式,加载速度比较慢,获得对象速度比较快,是线程安全的;
  • 懒汉模式,加载速度比较快,获得对象的速度比较慢,是线程不安全的;

2、工厂模式

概念:把创建对象的过程封装为一个方法,工厂方法模式。

实例

  • 发型接口:

public interface IHair { //更换发型 public void change(); }

  • 具体发型实现类(以左偏分为例):

public class LeftHair implements IHair { @Override public void change() { System.out.println("左偏分。。。。。。"); } }

  • 工厂类:

public class HairFactory { public static IHair getHairByClassKey(String key){ //读取配置文件的内容 Map<String,String> map = new ReaderProp().reader(); try { Class c = Class.forName(map.get(key)); IHair ih = (IHair) c.newInstance(); return ih; } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; } }

  • 属性文件:

left=com.oracle.test2.LeftHair right=com.oracle.test2.RightHair center=com.oracle.test2.CenterHair

  • 属性文件读取类:

public class ReaderProp { //用来读取配置文件信息的方法 public Map<String,String> reader(){ Properties prop = new Properties(); Map<String,String> map = new HashMap<String,String>(); try { prop.load(new FileInputStream("hair.properties")); Enumeration en = prop.propertyNames();//获得属性文件中所有键的枚举 while(en.hasMoreElements()){ String key = (String) en.nextElement(); String value = prop.getProperty(key); map.put(key, value); } return map; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } }

  • 客户端实现:

IHair ih = HairFactory.getHairByClassKey("left"); ih.change();

附:JavaSE知识点汇总

https://www.cnblogs.com/almm/p/11637457.html

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券