Java 基础(一)

Java是当今世界最重要、使用最广泛的计算机语言之一,全球每天有超百万的开发者在用Java进行开发。

1 Java概述

  • Java概述
    • Java SE,平台标准版,提供了基础。
    • Java EE,平台企业版,基础上构建。
    • Java ME,平台微型版,移动和嵌入式设备。
    • Java各种集成开发工具 > JDK开发工具包 > JRE运行时类库 > JVM(Java虚拟机)。

1-1 注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public class Test001 {
// 单行注释

/*
* 多行注释
* 多行注释
*/
public static void main(String[] args) {
/**
* 文档注释:只放在类、接口、成员变量、方法之前
* Javadoc只处理这些地方的文档注释,Javadoc是Sun公司提供的工具
* 可从源代码中抽取类、方法等注释,形成和源代码配套的API帮助文档
*
* 不被{}包围的标签为块标签、{}包围的标签为内联标签
* 标签···········描述
* @author········标识一个类的作者,一般用于类注释
* @deprecated····指明一个过期的类或成员,表明该类或方法不建议使用
* {@docRoot}·····指明当前文档根目录的路径
* @exception·····可能抛出异常的说明,一般用于方法注释
* {@inheritDoc}··从直接父类继承的注释
* {@link}········插入一个到另一个主题的链接
* {@linkplain}···插入一个到另一个主题的链接,但是该链接显示纯文本字体
* @param·········说明一个方法的参数,一般用于方法注释
* @return········说明返回值类型,一般用于方法注释,不能出现在构造方法中
* @see···········指定一个到另一个主题的链接
* @serial········说明一个序列化属性
* @serialData····说明通过writeObject()和writeExternal()方法写的数据
* @serialField···说明一个ObjectStreamField组件
* @since·········说明从哪个版本起开始有了这个函数
* @throws········和@exception标签一样
* {@value}·······显示常量的值,该常量必须是static属性
* @version·······指定类的版本,一般用于类注释
*
* javadoc -help·········查看Javadoc的用法和选项
* Javadoc命令用法格式····javadoc [options] [packagenames] [sourcefiles]
* -public···············仅显示public类和成员
* -protected············显示protected/public类和成员(默认值)
* -package··············显示package/protected/public类和成员
* -private··············显示所有类和成员
* -d <directory>········输出文件的目标目录
* -version··············包含@version
* -author···············包含@author
* -splitindex···········将索引分为每个字母对应一个文件
* -windowtitle <text>···文档的浏览器窗口标题
* 执行命令生成该文件的API文档:javadoc -author -version Test001.java
* 文档注释时,换行使用<br>,分段使用<p>,可以结合HTML标签使用
*/
System.out.println("注释");
}
}

1-2 常量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public class Test002 {
// 静态常量,不需要创建对象就能访问,类外部访问形式为Test002.PI
public static final double PI = 3.14;

// 声明静态成员常量,不能修改
static final double X = 3.12;

// 声明非静态成员常量,不能修改
final double Y = 3.13;

public static void main(String[] args) {
// 常量值又称为字面常量,通过数据直接表示
// 整型:十进制数、八进制数、十六进制数
// 实型:十进制数(包含小数)、科学记数法
// 布尔型:false、true
// 字符型和字符串:字符型用单引号引起来一个字符、双引号用来表字符串

// 常量的三种类型:静态常量、成员常量、局部常量
// 注意:定义常量前需要先初始化,常量取名一般用大写字符
// final关键字修饰基本数据类型的常量,还修饰对象的引用或方法

/*
* 转义字符·········说明
* \101············表示'A',1~3位八进制数所表示的字符
* \u0041··········表示'A',1~4位十六进制数所表示的字符
* \'··············单引号字符
* \"··············双引号字符
* \\··············双斜杠字符
* \r··············回车
* \n··············换行
* \b··············退格
* \t··············横向跳格
*/

// 声明局部常量,不能修改
final double Z = 3.11;

System.out.println(Z);
// 通过类名访问“静态成员常量”
System.out.println(Test002.X);
// 通过对象访问“非静态成员常量”
Test002 myObject = new Test002();
double value = myObject.Y;
System.out.println(value);
System.out.println(Test002.PI);
}
}

1-3 变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class Test003 {
/*
* Java强类型,所有变量必须先声明后使用
* 指定类型的变量只能接受类型与之匹配的值
*/
public static void main(String[] args) {
// 初始化变量方式1:直接赋值
String username1 = "刘一";

// 初始化变量方式2:先声明后赋值
String username2;
username2 = "陈二";

System.out.println(username1);
System.out.println(username2);

// 同时声明多个变量,逗号隔开
String username3, username4, username5;
username3="张三";
username4="李四";
username5="王五";

// 同时声明多个变量并初始化,逗号隔开
String username6="赵六", username7="孙七";

System.out.println(username3);
System.out.println(username4);
System.out.println(username5);
System.out.println(username6);
System.out.println(username7);
}
}

(1) 成员变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Test004 {
/*
* Java变量的作用域:成员变量(实例变量、静态变量)、局部变量
*/

// 成员变量(实例变量)
String name1="刘一";

// 成员变量(静态变量,即类变量)
static final String name2="陈二";

public static void main(String[] args) {
// 创建类的对象
Test004 myClass=new Test004();
// 访问实例变量
System.out.println(myClass.name1);
// 访问静态变量
System.out.println(Test004.name2);
}
}

(2) 局部变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class Test005 {
/*
* Java变量的作用域:成员变量(实例变量、静态变量)、局部变量
* 局部变量指在方法或方法代码块中定义的变量,作用域是其所在的代码块
*/

// 方法参数变量(形参),作用域是testFun()方法体内
public static void testFun(int c) {
System.out.println("c=" + c);
}

// 代码块局部变量(代码块内定义)
public static void testExcept() {
// 代码块局部变量常用于try...catch代码块中,成为异常处理参数变量
// 作用域在异常处理块中,将异常处理参数传递给异常处理块,类似方法参数变量
try {
System.out.println("Exception!");
} catch (Exception e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
// a的作用域是整个main()方法
int a = 7;
if (a > 5) {
// 方法局部变量(方法内定义),s的作用域是if语句的代码块内
int b = 3;
System.out.println("b=" + b);
System.out.println("a=" + a);
}
System.out.println("a=" + a);

// 调用方法
testFun(9);
testExcept();
}
}

2 数据类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class Test006 {
/**
* Java是强制类型语言,所有变量必须先定义数据类型才能使用
* Java支持两种数据类型:基本数据类型、引用数据类型
* 基本
*** 单精度浮点型float、双精度浮点型double
*** 布尔型boolean、字符型char、字节型byte
*** 短整型short、整型int、长整型long
* 引用:由用户自定义,用来限制其他数据的类型
*** 类class、接口interface、数组[]
*** 还有一种特殊的null类型
*/
public static void main(String[] args) {
// 整数类型,有符号的值,正数或负数
byte a = 20;
short b = 10;
int c = 30;
long d = 40;
long sum = a + b + c + d;
System.out.println(sum);

// 字符类型
char e = 'X';
char f = '@';
char g = '9';
System.out.println(e + f + g);

// 浮点类型,带小数部分
double h = 111.1d;
float i = 222.2f;
float total = (float) (h + i);
System.out.println(total);

// 布尔类型,对数值通过逻辑运算判定真假
boolean j = false;
System.out.println(j);

/**
* 隐式转换,自动类型转换(小转大)
* 数值型数据的转换:byte→short→int→long→float→double。
* 字符型转换为整型:char→int
* 显示转换,强制类型转换(大转小)
*/
}
}

3 运算符操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
public class Test007 {
public static void main(String[] args) {
// 一元算术运算符:-、++、--
int a = 1;
System.out.println("a++=" + (a++));
System.out.println("++a=" + (++a));
System.out.println("a--=" + (a--));
System.out.println("--a=" + (--a));
System.out.println("-a=" + (-a));

// 二元算术运算符:+、-、*、/、%
int b = 9, c = 2, d = 3;
int e = b * (c + d) % c - b;
System.out.println("e=" + e);

// 赋值运算符:+=、-=、*=、/=、%=、=
a += b;
System.out.println("a=" + a);

// 逻辑运算符:&&、||、!、|、&
System.out.println(a > 9 && a <= 11);

// 关系运算符:>、>=、<、<=、==、!=
System.out.println(a != b);
System.out.println(c <= d);

// 位逻辑运算符:&(与AND)、|(或OR)、~(非NOT)、^(异或XOR)
// &:低位对齐,高位不足的补零,同时为1结果为1,否则为0
// |:低位对齐,高位不足的补零,只要有一个为1,结果就为1
// ~:低位对齐,高位不足的补零,将操作数二进制中的1改为0,0改为1
// ^:低位对齐,高位不足的补零,同时为0或同时为1,结果为0,否则为1
System.out.println("~:" + (~10010));
System.out.println("|:" + (100100 | 101000));
System.out.println("&:" + (1001000 & 1010000));
System.out.println("^:" + (10010000 ^ 10100000));

// 位移运算符:>>(右移)、<<(左移)
// >>:低位舍弃移出,高位空位补零
// <<:高位舍弃移出,低位空位补零

// 复合位赋值运算符:&=、|=、^=、-=、<<=、>>=
System.out.println(a &= 7);
System.out.println(a |= 5);
System.out.println(a ^= 3);
System.out.println(a -= 1);
System.out.println(a >>= 1);
System.out.println(a <<= 1);

// 三目运算符(条件运算符):?:
int x = 1, y = 2, z = 3;
System.out.println(z > x ? y : z);

/**
* 优先级(高到低):()、[]、{}
* 算术运算符优先级较高,关系、逻辑运算符优先级较低
* 多数运算符具左结合性,单目、三目、赋值运算符具右结合性
* 不要过多依赖优先级高低,尽量用()来控制表达式的执行顺序
*/

// 直接量是指在程序中通过源代码直接给出的值
// 通常只有三种类型能指定直接量:基本类型、字符串类型、null类型
// int:二进制(0B开头)、八进制(0开头)、十进制、十六进制(0X开头)
// long:整型数值后添加l和L,例如3L、Ox12l
// float:浮点数后添加f或F,例如5.34f、3.1415F
// double:标准小数或科学计数法形式的浮点数,例如5.34、3.14E5
// boolean:true、false
// char:单引号括起来的字符、转义字符、Unicode值表示的字符
// String:双引号括起来的字符序列
// null:一种特殊类型,只有一个值null,可赋给任何引用类型的变量
}
}

4 流程的控制

  • 流程的控制
    • 顺序结构:表达式语句、空语句、复合语句。
    • 选择结构:if语句、if…else语句、switch语句。
    • 循环结构:while语句、for语句、foreach语句(for循环的变形)。

4-1 选择结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import java.util.Calendar;

public class Test008 {
public static void main(String[] args) {
// if条件语句
String today = "周六";
String weather = "晴";
if (today.equals("周六")) {
if (weather.equals("晴")) {
System.out.println("户外出行");
} else {
System.out.println("室内游戏");
}
} else if (today.equals("周日")) {
System.out.println("室内看剧");
} else {
System.out.println("公司上班");
}

// switch语句
String weekDate = "";
// 获取当前时间
Calendar calendar = Calendar.getInstance();
// 获取一周的第n天,Calendar.DAY_OF_WEEK返回值1-7,1指周日
int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
switch ((week)) {
case 0:
weekDate = "周日";
break;
case 1:
weekDate = "周一";
break;
case 2:
weekDate = "周二";
break;
case 3:
weekDate = "周三";
break;
case 4:
weekDate = "周四";
break;
case 5:
weekDate = "周五";
break;
case 6:
weekDate = "周六";
break;
default:
break;
}
System.out.println("今天" + weekDate);

/**
* if语句应用最广泛最实用,switch语句更高效,分支越多越明显
* 一般情况下,判定条件较少的用if语句,多条件判断则用switch语句
*/
}
}

4-2 循环结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class Test009 {
public static void main(String[] args) {
// while语句
int a = 1, b = 1;
while (a <= 5) {
b = b * a;
a++;
}
System.out.println("5的阶乘结果:" + b);

// do...while语句
int c = 1, d = 1;
do {
d *= c;
c++;
} while (c <= 5);
System.out.println("5的阶乘结果:" + d);

/**
* while先判断再执行,do...while先执行再判断
*/

// for语句
int e = 1, f = 1;
for (; e <= 5; e++) {
f *= e;
}
System.out.println("5的阶乘结果:" + f);
}
}

(1) for循环嵌套

1
2
3
4
5
6
7
8
9
10
11
12
public class Test010 {
public static void main(String[] args) {
System.out.println("九九乘法表");
// for循环嵌套
for (int x = 1; x <= 9; x++) {
for (int y = 1; y <= x; y++) {
System.out.print(y + "*" + x + "=" + y * x + "\t");
}
System.out.println();
}
}
}

(2) foreach语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Test011 {
public static void main(String[] args) {
int[] numbers = { 43, 32, 53, 54, 75, 73, 10 };

// for语句
System.out.println("*****for*****");
for (int x = 0; x < numbers.length; x++) {
System.out.println("Count is: " + numbers[x]);
}

// foreach语句
System.out.println("***foreach***");
for (int item : numbers) {
System.out.println("Count is: " + item);
}
}
}

4-3 break语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Test012 {
public static void main(String[] args) {
// 一个循环中可以有一个以上的break语句,过多会破坏代码结构
// switch语句的break仅仅影响switch语句本身,不会影响循环
for (int x = 0; x < 5; x++) {
System.out.print("外" + (x + 1) + ":");
for (int y = 0; y < 10; y++) {
if (y == 3) {
break;
}
System.out.print("内" + (y + 1));
}
System.out.println();
}

// 带标签的break语句,用于跳出多重嵌套的循环语句(goto功能)
// label是标签名称,标签语句必须和循环匹配使用,以冒号结束
// 若需中断标签语句对应的循环,可采用break后跟标签名的方式
label: for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
System.out.println(j);
if (j % 2 != 0) {
break label;
}
}
}
}
}

4-4 return语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.Scanner;

public class Test013 {
/**
* return用于终止函数的执行或退出类方法
* 若该方法有返回类型,必须返回该类型的值
* 若没有返回值,可使用没有表达式的return语句
*/
public static double sum(double i, double j) {
double sum = i + j;
return sum;
}

public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("请输入操作数(1):");
double num1 = input.nextDouble();
System.out.print("请输入操作数(2):");
double num2 = input.nextDouble();
double s = sum(num1, num2);
System.out.println(num1 + " + " + num2 + " = " + s);
}
}

4-5 continue语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Test014 {
/**
* continue语句只能出现在while、for、foreach循环体中
* continue是忽略循环语句的当次循环,进入下一次的迭代
*/
public static void main(String[] args) {
int[] num = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (int i = 0; i < num.length; i++) {
if (i == 3) {
continue;
}
System.out.println("Count is:" + i);
}

label: for (int x = 0; x < 3; x++) {
for (int y = 3; y > 0; y--) {
if (y == x) {
continue label;
}
System.out.println(x + ", " + y);
}
}
System.out.println("Game Over!");
}
}

4-6 打印杨辉三角

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import java.util.Scanner;

public class Test015 {
/**
* 杨辉三角由数字进行排列,可以将其看作一个数字表
* 两侧数值均为1,其他位置的数值是其左右两侧上方的数值之和
*/
public static int num(int x, int y) {
if (y == 1 || y == x) {
return 1;
}
int c = num(x - 1, y - 1) + num(x - 1, y);
return c;
}

public static void calculate(int row) {
for (int i = 1; i <= row; i++) {
for (int j = 1; j <= row - i; j++) {
System.out.print(" ");
}
for (int j = 1; j <= i; j++) {
System.out.print(num(i, j) + " ");
}
System.out.println();
}
}

public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("打印行数:");
int row = scan.nextInt();
calculate(row);
}
}

5 字符串处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class Test016 {
/**
* 字符串对象一旦被创建,其值是不能改变的
* 但可使用其他变量重新赋值的方式进行更改
*/
public static void main(String[] args) {
// 直接定义字符串,使用双引号表示字符串中的内容
String str1 = "Hi";
System.out.println(str1);

// 使用String类定义字符串
String str2 = new String("Aha");
System.out.println(str2);

char a[] = { 'W', 'o', 'w' };
String str3 = new String(a);
System.out.println(str3);

// offset是子数组第一个字符的索引,count指定子数组长度
String str4 = new String(a, 0, 3);
System.out.println(str4);

// String转int:Integer.parseInt(str)
// String的值必须是整数,否则转换NumberFormatException
String str5 = "123";
int n = 0;
n = Integer.parseInt(str5);
System.out.println(n);

// String转int:Integer.valueOf(str).intValue()
n = Integer.valueOf(str5).intValue();
System.out.println(n);

// int转String:String.valueOf()
// 括号中的值不能为空,否则NullPointerException(空指针异常)
int num = 345;
String str6 = String.valueOf(num);
System.out.println(str6);

// int转String:Integer.toString()
String str7 = Integer.toString(num);
System.out.println(str7);

// int转String:"" + i,耗时大
String str8 = num + "";
System.out.println(str8);

/*
* valueOf():将数据的内部格式转换为可读的形式
* parseXxx(String):把字符串转换为数值型,Xxx对应不同的数据类型
* toString():把一个引用类型转换为String字符串类型
*/
}
}

5-1 拼接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class Test017 {
/**
* “+”可连接任何类型数据将其拼接成字符串
* concat方法只能拼接String类型的字符串
*/
public static void main(String[] args) {
// 字符串拼接:使用连接运算符“+”
String str1 = new String("老龙恼怒闹老农");
String str2 = new String("老农恼怒闹老龙");
System.out.println(str1 + "," + str2 + "。");

// 字符串拼接:使用concat()方法
String str3 = "农怒龙恼农更怒";
String str4 = "龙恼农怒龙怕农";
String str5 = str3.concat(",").concat(str4).concat("。");
System.out.println(str5);

// 拼接其他数据类型
// 只要其中一个操作数是字符串,编译器就会将其他操作数转换成字符串形式
String str6 = "我有一本《水浒传》";
float time = 0.5f;
String str7 = str6 + ",每天阅读" + time + "小时。";
System.out.println(str7);

// 获取字符串长度
System.out.println(str7 + "字符串长度:" + str7.length());

// str.toLowerCase():字母转换为小写
// str.toUpperCase():字母转换为大写
String str8 = "ABCDEFG、hijklmn、OpQ、RsT、UVW、xyz";
System.out.println(str8.toLowerCase());
System.out.println(str8.toUpperCase());

// str.trim():去除字符串首尾两侧的英文空格
// str.replace():用于替换字符串中的字母
String str9 = " H e l l o ";
System.out.println("去除字符串首尾两侧的空格:" + str9.trim());
System.out.println("用于替换字符串中的字母:" + str9.replace(" ", "a"));
}
}

5-2 提取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import java.util.Arrays;

public class Test018 {
public static void main(String[] args) {
// 提取字符串:substring(int beginIndex)
String str1 = "Peter Piper picked a peck of pickled peppers.";
System.out.println(str1.substring(19));

// 提取字符串:substring(int beginIndex,int endIndex)
System.out.println(str1.substring(19, 45));

// 分割字符串:str.split(String sign)
String str2 = "abcd,efg,hijk,lmn,opq,rst,uvw,xyz";
String[] str3 = str2.split(",");
System.out.println(Arrays.toString(str3));

// 分割字符串:str.split(String sign, int limit)
String[] str4 = str2.split(",", 8);
System.out.println(Arrays.toString(str4));

// 分割字符串:str.split(String sign | String sign)
String str5 = "4*apple+pear=3*banana and 1*cherry or 2*strawberry";
String[] str6 = str5.split("and | or");
System.out.println(Arrays.toString(str6));

// 字符串替换:str.replace(String oldChar, String newChar)
System.out.println(str1.replace("P", "T"));

// 替换第一个:str.replaceFirst(String regex, String replacement)
System.out.println(str1.replaceFirst("Peter", "Nancy"));

// 替换所有的:str.replaceAll(String regex, String replacement)
System.out.println(str1.replaceAll("pi", "ar"));
}
}

5-3 比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Test019 {
public static void main(String[] args) {
// str.equals():逐个比较两个字符串的每个字符
String str1 = "abc";
String str2 = new String("abc");
String str3 = "ABC";
System.out.println(str1.equals(str2));
System.out.println(str1.equals(str3));
System.out.println("-----");

// str.equalsIgnoreCase():同equals(),不区分大小写
System.out.println(str1.equalsIgnoreCase(str3));
System.out.println("-----");

// ==运算符比较两个对象引用,看是否引用相同的实例
// equals()比较字符串对象中的字符
System.out.println(str1 == str2);
System.out.println(str1.equals(str2));
System.out.println("-----");

// str.compareTo():按字典顺序比较两个字符串的大小
// 按字典顺序str位于otherster参数前,结果为一个负整数
// 按字典顺序str位于otherster参数前,结果为一个负整数
// 如果两个字符串相等,则结果为0
System.out.println(str1.compareTo(str2));
System.out.println(str1.compareTo(str3));
System.out.println(str1.compareTo("abcd"));
}
}

5-4 查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Test020 {
public static void main(String[] args) {
// indexOf():返回在指定字符串中首次出现的索引位置,找不到则返回-1
String str = "A peck of pickled peppers Peter Piper picked.";
System.out.println(str.indexOf("peck"));
System.out.println(str.indexOf("p", 3));

// lasstIndexOf():返回在指定字符串中最后一次出现的索引位置
// 查找策略是从右往左查找,不指定起始索引则默认从末尾开始查找
System.out.println(str.lastIndexOf("pe"));
System.out.println(str.lastIndexOf("pe", 20));

// charAt():在字符串内根据指定的索引查找字符
System.out.println(str.charAt(5));
}
}

5-5 StringBuffer

  • StringBuffer
    • Java提供了两个可变字符串类StringBuffer和StringBuilder,即字符串缓冲区。
    • StringBuffer线程安全,StringBuilder线程不安全,性能略高,功能基本相似。
    • 一般情况下,相对速度从快到慢依次为:StringBuilder>StringBuffer>String。
    • 少量数据用String,单线程大量数据用StringBuilder,多线程大量数据用StringBuffer。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class Test021 {
/**
* StringBuffer类比String类处理字符串更高效
* 可变字符串类,创建StringBuffer类的对象后可随意修改字符串内容
* 每个StringBuffer类的对象都能够存储指定容量的字符串
* 如果字符串长度超过容量,那么该对象的容量就会自动扩大
*/
public static void main(String[] args) {
// 构造方法:定义一个空字符串缓冲区,初始化含16个字符容量
StringBuffer str1 = new StringBuffer();
System.out.println(str1.capacity());

// 构造方法:定义一个指定18个字符长度容量的空字符串缓冲区
StringBuffer str2 = new StringBuffer(18);
System.out.println(str2.capacity());

// 构造方法:定义一个指定16+4的字符串缓冲区,“学海无涯”为4个字符
StringBuffer str3 = new StringBuffer("学海无涯");
System.out.println(str3.capacity());

StringBuffer str4 = new StringBuffer("Hay");
System.out.println(str4);

// 替换字符:setCharAt()
str4.setCharAt(1, 'e');
System.out.println(str4);

// 反转字符串:reverse()
str4.reverse();
System.out.println(str4);

// 追加字符串:append()
str4.reverse();
String str5 = " Baby";
System.out.println(str4.append(str5).substring(0));

// 删除字符:deleteCharAt()
str4.append(str5).deleteCharAt(8);
System.out.println(str4);

// 删除字符串:delete()
str4.append(str5).delete(12, 17);
System.out.println(str4);
}
}

5-6 正则表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Test022 {
/**
* 支持字符、特殊字符、预定义字符、方括号表达式
*** 枚举:[abc]指abc中任意一个字符、[gz]指gz其中任意一个字符
*** 范围:[a-f]指a~f范围内的任意字符、[a-cx-z]指a~c、x~z范围内的任意字符
*** 求否:[^abc]指非abc的任意字符、[^a-f]指非a~f范围内的任意字符
*** 与运算:[a-z&&[def]]指a~z和[def]的交集de
*** 并运算:[a-d[m-p]]指[a-dm-p]
* 边界匹配符:^(行头)、$(行尾)等
* 贪婪模式、勉强模式(?)、占有模式(+)
*** X?、X??、X?+(X表达式出现零次或一次)
*** X*、X*?、X*+(X表达式出现零次或多次)
*** X+、X+?、X++(X表达式出现一次或多次)
*** X{n}、X{n}?、X{n}+(X表达式出现n次)
*** X{n,}、X{n,}?、X{n,}+(X表达式最少出现n次)
*** X{n,m}、X{n,m}?、X{n,m}+(X表达式最少出现n次,最多出现m次)
*/
public static void main(String[] args) {
String str = "Hello, this is Mike speaking.";

// 贪婪模式,尽可能多匹配
System.out.println(str.replaceFirst("\\w*", "·"));

// 勉强模式,尽可能少匹配,首先匹配空字符串(0长度)
System.out.println(str.replaceFirst("\\w*?", "·"));
}
}

(1) regex类库

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

public class Test023 {
/**
* 正则表达式字符串必须先被编译为Pattern对象
* 再利用该Pattern对象创建对应的Matcher对象
* Matcher类常用方法
*** find():返回目标字符串中是否包含与Pattern匹配的子串
*** group():返回上一次与Pattern匹配的子串
*** start():返回上一次与Pattern匹配的子串在目标字符串中的开始位置
*** end():返回上一次与Pattern匹配的子串在目标字符串中的结束位置加1
*** lookingAt():只要字符串以Pattern开头就会返回true
*** matches():要求整个字符串和Pattern完全匹配时才返回true
*** reset():将现有的Matcher对象应用于新的字符序列
*/
public static void main(String[] args) {
String str = "联系13500006666,电话号码13611125565,联系15899903312";
// 只抓取13X和15X段的手机号
Matcher m = Pattern.compile("((13\\d)|(15\\d))\\d{8}").matcher(str);
while (m.find()) {
System.out.println(m.group());
}

String regStr = "Java Easy!";
Matcher n = Pattern.compile("\\w+").matcher(regStr);
while (n.find()) {
System.out.println(n.group() + "---起:" + n.start() + ",止:" + n.end());
}

String[] mails = {
"Test626@outlook.com", "Test626@hotmail.com",
"Test626@crazyit.org", "Test626@foxmail.xxx"
};
String mailRegEx = "\\w{3,20}@\\w+\\.(com|org|cn|net|gov)";
Pattern mailPattern = Pattern.compile(mailRegEx);
Matcher matcher = null;
for (String mail : mails) {
if (matcher == null) {
matcher = mailPattern.matcher(mail);
} else {
matcher.reset(mail);
}
String result = mail + (matcher.matches() ? "---有效" : "---无效");
System.out.println(result);
}
}
}

(2) 验证IP地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test024 {
// IPv4正则表达式
private static final String IP_REGEX =
"^((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)\\.){3}" +
"(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)$";

private static final Pattern IP_PATTERN = Pattern.compile(IP_REGEX);

public static boolean isValidIP(String ip) {
if (ip == null || ip.isEmpty()) {
return false;
}
Matcher matcher = IP_PATTERN.matcher(ip);
return matcher.matches();
}

public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入IP地址:");
String input = scanner.nextLine();

System.out.println(
input + "---" + (isValidIP(input) ? "格式正确!" : "格式错误!")
);

scanner.close();
}
}

(3) 验证座机号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test025 {
public static void main(String[] args) {
String answer = "Y";
String regex =
"0\\d{2,3}[-]?\\d{7,8}|0\\d{2,3}\\s?\\d{7,8}|"
+ "13[0-9]\\d{8}|15[1089]\\d{8}";

do {
System.out.print("请输入座机号:");
Scanner scanner = new Scanner(System.in);
String phone = scanner.next();
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(phone);
boolean bool = matcher.matches();
if (bool) {
System.out.println("您输入的座机号格式正确。");
} else {
System.out.println("您输入的座机号格式错误!");
}
System.out.print("是否继续输入(Y/N or y/n)?");
answer = scanner.next();
} while (answer.equalsIgnoreCase("Y"));
}
}

6 数字与日期

  • 数字与日期
    • Math类:提供基本的数学操作,如指数等。
    • Random类:提供了丰富的随机数生成方法。
    • BigInteger类:针对整型大数字的处理类。
    • BigDecimal类:是指针对大小数的处理类。
    • Date类:系统特定的时间戳,可精确到毫秒。
    • Calendar类:为特定瞬间的转换提供了方法。
    • DateFormat类:是日期、时间格式化子类的抽象类。
    • SimpleDateFormat类:格式化和解析日期的具体类。

6-1 Math类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Test026 {
public static void main(String[] args) {
// 静态常量,例如:自然对数e、圆周率Π等
System.out.println(Math.E);

// 最大值、最小值、绝对值
System.out.println(Math.max(10, -50));
System.out.println(Math.min(70, 10));
System.out.println(Math.abs(-50));

// 求整运算
System.out.println(Math.round(18.153));
System.out.println(Math.ceil(18.153));
System.out.println(Math.floor(18.153));
System.out.println(Math.rint(18.153));

// 三角函数
System.out.println(Math.sin(Math.PI / 2));
System.out.println(Math.cos(0));
System.out.println(Math.atan(1));
System.out.println(Math.toRadians(120));

// 指数运算
System.out.println(Math.pow(4, 2));
System.out.println(Math.sqrt(100));
System.out.println(Math.log10(16));
}
}

6-2 生成随机数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.util.Random;

public class Test027 {
public static void main(String[] args) {
// 生成一个2~100的随机数
System.out.println((int) (2 + Math.random() * 100));

Random r = new Random();
System.out.println(r.nextBoolean());
System.out.println(r.nextInt());
System.out.println(r.nextFloat());
System.out.println(r.nextDouble());
System.out.println(r.nextLong());
}
}

6-3 数字格式化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import java.util.Scanner;
import java.text.DecimalFormat;

public class Test028 {
/**
* DecimalFormat是NumberFormat的一个子类,用于格式化十进制数字
* DecimalFormat类包含一个模式和一组符号
*** 0:显示数字,如果位数不够则补0
*** #:显示数字,如果位数不够不发生变化
*** .:小数分隔符
*** -:减号
*** ,:组分隔符
*** E:分隔科学记数法中的尾数和小数
*** %:前缀或后缀,乘以100后作为百分比显示
*** ?:乘1000后作为千进制货币符显示,用货币符号代替
*/
public static void main(String[] args) {
// 实例化DecimalFormat类的对象,并指定格式
DecimalFormat df1 = new DecimalFormat("0.0");
DecimalFormat df2 = new DecimalFormat("#.#");
DecimalFormat df3 = new DecimalFormat("000.000");
DecimalFormat df4 = new DecimalFormat("###.###");

Scanner scan = new Scanner(System.in);
System.out.print("请输入一个float类型的数字:");
float f = scan.nextFloat();

// 对输入的数字应用格式,并输出结果
System.out.println("0.0 格式:" + df1.format(f));
System.out.println("#.# 格式:" + df2.format(f));
System.out.println("000.000 格式:" + df3.format(f));
System.out.println("###.### 格式:" + df4.format(f));
}
}

6-4 大数字运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.math.BigDecimal;
import java.math.BigInteger;

public class Test029 {
public static void main(String[] args) {
// 将数字5转换为BigInteger对象
BigInteger bi = new BigInteger("10");
System.out.println(bi);
System.out.println(bi.add(new BigInteger(("70"))));

// 使用输入的数字创建BigDecimal对象
BigDecimal bd = new BigDecimal(10);
System.out.println(bd);
System.out.println(bd.subtract(new BigDecimal((-11))));
}
}

6-5 时间的处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.util.Date;
import java.util.Calendar;

public class Test030 {
public static void main(String[] args) {
// Date类表示系统特定的时间戳,可以精确到毫秒
Date date = new Date();
System.out.println(date);

// Calendar类是一个抽象类
Calendar c = Calendar.getInstance();
// 将系统当前时间赋值给Calendar对象
c.setTime(new Date());
System.out.println(c.getTime());

// YEAR、MONTH、DATE(DAY_OF_MONTH)
// HOUR(12小时制)、HOUR_OF_DAY(24小时制)
// MINUTE、SECOND、DAY_OF_WEEK(星期)
System.out.println(c.get(Calendar.YEAR));
}
}

6-6 日期格式化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.util.Date;
import java.util.Locale;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class Test031 {
/**
* SHORT:完全为数字,如12.5.10或5:30pm
* MEDIUM:较长,如May 10,2016
* LONG:更长,如May 12,2016或11:15:32am
* FULL:是完全指定,如Tuesday、May 10、2012 AD或11:l5:42am CST
*/
public static void main(String[] args) {
// DateFormat是日期/时间格式化子类的抽象类
DateFormat dfdate = DateFormat.getDateInstance(DateFormat.FULL, Locale.CHINA);
DateFormat dftime = DateFormat.getTimeInstance(DateFormat.FULL, Locale.CHINA);
String date = dfdate.format(new Date());
String time = dftime.format(new Date());
System.out.println(date + " " + time);

// SimpleDateFormat可以选择任何用户定义的日期/时间格式的模式
Date now = new Date();
SimpleDateFormat f = new SimpleDateFormat("yyyy年M月d日 E HH点mm分ss秒 SSS毫秒");
System.out.println(f.format(now));
}
}

Java 基础(一)
https://stitch-top.github.io/2025/05/30/java/java01-java-ji-chu-yi/
作者
Dr.626
发布于
2025年5月30日 21:33:10
许可协议