java基础
Java学习总结
一、Java基础学习
1、变量与数据类型
1.1、变量的含义
变量就是内存中一块临时存放数据的区域。
1.2、变量的命名规则
- 变量名由字母、数字、下划线、$这四种字符组成。
- 变量名的首字符不能是数字
- 变量名是区分大小写字母
- 变量名不能是java关键字或保留字
1.3、变量的命名规范
- 使用驼峰式命名
- 望文生义
- 写详细注释
1.4、java的八种基本数据类型
整型:byte、short、int、long
数据类型 | 占字节数 | 大小/位 | 数据范围 |
---|---|---|---|
byte(字节型) | 1 | 8 | -128~127 |
short(短整型) | 2 | 16 | -32768~32767 |
int(整型) | 4 | 32 | -2147483648~2147483647 |
long(长整型) | 8 | 64 | -9223372036854775808~9223372036854775807 |
/**
*八种基本数据类型:byte、short、int、long、float、double、char、boolean
* 1、整型:
* byte:字节型、占1个字节、8位
* short:短整型、占2个字节、16位
* int:整型、占4个字节、32位
* long:长整型、占8个字节、64位
*/
public static void main(String[] args) {
//byte:-128~127
byte b = 10;
byte byteMaxValue = Byte.MAX_VALUE;
byte byteMinValue = Byte.MIN_VALUE;
System.out.println("byteMaxValue = " + byteMaxValue);
System.out.println("byteMinValue = " + byteMinValue);
System.out.println("------------------------------");
//short:-32768~32767
short s = 121;
short shortMaxValue = Short.MAX_VALUE;
short shortMinValue = Short.MIN_VALUE;
System.out.println("shortMaxValue = " + shortMaxValue);
System.out.println("shortMinValue = " + shortMinValue);
System.out.println("------------------------------");
//int:-2147483648~2147483647
int i =10;
int intMaxValue = Integer.MAX_VALUE;
int intMinValue = Integer.MIN_VALUE;
System.out.println("intMaxValue = " + intMaxValue);
System.out.println("intMinValue = " + intMinValue);
System.out.println("------------------------------");
//long:-9223372036854775808~9223372036854775807
long l = 123L;
long longMaxValue = Long.MAX_VALUE;
long longMinValue = Long.MIN_VALUE;
System.out.println("longMaxValue = " + longMaxValue);
System.out.println("longMinValue = " + longMinValue);
}
浮点型:float、double
数据类型 | 占字节数 | 大小/位 | 精确度 |
---|---|---|---|
float(单精度) | 4 | 32 | 7位有效数字 |
double(双精度) | 8 | 64 | 15位有效数字 |
/**
* float 单精度浮点类型 占4个字节 精确度为7位
*/
@Test
public void test02(){
//1.java中的小数类型都是double类型,如果直接写float f = 3.14会报错。
float f1 = 3.14f;//第一种解决办法:在数字后面加上f
float f2 = (float) 3.14;//第二种解决办法:将double类型转换为float类型
//2.float精确度(精确度为7位)
float f3 = 5.332326231115325325155215f;
System.out.println("f3 = " + f3);
//3.进行运算
int a = 2;
float b = 3.14f;
float c = a+b;
System.out.println("c = " + c);
}
/**
* double 双精度浮点类型 占8个字节 精确度为15位
*/
@Test
public void test03(){
//1、声明一个变量,输出的值精确到15位
double d = 5.332326231115325325155215;
System.out.println("d = " + d);
//2.进行运算
long l = 10L;
double d1 = 3.14;
double d2 = l + d1;
}
字符型:char
数据类型 | 占字节数 | 大小/位 |
---|---|---|
char(字符型) | 2 | 16 |
编码 | 范围 |
---|---|
大写字母(A-Z) | 65~90 |
小写字母(a-z) | 97~122 |
数字(0-9) | 48~57 |
/**
* char 占两个字节 :键盘上的每一种字符都对应一个数字
* a-z:97-122
* A-Z:65-90
* 0-9:48-57
*/
@Test
public void test05(){
//1.声明一个字符型变量
char ch = '中';//一个中文占两个字符
System.out.println("ch = " + ch);
//2.声明一个字母型变量
char c1 = 'A';
System.out.println("c1 = " + (int)c1);
}
布尔型:boolean
/**
* boolean:true,false
*/
@Test
public void test04(){
//1.声明一个boolean型变量
boolean b = true;
System.out.println("b = " + b);
//2.取反
b = !b;
System.out.println("b = " + b);
}
2、运算符与表达式
2.1、算术运算符
双目运算符(+ – * / %)
/**
* 双目运算符
*/
@Test
public void test01() {
int a = 10, b = 4;
int e = a + b;
int f = a - b;
int g = a * b;
int h = a / b;
int i = a % b;
System.out.println("e = " + e);
System.out.println("f = " + f);
System.out.println("g = " + g);
System.out.println("h = " + h);
System.out.println("i = " + i);
}
单目运算符(++ –)
/**
* 单目运算符
* a++:先取值后自增
* ++a:先自增后取值
*/
@Test
public void test02() {
//1.1、定义两个变量
int a = 1;
int b;
//1.2、++运算符用法
//1.2.1、前加
//1.2.1.1、单独使用
++a;
System.out.println("a = " + a);
//1.2.1.2、与表达式一起使用
b = ++a;
System.out.println("a = " + a + ",b = " + b);
//1.2.2、后加
//1.2.2.1、单独使用
a++;
System.out.println("a = " + a);
//1.2.2.2、与表达式一起使用
b = a++;
System.out.println("a = " + a + ",b = " + b);
//1.3、--运算符
//1.3.1、前减
//1.3.1.1、单独使用
--a;
System.out.println("a = " + a);
//1.3.1.2、与表达式一起使用
b = --a;
System.out.println("a = " + a + ",b = " + b);
//1.3.2、后减
//1.3.2.1、单独使用
a--;
System.out.println("a = " + a);
//1.3.2.2、与表达式一起使用
b = a--;
System.out.println("a = " + a + ",b = " + b);
}
自增和自减
- ++变量、–变量:先进行变量的自增或自减,再使用该变量参与运算。
- 变量++、变量–:先用该变量参与运算,再进行自增或自减
2.2、关系运算符(> >= < <= == !=)
@Test
public void test01() {
//1、定义几个变量
int a = 10, b = 5, c = 6, d = 5;
//2、判断
boolean b1 = a > b;
boolean b2 = c < d;
boolean b3 = b == d;
System.out.println("b1 = " + b1);
System.out.println("b2 = " + b2);
System.out.println("b3 = " + b3);
}
2.3、逻辑运算符(!& && | ||)
/**
* 逻辑与(&&):代表参与运算的表达式需要同时为true,整个表达式才成立
*/
@Test
public void test01() {
//1.1定义几个变量
int a = 10, b = 5, c = 4, d = 3;
//1.2逻辑与的一般用法:参与运算的多个表达式都成立,整个表达式才成立。
if (a++ > --b && c-- > d++) { //a=10,b=4,c=4,d=3;true&&true
System.out.println("a = " + a + ",b = " + b + ",c = " + c + ",d = " + d); //a=11,b=4,c=3,d=4
}
//1.3逻辑与的短路用法:参与运算的表达式只要有一个为false,其后面的表达式就不需要执行了
if (a++ < --b && c-- > d++) { //a=12,b=3,c=2,d=5;
}
System.out.println("a = " + a + ",b = " + b + ",c = " + c + ",d = " + d);
}
/**
* 逻辑或(||):代表参与运算的表达式需要同时为false,整个表达式才成立
*/
@Test
public void test02() {
//1.1定义几个变量
int a = 10, b = 5, c = 4, d = 3;
//1.2逻辑或的一般用法:参与运算的多个表达式都成立,整个表达式才成立。
if (a++ < b-- || c++ > d--) {
System.out.println("a = " + a + ",b = " + b + ",c = " + c + ",d = " + d); //a=11,b=4,c=5,d=2
}
//1.3逻辑或的短路用法:参与运算的表达式只要有一个为true,其后面的表达式就不需要执行了
if (a++ > b-- || c++ < d--) {
}
System.out.println("a = " + a + ",b = " + b + ",c = " + c + ",d = " + d); //a=12,b=3,c=5,d=2
}
/**
* 逻辑非(!)
*/
@Test
public void test03() {
boolean b = true;
System.out.println("b = " + b);
b = !b;
System.out.println("b = " + b);
}
2.4、赋值运算符(= += -= *= /= %=)
@Test
public void test01(){
int a = 10;
a += 3;
System.out.println("a = " + a); //a=a+3
a -= 5;
System.out.println("a = " + a); //a=a-5
a *= 4;
System.out.println("a = " + a); //a=a*4
a /= 3;
System.out.println("a = " + a); //a=a/3
a %= 2;
System.out.println("a = " + a); //a=a%2
}
2.5、运算符的优先级
运算符的优先级:
① ( )
② ++ — !
算术运算符
③ * / %
④ + –
关系运算符
⑤ > >= < <= == !=
逻辑运算符
⑥ &&
⑦ ||
赋值运算符
⑧ = += -= *= /= %=
3、if条件结构
3.1、简单if语句
/**
* 功能:简单if条件结构
* 时间:2021/12/8 14:35
*/
@Test
public void test01() {
//1、定义两个变量
int a = 10, b = 4;
//2、判断
if (a > b) {
System.out.println("a > b");
}
}
3.2、if…else条件结构
/**
* 功能:if...else条件结构
* 时间:2021/12/8 14:37
*/
@Test
public void test02() {
//1、得到当前时间的小时数
int hour = LocalDateTime.now().getHour();
//2、判断
if (hour > 10) {
System.out.println("上午好");
} else {
System.out.println("早上好");
}
//3、使用三元表达式
System.out.println(hour > 10 ? "上午好" : "早上好");
}
3.3、if…else if…else if…else多重if结构
/**
* 功能:if...else if...else结构
* 案例:根据学生成绩打印评分
* 时间:2021/12/8 14:42
*/
@Test
public void test03() {
//1、定义学生成绩
int score = 56;
//2、根据成绩的范围进行评分的判断
if (score >= 90) {
System.out.println("优秀");
} else if (score >= 80) {
System.out.println("良好");
} else if (score >= 70) {
System.out.println("一般");
} else if (score >= 60) {
System.out.println("及格");
} else {
System.out.println("不及格");
}
}
4、Switch…case多分支选择结构
4.1、案例一:输入一个字母判断是不是元音字母
private static void test01(Scanner scanner) {
//1、输入提示信息并获取输入的信息
System.out.println("请输入一个字母:");
String next = scanner.next();
//2、对输入的值进行判断
switch (next) {
case "a":
System.out.println("a是一个元音字母");
break;
case "e":
System.out.println("e是一个元音字母");
break;
case "i":
System.out.println("i是一个元音字母");
break;
case "o":
System.out.println("o是一个元音字母");
break;
case "u":
System.out.println("u是一个元音字母");
break;
default:
System.out.println(next + "不是一个元音字母");
}
}
4.2、案例二:根据输入的月份数,打印对应的天数!
private static void test03(Scanner scanner) {
//1、输入提示信息并获取对应的值
System.out.println("请输入一个月份数:");
int month = scanner.nextInt();
int days = 0;
//2、根据输入的月份进行判断
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
days = 31;
break;
case 4:
case 6:
case 9:
case 11:
days = 30;
break;
case 2:
days = 28;
break;
default:
System.out.println("月份只能在1~12月份之间");
break;
}
System.out.println(month + "月有" + days + "天");
}
4.3、案例三:根据输入的学生成绩打印评语
private static void test04(Scanner scanner) {
//1、输入提示信息并获取对应的值
System.out.println("请输入学生的成绩:");
int score = scanner.nextInt();
//2、对获取的值分区间判断
switch (score / 10) {
case 9:
System.out.println("优秀");
break;
case 8:
System.out.println("良好");
break;
case 7:
System.out.println("一般");
break;
case 6:
System.out.println("及格");
break;
default:
System.out.println("不及格");
break;
}
}
5、while、do…while与for循环
5.1、while循环:先判断后执行
案例一:打印10遍 “hello,world”
/**
* 功能:案例一:打印10遍 "hello,world"
* 时间:2021/12/8 15:31
*/
@Test
public void test01() {
int i = 1;
while (i <= 10) {
System.out.println("hello,world");
i++;
}
}
案例二:求 1-100 之间所有数字之和
/**
* 功能:案例二:求 1-100 之间所有数字之和
* 时间:2021/12/8 15:34
*/
@Test
public void test02() {
//1、定义一个循环初始变量
int i = 1;
//2、求和变量初始化
int sum = 0;
//3、求和
while (i <= 100) {
sum += i;
i++;
}
//4、输出
System.out.println("sum = " + sum);
}
案例三:输出1-100之间所有奇数并且每5个一换行?
/**
* 功能:案例三:输出1-100之间所有奇数并且每5个一换行?
* 分析:
* (1)先筛选出1~100之间的所有奇数:i%2==1
* (2)对筛选出的所有奇数进行统计
* (3)每5个一换行:count%5==0
* 时间:2021/12/8 15:38
*/
@Test
public void test03() {
//1、初始化循环变量
int i = 1;
//2、初始化计数变量
int count = 0;
//3、循环判断
while (i <= 100) {
if (i % 2 == 1) {
System.out.print(i + "\t");
count++;
if (count % 5 == 0) {
System.out.println();
}
}
i++;
}
}
案例四:输出1-1000之间所有个位数为3且能被7整除的数字之和,每3个一换行?
/**
* 功能:案例四:输出1-1000之间所有个位数为3且能被7整除的数字之和,每3个一换行?
* 分析:
* (1)先筛选出1~1000之间所有个位数为3且能被7整除的数字之和:i%10==3 && i%7==0
* (2)每3个一换行:count%3==0
* 时间:2021/12/8 15:41
*/
@Test
public void test04() {
//1、初始化循环变量
int i = 1;
//2、初始化计数变量、求和变量
int count = 0, sum = 0;
//3、循环判断
while (i <= 1000) {
if (i % 10 == 3 && i % 7 == 0) {
System.out.print(i + "\t");
sum += i;
count++;
if (count % 3 == 0) {
System.out.println();
}
}
i++;
}
System.out.println("\nsum = " + sum);
}
5.2、do…while循环:先执行后判断
案例一:找到10个整数中的最大值并输出?
/**
* 功能: 案例二:找到10个整数中的最大值并输出?
* 分析:
* (1)初始化最大值
* (2)循环输入10个数
* (3)最大值和每一个整数进行比较
* (4)输出最大值
* 时间:2021/12/9 11:19
*/
private static void test02(Scanner scanner) {
//1、初始化最大值
int maxNum = 0;
//2、循环输入10个数
int i = 1;
do {
System.out.print("请输入第" + i + "个数:");
int num = scanner.nextInt();
//3、使用if语句对输入的每一个值跟最大值进行比较
if (num > maxNum) {
maxNum = num;
}
i++;
} while (i <= 10);
//4、输出最大值
System.out.println("最大值:" + maxNum);
}
案例二:输出超市管理系统的菜单项?
/**
* 功能:案例三:输出超市管理系统的菜单项?
* 时间:2021/12/9 11:35
*/
private static void test03(Scanner scanner) {
//打印主菜单
showMenu();
//用户选择操作菜单
userSelect(scanner);
}
//主菜单
private static void showMenu() {
System.out.println("===============南山超市管理系统===============");
System.out.println("[1]添加商品");
System.out.println("[2]修改商品");
System.out.println("[3]删除商品");
System.out.println("[4]查看商品");
System.out.println("[5]退出系统");
System.out.println("===========================================");
}
//用户选择
private static void userSelect(Scanner scanner) {
//定义是否选择的变量
String inCon = "y";
//循环
do {
System.out.print("请选择菜单:");
int choice = scanner.nextInt();
//对输入的选择进行判断
switch (choice) {
case 1:
System.out.println("添 加 商 品");
break;
case 2:
System.out.println("修 改 商 品");
break;
case 3:
System.out.println("删 除 商 品");
break;
case 4:
System.out.println("查 看 商 品");
break;
case 5:
System.exit(0);
break;
}
System.out.print("\n是否继续(y/n):");
inCon = scanner.next();
} while (inCon.equalsIgnoreCase("y"));
System.out.println("\n程序结束!");
}
5.3、while循环与do…while循环的区别
(1)while循环:先判断后循环,如果循环的条件不成立一次也不会执行 (2)do...while循环:先循环后判断,如果循环的条件不成立也会执行一次
5.4、for循环
案例一:打印1-100之间所有整数之和
/**
* 功能:案例一:打印1-100之间所有整数之和
* 时间:2021/12/9 11:58
*/
@Test
public void test01() {
//定义求和变量并初始化
int sum = 0;
//循环
for (int i = 1; i <= 100; i++) {
sum += i;
}
System.out.println("1-100之间所有整数之和为:" + sum);
}
案例二:输出1-1000之间即能被3又能被7整除的整数,每五个一换行。
/**
* 功能:案例二:输出1-1000之间即能被3又能被7整除的整数,每五个一换行。
* 分析:
* (1)先筛选出1~1000之间即能被3又能被7整除的整数:i%3==0 && i%7==0
* (2)每5个一换行:count%5==0
* 时间:2021/12/9 11:59
*/
@Test
public void test02() {
//定义一个计数变量
int count = 0;
//循环
for (int i = 1; i <= 1000; i++) {
if (i % 3 == 0 && i % 7 == 0) {
System.out.print(i + "\t");
count++;
if (count % 5 == 0) {
System.out.println();
}
}
}
}
案例三:输入10个字符,判断其中数字和字母的个数?
/**
* 功能:案例三:输入10个字符,判断其中数字和字母的个数?
* 方法一:每次输入一个字符,以空格或回车作为结束符号!
* 时间:2021/12/9 12:00
*/
private static void test03(Scanner scanner) {
//1、定义计数器
int m = 0, n = 0;
//2、输入10个字符
System.out.println("请输入10个字符:");
for (int i = 0; i < 10; i++) {
char ch = scanner.next().charAt(0);
if (ch >= '0' && ch <= '9') { //数字
m++;
}
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) { //字母
n++;
}
}
System.out.println("10个字符中数字的个数:" + m);
System.out.println("10个字符中字母的个数:" + n);
}
/**
* 功能:案例三:输入10个字符,判断其中数字和字母的个数?
* 方法二:一次性输入一个字符串!
* 时间:2021/12/9 12:00
*/
private static void test04(Scanner scanner) {
//定义计数器
int m = 0, n = 0;
//输入信息
System.out.println("请输入10个字符:");
String str = scanner.next();
//循环输出
for (int i = 0; i < 10; i++) {
char ch = str.charAt(i);
//统计出现数字的个数
if (ch >= '0' && ch <= '9') {
m++;
}
//统计出现字母的个数
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
n++;
}
}
System.out.println("10个字符中数字的个数:" + m);
System.out.println("10个字符中字母的个数:" + n);
}
案例四:求给定数字的阶乘?
/**
* 功能:案例四:求给定数字的阶乘?
* 分析:例如:5!=5x4x3x2x1
* 时间:2021/12/9 12:00
*/
private static void test05(Scanner scanner) {
//定义一个阶乘结果变量
long fax = 1;
//输入提示信息
System.out.println("请输入一个整数:");
int num = scanner.nextInt();
for (int i = 1; i <= num; i++) {
fax *= i;
}
//输出信息
System.out.println(num + "的阶乘为:" + fax);
}
5.5、嵌套for循环
案例一:打印直角三角形
/**
* 功能:案例一:打印直角三角形
* 时间:2021/12/9 14:30
*/
@Test
public void test01() {
//打印行数
for (int i = 1; i <= 5; i++) {
//打印*数
for (int j = 1; j <= i; j++) {
System.out.print("* ");
}
//换行
System.out.println();
}
}
案例二:打印九九乘法表
/**
* 功能:案例二:打印九九乘法表
* 时间:2021/12/9 14:34
*/
@Test
public void test02() {
//打印行数
for (int i = 1; i <= 9; i++) {
//打印列数
for (int j = 1; j <= i; j++) {
//输出并计算
System.out.print(j + "x" + i + "=" + (j * i) + "\t");
}
//换行
System.out.println();
}
}
案例三:打印等腰三角形
/**
* 功能:案例三:打印等腰三角形
* 分析:
* (1) 行数:1、2、3、4、5
* (2)空格数:4、3、2、1、0(5-行数)
* (3)*个数:1、3、5、7、9(2*行数-1)
* 时间:2021/12/9 14:38
*/
@Test
public void test03() {
//打印行数
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 5 - i; j++) { //打印空格数
System.out.print(" ");
}
for (int k = 1; k <= 2 * i - 1; k++) { //打印*数
System.out.print("*");
}
System.out.println();//换行
}
}
案例四:打印实心菱形和空心菱形
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
showMenu();
userSelect(scanner);
}
//主菜单
private static void showMenu() {
System.out.println("===============打印菱形===============");
System.out.println("[1]打印实心菱形");
System.out.println("[2]打印空心菱形");
System.out.println("[3]退出系统");
System.out.println("===========================================");
}
//用户选择
private static void userSelect(Scanner scanner) {
//定义是否选择的变量
String inCon = "y";
//循环
do {
System.out.print("请选择菜单:");
int choice = scanner.nextInt();
//对输入的选择进行判断
switch (choice) {
case 1:
test01(scanner); //调用打印实心菱形的方法
break;
case 2:
test02(scanner); //调用打印空心菱形的方法
break;
default:
System.exit(0);
break;
}
System.out.print("\n是否继续(y/n):");
inCon = scanner.next();
} while (inCon.equalsIgnoreCase("y"));
System.out.println("\n程序结束!");
}
/**
* 功能:案例四:打印菱形
* 分析:
* (1)先打印出正等腰三角形
* (1.1) 行数:1、2、3、4、5
* (1.2)空格数:4、3、2、1、0(5-行数)
* (1.3)*个数:1、3、5、7、9(2*行数-1)
* <p>
* (2)打印出倒等腰三角形
* (2.1) 行数:1、2、3、4
* (2.2)空格数:1、2、3、4(行数)
* (2.3)*个数:7、5、3、1(9-2*行数)
* 时间:2021/12/9 14:43
*/
private static void test01(Scanner scanner) {
System.out.print("请输入要打印的行数:");
int num = scanner.nextInt();
for (int i = 1; i <= num; i++) {
for (int j = 1; j <= num - i; j++) {
System.out.print(" ");
}
for (int k = 1; k <= 2 * i - 1; k++) {
System.out.print("*");
}
System.out.println();
}
for (int m = 1; m <= num - 1; m++) {
for (int n = 1; n <= m; n++) {
System.out.print(" ");
}
for (int p = 1; p <= (2 * num - 1) - 2 * m; p++) {
System.out.print("*");
}
System.out.println();
}
}
/**
* 功能:案例五:打印空心菱形(每行只打印第一个*号和最后一个*号,除了第一行和最后一行只打印一个*)
* 分析:
* (1)打印正等腰三角形的空心
* (2)打印倒等腰三角形的空心
* 时间:2021/12/9 15:18
*/
private static void test02(Scanner scanner) {
System.out.print("请输入要打印的行数:");
int num = scanner.nextInt();
for (int i = 1; i <= num; i++) {
for (int j = 1; j <= num - i; j++) {
System.out.print(" ");
}
for (int k = 1; k <= 2 * i - 1; k++) {
if (k == 1 || k == 2 * i - 1) {
System.out.print("*");
} else {
System.out.print(" ");
}
}
System.out.println();
}
for (int m = 1; m <= num - 1; m++) {
for (int n = 1; n <= m; n++) {
System.out.print(" ");
}
for (int p = 1; p <= (2 * num - 1) - 2 * m; p++) {
if (p == 1 || p == (2 * num - 1) - 2 * m) {
System.out.print("*");
} else {
System.out.print(" ");
}
}
System.out.println();
}
}
6、流程控制语句
6.1、break语句:退出当前循环
/**
* break语句的使用:退出当前循环
* 功能:案例一:打印1-1000之间个位数是3的数字,只打印前三个?
* 分析:
* ①定义一个计数器
* ②在循环中筛选中个位数为3的数字
* ③在筛选出的数字中打印前三个数字
*/
@Test
public void test01() {
//定义一个计数器
int count = 0;
//在循环中筛选中个位数为3的数字
for (int i = 1; i <= 1000; i++) {
int ge = i % 10;
//在筛选出的数字中打印前三个数字
if (ge == 3) {
System.out.print(i + "\t");
count++;
if (count == 3) {
break;
}
}
}
}
6.2、continue语句:退出当前循环,进行下一次循环
/**
* continue语句的使用:退出当前循环,接着执行下一次循环
* 功能:案例二:打印1-100之间所有奇数之和?
* 分析:
* ①定义求和变量
* ②在循环中找出所有的奇数
* ③对所有的奇数累加求和
*/
@Test
public void test02() {
//定义求和变量
int sum = 0;
//循环找出所有奇数的数字
for (int i = 1; i <= 100; i++) {
if (i % 2 == 0) {
continue;
}
//累加求和
sum += i;
}
//打印结果
System.out.println("sum = " + sum);
}
6.3、return语句
- 代表退出整个结构,如果在方法中就退出方法,如果在循环中就退出整个循环结构
- 如果有多重循环则退出所有的循环
/**
* return语句的使用
* 代表退出整个结构,如果在方法中就退出方法,如果在循环中就退出整个循环结构。
* 如果有多重循环则退出所有的循环
* 功能:案例一:1-1000之间个位数是3的数字,只对前三个求和?
* 分析:
* ①获取个位数为3的数字:i % 10 == 3
* ②计数:count == 3
* ③求和
*/
@Test
public void test03() {
//定义求和变量和计数器
int sum = 0;
int count = 0;
//循环
for (int i = 1; i <= 1000; i++) {
//个位数为3
if (i % 10 == 3) {
count++;
//累加求和
sum += i;
System.out.print(i + "\t");
if (count == 3) {
System.out.println("\nsum = " + sum);
return;
}
}
}
System.out.println("return后的语句都不会执行");
}
7、数组
7.1、一维数组的定义与声明
/**
* 功能:一维数组的定义与声明
*/
@Test
public void test01() {
//1、定义一维数组
int[] scores = new int[5];
int a[] = new int[3];
//2、为数组赋值
//2.1、静态赋值
a[0] = 1;
int[] b = {1, 2, 3, 4};
int[] c = new int[]{3, 4, 5, 6};
}
7.2、一维数组的动态赋值
public static void main(String[] args) {
//定义一个扫描器对象
Scanner scanner = new Scanner(System.in);
test02(scanner);
}
/**
* 功能:实现一维数组的动态赋值
*/
private static void test02(Scanner scanner) {
//定义一个代表学生成绩的数组
int[] scores = new int[5];
//为数组动态赋值
System.out.println("请输入5个学生的成绩:");
for (int i = 0; i < scores.length; i++) {
//将得到的学生分数赋值给数组
scores[i] = scanner.nextInt();
}
//使用foreach循环打印数组的元素
for (int score : scores) {
System.out.print(score + "\n");
}
}
7.3、二维数组的定义与声明
/**
* 功能:二维数组的定义与声明
*/
@Test
public void test01() {
//定义二维数组
int[][] a = new int[3][4];
int[][] b = new int[3][];
b[0] = new int[5];
b[1] = new int[4];
b[2] = new int[3];
//为二维数组赋值
b[0][0] = 11;
b[0][1] = 12;
b[0][2] = 13;
b[0][3] = 14;
b[0][4] = 15;
b[1][0] = 16;
b[1][1] = 17;
b[1][2] = 18;
b[1][3] = 19;
b[2][0] = 20;
b[2][1] = 21;
b[2][2] = 22;
//遍历二维数组
for (int i = 0; i < b.length; i++) {
for (int j = 0; j < b[i].length; j++) {
System.out.print(b[i][j] + "\t");
}
System.out.println();
}
}
7.4、二维数组的动态赋值
public static void main(String[] args) {
//定义一个扫描器对象
Scanner scanner = new Scanner(System.in);
test02(scanner);
}
/**
* 功能:实现二维数组的动态赋值
* 时间:2021/12/13 16:24
*/
private static void test02(Scanner scanner) {
//定义一个二维数组存储2名学生的三门成绩
int[][] scores = new int[2][3];
//为二维数组动态赋值
for (int i = 0; i < scores.length; i++) {
System.out.print("请输入" + (i + 1) + "名学生的3门成绩:");
for (int j = 0; j < scores[i].length; j++) {
scores[i][j] = scanner.nextInt();
}
}
//遍历二维数组
for (int[] score : scores) {
for (int i : score) {
System.out.print(i + "\t");
}
System.out.println();
}
}
7.5、数组的常用算法
案例一:在数组中查找最大值与最小值
/**
* 功能:案例一:在数组中查找最大值与最小值
* 分析:【方法一】
* 1、定义一维数组
* 2、初始化最大值与最小值,默认为数组的第一个值
* 3、遍历判断最大值与最小值
* 4、打印输出
*/
@Test
public void test01() {
//定义一维数组
int[] a = {3, 1, 9, 10, 2, 11, 8, 7, 4, 3};
//初始化最大值与最小值
int max = a[0];
int min = a[0];
//遍历数组
for (int i = 0; i < a.length; i++) {
//最大值
if (a[i] > max) {
max = a[i];
}
//最小值
if (a[i] < min) {
min = a[i];
}
}
//输出最大值与最小值
System.out.println("max = " + max);
System.out.println("min = " + min);
}
/**
* 功能:案例一:在数组中查找最大值与最小值
* 分析:【方法二】使用Arrays.sort()
*/
@Test
public void test02() {
//定义一维数组
int[] a = {3, 1, 9, 10, 2, 11, 8, 7, 4, 3};
//使用Arrays.sort()方法:升序排列
Arrays.sort(a);
//输出最大值与最小值
System.out.println("max = " + a[a.length - 1]);
System.out.println("min = " + a[0]);
}
/**
* 功能:案例一:在数组中查找最大值与最小值
* 分析:【方法三】使用冒泡排序算法:升序
*/
@Test
public void test03() {
//定义一维数组
int[] a = {3, 1, 9, 10, 2, 11, 8, 7, 4, 3};
//循环遍历数组
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length - i - 1; j++) {
if (a[j] > a[j + 1]) {
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
//输出数组的最大值与最小值
System.out.println("max = " + a[a.length - 1]);
System.out.println("min = " + a[0]);
}
案例二:在数组中查找元素及其下标?【元素在数组中只出现一次】
/**
* 功能: 案例二:在数组中查找元素及其下标?【元素在数组中只出现一次】
* 分析:【方法一】
* 1、可以定义一个代表找到的元素的下标,如:int index = -1;
* 2、遍历开始查找元素,如果找到就赋值给index,并退出。
*/
@Test
public void test04() {
//定义一个数组
int[] a = {3, 1, 9, 10, 2, 11, 8, 7, 4, 3};
//定义要查找的元素
int e = 3;
//定义查找到的元素在数组中的下标
int index = -1;
//开始遍历查找
for (int i = 0; i < a.length; i++) {
//根据查找的元素是否与当前正在遍历的元素相等,就可以确定是否找到了元素
if (a[i] == e) {
index = i;
break;
}
}
//如果index不等于-1,代表找到了元素
if (index != -1) {
System.out.println("在" + index + "位置找到了元素" + e + "!");
} else {
System.out.println("没有找到元素" + e + "!");
}
}
/**
* 功能:案例二:在数组中查找元素及其下标?【元素在数组中只出现一次】
* 分析:【方法二】
* 1、在遍历循环完成后,如果循环变量i的值小于数组的长度,则说明这个循环中途退出了并且找到了这个元素。
*/
@Test
public void test05() {
//定义一个数组
int[] a = {3, 1, 9, 10, 2, 11, 8, 7, 4, 3};
//定义要查找的元素
int e = 4;
//定义循环变量i
int i = 0;
//开始循环
for (; i < a.length; i++) {
if (a[i] == e) {
break;
}
}
//判断循环变量i的值是否小于数组的长度
if (i < a.length) {
System.out.println("在" + i + "位置找到了元素" + e + "!");
} else {
System.out.println("没有找到元素" + e + "!");
}
}
/**
* 功能:案例二:在数组中查找元素及其下标?【元素在数组中只出现一次】
* 分析:【方法三】
* 1、使用return语句,如果找到了直接打印输出
*/
@Test
public void test06() {
//定义一个数组
int[] a = {3, 1, 9, 10, 2, 11, 8, 7, 4, 3};
//定义要查找的元素
int e = 4;
//循环
for (int i = 0; i < a.length; i++) {
if (a[i] == e) {
System.out.println("在" + i + "位置找到了元素" + e + "!");
return;
}
}
System.out.println("没有找到元素" + e + "!");
}
案例三:在数组中查找元素及其下标?【元素在数组中出现多次】
/**
* 功能:案例三:在数组中查找元素及其下标?【元素在数组中出现多次】
* 分析:【方法一】
* 1、使用continue语句,如果找到了就继续
*/
@Test
public void test07() {
//定义要查找的数组
int[] a = {3, 1, 9, 1, 2, 1, 2, 1, 2, 2};
//定义要查找的元素
int e = 2;
//遍历
System.out.println("在如下位置找到了元素" + e + ":");
System.out.println("-------------------------");
for (int i = 0; i < a.length; i++) {
if (a[i] == e) {
System.out.print(i + "\t");
continue;
}
}
System.out.println("\n-------------------------");
}
/**
* 功能:案例三:在数组中查找元素及其下标?【元素在数组中出现多次】
* 分析:【方法二】
* 1、可以将找到的元素在数组中的下标放到一个新的数组中。
* 2、新的数组的长度可以定义为与源数组长度一致。
* 3、新的数组的下标可以定义一个计数器来实现。此时的计数器充当下标及代表找到的元素的个数的计数器。
*/
@Test
public void test08() {
//定义要查找的数组
int[] a = {3, 1, 9, 1, 2, 1, 2, 1, 2, 2};
//定义要查找的元素
int e = 2;
//定义存放找到的元素在数组中下标的数组
int[] b = new int[a.length];
//定义计数器同时充当b数组的下标
int count = 0;
//开始查找并将找到的下标放到b数组中
for (int i = 0; i < a.length; i++) {
if (a[i] == e) {
b[count++] = i;
}
}
//打印找到的元素下标
if (count > 0) {
System.out.println("在如下位置找到元素" + e + ":");
System.out.println("-----------------------------------");
for (int i = 0; i < count; i++) {
System.out.print(b[i] + "\t");
}
System.out.println("\n-----------------------------------");
} else {
System.out.println("没有找到元素" + e + "!");
}
}
/**
* 功能:案例三:在数组中查找元素及其下标?【元素在数组中出现多次】
* 分析:【方法三】
* 1、将找到的下标用一个字符串连接起来
*/
@Test
public void test09() {
//定义要查找的数组
int[] a = {3, 1, 9, 1, 2, 1, 2, 1, 2, 2};
//定义要查找的元素
int e = 1;
//定义查找到的元素的下标存放的字符串
String str = "";
//开始查找
for (int i = 0; i < a.length; i++) {
if (a[i] == e) {
str += i + " ";
}
}
//根据str的长度是否为0,判断是否找到元素
if (str.trim().length() == 0) {
System.out.println("没有找到元素" + e + "!");
} else {
System.out.println("在如下位置找到元素" + e + ":");
System.out.print(str);
}
}
7.6、数组的排序
/**
* 功能:冒泡排序
*/
@Test
public void test01() {
//定义一个数组
int[] a = {11, 1, 19, 2, 5, 3, 7, 6};
//开始循环
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length - i - 1; j++) {
if (a[j] > a[j + 1]) {
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
//打印排序后的数组
for (int i : a) {
System.out.print(i + "\t");
}
}
/**
* 功能:Arrays类的用法
*/
@Test
public void test02() {
//定义一个数组
int[] a = {11, 1, 19, 2, 5, 3, 7, 6};
//对数组进行排序
Arrays.sort(a);
//打印排序后的数组
for (int i : a) {
System.out.print(i + "\t");
}
//在数组中查找元素
int e = 5;
int index = Arrays.binarySearch(a, e);
System.out.println("\nindex = " + index);
}
8、Math类的使用
@Test
public void test01(){
//1、绝对值
int abs = Math.abs(-10);
System.out.println("abs = " + abs);
//2、随机数[0,10)
double random = Math.random();
System.out.println("random = " + random);
//3、返回小于等于给定参数的最大整数
double floor = Math.floor(3.14);
System.out.println("floor = " + floor);
//4、返回大于等于给定参数的最小整数
double ceil = Math.ceil(3.14);
System.out.println("ceil = " + ceil);
//5、返回两个参数的最大值与最小值
int max = Math.max(4, 5);
System.out.println("max = " + max);
int min = Math.min(6, 4);
System.out.println("min = " + min);
//6、返回一个参数的n次幂
double pow = Math.pow(2, 3);
System.out.println("pow = " + pow);
//6、返回一个四舍五入的数(将给定的数+0.5后再向下取整)
long round = Math.round(3.456);
System.out.println("round = " + round);
//7、返回圆周率
double pi = Math.PI;
System.out.println("pi = " + pi);
//8、求给定参数的正弦值
double sin = Math.sin(Math.PI / 3);
System.out.println("sin = " + sin);
//9、求给定参数的算术平方根
double sqrt = Math.sqrt(2);
System.out.println("sqrt = " + sqrt);
}
9、String类的使用
/**
* 功能:String类的使用
*/
@Test
public void test01() {
//定义一个字符串类
String str = "hello,world";
//得到指定位置的字符
char c = str.charAt(1);
System.out.println("c = " + c);
//得到指定字符第一次出现的位置
int indexOf = str.indexOf("o");
System.out.println("indexOf = " + indexOf);
//得到指定字符最后一次出现的位置
int lastIndexOf = str.lastIndexOf("o");
System.out.println("lastIndexOf = " + lastIndexOf);
//将当前字符串转换成大写
String toUpperCase = str.toUpperCase();
System.out.println("toUpperCase = " + toUpperCase);
//将当前字符串转换成小写
String toLowerCase = str.toLowerCase();
System.out.println("toLowerCase = " + toLowerCase);
//字符串的拆分
String[] split = str.split(",");
for (String s : split) {
System.out.println(s);
}
//从指定字符串的当前位置开始截取到结束
String substring = str.substring(1);
System.out.println("substring = " + substring);
//在字符串中间截取
String substring1 = str.substring(2, 4);
System.out.println("substring1 = " + substring1);
//替换字符串
String replace = str.replace("o","O");
System.out.println("replace = " + replace);
//以指定字符开头的字符串
boolean startsWith = str.startsWith("he");
System.out.println("startsWith = " + startsWith);
//以指定字符结尾的字符串
boolean endsWith = str.endsWith("ld");
System.out.println("endsWith = " + endsWith);
//字符串是否包含指定字符
boolean contains = str.contains("e");
System.out.println("contains = " + contains);
//字符串的长度
int length = str.length();
System.out.println("length = " + length);
}
10、StringBuffer类的使用
/**
*功能:StringBuffer类的使用
*/
@Test
public void test02(){
//定义字符串
StringBuffer buffer = new StringBuffer("hello");
//追加字符串
buffer.append(1);
//打印字符串
System.out.println("buffer = " + buffer);
//插入一个字符串
buffer.insert(5,"中国人");
System.out.println("buffer = " + buffer);
//删除一个指定字符
buffer.deleteCharAt(8);
System.out.println("buffer = " + buffer);
//删除指定范围内的字符
buffer.delete(5,8);
System.out.println("buffer = " + buffer);
//反转字符转
buffer.reverse();
System.out.println("buffer = " + buffer);
}
11、第一阶段综合实战案例
面试题一:将一个给定字符串逆序输出
/**
* 功能:面试题一:将一个给定字符串逆序输出。
* 分析:【方法一】通过循环
*/
@Test
public void test01() {
//定义一个字符串
String str = "hello,world";
//将字符串倒叙输出
for (int i = str.length() - 1; i >= 0; i--) {
//得到字符串的字符
char c = str.charAt(i);
//打印输出
System.out.print(c);
}
}
/**
* 功能:面试题一:将一个给定字符串逆序输出。
* 分析:【方法二】使用StringBuffer类
*/
@Test
public void test02() {
//定义一个字符串
String str = "hello,world";
//声明一个StringBuffer
StringBuffer buffer = new StringBuffer(str);
//将字符串逆序
buffer.reverse();
//打印结果
System.out.println(buffer);
}
面试题二:写一个字符串转换成驼峰的方法
/**
* 功能:面试题二:写一个字符串转换成驼峰的方法
* 分析:【方法一】
*/
@Test
public void test03() {
//给定一个字符串
String str = "border-bottom-color-hello-world-welcome";
//遍历字符串,将-号的下一个位置的字符转换成大写
for (int i = 0; i < str.length(); i++) {
//找到第一个-号的位置
int indexOf = str.indexOf("-");
//得到下一个位置的字符
char c = str.charAt(indexOf + 1);
//将下一个位置的字符转换成大写
str = str.replace("-" + c, (char) (c - 32) + "");
}
System.out.println(str);
}
/**
* 功能:面试题二:写一个字符串转换成驼峰的方法
* 分析:【方法二】将当前字符串拆分成字符串数组
*/
@Test
public void test04() {
//给定一个字符串
String str = "border-bottom-color-hello-world-welcome";
//拆分
String[] split = str.split("-");
//定义结果字符串
String result = split[0];
//循环拆分后的数组
for (int i = 0; i < split.length; i++) {
//得到当前字符串
String s = split[i];
//将第一个字符转换为大写并连接到result中
result += (char) (s.charAt(0) - 32);
//截取字符串
result += s.substring(1);
}
//打印结果字符串
System.out.println(result);
}
/**
* 功能:面试题二:写一个字符串转换成驼峰的方法
* 分析:【方法三】使用CaseUtils对Java字符串进行转换为驼峰格式
*/
@Test
public void test05(){
//给定一个字符串
String str = "border-bottom-color-hello-world-welcome";
//使用CaseUtils
String s = CaseUtils.toCamelCase(str, false, '-');
System.out.println(s);
}
面试题三:返回一个只包含数字类型的一个数组
/**
* 功能:面试题三:返回一个只包含数字类型的一个数组
*/
@Test
public void test01() {
//定义一个字符串
String str = "f-[}f242fsdf2432agst5k232sfsa";
//利用正则表达式将非数字的字符替换成空字符
String s = str.replaceAll("[^0-9]", "");
//将新字符串转换成字符数组
char[] chars = s.toCharArray();
//将字符数组打印输出
for (char c : chars) {
System.out.print(c);
}
}
面试题四:如何判断一个字符串是否是一个回文字符串?
/**
* 功能:面试题四:如何判断一个字符串是否是一个回文字符串?
* 分析:【方法一】
*/
@Test
public void test02() {
//定义一个字符串
String str = "abcba";
//遍历字符串
for (int i = 0, len = str.length(); i < len / 2; i++) {
//取出左边字符
char left = str.charAt(i);
//取出右边字符
char right = str.charAt(len - 1 - i);
//判断左右两边字符是否相等
if (left != right) {
System.out.println(str + "不是一个回文字符串");
return;
}
}
System.out.println(str + "是一个回文字符串");
}
/**
* 功能:面试题四:如何判断一个字符串是否是一个回文字符串?
* 分析:【方法二】
*/
@Test
public void test03() {
//定义一个字符串
String str = "abcba";
//将字符串逆序输出
StringBuffer buffer = new StringBuffer(str);
buffer.reverse();
//将新字符串与原字符串进行比较,如果相等则是回文字符串
if (buffer.toString().equals(str)) {
System.out.println(str + "是一个回文字符串");
} else {
System.out.println(str + "不是一个回文字符串");
}
}
面试题五:将一个给定字符串如:”abcde”转换为”bcdef”
/**
* 功能:面试题五:将一个给定字符串如:”abcde”转换为”bcdef”
*/
@Test
public void test04() {
//定义一个字符串
String str = "abcde";
//遍历当前字符串
for (int i = 0; i < str.length(); i++) {
//得到每一个字符
char c = str.charAt(i);
//将得到的每一个字符加1
System.out.print((char) (c + 1));
}
}
面试题六:如何判断一个字符串中是否存在重复元素
/**
* 功能:面试题六:如何判断一个字符串中是否存在重复元素?(面试题)
*/
@Test
public void test05() {
//定义一个字符串
String str = "abcdefagt";
//遍历字符串
for (int i = 0; i < str.length(); i++) {
//得到每一个字符
char c = str.charAt(i);
//得到字符第一次出现的位置
int indexOf = str.indexOf(c);
//得到字符最后一次出现的位置
int lastIndexOf = str.lastIndexOf(c);
//比较两次出现的位置是否相等
if (indexOf != lastIndexOf) {
System.out.println(str + "中存在重复字符");
return;
}
}
System.out.println(str + "中不存在重复字符");
}
二、JavaOOP学习
1、类和对象
类和对象的关系:
1.对象是具体的,是看得见也摸得着的现实世界实实在在的个体。
2.类是抽象的,是现实世界中很多个同类事物的抽象
2、构造方法和this关键字
2.1、构造方法
1.构造方法一般定义为public的。[备注:在单例时会用到private.]
2.构造方法没有返回值,包括也没有void这种类型的返回值。
3.构造方法名与类名必须一致。
4.一个类如果没有提供构造方法,则JVM会为我们提供一个默认无参的构造方法。但是,
一旦我们定义了自己的构造方法,则系统不会再为我们提供任何形式的构造方法了。
5.构造方法的作用:就是实现局部变量为全局赋值(简化了对对象的赋值操作)。
2.2、this关键字
1.如果在构造方法中使用this,代表通过局部变量为全局变量进行赋值。如果没有this根据软件开发中的就近原则,就会自己赋值给己。
2.this在构造方法中就代表当前构造出来的哪个对象
3.this([参数列表])代表调用本类的其它构造方法,它只能放在调用的构造方法的第一行上,所以在一个构造方法中只能调用一次this([参数列表])
/**
* 功能:汽车类
*/
public class Car {
public String brand; //汽车品牌
public String color; //汽车颜色
public double price; //汽车价格
public Integer wheels; //汽车轮子数
//创建无参构造方法
public Car() {
System.out.println("这是一个无参构造方法");
}
//创建带一个参数的有参构造方法
public Car(String brand) {
this(); //调用无参构造方法
this.brand = brand;
System.out.println("这是一个带一个参数的有参构造方法");
}
//创建带两个参数的有参构造方法
public Car(String brand, String color) {
this(brand); //调用带一个参数的有参构造方法
this.color = color;
System.out.println("这是一个带两个参数的有参构造方法");
}
//创建带三个参数的有参构造方法
public Car(String brand, String color, double price) {
this(brand, color); //调用带两个参数的有参构造方法
this.price = price;
System.out.println("这是一个带三个参数的有参构造方法");
}
//创建带四个参数的有参构造方法
public Car(String brand, String color, double price, Integer wheels) {
this(brand, color, price); //调用带三个参数的有参构造方法
this.wheels = wheels;
System.out.println("这是一个带四个参数的有参构造方法");
}
public void start() {
System.out.println("一辆颜色为" + color + "的" + brand + "汽车正在启动....");
}
public void run() {
System.out.println("一辆颜色为" + color + "的" + brand + "汽车正在奔跑....");
}
public void stop(){
System.out.println("一辆颜色为" + color + "的" + brand + "汽车正在停止....");
}
}
2.3、利用构造方法创建对象
public static void main(String[] args) {
//test01();
test02();
}
/**
* 功能:利用无参构造方法创建对象
* 分析:默认为执行一遍无参构造方法
*/
private static void test01() {
//创建一个汽车对象
Car car = new Car();
//通过对象.属性的方法为对象赋值
car.brand = "宝马";
car.color = "白色";
car.price = 300000;
car.wheels = 4;
//调用方法
car.start();
car.run();
car.stop();
}
/**
*功能:利用有参构造方法创建对象
* 分析:多个有参构造方法的调用会出现层级调用
*/
private static void test02() {
//创建一个带四个参数的有参构造方法
Car car = new Car("奔驰","黑色",400000,4);
//调用方法
car.start();
car.run();
car.stop();
}
3、toString方法与equals方法
toString方法的作用:简化对对象属性的打印输出
equals方法的作用:定义我们自己对对象的比较规则。此时,我们需要重写父类Object的equals方法
//重写父类的toString方法
public String toString() {
return "品牌:" + this.brand + "\n颜色:" + this.color + "\n价格:" + this.price + "\n轮子数:" + this.wheels;
}
//重写equals方法
public boolean equals(Object obj) {
Car car = (Car) obj;
return this.brand.equals(car.brand) && this.price == price;
}
4、Java访问修饰符
private: 修饰符代表只在当前类的内部访问 protected: 只在父子类中可以访问,无论是否是父子类都可以在同一个包下访问 public:可以在任意位置访问 default:只要在包的内部都可以访问 public>protected>default>private
修饰符 | 当前类 | 同一包类 | 父子类 | 其他包(父子类) | 使用范围 |
---|---|---|---|---|---|
private | ok | no | no | no | 变量、方法、不能修饰外部类 |
protected | ok | ok | ok | ok | 变量、方法、不能修饰外部类 |
default | ok | ok | no | no | 类、接口、变量、方法 |
public | ok | ok | ok | ok | 类、接口、变量、方法 |
5、面向对象三大特征—-封装
public class Manager {
public String username; //登录名
public String password; //密码
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
6、面向对象三大特征—-继承
父类:
public class Person {
private int pid;
private String pname;
protected String sex;
private int age;
public String addr;
public Person() {
}
public Person(String pname, String sex) {
this.pname = pname;
this.sex = sex;
}
public Person(String pname, String sex, int age, String addr) {
this(pname, sex);
this.age = age;
this.addr = addr;
}
public Person(int pid, String pname, String sex, int age, String addr) {
this.pid = pid;
this.pname = pname;
this.sex = sex;
this.age = age;
this.addr = addr;
}
//定义读取年龄的方法
public int getAge() {
return this.age;
}
//定义设置年龄的方法
public void setAge(int age) {
if (age > 0 && age <= 150) {
this.age = age;
} else {
System.out.println("年龄不合法!");
}
}
//定义读取pname的方法
public String getPname() {
return this.pname;
}
//定义设置pname的方法
public void setPname(String pname) {
if (pname.length() >= 2) {
this.pname = pname;
} else {
System.out.println("人名不合法!");
}
}
//自定义方法
public void welcome() {
this.pid = 1001;
this.pname = "小明";
System.out.println("Person ---> welcome()");
}
@Override
public String toString() {
return pid + "\t" + pname + "\t" + sex + "\t" + age + "\t" + addr;
}
}
子类(super关键字):
public class Student extends Person {
private int score;//成绩
public Student() {
}
public Student(int score) {
this();
this.score = score;
}
public Student(int pid, String pname, String sex, int age, String addr, int score) {
super(pid, pname, sex, age, addr); //调用父类的有参构造方法
this.score = score;
}
public void sayHello() {
this.sex = "男";
}
//重写父类的welcome()方法:
public void welcome() {
super.welcome();
System.out.println("Student--->welcome().");
}
@Override
public String toString() {
return super.toString() + "\t" + this.score;
}
}
继承小结:
1、所有类的父类是Object类。
2、父类有的子类都有,父类没有的子类可以添加,父类有的子类可以改变
3、构造方法不能被继承,方法和属性可以被继承
4、子类的构造方法隐式调用父类不带参数的构造方法,子类显示调用父类构造方法使用super关键字
7、面向对象三大特征—-多态
多态:同一种事物的多种形态,如水果类就有苹果、香蕉、桔子等。继承的表现形式就是多态的体现
8、方法的重载和重写
重载和重写的区别:
重载(overload):可以发生于一个类,也可以发生于子类和父类之间(子类继承父类方法,同时完成方法重载)
- 方法名相同,参数类型、顺序、个数不同
- 访问修饰符、返回值类型不能成为构成重载的条件
- 例如:无参构造方法和有参构造方法
重写(override):子类重写父类的方法
- 方法名、返回值类型、参数列表相同
- 子类的访问修饰符权限不得低于父类的访问修饰符权限
重载:
public class Calcuator {
public int add(int a, int b) {
return a + b;
}
public int add(int a, int b,int c) {
return a + b+c;
}
public double add(int a, double b) {
return a + b;
}
public float add(int a, float b) {
return a + b;
}
public float add(float a, int b) {
return a + b;
}
}
重写:
/**
* 类名:Parent父类
*/
public class Parent {
public void sayHello(){
System.out.println("Parent--->sayHello()");
}
}
/**
* 类名:Child子类继承Parent父类并重写父类的sayHello方法
*/
public class Child extends Parent{
@Override
public void sayHello() {
System.out.println("Child--->sayHello()");
}
}
测试重载和重写:
/**
* 测试方法的重载
*/
@Test
public void test01(){
Calcuator calcuator = new Calcuator();
int s1 = calcuator.add(1, 2);
System.out.println("s1 = " + s1);
int s2 = calcuator.add(1, 2, 3);
System.out.println("s2 = " + s2);
float s3 = calcuator.add(3.14f, 1);
System.out.println("s3 = " + s3);
float s4 = calcuator.add(2, 3.14f);
System.out.println("s4 = " + s4);
double s5 = calcuator.add(3, 3.14);
System.out.println("s5 = " + s5);
}
/**
* 测试方法的重写
*/
@Test
public void test02(){
Parent parent = new Child();
parent.sayHello();
}
9、final关键字
1、被final修饰的类不能被继承
2、被final修饰的变量一般为常量,不能被修改,常量字段必须赋初始值
3、被final修饰的方法不能被重写
10、Java单例设计模式
懒汉式:
public class User{
//1、懒汉式
private static User user = null;
private User(){}
public static User getUser(){
if(user==null){
user=new User();
}
return user;
}
}
饿汉式:
public class User{
//2、饿汉式
private static User user = new User();
private User(){}
public static User getUser(){
return user;
}
}
测试单例模式:
@Test
public void test01() {
User user1 = User.getUser();
System.out.println("user1 = " + user1);
User user2 = User.getUser();
System.out.println("user2 = " + user2);
}
两者的区别
(1)在饿汉式中可以在本类中创建本类对象时加上final关键字,但在懒汉式中不可以。
(2)饿汉式在类加载时就创建了对象实例,懒汉式则是在使用时才创建对象实例。 –最主要的区别
(3)饿汉式不存在线程安全问题,而懒汉式存在线程安全问题。
(4)饿汉式存在浪费资源的问题,而懒汉式不存在浪费资源的问题。
饿汉式 | 懒汉式 | |
---|---|---|
创建对象的时机 | 类加载时 | 使用时 |
线程安全方面 | 不存在 | 存在 |
资源浪费方面 | 存在 | 不存在 |
11、Java的向上转型和向下转型
向上转型:父类的引用指向了子类
优点:增强了程序的扩展性
缺点:不能调用子类有父类没有的方法
/**
*功能:向上转型:父类的引用指定子类(开发中常用):如果父子类都有相同的方法,使用的是子类的对象
*/
@Test
public void test01(){
Fruit fruit = new Apple(3);
fruit.sayHello();
}
向下转型:把父类引用强制转换为子类对象
优点:可以调用子类有父类没有的方法
缺点:不能增强程序的扩展性
/**
*功能:向下转型:子类有方法而父类没有方法
*/
@Test
public void test02(){
Fruit fruit = new Apple(5);
((Apple)fruit).welcome();
}
12、抽象类和接口
12.1、抽象类
1、必须使用abstract修饰
2、抽象类中可以有抽象方法,也可以有实现的方法
3、一个抽象方法必须存在于抽象类中
4、一个抽象类的子类必须完全实现这个抽象类中的所有抽象方法,否则,它也是一个抽象子类
5、抽象类中可以有构造方法,但不能被实例化
6、抽象类的作用:提供一种对子类行为的约束机制
public abstract class Animal {
//1. 抽象方法必须存在于抽象类中
public abstract void breathe();
public Animal(){
System.out.println("Animal构造方法.");
}
public void sayHello(){
System.out.println("Animal-->sayHello()");
}
public abstract void welcome();
}
12.2、接口
1、必须使用interface修饰
2、接口中的方法是由:public abstract来修饰
3、接口中的变量都是常量,是由:public static final来修饰的。必须要赋初始值
4、接口中不能有构造方法,也不能被实例化
5、接口中可以有默认方法和静态方法,前者可以由接口的实现类来调用,后者由接口直接调用
6、子类实现接口,必须要实现其中的所有抽象方法,否则,它也是一个抽象子类
7、接口主要是定义规范的,而抽象类主要是一种对子类的一种约束机制
8、因为接口中有了默认方法,所以,我们可以在默认中定义好默认功能实现,到时,就可以根据需要 重写我们需要的方法,完成自己的功能就可以了,而这一操作,原来需要使用适配器模式才能实现。
public interface USB {
//1. 接口中的变量是由: public static final 修饰的,是常量,必须要赋初始值
int width = 1;
//2. 接口中的方法是由public abstract 修饰的
void read();
void write();
//3. 接口中不能定义构造方法
// public USB(){
//
// }
//4. 【JDK1.7之后才出现】接口中的定义的默认方法,它是由接口的实现类来调用的
default void print(){
System.out.println("这是接口的默认方法.");
}
//5. 【JDK1.7之后才出现】接口中的定义的静态方法,它是由接口直接来调用的
static void welcome(){
System.out.println("这是接口中的静态方法.");
}
}
12.3、抽象类和接口的区别
区别 | 抽象类 | 接口 |
---|---|---|
关键字 | abstract | interface |
组成 | 构造方法、普通方法、抽象方法、static方法、常量、变量 | 抽象方法、全局变量 |
子类使用 | class 子类 extends 抽象类 | class 子类 implements 接口,接口 |
关系 | 抽象类可以实现多个接口 | 接口不能继承抽象类,却可以继承多个父接口 |
权限 | 可以使用各种权限 | 只能使用public权限 |
限制 | 单继承局限 | 没有单继承局限 |
子类 | 抽象类和接口都必须由子类,子类必须要覆写全部的抽象方法 |
---|---|
实例化对象 | 依靠子类对象的向上转型进行对象的实例化 |
12.4、接口的使用方法
jdk1.7之前的使用方法:(适配器设计模式)
public interface A{
void t1();
void t2();
void t3();
void t4();
void t5();
void t6();
}
public class Test01 implements A{
public void t1(){
xxxx
}
public void t2(){
}
public void t3(){
}
public void t4(){
}
public void t5(){
}
public void t6(){
}
}
public class Aadapter implements A{
public void t1(){
}
public void t2(){
}
public void t3(){
}
public void t4(){
}
public void t5(){
}
public void t6(){
}
}
public class Test02 extends Aadapter {
public void t1(){
xxxx
}
}
public class Test03 extends Aadapter {
public void t2(){
yyyy
}
}
jdk1.7之后的使用方法:(默认方法)
public interface AA{
default void t1(){
}
default void t2(){
}
default void t3(){
}
default void t4(){
}
default void t5(){
}
default void t6(){
}
}
public class Test04 implements AA{
void t1(){
xxxxxsx
}
}
12.5、面向接口编程思想
USB接口
public interface USB {
void read(); //读
void write(); //写
}
Mp3实现类
public class Mp3 implements USB{
@Override
public void read() {
System.out.println("Mp3正在读取数据...");
}
@Override
public void write() {
System.out.println("Mp3正在写入数据...");
}
}
FlashDisk实现类
public class FlashDisk implements USB{
@Override
public void read() {
System.out.println("FlashDisk正在读取数据...");
}
@Override
public void write() {
System.out.println("FlashDisk正在写入数据...");
}
}
Computer类(面向接口编程)
public class Computer {
public void run(USB usb){
usb.read();
usb.write();
}
}
测试类:
/**
* 测试面向接口编程
*/
@Test
public void test02() {
Computer computer = new Computer();
USB usb = new Mp3();
computer.run(usb);
usb = new FlashDisk();
computer.run(usb);
}
12.6、接口中实现与继承问题
1、接口可以继承自多个接口
2、一个类可以实现多个接口,多个接口之间用逗号隔开
3、一个类可以继承自另一个类,并且同时可以实现多个接口
/**
* 接口可以继承自多个接口
* extends关键字:必须发生在同种事物之间,如类与类之间、接口与接口之间
*/
public interface A extends B,C{
void a();
}
interface B{
void b();
}
interface C{
void c();
}
/**
* 一个类可以实现多个接口,多个接口之间用,隔开
*/
class TC implements B,C{
@Override
public void b() {
}
@Override
public void c() {
}
}
class TB{
void b(){}
}
/**
* 一个类继承自另一个类,同时可以实现多个接口
*/
class TD extends TB implements B,C{
@Override
public void b() {
}
@Override
public void c() {
}
}
12.7、案例:宠物超市
宠物IPet接口:
public interface IPet {
String getName();//获取名称
String getColor();//获取颜色
int getAge();//获取年龄
}
Cat类实现IPet接口:
public class Cat implements IPet{
String name;
String color;
int age;
public Cat(){
}
public Cat(String name,String color,int age){
this.name=name;
this.color=color;
this.age=age;
}
public void setColor(String color) {
this.color = color;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name){
this.name=name;
}
@Override
public String getName() {
return name;
}
@Override
public String getColor() {
return color;
}
@Override
public int getAge() {
return age;
}
}
Dog类实现IPet接口:
public class Dog implements IPet{
String name;
String color;
int age;
public Dog() {
}
public Dog(String name, String color, int age) {
this.name = name;
this.color = color;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setColor(String color) {
this.color = color;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String getName() {
return name;
}
@Override
public String getColor() {
return color;
}
@Override
public int getAge() {
return age;
}
}
PetUI界面类:
public class PetUI {
private PetManager manager = new PetManager();
//1、展示菜单
public void showMenu() {
System.out.println("========== 宠物商店 ==========");
System.out.println("[1] 添加宠物");
System.out.println("[2] 查看宠物");
System.out.println("[3] 查找宠物");
System.out.println("[4] 修改宠物");
System.out.println("[5] 退出系统");
System.out.println("=============================");
Scanner scanner = new Scanner(System.in);
//用户选择
userSelect(scanner);
}
//2、用户选择
private void userSelect(Scanner scanner) {
System.out.println("请选择:");
int choice = scanner.nextInt();
switch (choice){
case 1:
addPet(scanner);
break;
case 2:
manager.printPetInfo();
break;
case 3:
searchPet(scanner);
break;
case 4:
System.out.println("修改宠物");
break;
case 5:
System.exit(0);
break;
}
//判断用户是否继续选择
System.out.println("是否继续(y/n):");
String inCon = scanner.next();
if (inCon.equalsIgnoreCase("y")){
userSelect(scanner);
}
}
//3、添加宠物界面
private void addPet(Scanner scanner) {
System.out.println("请输入宠物类型(1:猫,2:狗):");
int type = scanner.nextInt();
System.out.println("请输入宠物名称:");
String name = scanner.next();
System.out.println("请输入宠物颜色:");
String color = scanner.next();
System.out.println("请输入宠物年龄:");
int age = scanner.nextInt();
//构造一个宠物对象
IPet pet = null;
switch (type){
case 1:
pet = new Cat(name,color,age);
break;
case 2:
pet = new Dog(name,color,age);
break;
default:
System.out.println("输入的类型不合法!");
break;
}
//添加宠物
manager.addPet(pet);
}
//4、查找宠物
private void searchPet(Scanner scanner) {
System.out.println("请输入要查找宠物的关键字:");
String keywords = scanner.next();
//查找宠物
manager.searchPet(keywords);
}
}
PetManager宠物管理类:
public class PetManager {
//定义一个宠物类型数组
private IPet[] pets = new IPet[5];
//定义数组的下标
private int count=0;
//添加宠物功能
public void addPet(IPet pet) {
if (count<pets.length){
pets[count++]=pet;
}else {
System.out.println("宠物已满!");
}
}
//查找宠物功能
public void searchPet(String keywords) {
//定义查找到的宠物数组
IPet[] petList = new IPet[pets.length];
//定义查找到的数组的下标
int n = 0;
//循环查询
for (int i = 0; i < count; i++) {
//得到当前的宠物
IPet pet = pets[i];
//根据宠物的名字或颜色查找
if (pet.getName().contains(keywords) || pet.getColor().contains(keywords)){
petList[n++]=pet;
}
}
//打印查找到的数组
if (n==0){
System.out.println("没有找到宠物");
}else {
printPetInfo(petList);
}
}
//打印数组
public void printPetInfo(IPet... petList) { //表示petList的长度是可变的
System.out.println("宠物信息如下:");
System.out.println("------------------------------");
//长度为0就打印全部信息
if (petList.length==0){
petList=pets;
}
for (int i = 0; i < petList.length; i++) {
//得到当前宠物
IPet pet = petList[i];
if (pet!=null){
//打印宠物信息
System.out.println("宠物的名称:"+pet.getName());
System.out.println("宠物的颜色:"+pet.getColor());
System.out.println("宠物的年龄:"+pet.getAge());
System.out.println("==============================");
}
}
System.out.println("---------------------------------");
}
}
测试类:
public class TestPet {
public static void main(String[] args) {
//构建页面
PetUI petUI = new PetUI();
petUI.showMenu();
}
}
13、Java异常类
13.1、编译期异常
1、文件未找到异常:FileNotFoundException
2、类不存在异常:ClassNotFoundException
/**
* 编译期异常
* 处理异常的方法一:使用throws关键字抛出对应的异常
*/
private static void test02() throws FileNotFoundException, ClassNotFoundException {
//文件不存在异常:FileNotFoundException
FileInputStream fileInputStream = new FileInputStream("c:/aa.txt");
//类不存在异常:ClassNotFoundException
Class.forName("xxx");
}
13.2、运行时异常
1、空指针异常:NullPointerException
2、数组下标越界异常:ArrayIndexOutOfBoundsException
3、算术异常:ArithmeticException
4、数字格式转换异常:NumberFormatException
5、输入不匹配异常:InputMismatchException
/**
*运行时异常RuntimeException
*/
private static void test01(Scanner scanner) {
//1、空指针异常:java.lang.NullPointerException
/*String str =null;
str.length();*/
//2、数组下标越界异常:ArrayIndexOutOfBoundsException
/*int[] a = new int[3];
a[3]=1;*/
//3、算术异常:ArithmeticException
//int i = 10 / 0;
//4、数字格式转换异常:NumberFormatException
//int a = new Integer("abc");
//5、输入不匹配异常:InputMismatchException
System.out.println("输入一个整数:");
int a = scanner.nextInt();
}
13.3、处理异常的方法
1、使用try…catch语句捕捉异常
2、使用throws抛出异常
3、使用自定义异常
13.4、try…finally的使用
/**
* 在try语句块中有return语句,此时,finally语句块是否执行,如果执行,是在return之前还是之后执行?(面试题)
* finally在return之前执行
*/
private static int test05(int i){
try {
System.out.println("(try)i = " + i);
return i++;
}finally {
System.out.println("(finally)i = " + i);
}
}
14、Java集合类
14.1、List接口
14.1.1、ArrayList子类
| 编号 | 方法名称 | 方法描述 | | :–: | :——————————————————–: | :——————————–: | | 1 | add(Object o)、add(int index,Object element) | 向集合中添加元素 | | 2 | addAll(Collection c)、addAll(int index,Collection c) | 将新集合中的元素添加到原来的集合中 | | 3 | remove(Object o)、remove(int index) | 从集合中移除元素 | | 4 | removeAll(Collection c) | 删除存在原来集合中的集合元素 | | 5 | set(int index,Object o) | 根据下标修改集合中对应的元素 | | 6 | get(int index) | 根据下标获取集合中的元素 | | 7 | contains() | 判断元素是否在集合中 |
/**
* ArrayList集合的基本使用
*/
@Test
public void test01(){
//创建一个List集合
List list = new ArrayList();
//添加集合元素
list.add("hello");
list.add(123);
list.add(3.4);
list.add('中');
list.add(true);
System.out.println("修改前的集合:"+list);
//修改集合元素
list.set(1,"world");
System.out.println("修改后的集合:"+list);
//添加多个元素
List smallList = new ArrayList();
smallList.add("aa");
smallList.add("bb");
smallList.add("cc");
list.addAll(smallList);
System.out.println("添加后的集合:"+list);
//遍历集合
//方法一:使用普通for循环
System.out.println("===== 使用普通for循环遍历 =====");
for (int i = 0; i < list.size(); i++) {
Object o = list.get(i);
System.out.print(o+" ");
}
//方法二:使用增强for循环
System.out.println("\n===== 使用增强for循环遍历 =====");
for (Object o : list) {
System.out.print(o+" ");
}
//方法三:使用迭代器Iterator
System.out.println("\n===== 使用迭代器Iterator遍历 =====");
Iterator iterator = list.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
System.out.print(next+" ");
}
//方法四:使用forEach循环遍历
System.out.println("\n===== 使用forEach循环遍历 =====");
list.forEach(f->{
System.out.print(f+" ");
});
//方法五:使用简化的forEach循环遍历
System.out.println("\n===== 使用简化的forEach循环遍历 =====");
list.forEach(System.out::println);
//方法六:使用stream流遍历
System.out.println("\n===== 使用stream流遍历 =====");
list.stream().forEach(System.out::println);
//根据下标移除集合元素
list.remove(3);
System.out.println("根据下标移除后的集合:"+list);
//根据指定内容移除集合元素
list.remove(true);
System.out.println("根据指定内容移除后的集合:"+list);
//移除多个元素
list.removeAll(smallList);
System.out.println("移除小集合后的集合:"+list);
}
14.1.2、Vector子类
/**
* Vector集合的基本使用
*/
@Test
public void test02(){
//创建一个List集合
List list = new Vector();
//添加集合元素
list.add("hello");
list.add(123);
list.add(3.4);
list.add('中');
list.add(true);
System.out.println("修改前的集合:"+list);
//修改集合元素
list.set(1,"world");
System.out.println("修改后的集合:"+list);
//添加多个元素
List smallList = new ArrayList();
smallList.add("aa");
smallList.add("bb");
smallList.add("cc");
list.addAll(smallList);
System.out.println("添加后的集合:"+list);
//遍历集合
//方法一:使用普通for循环
System.out.println("===== 使用普通for循环遍历 =====");
for (int i = 0; i < list.size(); i++) {
Object o = list.get(i);
System.out.print(o+" ");
}
//方法二:使用增强for循环
System.out.println("\n===== 使用增强for循环遍历 =====");
for (Object o : list) {
System.out.print(o+" ");
}
//方法三:使用迭代器Iterator
System.out.println("\n===== 使用迭代器Iterator遍历 =====");
Iterator iterator = list.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
System.out.print(next+" ");
}
//方法四:使用forEach循环遍历
System.out.println("\n===== 使用forEach循环遍历 =====");
list.forEach(f->{
System.out.print(f+" ");
});
//方法五:使用简化的forEach循环遍历
System.out.println("\n===== 使用简化的forEach循环遍历 =====");
list.forEach(System.out::println);
//方法六:使用stream流遍历
System.out.println("\n===== 使用stream流遍历 =====");
list.stream().forEach(System.out::println);
//根据下标移除集合元素
list.remove(3);
System.out.println("根据下标移除后的集合:"+list);
//根据指定内容移除集合元素
list.remove(true);
System.out.println("根据指定内容移除后的集合:"+list);
//移除多个元素
list.removeAll(smallList);
System.out.println("移除小集合后的集合:"+list);
}
14.1.3、Vector类与ArrayList类的区别
1、Vector集合开始出现在jdk1.0版本,ArrayList集合开始出现在jdk1.2版本
2、Vector集合是线程同步、安全性高、性能低;ArrayList集合是线程异步、性能更高
3、当集合容量不足时,Vector集合的长度会增加为原来的1倍,ArrayList集合的长度会增加为原来的1/2
14.1.4、ArrayList的应用:宠物超市
IPet接口:
/**
* 宠物类
*/
public interface IPet {
String getName();
String getColor();
int getAge();
}
Cat类:
/**
* 猫类
*/
public class Cat implements IPet{
private String name;
private String color;
private int age;
public Cat() {
}
public Cat(String name, String color, int age) {
this.name = name;
this.color = color;
this.age = age;
}
@Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Dog类:
/**
* 狗类
*/
public class Dog implements IPet{
private String name;
private String color;
private int age;
public Dog() {
}
public Dog(String name, String color, int age) {
this.name = name;
this.color = color;
this.age = age;
}
@Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
petUI界面类:
public class PetUI {
//创建宠物管理类对象
private PetManager manager = new PetManager();
/**
* 1、展示菜单
*/
public void showMenu() {
//1.1、展示菜单
System.out.println("========== 宠物商店 ==========");
System.out.println("[1] 添加宠物");
System.out.println("[2] 查看宠物");
System.out.println("[3] 查找宠物");
System.out.println("[4] 修改宠物");
System.out.println("[5] 退出系统");
System.out.println("=============================");
//1.2、用户选择
Scanner scanner = new Scanner(System.in);
userSelect(scanner);
}
/**
* 2、用户选择
*/
private void userSelect(Scanner scanner) {
//2.1、输入提示信息
System.out.println("请选择:");
int choice = scanner.nextInt();
//2.2、根据用户选择进入对应的菜单
switch (choice) {
case 1:
addPetMenu(scanner);
break;
case 2:
manager.printPetInfo(null);
break;
case 3:
searchPetMenu(scanner);
break;
case 4:
System.out.println("修改宠物");
break;
case 5:
System.exit(0);
break;
default:
System.out.println("请重新选择!");
break;
}
//2.3、是否继续选择菜单
System.out.println("是否继续选择(y/n):");
String isCon = scanner.next();
if ("y".equalsIgnoreCase(isCon)) {
userSelect(scanner);
}
}
/**
* 3、添加宠物菜单界面
*/
private void addPetMenu(Scanner scanner) {
//3.1、输入提示信息
System.out.println("请输入要添加宠物的类型(1:猫,2:狗):");
int type = scanner.nextInt();
System.out.println("请输入宠物的名称:");
String name = scanner.next();
System.out.println("请输入宠物的颜色:");
String color = scanner.next();
System.out.println("请输入宠物的年龄:");
int age = scanner.nextInt();
//3.2、构建宠物对象
IPet pet = null;
//3.3、根据类型构建对象
switch (type) {
case 1:
pet = new Cat(name, color, age);
break;
case 2:
pet = new Dog(name, color, age);
break;
default:
System.out.println("请重新输入!");
break;
}
//3.4、实现添加宠物
manager.addPet(pet);
}
/**
* 4、查找宠物界面
*/
private void searchPetMenu(Scanner scanner) {
//4.1、输入提示信息
System.out.println("请输入要查找宠物的关键字(名字或颜色):");
String keywords = scanner.next();
//4.2、打印查找的信息
manager.searchPet(keywords);
}
}
PetManager宠物管理类:
/**
* 宠物管理类
*/
public class PetManager {
//创建集合用来存储宠物对象
private List<IPet> pets = new ArrayList<IPet>();
/**
* 1、添加宠物
*/
public void addPet(IPet pet) {
pets.add(pet);
}
/**
* 2、打印宠物信息
*/
public void printPetInfo(List<IPet> petList) {
if (petList == null) {
petList = pets;
}
//打印宠物信息
System.out.println("宠物信息如下:");
for (IPet pet : petList) {
System.out.println("宠物的名称:" + pet.getName());
System.out.println("宠物的颜色:" + pet.getColor());
System.out.println("宠物的年龄:" + pet.getAge());
System.out.println("---------------------------");
}
}
/**
* 3、查找宠物
*/
public void searchPet(String keywords) {
//定义一个新集合用来存储查找的信息
List<IPet> list = new ArrayList<>();
for (IPet pet : list) {
if (pet.getName().contains(keywords) || pet.getColor().contains(keywords)){
list.add(pet);
}
}
//判断集合里面是否有内容
if (list.size()>0){
printPetInfo(list);
}else {
System.out.println("没有找到宠物!");
}
}
}
测试类:
public class TestPet {
public static void main(String[] args) {
PetUI petUI = new PetUI();
petUI.showMenu();
}
}
14.1.5、ArrayList泛型的使用
/**
* ArrayList泛型的使用
*/
@Test
public void test01(){
//1、定义一个ArrayList集合
List<Student> studentList = new ArrayList<>();
//2、为学生对象赋值
Student student1 = new Student(1001,"张三","男",20,"上海");
Student student2 = new Student(1002,"李四","男",21,"武汉");
Student student3 = new Student(1003,"王五","男",22,"成都");
//3、将学生对象添加到集合中去
studentList.add(student1);
studentList.add(student2);
studentList.add(student3);
//4、打印学生信息
//4.1、方法一:增强for循环
for (Student student : studentList) {
System.out.println(student);
}
System.out.println("-------------------------------------------------------------");
//4.2、方法二:使用流式编程
studentList.stream().forEach(System.out::println);
//5、修改学生
//5.1、定义修改后的学生对象
Student student4 = new Student(1004,"赵六","女",19,"杭州");
//5.2、开始修改
studentList.set(1,student4);
System.out.println("-------------------------------------------------------------");
studentList.forEach(System.out::println);
//6、删除学生
//6.1、根据下标删除
studentList.remove(1);
System.out.println("-------------------------------------------------------------");
studentList.forEach(System.out::println);
//6.2、根据内容删除
studentList.remove(student3);
System.out.println("-------------------------------------------------------------");
studentList.forEach(System.out::println);
}
14.1.6、LinkedList集合
/**
* LinkedList集合
*/
@Test
public void test02(){
//1、定义一个LinkedList集合
LinkedList<String> linkedList = new LinkedList<>();
//2、向集合中添加元素
linkedList.add("《三国演义》");
linkedList.addFirst("《西游记》");//将元素放到集合的头部
linkedList.addLast("《水浒传》");//将元素放到集合的尾部
linkedList.push("《红楼梦》");//入栈
//3、遍历集合
for (String s : linkedList) {
System.out.println(s);
}
System.out.println("------------");
//4、出栈元素(从栈顶取出一个元素)
String pop = linkedList.pop();
System.out.println("pop = " + pop);
System.out.println("------------");
for (String s : linkedList) {
System.out.println(s);
}
//5、查看栈顶元素(对栈元素没有影响)
String peek = linkedList.peek();
System.out.println("peek = " + peek);
System.out.println("------------");
for (String s : linkedList) {
System.out.println(s);
}
//6、判断集合是否为空
boolean empty = linkedList.isEmpty();
System.out.println("empty = " + empty);
//7、集合元素通过循环出栈演示
System.out.println("集合元素通过循环出栈演示:");
while (!linkedList.isEmpty()){
String pop1 = linkedList.pop();
System.out.println(pop1);
}
//8、获取集合的长度
int size = linkedList.size();
System.out.println("size = " + size);
}
14.2、Set接口
14.2.1、HashSet集合
/**
* 1、HashSet的用法
*/
@Test
public void test01(){
//1.1、定义一个Set集合
Set<String> set = new HashSet<>();
//1.2、向Set集合中添加元素
set.add("周4");
set.add("周1");
set.add("周3");
set.add("周2");
set.add("周6");
set.add("周5");
//1.3、遍历集合
//1.3.1、方法一:使用增强for循环
for (String s : set) {
System.out.print(s+" ");
}
System.out.println("\n---------------------");
//1.3.2、方法二:使用迭代器
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()){
String next = iterator.next();
System.out.print(next+" ");
}
System.out.println("\n---------------------");
//1.3.3、使用foreach
set.forEach(s -> System.out.print(s+" "));
System.out.println("\n---------------------");
//1.4、删除元素
set.remove("周3");
set.forEach(s -> System.out.print(s+" "));
}
14.2.2、TreeSet集合
/**
* 2、TreeSet集合
*/
@Test
public void test02(){
//2.1、定义一个Set集合
Set<String> set = new TreeSet<>();
//2.2、向Set集合中添加元素
set.add("周4");
set.add("周1");
set.add("周3");
set.add("周2");
set.add("周6");
set.add("周5");
//2.3、遍历集合
for (String s : set) {
System.out.print(s+" ");
}
}
14.3、Map接口
14.3.1、HashMap集合
/**
* 1、HashMap的用法
*/
@Test
public void test01(){
//1.1、定义一个HashMap集合
Map<Integer, Student> map = new HashMap<>();
//1.2、定义几个学生数据
Student student1 = new Student(1001,"张三","男",20,"上海");
Student student2 = new Student(1002,"李四","男",21,"武汉");
Student student3 = new Student(1003,"王五","男",22,"成都");
Student student4 = new Student(1004,"赵六","女",19,"杭州");
//1.3、将数据添加到集合中
map.put(student1.getId(),student1);
map.put(student2.getId(),student2);
map.put(student3.getId(),student3);
//1.4、遍历集合
//1.4.1、方法一:遍历所有的key的集合,通过key取得值
Set<Integer> keySet = map.keySet();
for (Integer key : keySet) {
Student student = map.get(key);
System.out.println(student);
}
//1.4.2、方法二:直接获取到值
Collection<Student> values = map.values();
for (Student value : values) {
System.out.println(value);
}
//1.4.3、方法三:将key和value看作一个整体进行遍历
Set<Map.Entry<Integer, Student>> entries = map.entrySet();
for (Map.Entry<Integer, Student> entry : entries) {
Integer key = entry.getKey();
Student value = entry.getValue();
System.out.println(key+"---->"+value);
}
//1.4.4、使用forEach遍历
map.forEach((k,v)->System.out.println(k+"---->"+v));
//1.5、修改集合元素
//1.5.1、如果不存在指定的key,就将元素添加到集合中去
map.putIfAbsent(student2.getId(),student4);
//1.5.2、如果在集合中已存在某个元素,可以使用put(),此时存在相同的key,那么新值会覆盖旧值
map.put(student2.getId(),student4);
map.forEach((k,v)->System.out.println(k+"---->"+v));
//1.6、根据key来删除集合元素
map.remove(1002);
map.forEach((k,v)->System.out.println(k+"---->"+v));
//1.7、替换元素
map.replace(1002,student2);
map.forEach((k,v)->System.out.println(k+"---->"+v));
//1.8、集合中是否包含指定的key
boolean b = map.containsKey(1002);
if (b){
Student student = map.get(1002);
System.out.println(student);
}
}
14.3.2、Hashtable集合
/**
* 2、Hashtable集合的用法
*/
@Test
public void test02(){
//2.1、定义一个HashMap集合
Hashtable<Integer, Student> map = new Hashtable<>();
//2.2、定义几个学生数据
Student stud1 = new Student(1001,"张三","男",20,"上海");
Student stud2 = new Student(1002,"李四","男",21,"武汉");
Student stud3 = new Student(1003,"王五","男",22,"成都");
Student stud4 = new Student(1004,"赵六","女",19,"杭州");
//2.3、将数据添加到集合中
map.put(stud1.getId(),stud1);
map.put(stud2.getId(),stud2);
map.put(stud3.getId(),stud3);
//2.4、遍历集合
//2.4.1、方法一:使用forEach遍历
map.forEach((k,v)->System.out.println(k+"---->"+v));
//2.4.2、方法二:使用枚举迭代器
Enumeration<Student> elements = map.elements();
while (elements.hasMoreElements()){
Student student = elements.nextElement();
System.out.println(student);
}
}
14.3.3、HashMap和Hashtable的区别
1、HashMap是JDK1.2后出现的新的集合类;Hashtable是JDK1.0后出现的旧的集合类。
2、HashMap是线程异步的,效率较高;Hashtable是线程同步的,效率较低,安全性较高
3、HashMap可以存放null键和null值;Hashtable放的话会出现空指针异常
4、二者都是key/value集合,都会出现在相同key的情况下出现新值覆盖旧值的情况
14.4、集合类的练习
案例一:从控制台接收10个整数进行排序,按降序在控制台输出
方法一:
/**
* 案例一:从控制台接收10个整数进行排序,按降序在控制台输出
* 方法一:使用Collections.sort()进行排序
*/
private static void test01(Scanner scanner) {
//定义一个整型集合
List<Integer> list = new ArrayList<>();
//通过循环录入10个数
System.out.println("请输入10个数字:");
for (int i = 0; i < 10; i++) {
//输入10个数
int num = scanner.nextInt();
//将这些数添加到集合中去
list.add(num);
}
//对集合进行升序排序
Collections.sort(list);
System.out.println("升序排列的集合:" + list);
//对集合进行降序排序
Comparator<Object> comparator = Collections.reverseOrder();
Collections.sort(list, comparator);
//打印集合
System.out.println("降序排列的集合:" + list);
}
方法二:
/**
* 案例一:从控制台接收10个整数进行排序,按降序在控制台输出
* 方法二:使用List集合
*/
private static void test02(Scanner scanner) {
//定义一个整型集合
List<Integer> list = new ArrayList<>();
//通过循环录入10个数
System.out.println("请输入10个数字:");
for (int i = 0; i < 10; i++) {
//输入10个数
int num = scanner.nextInt();
//将这些数添加到集合中去
list.add(num);
}
//对集合进行排序
//方法一:使用匿名内部类实现比较规则(降序)
list.sort(new Comparator<Integer>() {
@Override
public int compare(Integer a, Integer b) {
return b - a;
}
});
//方法二:自定义内部静态类实现比较规则
list.sort(null);
list.sort(new MyListComparator());
//方法三:使用lambda表达式
list.sort((a, b) -> b - a);
//方法四:使用stream排序
list.stream().sorted((a, b) -> b - a).forEach(r -> System.out.print(r + "\t"));
}
/**
* 自定义比较规则
*/
private static class MyListComparator implements Comparator<Integer> {
//b-a:降序
//a-b:升序
@Override
public int compare(Integer a, Integer b) {
return b - a;
}
}
案例二:写一个程序通过集合类Vector类,实现有学生添加、修改、查询、删除功能
/**
* 案例二:写一个程序通过集合类Vector类,实现有学生添加、修改、查询、删除功能。
*/
@Test
public void test04(){
//定义两个学生对象
Student student1 = new Student(1001,"张三","男",20,"上海");
Student student2 = new Student(1002,"李四","男",21,"武汉");
//定义一个学生管理类
StudentManager manager = new StudentManager();
//添加学生功能
manager.add(student1);
//修改学生功能
student1.setName("张小三");
student1.setAddress("杭州");
boolean b = manager.update(student1);
if (b){
System.out.println("修改成功!");
}
//查看学生
manager.findAll();
//删除学生
manager.delete(student1.getId());
}
/**
* 学生管理类
*/
public class StudentManager {
//定义存储学生对象的集合
private Map<Integer,Student> studentMap = new HashMap<>();
/**
*添加学生
*/
public void add(Student st1) {
studentMap.put(st1.getId(),st1);
}
/**
*修改学生
*/
public boolean update(Student st) {
//判断集合中是否包含key
if (studentMap.containsKey(st.getId())){
studentMap.put(st.getId(),st);
return true;
}
return false;
}
/**
* 查看学生
*/
public void findAll() {
System.out.println("学生信息如下:");
System.out.println("----------------------------------");
if (studentMap.size()>0){
studentMap.values().forEach(stud -> {
System.out.println("编号:"+stud.getId());
System.out.println("姓名:"+stud.getName());
System.out.println("性别:"+stud.getSex());
System.out.println("年龄:"+stud.getAge());
System.out.println("地址:"+stud.getAddress());
});
}else {
System.out.println("没有学生");
}
}
/**
* 删除学生
*/
public void delete(int id) {
if (studentMap.containsKey(id)){
studentMap.remove(id);
}else {
System.out.println("没有您要删除的学生信息");
}
}
}
案例三:写一个程序向List集合类添加”a”,”abc”,”ab”,”ac”,”ab”,”b”,”b”等字符串,找出集合中存在重复的字符串在控制台输出,不重复的不输出。
/**
* 功能: 案例三:写一个程序向List集合类添加”a”,”abc”,”ab”,”ac”,”ab”,”b”,”b”等字符串,
* 找出集合中存在重复的字符串在控制台输出,不重复的不输出。30分
*/
@Test
public void test01() {
//定义两个list集合和一个set集合
List<String> list1 = new ArrayList<>();//原始数据集合
List<String> list2 = new ArrayList<>();//元素不重复数据集合
Set<String> set = new HashSet<>();//元素重复数据集合
//向List1中添加元素
list1.add("a");
list1.add("abc");
list1.add("ab");
list1.add("ac");
list1.add("ab");
list1.add("b");
list1.add("b");
//遍历list1集合,看list2集合中是否有此元素
for (String s : list1) {
if (list2.contains(s)) {
set.add(s);
} else {
list2.add(s);
}
}
//打印set集合
System.out.println("set = " + set);
}
案例四:写一个方法排除掉List集合中的重复对象后输出
/**
* 案例四、写一个方法排除掉List集合中的重复对象后输出
*/
@Test
public void test02() {
//定义两个list集合和一个set集合
List<String> list1 = new ArrayList<>();//原始数据集合
List<String> list2 = new ArrayList<>();//元素不重复数据集合
Set<String> set = new HashSet<>();//元素重复数据集合
//向List1中添加元素
list1.add("a");
list1.add("abc");
list1.add("ab");
list1.add("ac");
list1.add("ab");
list1.add("b");
list1.add("b");
//遍历list1集合,看list2集合中是否有此元素
for (String s : list1) {
if (list2.contains(s)) {
set.add(s);
list2.remove(s);//在集合list2中移除在list1中出现的重复元素
} else {
list2.add(s);
}
}
//打印list1集合中元素不重复的数据
System.out.println("list2 = " + list2);
}
案例五:自已编写一个程序,将list集合中所有重复的字符串去掉,只保留非重复的。
/**
* 案例五:自已编写一个程序,将list集合中所有重复的字符串去掉,只保留非重复的。
*/
@Test
public void test03() {
//定义两个list集合和一个set集合
List<String> list1 = new ArrayList<>();//原始数据集合
List<String> list2 = new ArrayList<>();//元素不重复数据集合
Set<String> set = new HashSet<>();//元素重复数据集合
//向List1中添加元素
list1.add("a");
list1.add("abc");
list1.add("ab");
list1.add("ac");
list1.add("ab");
list1.add("b");
list1.add("b");
//遍历list1集合,看list2集合中是否有此元素
for (String s : list1) {
if (list2.contains(s)) {
set.add(s);
} else {
list2.add(s);
}
}
//在list1集合中移除重复的元素
list1.removeAll(set);
//打印list1集合中元素不重复的数据
System.out.println("list1 = " + list1);
}
案例六:有以下字符串String str=“56.89.5.3.75.98.98.26.15.44”,请定义一个类,写个方法,实现对该字符串按照.号进行分隔,并将结果按照从大到小的顺序进行排列。
/**
* 功能: 案例六:有以下字符串String str=“56.89.5.3.75.98.98.26.15.44”,请定义一个类,
* 写个方法,实现对该字符串按照.号进行分隔,并将结果按照从大到小的顺序进行排列。
*/
@Test
public void test04() {
//定义一个字符串
String str = "56.89.5.3.75.98.98.26.15.44";
//定义一个整型的list集合用来存储分割后的数据
List<Integer> list = new ArrayList<>();
//定义字符串的分割
String[] split = str.split("\\.");
//遍历数组
for (String s : split) {
//将每一项转换成整数后添加到集合中去
list.add(new Integer(s));
}
//对集合进行排序
list.sort((a, b) -> b - a);
//打印排序后的集合
list.forEach(r -> System.out.print(r + "\t"));
}
案例七:编一段代码,实现在控制台输入一组数字后,排序后在控制台输出
public static void main(String[] args) {
test05(new Scanner(System.in));
}
/**
* 案例七:编一段代码,实现在控制台输入一组数字后,排序后在控制台输出 。
*/
private static void test05(Scanner scanner) {
//定义一个存放数字的集合
List<Integer> list = new ArrayList<>();
//开始输出
System.out.println("开始输入一组数据:");
while (true){
//得到输入的数字
String number = scanner.next();
//判断输入的数字是否是end
if (number.equals("end")){
break;
}
//使用正则表达式提取数字
if (number.matches("[^0-9]+$")){
list.add(new Integer(number));
}
}
//对数字集合进行排序
Collections.sort(list);
//打印集合
System.out.println(list);
}
案例八:从类似如下的文本文件中读取出所有的姓名,并打印出重复次数最多的姓名和重复的次数。
@Test
public void test01() {
//1、定义一个list集合并且将这些数据添加到集合
List<String> list = Arrays.asList("1,张三,28", "2,李四,35", "3,张三,28", "4,王五,35", "5,张三,28", "6,李四,35", "7,赵六,28", "8,田七,35");
//2、定义一个map集合存储取出来的姓名和出现的次数
Map<String, Integer> map = new HashMap<>();
//3、遍历list集合
for (String s : list) {
//3.1、根据逗号拆分字符串
String[] split = s.split(",");
//3.2、得到人名
String name = split[1];
//3.3、根据人名获取出现的次数
Integer count = map.get(name);
//3.4、如果出现的次数为null,证明是第一次将人名放进map中
if (count == null) {
count = 0;
}
//3.5、将人名作为key,次数作为键存入到map集合中
map.put(name, count + 1);
}
//4、找到人名出现最多的次数
Integer max = Collections.max(map.values());
System.out.println("max = " + max);
//5、遍历map集合
map.forEach((k, v) -> {
if (v == max) {
System.out.print(k + "\t");
}
});
}
15、Java常用类的使用
随机数类:
/**
* Random类的基本用法
*/
@Test
public void test01(){
//1、定义一个随机数类对象
Random random = new Random();
//2、查看一个整数范围内的随机数
//2.1、查看整数范围
int minValue = Integer.MIN_VALUE;
int maxValue = Integer.MAX_VALUE;
System.out.println("minValue = " + minValue);
System.out.println("maxValue = " + maxValue);
//2.2、输出随机数
int i = random.nextInt();
System.out.println("i = " + i);
//3、在指定整数范围内产生随机数
int i1 = random.nextInt(100);
System.out.println("在[0,100)内的随机数:" + i1);
//4、如何产生一个指定范围内的随机数?(m,n)之间的随机数?
//4.1、定义参数的范围
int m = 10,n=50;
//4.2、产生在(0,n-m)之间的随机数
int i2 = random.nextInt(n - m);
//4.3、将当前获取的随机数加上m,即获取(m,n)之间的随机数
int x = i2+m;
//打印输出的随机数
System.out.println("在[m,n)内的随机数:" + x);
}
日期类:
/**
* 1、日期类(Date)
*/
@Test
public void test01() {
//1.1、定义一个日期对象
Date dt = new Date();
//1.2、获取当前系统时间
String s = dt.toLocaleString();
System.out.println("当前系统时间:" + s);
//1.3、得到日期的各个部分
//1.3.1、获取当前日期的年份
int year = dt.getYear() + 1900;
//1.3.2、获取当前日期的月份
int month = dt.getMonth() + 1;
//1.3.3、获取当前日期的日
int date = dt.getDate();
//1.3.4、获取当前日期的时
int hours = dt.getHours();
//1.3.5、获取当前日期的分
int minutes = dt.getMinutes();
//1.3.6、获取当前日期的秒
int seconds = dt.getSeconds();
System.out.println(year + "-" + month + "-" + date + " " + hours + ":" + minutes + ":" + seconds);
}
日期格式化类:
/**
* 2、日期格式化类(SimpleDateFormat)
*/
@Test
public void test02() {
//获取当前时间
Date date = new Date();
//创建一个SimpleDateFormat对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");
//对当前日期进行格式化处理
String format = sdf.format(date);
//打印结果
System.out.println("format = " + format);
}
日历类:
/**
* 3、日历类(Calendar)
*/
@Test
public void test03() {
//3.1、创建日历类对象
Calendar calendar = Calendar.getInstance();
//3.2、得到日历的各个部分
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH) + 1;
int date = calendar.get(Calendar.DAY_OF_MONTH);
int hours = calendar.get(Calendar.HOUR_OF_DAY);
int minutes = calendar.get(Calendar.MINUTE);
int seconds = calendar.get(Calendar.SECOND);
//3.3、打印
System.out.println(year + "-" + month + "-" + date + " " + hours + ":" + minutes + ":" + seconds);
//3.4、修改日历
//3.4.1、修改指定年月日
calendar.set(2000, 1, 1);
//3.4.2、查看修改后的日历
Date time = calendar.getTime();
System.out.println(time.toLocaleString());
//3.4.3、修改年份
calendar.set(Calendar.YEAR, 2010);
System.out.println(calendar.getTime().toLocaleString());
//3.4.4、添加指定日期
calendar.add(Calendar.MONTH, 5);
System.out.println(calendar.getTime().toLocaleString());
}
日历类的应用:
/**
* 案例一:求从2013年1月1日起,至2013年12月31日止,有多少个星期日
*/
@Test
public void test04() {
//1、创建日历类
Calendar calendar = Calendar.getInstance();
//2、将日期修改为2013年1月1日
calendar.set(2013, 1 - 1, 1);
//3、定义一个计数器来统计出现星期日的次数
int count = 0;
//4、开始循环
while (true) {
//4.1、得到当前年份数,如果年份数不等于2013则跳出循环
int year = calendar.get(Calendar.YEAR);
if (year != 2013) {
break;
}
//4.2、判断当前的星期数是不是星期日
if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
count++;
//格式化当前日期
String dtStr = formatDate(calendar.getTime());
//输出当前日期
System.out.println(dtStr);
}
//4.3、将当前日期增加1天
calendar.add(Calendar.DATE, 1);
}
System.out.println("2013年一共有" + count + "个星期日");
}
/**
* 日期格式化
*/
private String formatDate(Date time) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss E");
return sdf.format(time);
}
/**
* 案例二:求本月所有星期六的日期,并以yyyy年MM月dd日的方式输出?
*/
@Test
public void test05() {
//1、创建日历类
Calendar calendar = Calendar.getInstance();
//2、修改日期为本月1日
calendar.set(Calendar.DATE, 1);
//3、得到当前月份数
int month = calendar.get(Calendar.MONTH);
//4、开始循环
while (true){
//4.1、判断当前月份数是不是本月
if (calendar.get(Calendar.MONTH)!=month){
break;
}
//4.2、判断是否是星期六,如果是就打印
if (calendar.get(Calendar.DAY_OF_WEEK)==Calendar.SATURDAY){
String dtStr = formatDate(calendar.getTime());
System.out.println(dtStr);
}
//4.3、每次添加1天
calendar.add(Calendar.DATE,1);
}
}
JDK8新特性 LocalDateTime类和ZonedDateTime类:
/**
* LocalDateTime与ZonedDateTime的使用
*/
@Test
public void test01() {
//1.1、得到LocalDateTime对象(LocalDateTime: 本地日期时间处理类)
LocalDateTime now = LocalDateTime.now();
//1.2、将上面的对象进行格式化处理
// String format = now.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E"));
// String format = now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
//ZonedDateTime: 代表一个跟时区相关的日期时间类,一般在一些通过框架中使用springboot/springCloud
String string = ZonedDateTime.now().toString();
System.out.println("string = " + string);
String fmt = ZonedDateTime.now().format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL));
//String format = now.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL));
//1.3、打印
System.out.println("fmt = " + fmt);
//1.4、修改时间并格式化(LocalDateTime的用法)
//1.4.1、增加时间,可以是负数
// String dtStr = now.plus(1, ChronoUnit.YEARS)
// .format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E"));
String dtStr = now.plusYears(1).format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E"));
System.out.println("dtStr = " + dtStr);
//1.4.2、减少1月
//now.minus(1,ChronoUnit.MONTHS);
dtStr = now.minusMonths(1).format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E"));
System.out.println("dtStr = " + dtStr);
//1.4.3、增加一天
dtStr = now.plusDays(1).format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E"));
System.out.println("dtStr = " + dtStr);
//1.5、修改日期与时间(ZonedDateTime的用法)
// dtStr = ZonedDateTime.now().plus(5, ChronoUnit.DAYS) //通用写法
dtStr = ZonedDateTime.now().plusDays(5) //简化写法
.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL));
System.out.println("dtStr = " + dtStr);
}
LocalDateTime类的应用:
1、使用LocalDateTime修改时间
/**
* 1、使用LocalDateTime修改时间
*/
@Test
public void test01() {
//1.1、定义LocalDateTime对象
String format = LocalDateTime.now()
.withYear(2011) //年份
.with(ChronoField.MONTH_OF_YEAR, 10) //月
.withDayOfMonth(20) //日
.withHour(12).withMinute(30).withSecond(50) //时分秒
.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E"));
//1.2、打印结果
System.out.println(format);
}
2、求本月所有星期六的日期,并以yyyy年MM月dd日的方式输出
/**
* 2、求本月所有星期六的日期,并以yyyy年MM月dd日的方式输出
*/
@Test
public void test02() {
//2.1、将当前时间的天数修改为当前月份的第一天
LocalDateTime dt = LocalDateTime.now().withDayOfMonth(1);
//2.2、得到当前时间的月份数
int month = dt.getMonthValue();
System.out.println("month = " + month);
//2.3、构造一个循环每次添加一天,直到月份数不是当前月
while (true) {
//2.3.1、判断是否是星期六
if (dt.getDayOfWeek() == DayOfWeek.SATURDAY) {
String dtStr = dt.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 E"));
System.out.println(dtStr);
}
//2.3.2、判断是否是本月,不是就退出
if (dt.getMonthValue() != month) {
break;
}
//2.3.3、每次增加一天
dt = dt.plusDays(1);
}
}
3、写一程序在控制台输出,今年下半年中,所有日期尾号是3、6、9的日期。如:3号、6号、9号、13号、16号、19号
/**
* 3、写一程序在控制台输出,今年下半年中,所有日期尾号是3、6、9的日期。如:3号、6号、9号、13号、16号、19号
*/
@Test
public void test03() {
//3.1、得到当前日期并修改为7月1日
LocalDateTime dt = LocalDateTime.now().withMonth(7).withDayOfMonth(1);
//3.2、得到当前日期的年份
int year = dt.getYear();
//3.3、构造一个循环,每次增加一天,判断当前天数的尾号是否是3、6、9
while (true) {
//3.3.1、得到当前天数
int day = dt.getDayOfMonth();
//3.3.2、判断个位数是否是3、6、9
if (day % 10 == 3 || day % 10 == 6 || day % 10 == 9) {
String dtStr = dt.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 E"));
System.out.println(dtStr);
}
//3.3.3、判断退出条件
if (dt.getYear() != year) {
break;
}
//3.3.4、每次增加一天
dt = dt.plusDays(1);
}
}
4、根据所学的java类库,设计一个方法,随机输入一个日期(例如2014-4-15)后,得到该日期对应星期几,距离下个月的1日(2014-5-1)还有多少天
/**
* 1、根据所学的java类库,设计一个方法,随机输入一个日期(例如2014-4-15)后,得到该日期对应星期几,距离下个月的1日(2014-5-1)还有多少天
*/
@Test
public void test01() {
//1.1 根据传入的日期字符串,返回这个日期距离下个月一号的天数
int days = getDays("2020-04-15");
System.out.println("距离下个月一号还有:" + days + "天!");
}
/**
* 2、根据传入的日期串,返回当前日期距离下个月一号的天数
*
* @param dtStr
* @return
*/
private int getDays(String dtStr) {
//2.1、转换字符串为日期
LocalDate dt = LocalDate.parse(dtStr, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
//2.2、得到当前月份数
int month = dt.getMonthValue();
//2.3、定义代表天数的计数器
int count = 0;
//2.4、构造循环,判断是否到了下个月一号
while (true) {
//2.4.1、每次增加一天
dt = dt.plusDays(1);
//2.4.2、累加计数器
count++;
//2.4.3、判断是否到达下个月
if (dt.getMonthValue() != month) {
break;
}
}
//2.5、返回实际的天数
return count;
}
5、将字符串”2021-1-1″表示的日期数据,使用LocalDate进行封装,并继续下面要求
/**
* 1、案例二:将字符串"2021-1-1"表示的日期数据,使用LocalDate进行封装,并继续下面要求 (20分)
* 1)输出为星期几(10分)
* 2)计算上面"2021-1-1"日期距离今天有多少天(10分)
*/
@Test
public void test01() {
//1.1、调用方法根据传入的日期串,返回距离今天的天数
int days = getDays("2021-01-01");
//1.2、打印天数
System.out.println("days = " + days);
}
private int getDays(String s) {
//2.1、定义返回的结果计数器
int count = 0;
//2.2、首先,将传入的日期字符串转换为日期对象LocalDate
LocalDate dt = LocalDate.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
//2.3、得到今天的年月日
LocalDate now = LocalDate.now();
//2.4、得到今天的年份数
int year = now.getYear();
//2.5、得到今天的月份数
int month = now.getMonthValue();
//2.6、得到今天的天数
int day = now.getDayOfMonth();
//2.7、开始循环,判断如果到达当前日期就退出
while (true) {
//2.7.1、每次增加一天
dt = dt.plusDays(1);
//2.7.2、累加计数器
count++;
//2.7.3、判断是否是今天的日期,如果是就退出
if (dt.getYear() == year && dt.getMonthValue() == month && dt.getDayOfMonth() == day) {
break;
}
}
//2.8、返回计数器对应的天数
return count;
}
6、根据所学的java类库,设计一个方法,随机输入一个日期(例如2021-4-15)
/**
* 1、根据所学的java类库,设计一个方法,随机输入一个日期(例如2021-4-15)
*/
@Test
public void test01() {
int days = getDays("2021-04-15");
System.out.println("距离下个月1号还有:" + days + "天!");
}
private int getDays(String dtStr) {
//2.1、将传入的日期串转换为日期对象
Date dt = MyUtil.convertToDate(dtStr);
//2.2、定义当前时间的日历对象
Calendar cal = Calendar.getInstance();
cal.setTime(dt);
//2.3、定义计数器
int count = 0;
//2.4、得到当前的月份数
int month = cal.get(Calendar.MONTH);
//2.5、循环判断,是否到达5月,如果到达就退出
while (true) {
//2.5.1、每次增加一天
cal.add(Calendar.DAY_OF_MONTH, 1);
//2.5.2、累加计数器
count++;
//2.5.3、判断当前的月份数是否与源来的相等,不相等证明到达了下个月
if (cal.get(Calendar.MONTH) != month) {
break;
}
}
//2.6 返回天数
return count;
}
public class MyUtil {
/**
* 将日期字符串转换为日期对象
* @param dtStr 日期字符串
* @return 返回值
*/
public static Date convertToDate(String dtStr) {
//1.1 定义SimpleDateFormat对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//1.2 转换并输出
try {
return sdf.parse(dtStr);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
16、Java IO流操作
16.1、File类的使用
File类对文件的操作:
/**
* 1、File类操作文件
*/
@Test
public void test01() throws IOException {
//1.1、定义一个File类
File file = new File("d:/abc.txt");
//1.2、判断文件是否存在
if (!file.exists()) {
//文件不存在就创建文件
file.createNewFile();
}
//1.3、查看文件是否可读、可写、可执行
boolean canRead = file.canRead(); //是否可读
boolean canWrite = file.canWrite(); //是否可写
boolean canExecute = file.canExecute(); //是否可执行
System.out.println("canRead = " + canRead + ", canWrite = " + canWrite + ", canExecute = " + canExecute);
//1.4、查看文件大小(以字节为单位)
long length = file.length();
System.out.println("length = " + length);
//1.5、查看文件名和文件路径
String fileName = file.getName();
System.out.println("文件名:" + fileName);
String fileAbsolutePath = file.getAbsolutePath();
System.out.println("文件的绝对路径:" + fileAbsolutePath);
String fileParent = file.getParent();
System.out.println("文件的父路径:" + fileParent);
//1.6、查看文件所在磁盘的总共大小(以字节为单位)
long totalSpace = file.getTotalSpace();
System.out.println("磁盘总大小:" + totalSpace / 1024 / 1024 / 1024 + "GB.");
//1.7、查看文件所在磁盘的可用大小
long freeSpace = file.getFreeSpace();
System.out.println("磁盘可用大小:" + freeSpace / 1024 / 1024 / 1024 + "GB.");
//1.8、给文件改名
file.renameTo(new File("d:/ac.txt"));
//1.9、删除文件
file.delete();
}
File类对文件夹的操作:
/**
* 2、File类操作文件夹
*/
@Test
public void test02(){
//2.1、创建单个文件夹
File dir = new File("d:/abcd");
//2.2、判断该文件夹是否存在
if (!dir.exists()){
dir.mkdir();
}
//2.3、创建多个文件夹
dir = new File("d:/a/b/c");
if (!dir.exists()){
dir.mkdirs();
}
//2.4、判断是文件还是文件夹
boolean dirDirectory = dir.isDirectory();
boolean dirFile = dir.isFile();
System.out.println("dirDirectory = " + dirDirectory);
System.out.println("dirFile = " + dirFile);
//2.5、遍历文件夹
//2.5.1、查看文件夹中的文件及文件夹名字
File dirs = new File("d:/java");
String[] list = dirs.list();
for (String s : list) {
System.out.println(s);
}
System.out.println("--------------------------------------------");
//2.5.2、将指定文件夹中的文件及文件夹遍历到File数组中
File[] files = dirs.listFiles();
for (File file : files) {
System.out.println(file.getAbsolutePath()+",大小:"+file.length());
}
}
File类的应用:
/**
* 3、File类实战-查看指定文件夹下所有内容(含子文件夹)
*/
@Test
public void test03(){
//3.1、定义要查看的文件夹
File dirs = new File("d:/java");
//3.2、定义要查看目录的文件
getDirs(dirs);
}
/**
* 递归查看指定文件夹
*/
private void getDirs(File dirs) {
if (dirs.isDirectory()){
System.out.println("[目录]:"+dirs.getAbsolutePath());
for (File file : dirs.listFiles()) {
getDirs(file);
}
}else {
System.out.println(dirs.getAbsolutePath());
}
}
16.2、字节流的使用
字节输入流:FileInputStream
/**
* 1、使用FileInputStream读取文件
*/
@Test
public void test01() throws IOException {
//1.1、定义文件对象
File file = new File("d:/abc.txt");
//1.2、定义输入流对象
FileInputStream fileInputStream = new FileInputStream(file);
//1.3、定义存放读取数据的数组
byte[] b = new byte[(int) file.length()];
//1.4、将文件读取到字节数组中
fileInputStream.read(b);
//1.5、将字节数组转换为字符串
String str = new String(b);
//1.6、打印
System.out.println("str = " + str);
//1.7、关闭流
fileInputStream.close();
}
字节输出流:FileOutputStream
/**
* 2、使用FileOutputStream读取文件
*/
@Test
public void test02() throws IOException {
//2.1、定义文件对象
File file = new File("d:/abc.txt");
//2.2、定义输出流对象
//情况一:采用覆盖的方式定义输出流
//FileOutputStream fileOutputStream = new FileOutputStream(file);
//情况二:采用追加的方式定义输出流
FileOutputStream fileOutputStream = new FileOutputStream(file,true);
//2.3、准备要写出去的数据
String info = "hahaha";
//2.4、将字符串转换为字节数组
byte[] bytes = info.getBytes();
//2.5、将指定的字节数组输出
fileOutputStream.write(bytes);
//2.6、关闭流
fileOutputStream.close();
}
字节流的应用:
案例一:使用字节流读写文本文件
/**
*3、使用字节流读写文本文件
*/
@Test
public void test03() throws IOException{
//3.1、定义要读取的文件对象
File file = new File("d:/abc.txt");
//3.2、定义要写入的文件对象
File destFile = new File("e:/abc.txt");
//3.3、定义输入流与输出流
FileInputStream fileInputStream = new FileInputStream(file);
FileOutputStream fileOutputStream = new FileOutputStream(destFile);
//3.4、定义存放数据的字节数组
byte[] b = new byte[(int) file.length()];
//3.5、将文件中的内容读取到字节数组中
fileInputStream.read(b);
//3.6、将字节数组中的数据写入到目标文件中
fileOutputStream.write(b);
//3.7、关闭流
fileInputStream.close();
fileOutputStream.close();
}
案例二:实现mp3文件的复制功能
/**
* 4、实现mp3文件的复制功能
*/
@Test
public void test04() throws IOException{
//4.1、定义要读取的源文件
File file = new File("f:/music/HandClap.mp3");
//4.2、定义要追加的目标文件
File destFile = new File("f:/music/生僻字.mp3");
//4.3、定义文件输入流对象
FileInputStream fileInputStream = new FileInputStream(file);
//4.4、定义文件输出流对象
FileOutputStream fileOutputStream = new FileOutputStream(destFile);
//4.5、定义存放读取数据的字节数组
byte[] b = new byte[(int) file.length()];
//4.6、将文件中的内容读取到字节数组中
fileInputStream.read(b);
//4.7、将字节数组中的数据写入到目标文件中
fileOutputStream.write(b);
//4.8、关闭流
fileInputStream.close();
fileOutputStream.close();
}
16.3、字符流的使用
字符输入流:FileReader
/**
* 1、FileReader读取文件内容
*/
@Test
public void test01() throws IOException {
//1.1、定义要读取的文件对象
File file = new File("d:/abc.txt");
//1.2、定义输入流对象
FileReader fileReader = new FileReader(file);
//1.3、定义存放数据的字符数组
char[] ch = new char[(int) file.length()];
//1.4、读取文件存放到字符数组中
fileReader.read(ch);
//1.5、将字符数组转换为字符串
String info = new String(ch);
//1.6、输出
System.out.println("info = " + info);
//1.7、关闭流
fileReader.close();
}
字符输出流:FileWriter
/**
* 2、FileWrite写入文件内容
*/
@Test
public void test02() throws IOException{
//2.1、定义要写入的文件内容
File file = new File("d:/abc.txt");
//2.2、定义文件的输出流写入文件内容,以追加的方式添加内容
FileWriter fileWriter = new FileWriter(file,true);
//2.3、定义要写入的文件内容
String info ="hello,java";
//2.4、开始写入文件内容
fileWriter.write(info);
//2.5、关闭流
fileWriter.close();
}
字符流的应用:
案例一:实现文本文件的复制
/**
* 3、实现文本文件的复制
*/
@Test
public void test03() throws IOException{
//3.1、定义源文件
File file = new File("d:/abc.txt");
//3.2、定义目标文件
File destFile = new File("d:/ab.txt");
//3.3、定义输入流对象用来读取文件内容
FileReader fileReader = new FileReader(file);
//3.4、定义输出流对象用来写入文件内容
FileWriter fileWriter = new FileWriter(destFile);
//3.5、定义字符数组用来存放读取的文件内容
char[] ch = new char[(int)file.length()];
//3.6、开始读取内容
fileReader.read(ch);
//3.7、将字符数组中的内容写入到目标文件中
fileWriter.write(ch);
//3.8、关闭流
fileReader.close();
fileWriter.close();
}
案例二:将某个目录下的.java的文件所有文件复制至另一个目录下,子目录文件也能复制
/**
*案例一:将某个目录下的.java的文件所有文件复制至另一个目录下,子目录文件也能复制
*/
@Test
public void test01() throws IOException {
//1.1、定义要读取文件的对象
File file = new File("d:/javabak");
//1.2、递归进行文件的复制
getDirs(file);
}
/**
* 2、递归复制文件
*/
private void getDirs(File file) throws IOException{
//2.1、如果是目录就递归
if (file.isDirectory()){
File[] files = file.listFiles();
for (File f : files) {
getDirs(f);
}
}else { //2.2、如果是文件,并且文件后缀名为.java,就复制文件
//2.2.1、得到文件名
String name = file.getName();
//2.2.2、判断后缀名是.java
if (name.endsWith(".java")){
//2.2.3、定义要复制到目标文件的对象
//第一步:得到源文件的父路径
String parent = file.getParent();
//第二步:将源文件的父路径替换成目标文件的父路径
String destParent = parent.replace("d:", "e:");
//第三步:根据源文件父路径创建多级文件夹
File parentDir = new File(destParent);
if (!parentDir.exists()){
parentDir.mkdirs();
}
//第四步:构建目标文件对象
File destFile = new File(parentDir,name);
//2.2.4、定义输入流对象用来读取文件内容
FileReader fileReader = new FileReader(file);
//2.2.5、定义输出流对象用来写入文件内容
FileWriter fileWriter = new FileWriter(destFile);
//2.2.6、定义字符数组用来存放读取的文件内容
char[] ch = new char[(int)file.length()];
//2.2.7、开始读取内容
fileReader.read(ch);
//2.2.8、将字符数组中的内容写入到目标文件中
fileWriter.write(ch);
//2.2.9、关闭流
fileReader.close();
fileWriter.close();
}
}
}
案例三:将指定文件中内容读取按指定格式输出
/**
* 案例二:将指定文件中内容读取按指定格式输出
* 方法一:对字符串按照|进行拆分
*/
@Test
public void test02() throws IOException{
//定义要读取的文件对象
File file = new File("f:/testdemo.txt");
//定义输入流对象
FileReader fileReader = new FileReader(file);
//定义存放读取的文件内容的字符数组
char[] ch = new char[(int) file.length()];
fileReader.read(ch);
//将字符数组转换为字符串
String info = new String(ch);
//将字符串进行拆分
String[] split = info.split("\\|");
//对拆分后的数组进行打印
for (String s : split) {
System.out.println(s);
}
//关闭流
fileReader.close();
}
/**
* 案例二:将指定文件中内容读取按指定格式输出
* 方法二:对字符串按照|进行拆分
*/
@Test
public void test03() throws IOException{
//定义要读取的文件对象
File file = new File("f:/testdemo.txt");
//定义输入流对象
FileReader fileReader = new FileReader(file);
//定义存放读取的文件内容的字符数组
char[] ch = new char[(int) file.length()];
fileReader.read(ch);
//将字符数组转换为字符串
String info = new String(ch);
//将字符串中的|替换成\n
String replace = info.replace("|", "\n");
System.out.println(replace);
//关闭流
fileReader.close();
}
案例四:递归某个指定目录,并输出此目录下的文件后缀名及后缀名出现的次数
/**
* 案例三:递归某个指定目录,并输出此目录下的文件后缀名及后缀名出现的次数
*/
@Test
public void test04(){
//定义一个大Map
Map<String,Map<String,Integer>> mapMap = new HashMap<>();
//定义要读取的文件对象
File file = new File("d:/java");
//进行递归调用
getFiles(file,mapMap);
//打印map值
System.out.println(mapMap);
}
/**
* 读取指定目录下的后缀名及其出现的次数
*/
private void getFiles(File file, Map<String, Map<String, Integer>> mapMap) {
//如果是目录就递归
if (file.isDirectory()){
//得到子目录
File[] files = file.listFiles();
//将当前的目录路径放到大map中作为key,其值为新的小map
mapMap.put(file.getAbsolutePath(), new HashMap<>());
//进行递归调用
for (File f : files) {
getFiles(f,mapMap);
}
}else{ //如果是文件就得到文件的父路径,根据父路径得到上面添加进去的小map,从而在小map中放后缀名和出现的次数
//得到当前文件的父路径
String parent = file.getParent();
//根据父路径得到小map
Map<String,Integer> small = mapMap.get(parent);
//得到当前文件的后缀名
//得到文件名
String name = file.getName();
//得到文件的后缀名
int index = name.lastIndexOf(".");
String suffix = ""; //代表后缀名
if (index > -1){
suffix = name.substring(index);
}
//根据后缀名在小map中获取出现的次数
Integer count = small.get(suffix);
//如果是第一次出现,次数为null,为count设置默认值为0
if (count == null){
count = 0;
}
//将当前后缀名出现的次数加1后添加到小map中
small.put(suffix,count + 1);
}
}
16.4、缓冲流的使用
缓冲输入流:BufferReader
import java.io.*;
/**
* Reader字符输入流(读文件)
* -子类BufferedReader
* -缓冲区,效率更高
*/
public class Demo04 {
public static void main(String[] args) {
//show1();
show2();
}
private static void show2() {
//通过InputStreamReader指定编码
try(FileInputStream inputStream = new FileInputStream("file/a.txt");
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "GBK");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader)){
//读完
String line;
while ((line = bufferedReader.readLine()) != null) {
//读不到换行符,所以需要println
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static void show1() {
try (FileReader fileReader = new FileReader("file/a.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader)) {
/**
* 读取一行,游标下移
* 返回读取到的内容,读不到时,返回null
* 读不到换行符
*/
//读一次
/* String line = bufferedReader.readLine();
System.out.println(line);
String line2 = bufferedReader.readLine();
System.out.println(line2);*/
//读完
String line;
while ((line = bufferedReader.readLine()) != null) {
//读不到换行符,所以需要println
System.out.println(line);
}
//可以读取到换行符
/*char[] c = new char[10];
int length;
while((length = bufferedReader.read(c)) != -1){
String s = new String(c, 0, length);
System.out.print(s);
}*/
} catch (IOException e) {
e.printStackTrace();
}
}
}
缓冲输出流:BufferWriter
import java.io.*;
/**
* Writer字符输出流(写文件)
* -子类BufferedWriter
* 带缓冲区,效率更高
*/
public class Demo08 {
public static void main(String[] args) {
//show1();
show2();
}
private static void show2() {
//BufferedWriter使用OutputStreamWriter构造,指定输出文件的编码
try (FileOutputStream outputStream = new FileOutputStream("file/d.txt");
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, "GBK");
BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter)) {
//输出字符串到文件中
String s = "Hello你好啊";
bufferedWriter.write(s);
//新建一行(输出一个换行符)
bufferedWriter.newLine();
bufferedWriter.write(s);
//输出流关闭前,刷新缓冲区
bufferedWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void show1() {
//BufferedWriter使用FileWriter构造,无法指定编码,默认当前程序的编码输出
try (FileWriter fileWriter = new FileWriter("file/c.txt");
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) {
//输出字符串到文件中
String s = "Hello你好啊";
bufferedWriter.write(s);
//新建一行(输出一个换行符),方案一:
bufferedWriter.newLine();
//新建一行(输出一个换行符),方案二:
//bufferedWriter.write("\r\n");
bufferedWriter.write(s);
//输出流关闭前,刷新缓冲区
bufferedWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
缓冲流的应用:
案例一:实现文本文件的复制
import java.io.*;
/**
* 练习:复制文本文件
* 复制文件:C:/Windows/setupact.log
* 到文件:D:/myFile/myPrime.txt
*/
public class Demo09 {
public static void main(String[] args) {
//判断目标文件夹是否存在
File file = new File("D:/myFile");
if (!file.exists()) {
//不存在则创建该文件夹
boolean mkdir = file.mkdir();
System.out.println("是否创建文件夹:" + mkdir);
}
try (InputStream inputStream = new FileInputStream("C:/Windows/setupact.log");
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "GBK");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
OutputStream outputStream = new FileOutputStream("D:/myFile/myPrime.txt");
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, "GBK");
BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter)) {
//读取内容
String line;
while ((line = bufferedReader.readLine()) != null) {
//将内容写到指定文件中,使用GBK编码输出
bufferedWriter.write(line);
//输出换行符
bufferedWriter.newLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
16.5、数据流的使用
数据输入流:DataInputStream
数据输出流:DataOutputStream
数据流的应用:
案例一:实现二进制文件的读写
import java.io.*;
/**
* 二进制文件的读写
*/
public class Demo10 {
public static void main(String[] args) {
try (InputStream inputStream = new FileInputStream("file/1.jpg");
DataInputStream dataInputStream = new DataInputStream(inputStream);
OutputStream outputStream = new FileOutputStream("file/222.png");
DataOutputStream dataOutputStream = new DataOutputStream(outputStream)) {
//读取文件内容
byte[] b = new byte[1024];
int length;
while ((length = dataInputStream.read(b)) != -1) {
//将读取到的内容存入另一个文件
dataOutputStream.write(b, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
16.6、序列化和反序列化
序列化:将对象的状态写入到特定的流中的过程
反序列化:从特定的流中获取数据重写构建对象的过程
实现序列化的步骤:
第一步:实现Serializable接口
第二步:
第三步:
第四步: