Java 基础(二)

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

1 包装类

  • 包装类
    • Java为每种基本数据类型分别设计了对应的包装类,也称之为外覆类,或是数据类型类。
    • 基本数据类型转换为包装类的过程称为装箱,包装类变为基本数据类型的过程称为拆箱。
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 Test032 {
public static void main(String[] args) {
int m = 70;
// 自动装箱
Integer obj = m;
// 自动拆箱
int n = obj;
System.out.println(n);

int x = 80;
// 手动装箱
Integer o = new Integer(x);
// 手动拆箱
int y = o.intValue();
System.out.println(y);

// 字符串转换为数值型
int a = Integer.parseInt("30");
float b = Float.parseFloat("50");
System.out.println(a);
System.out.println((int) b);

// 整数转换为字符串
String s = Integer.toString(10);
System.out.println(s);
}
}

1-1 Byte

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Test033 {
public static void main(String[] args) {
// Byte(byte value)
byte b1 = 5;
Byte b2 = new Byte(b1);
System.out.println(b2);

// Byte(String s)
String b3 = "5";
Byte b4 = new Byte(b3);
System.out.println(b4);

// byteValue():以一个byte值返回Byte对象
// compareTo():在数字上比较两个Byte对象
// doubleValue():以一个double值返回此Byte的值
// intValue():以一个int值返回此Byte的值
System.out.println(b2.byteValue());
System.out.println(b2.compareTo(b4));
}
}

1-2 Float

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 Test034 {
public static void main(String[] args) {
// 构造方法:Float(double value)
Float f1 = new Float(3.1415);
System.out.println(f1);

// 构造方法:Float(float value)
Float f2 = new Float(6.5147f);
System.out.println(f2);

// 构造方法:Float(String s)
Float f3 = new Float("3.15789");
System.out.println(f3);

// 字符串转float类型,若字符串包含非数值类型字符,则报错
String str1 = "4.45678";
float f4 = Float.parseFloat(str1);
System.out.println(f4);

// float类型转字符串
float f5 = 5.15437f;
String str2 = Float.toString(f5);
System.out.println(str2);

// 常用类型:MIN_VALUE、MAX_VALUE、MIN_EXPONENT
// MAX_EXPONENT、MIN_NORMAL、NaN、SIZE、TYPE
float max_value = Float.MAX_VALUE;
System.out.println(max_value);
}
}

1-3 Object

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
import java.util.Scanner;

public class Test035 {
/**
* Object是所有类的父类,允许将任何类型的对象赋给Object类型的变量
* 当一个类被定义后,若没有指定继承的父类,那么默认父类就是Object类
*/
private String name;
private int age;

public Test035(String name, int age) {
this.name = name;
this.age = age;
}

public String toString() {
return "姓名:" + this.name + ",年龄:" + this.age;
}

public static boolean check(String pwd) {
boolean con = false;
if (pwd.equals("123456")) {
con = true;
} else {
con = false;
}
return con;
}

public static void printInfo(Object obj) {
// 获取类名
System.out.println("类名:" + obj.getClass().getName());

// 获取父类名
System.out.println("父类:" + obj.getClass().getSuperclass().getName());

// 获取实现的接口并输出
for (int i = 0; i < obj.getClass().getInterfaces().length; i++) {
System.out.println(obj.getClass().getInterfaces()[i]);
}
}

public static void main(String[] args) {
// toString():返回该对象的字符串
Test035 per = new Test035("张三", 30);
System.out.println(per);

// equals():比较两个对象的内容是否相等
Scanner input = new Scanner(System.in);
System.out.print("输入您的密码:");
String pwd = input.next();
boolean con = check(pwd);
if (con) {
System.out.println("冰狗~您输入的密码正确!");
} else {
System.out.println("啊偶~是不是忘记密码啦!");
}

// getClass():返回对象所属的类,是一个Class对象
String strObj = new String();
printInfo(strObj);
}
}

(1) 接收接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
interface A {
public String getInfo();
}

class B implements A {
public String getInfo() {
return "Hi~";
}
}

public class Test036 {
public static void main(String[] args) {
// 为接口实例化
A a = new B();
// 对象向上转型
Object obj = a;
// 对象向下转型
A x = (A) obj;
// 接口本身是引用数据类型,可进行向上转型
System.out.println(x.getInfo());
}
}

(2) 接收数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Test037 {
public static void main(String[] args) {
int temp[] = { 1, 3, 5, 7, 9 };
// object接收数组
Object obj = temp;
// 传递数组引用
print(obj);
}

public static void print(Object o) {
// 判断对象类型
if (o instanceof int[]) {
// 向下转型
int x[] = (int[]) o;
// 循环输出
for (int i = 0; i < x.length; i++) {
// 数组本身属于引用数据类型
System.out.print(x[i] + "\t");
}
}
}
}

1-4 Double

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
public class Test038 {
public static void main(String[] args) {
// 构造方法:Double(double value)
Double d1 = new Double(5.123);
System.out.println(d1);

// 构造方法:Double(String s)
Double d2 = new Double("6.456");
System.out.println(d2);

// 字符串转为double类型数值,若字符串包含非数值类型字符,则报错
String s1 = "7.156";
double d3 = Double.parseDouble(s1);
System.out.println(d3);

// double类型数值转为字符串
double d4 = 9.125;
String s2 = Double.toString(d4);
System.out.println(s2);

// 常用常量:MAX_VALUE、MIN_VALUE、NaN、TYPE
// NEGATIVE_INFINITY、POSITIVE_INFINITY、SIZE
Double d5 = Double.MAX_VALUE;
System.out.println(d5);
}
}

1-5 System

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
package java02;

import java.io.IOException;
import java.io.InputStreamReader;

public class Test039 {
/**
* System类位于java.lang包,代表当前Java程序的运行平台
* 系统级的很多属性和控制方法都放置在该类内部
* 构造方法是private的,无法创建该类的对象(无法实例化该类)
*/
public static void main(String[] args) {
// 静态成员变量:PrintStream out,标准输出流
System.out.print("请输入字符,回车结束输入:");
int c;
try {
// 静态成员变量:InputStream in,标准输入流
// c = System.in.read();
// 确保输入汉字能正常输出
InputStreamReader in = new InputStreamReader(System.in, "GB2312");
c = in.read();
while (c != '\r' && c != -1 && c != '\n') {
System.out.println("您输入的字符内容如右所示:" + (char) c);
// c = System.in.read();
c = in.read();
}
} catch (IOException e) {
System.out.print(e.toString());
} finally {
// 静态成员变量:PrintStream err,标准错误输出流
System.err.println();
}

// 成员方法:arraycopy(),数组复制
char[] srcArray = {'A', 'B', 'C', 'D'};
char[] desArray = {'E', 'F', 'G', 'H'};
System.arraycopy(srcArray, 1, desArray, 1, 2);
for (int i = 0; i < srcArray.length; i++) {
System.out.print(srcArray[i]);
}
System.out.println();
for (int j = 0; j < desArray.length; j++) {
System.out.print(desArray[j]);
}
System.out.println();

// 成员方法:currentTimeMillis(),返回当前的计算机时间
long start = System.currentTimeMillis();
for (int i = 0; i < 100000000; i++) {
int temp = 0;
}
long end = System.currentTimeMillis();
long time = end - start;
System.out.println("程序执行时间:" + time + "秒");

// 成员方法:exit(),终止当前正在运行的Java虚拟机
// public static void exit(int status)
// status为0时正常退出,非零时异常退出,用于图形界面编程

// 成员方法:gc(),请求系统进行垃圾回收,完成内存中的垃圾清除
// public static void gc()

// 成员方法:getProperty(),获得系统中属性名为key属性对应的值
String java_version = System.getProperty("java.version");
System.out.println("运行时版本号:" + java_version);
String system = System.getProperty("os.name");
System.out.println("当前操作系统:" + system);
}
}

1-6 Integer

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
public class Test040 {
/**
* Integer类在对象中包装了一个基本类型int的值
* 提供多个方法能在int类型和String类型之间相互转换
*/
public static void main(String[] args) {
// 构造方法:Integer(int value)
Integer i1 = new Integer(100);
System.out.println(i1);

// 构造方法:Integer(String s)
Integer i2 = new Integer("100");
System.out.println(i2);

// 字符串转换为int类型,若字符串包含非数值类型字符,则报错
String s1 = "123";
int i3 = Integer.parseInt(s1);
System.out.println(i3);

// int类型数值转换为字符串
int i4 = 789;
String s2 = Integer.toString(i4);
System.out.println(s2);

int num = 1001;
// 八进制
String s3 = Integer.toHexString(num);
System.out.println(s3);
// 十进制
String s4 = Integer.toString(num);
System.out.println(s4);
// 十六进制
String s5 = Integer.toOctalString(num);
System.out.println(s5);
// 二进制
String s6 = Integer.toBinaryString(num);
System.out.println(s6);

// 常量:MAX_VALUE、MIN_VALUE、SIZE、TYPE
int max_value = Integer.MAX_VALUE;
System.out.println(max_value);
}
}

1-7 Number

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Test041 {
/**
* Number是一个抽象类,也是一个超类(即父类)
* 属于java.lang包,所有包装类都是抽象类Number的子类
* 抽象类不能直接实例化,而是必须实例化其具体的子类
*/
public static void main(String[] args) {
Number num = new Double(3.14159);
System.out.println("int 类型:" + num.intValue());
System.out.println("float 类型:" + num.floatValue());
System.out.println("double类型:" + num.doubleValue());
}
}

1-8 Boolean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Test042 {
/**
* Boolean类将基本类型为boolean的值包装在一个对象中
*/
public static void main(String[] args) {
// 构造方法:Boolean(boolean boolValue)
Boolean b1 = new Boolean(true);
System.out.println(b1);

// 构造方法:Boolean(String boolString)
Boolean b2 = new Boolean("true");
System.out.println(b2);

// 常用常量:TRUE、FALSE、TYPE
Boolean b3 = Boolean.FALSE;
System.out.println(b3);
}
}

1-9 Character

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
import java.util.Scanner;

public class Test043 {
public static void main(String[] args) {
Character c = new Character('A');
int r1 = c.compareTo(new Character('B'));
System.out.println("比 较:" + r1);

Scanner input = new Scanner(System.in);
System.out.print("用户名:");
String name = input.next();
System.out.print("密 码:");
String pwd = input.next();
boolean con = Test043.checkRegister(name, pwd);
if (con) {
System.out.println("太棒啦~恭喜注册成功!");
} else {
System.out.println("真遗憾~您注册失败了!");
}
}

public static boolean checkRegister(String name, String pwd) {
boolean conname = true;
boolean conpwd = true;

if (name == null || name.length() == 0) {
System.out.println("啊哦~用户名不能为空!");
conname = false;
} else {
for (int i = 0; i < name.length(); i++) {
if (!Character.isLetter(name.charAt(i))) {
System.out.println("用户名只由字母组成!");
conname = false;
break;
}
}
}

if (pwd == null || pwd.length() == 0) {
System.out.println("啊哦~密码不能为空呀!");
conpwd = false;
} else {
for (int j = 0; j < pwd.length(); j++) {
if (!Character.isLetterOrDigit(pwd.charAt(j))) {
System.out.println("密码由数字字母组成!");
conpwd = false;
break;
}
}
}

return conname && conpwd;
}
}

2 数组处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
public class Test044 {
/**
* 数组是一种简单的复合数据类型,有序数据的集合
* 依据数组的维度,将其分为一维、二维、多维数组
* 数组也是一种数据类型,本身是一种引用类型
*/
public static void main(String[] args) {
// 使用new指定数组大小后进行初始化
int[] n1 = new int[3];
n1[0] = 1;
n1[1] = 3;
n1[2] = 4;
System.out.println(n1.length);

// 使用new指定数组元素的值
int[] n2 = new int[] { 1, 2, 3, 4, 5 };
System.out.println(n2.length);

// 直接指定数组元素的值
int[] n3 = { 2, 4, 6, 8, 0 };
System.out.println(n3.length);

// 获取单个元素
System.out.println(n3[0]);

// 获取全部元素
for (int i = 0; i < n3.length; i++) {
System.out.print(n3[i]);
}
System.out.println();
for (int val : n3) {
System.out.print(val);
}
System.out.println();

// 初始化二维数组
int[][] x = new int[][] { { 1, 2 }, { 3, 4, 5 } };
// System.out.println(x[1][0]);
for (int i = 0; i < x.length; i++) {
for (int j = 0; j < x[i].length; j++) {
System.out.print(x[i][j]);
}
}

// 初始化高维、不规则数组
int intArray[][] = new int[4][];
intArray[0] = new int[2];
intArray[1] = new int[1];
intArray[2] = new int[3];
intArray[3] = new int[3];
// for循环遍历
for (int i = 0; i < intArray.length; i++) {
for (int j = 0; j < intArray[i].length; j++) {
intArray[i][j] = i + j;
}
}
System.out.println();
// for-each循环遍历
for (int[] row : intArray) {
for (int column : row) {
System.out.print(column);
// 元素之间添加制表符
// System.out.print("\t");
}
// 一行元素打印完换行打印
// System.out.println();
}
// 注意下标越界异常发生
// System.out.println(intArray[0][2]);
}
}

2-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
import java.util.Arrays;
import java.util.function.IntUnaryOperator;
import java.util.function.IntBinaryOperator;

public class Test045 {
public static void main(String[] args) {
// 定义两个数组
int[] a1 = new int[] { 3, 4, 5, 6 };
int[] a2 = new int[] { 3, 4, 5, 6 };
System.out.println(Arrays.equals(a1, a2));

// copyOf():复制成一个新数组,length长度可自定义
int[] a3 = Arrays.copyOf(a1, 5);
System.out.println(Arrays.equals(a1, a3));
System.out.println(Arrays.toString(a3));

// 将数组的[3, 5)即第3个元素到第5个元素赋值为1
Arrays.fill(a3, 2, 4, 1);
System.out.println(Arrays.toString(a3));

// 对数组进行排序
Arrays.sort(a3);
System.out.println(Arrays.toString(a3));

// 对数组进行并发排序,并发支持可利用硬件来提高运行性能
Arrays.parallelSort(a3);
System.out.println(Arrays.toString(a3));

Arrays.parallelPrefix(a3, new IntBinaryOperator() {
// left指数组中前一个索引处的元素,计算第一个元素时,left为1
// right指数组中当前索引处的元素
public int applyAsInt(int left, int right) {
return left + right;
}
});
System.out.println(Arrays.toString(a3));

Arrays.parallelSetAll(a3, new IntUnaryOperator() {
// operand指正在计算的元素索引
public int applyAsInt(int operand) {
return operand * 2;
}
});
System.out.println(Arrays.toString(a3));
}
}

2-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
import java.util.Arrays;

public class Test046 {
public static void main(String[] args) {
// 数组相等条件:元素个数相等,对应位置的元素也相等
double[] d1 = { 1, 3, 5 };
double[] d2 = new double[3];
d2[0] = 1;
d2[1] = 3;
d2[2] = 5;
System.out.println(Arrays.equals(d1, d2));

// 只能使用同一个数值进行填充:fill()
double[] d3 = new double[3];
for (int i = 0; i < d3.length; i++) {
Arrays.fill(d3, i);
System.out.println(i);
}

// 从数组中查询指定位置的元素:binarySearch()
double[] d4 = { 99.5, 100, 97.5, 96, 100, 83.5, 89, 91 };
// 进行数组查询前,必须先对数组排序,若未排序,结果不确定
Arrays.sort(d4);
int index1 = Arrays.binarySearch(d4, 60);
int index2 = Arrays.binarySearch(d4, 100);
System.out.println("60位置:" + index1);
System.out.println("100位置:" + index2);
int index3 = Arrays.binarySearch(d4, 0, 6, 60);
int index4 = Arrays.binarySearch(d4, 3, 7, 100);
System.out.println("60位置:" + index3);
System.out.println("100位置:" + index4);
}
}

2-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
import java.util.Arrays;

public class Test047 {
/**
* 以下方法都属于浅拷贝
* 浅拷贝:只复制对象的引用地址,两对象指向同一内存,修改其中一个,另一个随之变化
* 深拷贝:将对象和值一起复制过来,如果修改两对象中的任意一个值,另一个值不会改变
*/
public static void main(String[] args) {
// Arrays类的copyOf():复制数组到指定长度
int s1[] = new int[] { 1, 2, 3 };
int[] s2 = (int[]) Arrays.copyOf(s1, 5);
for (int i = 0; i < s2.length; i++) {
System.out.print(s2[i] + "\t");
}
System.out.println();

// Arrays类的copyOfRange():将指定数组的指定长度复制到一个新数组中
int s3[] = (int[]) Arrays.copyOfRange(s1, 0, 5);
for (int i = 0; i < s3.length; i++) {
System.out.print(s3[i] + "\t");
}
System.out.println();

// System类的arraycopy()
int s4[] = { 1, 3, 5, 7, 9 };
// 目标数组必须已存在,并且不会被重构,相当于替换目标数组中的部分元素
System.arraycopy(s1, 0, s4, 0, 3);
for (int i = 0; i < s4.length; i++) {
System.out.print(s4[i] + "\t");
}
System.out.println();

// Object类的clone():返回值是Object类型,需要使用强制类型转换
int s5[] = (int[]) s4.clone();
for (int i = 0; i < s5.length; i++) {
System.out.print(s5[i] + "\t");
}
}
}

2-4 数组排序

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
import java.util.Arrays;
import java.util.Comparator;
import java.util.Collections;

public class Test048 {
public static void main(String[] args) {
// 升序
double[] d1 = new double[] { 77, 93, 25, 68, 67 };
Arrays.sort(d1);
for (int i = 0; i < d1.length; i++) {
System.out.print(d1[i] + "\t");
}
System.out.println();

// 使用以下两种方法时,数组必须是包装类型,否则编译不通过
// 降序:Collections.reverseOrder(),数组类型必须为Integer
Integer[] d2 = { 77, 93, 25, 68, 67 };
Arrays.sort(d2, Collections.reverseOrder());
for (int arr : d2) {
System.out.print(arr + "\t");
}
System.out.println();

// 降序:实现Comparator接口的复写compare()方法
Integer[] d3 = { 77, 93, 25, 68, 67 };
Comparator c = new MyComparator();
Arrays.sort(d3, c);
for (int arr : d3) {
System.out.print(arr + "\t");
}
}
}

// 实现Comparator接口
class MyComparator implements Comparator<Integer> {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
}

(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
import java.util.Scanner;

public class Test049 {
/**
* 冒泡排序:对比相邻的元素值,小的排前面,大的排后面
* 冒泡排序在双层循环中实现,外层循环控制排序轮数,总循环次数为要排序数组的长度减1
* 内层循环对比相邻元素的大小,以确定是否交换位置,对比和交换次数依排序轮数而减少
*/
public static void main(String[] args) {
// 获取用户输入的5个数值,冒泡排序输出结果
Scanner s = new Scanner(System.in);
double[] d = new double[5];
for (int i = 0; i < d.length; i++) {
System.out.print("第" + (i + 1) + "个值:");
d[i] = s.nextDouble();
}

// 冒泡前输出
for (double val : d) {
System.out.print(val + "\t");
}
System.out.println();

// 冒泡后输出
System.out.println("*****************************************");
for (int i = 0; i < d.length - 1; i++) {
// 比较相邻的两个元素,大的排后面
for (int j = 0; j < d.length - 1 - i; j++) {
if (d[j] > d[j + 1]) {
double t = d[j + 1];
d[j + 1] = d[j];
d[j] = t;
}
System.out.print(d[j] + "\t");
}
System.out.print("[");
for (int j = d.length - 1 - i; j < d.length; j++) {
System.out.print(d[j] + "\t");
}
System.out.println("]");
}
}
}

(2) 快速排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public class Test050 {
/**
* 快速排序:是对冒泡排序的改进,是一种排序执行效率很高的排序算法
* 将要排序的数据分隔成独立的两部分,其中一部分的所有数据比另一部分都要小
* 然后再按照此方法,对这两部分数据分别再进行快速排序
* 整个排序过程可递归进行,以此使整个数据变成有序序列
*/
public static void main(String[] args) {
int[] num = { 13, 15, 25, 98, 16, 10, 90, 23 };
System.out.print("排序前:");
for (int val : num) {
System.out.print(val + " ");
}
System.out.println();
quick(num);
System.out.print("排序后:");
for (int val : num) {
System.out.print(val + " ");
}
}

// 声明静态的getMiddle()方法:方法中传入3个参数,并返回一个int类型的参数值
public static int getMiddle(int[] middle, int small, int large) {
int tmp = middle[small];
while (small < large) {
while (small < large && middle[large] > tmp) {
large--;
}
middle[small] = middle[large];
while (small < large && middle[small] < tmp) {
small++;
}
middle[large] = middle[small];
}
middle[small] = tmp;
return small;
}

// 创建静态unckSort()方法:判断small参数是否小于large参数,是则调用getMiddle()
public static void unckSort(int[] middle, int small, int large) {
if (small < large) {
// 将数组一分为二,并且调用自身方法进行递归排序
int m = getMiddle(middle, small, large);
unckSort(middle, small, m - 1);
unckSort(middle, m + 1, large);
}
}

// 声明静态quick()方法:判断传入的数组是否为空,不为空则调用unckSort()方法进行排序
public static void quick(int[] str) {
if (str.length > 0) {
unckSort(str, 0, str.length - 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
public class Test051 {
/**
* 选择排序:每次从待排序的元素中选出最大或最小的一元素
* 顺序放在已排好序的数列最后,直到全部待排序的元素排完
*/
public static void main(String[] args) {
int[] num = { 13, 15, 25, 98, 16, 10, 90, 23 };
String end = "\n";
int index;
for (int i = 1; i < num.length; i++) {
index = 0;
for (int j = 1; j <= num.length - i; j++) {
if (num[j] > num[index]) {
index = j;
}
}
end = num[index] + " " + end;
int tmp = num[num.length - i];
num[num.length - 1] = num[index];
num[index] = tmp;
System.out.print("【");
for (int j = 0; j < num.length - i; j++) {
System.out.print(num[j] + " ");
}
System.out.print("】" + end);
}
}
}

(4) 插入排序

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 Test052 {
/**
* 直接插入排序:将n个有序数存放在数组a中,要插入的数为x
* 首先确定x插在数组中的位置p,将p后的元素都向后移一个位置
* 空出a(p),最后将x放入a(p),这样就可实现插入x后仍然有序了
*/
public static void main(String[] args) {
int[] num = { 13, 15, 25, 98, 16, 10, 90, 23 };
System.out.print("排序前:");
for (int val : num) {
System.out.print(val + " ");
}
System.out.println();

int tmp, j;
for (int i = 1; i < num.length; i++) {
tmp = num[i];
for (j = i - 1; j >= 0 && num[j] > tmp; j--) {
num[j + 1] = num[j];
}
num[j + 1] = tmp;
}
System.out.print("排序后:");
for (int val : num) {
System.out.print(val + " ");
}
}
}

2-5 最大值最小值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Test053 {
public static void main(String[] args) {
int[] num = { 13, 15, 25, 98, 16, 10, 90, 23 };
int max = 0;
int min = 0;
max = min = num[0];
for (int x = 0; x < num.length; x++) {
if (num[x] > max) {
max = num[x];
}
if (num[x] < min) {
min = num[x];
}
}
System.out.println("最小值:" + min);
System.out.println("最大值:" + max);
}
}

2-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
import java.util.Scanner;

public class Test054 {
public static void main(String[] args) {
int[] prices = new int[5];
int maxPrice = 0, avgPrice = 0, sumPrice = 0;
Scanner input = new Scanner(System.in);
System.out.println("请分别输入五件商品价格(回车输入下一件商品价格):");
for (int i = 0; i < 5; i++) {
prices[i] = input.nextInt();
}
maxPrice = prices[0];
for (int j = 1; j < prices.length; j++) {
sumPrice += prices[j];
if (prices[j] > maxPrice) {
maxPrice = prices[j];
}
}
avgPrice = sumPrice / prices.length;
System.out.println("平均价:" + avgPrice);
System.out.println("最高价:" + maxPrice);
System.out.println("总价格:" + sumPrice);
}
}

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
import java.util.List;
import java.util.Scanner;
import java.util.HashMap;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.nio.charset.Charset;
import java.io.InputStreamReader;

public class Test055 {
// 用户名和密码的映射
private static HashMap<String, String> users = new HashMap<>();

// 使用BufferedReader和InputStreamReader并指定编码为GBK,避免默认编码不一致
BufferedReader br = new BufferedReader(new InputStreamReader(System.in, Charset.forName("GBK")));
private static Scanner scan = new Scanner(System.in, "GBK");

// 用户名和商品的映射
private static HashMap<String, List<Product>> userProducts = new HashMap<>();

public static void main(String[] args) {
System.out.println("****************************************");
System.out.println("***** 欢迎登录:后台商品库存系统 *****");
System.out.println("****************************************");

while (true) {
System.out.print("您是否已注册过账户?(输入“是”或“否”): ");
// 使用trim()去掉空格
String choice = scan.nextLine().trim();

if ("是".equals(choice)) {
boolean loginSuccess = login();
if (loginSuccess) {
break;
} else {
boolean registeredLogin = registerFlow();
if (registeredLogin) {
break;
}
}
} else if ("否".equals(choice)) {
boolean registeredLogin = registerFlow();
if (registeredLogin) {
break;
}
} else {
System.out.println("[校验]无效输入,请输入“是”或“否”重新确认!");
}
}
}

// 注册
private static boolean registerFlow() {
while (true) {
System.out.print("[注册]请输入账户:");
String username = scan.nextLine().trim();

// 检查账户是否为空
if (username.isEmpty()) {
System.out.println("[校验]账户为空,请重新输入!");
continue;
}

// 检查账户是否已经存在
if (users.containsKey(username)) {
System.out.println("[校验]账户存在,请重新输入!");
continue;
}

// 输入密码部分,放入循环,直到输入合法密码为止
String password;
while (true) {
System.out.print("[注册]请输入密码: ");
password = scan.nextLine().trim();

// 检查密码是否为空
if (password.isEmpty()) {
System.out.println("[校验]密码为空,请重新输入!");
} else {
// 密码合法,跳出密码输入循环
break;
}
}

// 存储账户和密码
users.put(username, password);
System.out.println("[校验]注册成功,可登录使用!");

// 询问用户是否立即登录
while (true) {
System.out.print("您是否立即登录账户?(输入“是”或“否”):");
String loginChoice = scan.nextLine().trim();
if ("是".equals(loginChoice)) {
boolean loginSuccess = login();
if (loginSuccess) {
// 登录成功,结束注册流程
return true;
} else {
break;
}
} else if ("否".equals(loginChoice)) {
while (true) {
System.out.print("是否继续注册新账户?(输入“是”或“否”):");
String continueReg = scan.nextLine().trim();
if ("是".equals(continueReg)) {
break;
} else if ("否".equals(continueReg)) {
// 不继续注册,跳转到登录入口
boolean loginSuccess = false;
while (true) {
System.out.print("您是否立即登录账户?(输入“是”或“否”):");
String wantLogin = scan.nextLine().trim();
if ("是".equals(wantLogin)) {
loginSuccess = login();
if (loginSuccess)
return true;
} else if ("否".equals(wantLogin)) {
return false;
} else {
System.out.println("[校验]无效输入,请输入“是”或“否”重新确认!");
}
}
} else {
System.out.println("[校验]无效输入,请输入“是”或“否”重新确认!");
}
}
// 跳出当前立即登录的询问循环,回到外层继续注册或登录判断
break;
} else {
System.out.println("[校验]无效输入,请输入“是”或“否”重新确认!");
}
}
}
}

// 登录
private static boolean login() {
while (true) {
System.out.print("[登录]请输入账户: ");
String username = scan.nextLine().trim();

// 检查用户名是否存在
if (!users.containsKey(username)) {
while (true) {
System.out.print("[校验]账户错误,是否重新注册?(是/否):");
String regChoice = scan.nextLine().trim();
if ("是".equals(regChoice)) {
return false;
} else if ("否".equals(regChoice)) {
break;
} else {
System.out.println("[校验]无效输入,请输入“是”或“否”重新确认!");
}
}
continue; // 用户名不存在,回到外层循环重新输入用户名
}

// 用户名存在,进入密码验证循环
while (true) {
System.out.print("[登录]请输入密码: ");
String password = scan.nextLine().trim();

if (!users.get(username).equals(password)) {
System.out.println("[校验]密码错误,请重新输入密码!");
} else {
System.out.println("[校验]登录成功,欢迎 “" + username + "” 使用后台管理!");
userMenu(username);
return true;
}
}
}
}

// 商品类
static class Product {
// 全局自增商品ID
private static int globalId = 1;

// id唯一编号、pname商品名称、price商品单价、stock库存数量
int id;
String pname;
double price;
int stock;

public Product(String pname, double price, int stock) {
this.id = globalId++;
this.pname = pname;
this.price = price;
this.stock = stock;
}

@Override
public String toString() {
return String.format("ID:%d 商品:%s 单价:%.2f 库存:%d", id, pname, price, stock);
}
}

// 商品操作
private static void userMenu(String username) {
while (true) {
System.out.println("\n---------- 用户商品管理菜单 ----------");
System.out.println("------------ 1、添加商品 -------------");
System.out.println("------------ 2、删除商品 -------------");
System.out.println("------------ 3、修改信息 -------------");
System.out.println("------------ 4、商品入库 -------------");
System.out.println("------------ 5、商品出库 -------------");
System.out.println("------------ 6、商品查询 -------------");
System.out.println("------------ 7、商品统计 -------------");
System.out.println("------------ 8、退出登录 -------------");
System.out.print("请选择操作(序号1-8任选一项,回车选择):");

String choice = scan.nextLine().trim();
switch (choice) {
case "1":
addProduct(username);
break;
case "2":
deleteProduct(username);
break;
case "3":
updateProduct(username);
break;
case "4":
stockIn(username);
break;
case "5":
stockOut(username);
break;
case "6":
listProducts(username);
break;
case "7":
statisticProducts(username);
break;
case "8":
System.out.println("账户 “" + username + "” 已退出登录!");
return;
default:
System.out.println("[校验]无效输入,请输入任意序号“1-8”确认!");
}
}
}

// 添加商品
private static void addProduct(String username) {
System.out.print("请输入初始商品名称:");
String pname = scan.nextLine().trim();
if (pname.isEmpty()) {
System.out.println("商品名称不可以为空!");
return;
}

double price;
while (true) {
System.out.print("请输入初始商品价格:");
String priceStr = scan.nextLine().trim();
try {
price = Double.parseDouble(priceStr);
if (price < 0) {
System.out.println("商品价格不能为负数!");
} else {
break;
}
} catch (Exception e) {
System.out.println("价格格式错误,请输入数字!");
}
}

int stock;
while (true) {
System.out.print("请输入初始库存数量:");
String stockStr = scan.nextLine().trim();
try {
stock = Integer.parseInt(stockStr);
if (stock < 0) {
System.out.println("库存数量不能为负数!");
} else {
break;
}
} catch (Exception e) {
System.out.println("库存格式错误,请输入整数!");
}
}

Product p = new Product(pname, price, stock);
userProducts.computeIfAbsent(username, k -> new ArrayList<>()).add(p);
System.out.println("商品添加成功!添加信息为:\n" + p);
}

// 删除商品
private static void deleteProduct(String username) {
List<Product> list = userProducts.get(username);
if (list == null || list.isEmpty()) {
System.out.println("当前账户没有商品可以删除!");
return;
}
listProducts(username);
System.out.print("请输入要进行删除的商品ID:");
String idStr = scan.nextLine().trim();
try {
int id = Integer.parseInt(idStr);
boolean removed = list.removeIf(p -> p.id == id);
if (removed) {
System.out.println("删除成功,选中商品已不在!");
} else {
System.out.println("抱歉,未找到指定ID的商品!");
}
} catch (Exception e) {
System.out.println("啊哦,输入商品ID格式有误!");
}
}

// 修改信息
private static void updateProduct(String username) {
List<Product> list = userProducts.get(username);
if (list == null || list.isEmpty()) {
System.out.println("当前账户没有商品可供修改!");
return;
}
listProducts(username);
System.out.print("请输入要进行修改的商品ID:");
String idStr = scan.nextLine().trim();
try {
int id = Integer.parseInt(idStr);
Product target = null;
for (Product p : list) {
if (p.id == id) {
target = p;
break;
}
}
if (target == null) {
System.out.println("抱歉,未找到指定ID的商品!");
return;
}

System.out.print("请您输入新的商品名称:");
String newName = scan.nextLine().trim();
if (!newName.isEmpty())
target.pname = newName;
System.out.print("请您输入新的商品价格:");
String newPriceStr = scan.nextLine().trim();
if (!newPriceStr.isEmpty()) {
try {
double newPrice = Double.parseDouble(newPriceStr);
if (newPrice >= 0)
target.price = newPrice;
else
System.out.println("价格不能为负数,保持不变!");
} catch (Exception e) {
System.out.println("价格格式错误啦,保持不变!");
}
}

System.out.print("请您输入新的库存数量:");
String newStockStr = scan.nextLine().trim();
if (!newStockStr.isEmpty()) {
try {
int newStock = Integer.parseInt(newStockStr);
if (newStock >= 0)
target.stock = newStock;
else
System.out.println("库存不能为负数,保持不变!");
} catch (Exception e) {
System.out.println("库存格式错误啦,保持不变!");
}
}
System.out.println("商品信息完成修改,修改为:\n" + target);
} catch (Exception e) {
System.out.println("啊哦,输入商品ID格式有误!");
}
}

// 商品入库
private static void stockIn(String username) {
List<Product> list = userProducts.get(username);
if (list == null || list.isEmpty()) {
System.out.println("当前账户没有商品可以入库!");
return;
}
listProducts(username);
System.out.print("请您输入要入库的商品ID:");
String idStr = scan.nextLine().trim();
System.out.print("请您输入入库商品的数量:");
String qtyStr = scan.nextLine().trim();
try {
int id = Integer.parseInt(idStr);
int qty = Integer.parseInt(qtyStr);
if (qty <= 0) {
System.out.println("入库的商品数量必须大于零!");
return;
}
Product target = null;
for (Product p : list) {
if (p.id == id) {
target = p;
break;
}
}
if (target == null) {
System.out.println("抱歉,未找到指定ID的商品!");
return;
}
target.stock += qty;
System.out.println("入库成功,当前商品库存为:" + target.stock);
} catch (Exception e) {
System.out.println("抱歉,输入的库存格式有误!");
}
}

// 商品出库
private static void stockOut(String username) {
List<Product> list = userProducts.get(username);
if (list == null || list.isEmpty()) {
System.out.println("当前账户没有商品可以出库!");
return;
}
listProducts(username);
System.out.print("请您输入要出库的商品ID:");
String idStr = scan.nextLine().trim();
System.out.print("请您输入出库商品的数量:");
String qtyStr = scan.nextLine().trim();
try {
int id = Integer.parseInt(idStr);
int qty = Integer.parseInt(qtyStr);
if (qty <= 0) {
System.out.println("出库的商品数量必须大于零!");
return;
}
Product target = null;
for (Product p : list) {
if (p.id == id) {
target = p;
break;
}
}
if (target == null) {
System.out.println("抱歉,未找到指定ID的商品!");
return;
}
if (target.stock < qty) {
System.out.println("库存不足,该商品无法出库!");
return;
}
target.stock -= qty;
System.out.println("出库成功,当前库存量为:" + target.stock);
} catch (Exception e) {
System.out.println("抱歉,输入的库存格式有误!");
}
}

// 商品查询
private static void listProducts(String username) {
List<Product> list = userProducts.get(username);
if (list == null || list.isEmpty()) {
System.out.println("啊哦,当前账户下没有商品!");
return;
}
System.out.println("*************** 商品列表 ***************");
for (Product p : list) {
System.out.println(p);
}
}

// 商品统计
private static void statisticProducts(String username) {
List<Product> list = userProducts.get(username);
if (list == null || list.isEmpty()) {
System.out.println("当前账户没商品,无法统计!");
return;
}
int totalStock = 0;
double totalValue = 0;
for (Product p : list) {
totalStock += p.stock;
totalValue += p.stock * p.price;
}
System.out.println("总商品种类:" + list.size());
System.out.println("总库存数量:" + totalStock);
System.out.printf("库存总价值:%.2f\n", totalValue);
}
}

4 类和对象

  • 类和对象
    • 面向对象,简称OO:面向对象分析OOA、面向对象设计OOD、面向对象程序设计OOP。
    • 三大核心特性
      • 继承:子类拥有父类的全部特征和行为,这是类之间的一种关系,Java只支持单继承。
      • 封装:目的在于保护信息,Java的基本封装单位是类,提供了私有和公有的访问模式。
      • 多态:一个接口多个方法,父类中定义的属性和方法被子类继承后,具有不同的属性或表现方式。
    • 类是对象的抽象,对象是类的具体。对象拥有的特征在类中称为类的属性,执行的操作称为类的方法。
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
// 声明一个Test056的类,类中的数据和方法统称为类成员
public class Test056 {
/**
* public、protected、private用于表示成员变量的访问权限
* static:该成员变量为类变量,也叫静态变量
* final:声明该成员变量为常量,其值无法更改
*/

// 类的属性,即类的数据成员(成员变量)
private String name;
// 定义类的成员变量,0表示女,1表示男
final int sex = 0;
static int sum;
private int age;
private boolean judge;

/**
* public、protected、private用于表示成员方法的访问权限
* static:限定该成员方法为静态方法
* final:限定该成员方法不能被重写或重载
* abstract:限定该成员方法为抽象方法,不提供具体的实现并且所属类型必须为抽象类
*/

// 类的方法,一个完整方法包括名称、主体、参数、返回值类型
public void tell() {
System.out.println(name + "今年" + age + "岁啦!");
}

public boolean isTrue() {
return judge;
}

public void setTrue(boolean judge) {
this.judge = judge;
}

public static void main(String[] args) {
System.out.println(sum);

// 创建一个实例
Test056 T = new Test056();

String isTrue = T.isTrue() ? "false" : "true";
System.out.println(isTrue);

T.judge = true;
System.out.println(T.judge);
}

// 形参是定义方法时参数列表中出现的参数,实参是调用方法时为方法传递的参数
// 局部变量只能在本方法体内有效或者可见,离开本方法则这些变量将被自动释放
// 在方法体内定义变量时,变量的前面不能加修饰符
// 局部变量在使用前必须明确赋值,否则编译时出错
public StringBuffer printInfo(Test056 st) {
StringBuffer s = new StringBuffer();
s.append(st.isTrue());
// 成员方法的返回值
return s;
}
}

4-1 this关键字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/**
* this关键字是Java常用关键字,可用于任何实例方法内指向当前对象
* 也可指向对其调用当前方法的对象,或在需要当前类型对象引用时使用
* this不能在普通方法中使用,只能写在构造方法中,使用时必须是第一条语句
*/
public class Test057 {
// this.属性名
private String name;
private double salary;
private int age;

// 创建构造方法,无参构造方法
public Test057() {
this("刘一");
}

// 创建构造方法,有参构造方法
public Test057(String name) {
this(name, 0.0, 0);
}

// 创建构造方法,为上面的3个属性赋初始值
public Test057(String name, double salary, int age) {
this.name = name;
this.salary = salary;
this.age = age;
}

// 调用构造方法给name赋值
public void print() {
System.out.println("姓名:" + name);
}

// this.方法名,定义一个jump()方法
public void jump() {
System.out.println("蹦迪中...");
}

// 定义一个run()方法,需借助jump()方法
public void run() {
this.jump();
System.out.println("跑步中...");
}

public static void main(String[] args) {
// 大多时候普通方法访问其他方法、成员变量时无须使用this前缀
// 当一个类的属性(成员变量)名与访问该属性的方法参数名相同时
// 需要使用this关键字来访问类中的属性,以区分类的属性和方法中的参数
Test057 t = new Test057("刘一", 8000, 37);
System.out.println(t.name + ":薪资" + t.salary + ",年龄" + t.age);

// static修饰的方法不能使用this引用,静态成员不能直接访问非静态成员
t.run();
t.print();
}
}

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
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
import java.io.Serializable;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

// 实现Cloneable接口才可以进行克隆clone()
// 否则抛出CloneNotSupportedException异常
public class Test058 implements Cloneable, Serializable {
/**
* 对象是对类的实例化,具有状态和行为
* 变量用来表明对象的状态,方法表明对象所具有的行为
* Java对象的生命周期包括创建、使用、清除
*/
private String name;
private int age;

public Test058(String name, int age) {
this.name = name;
this.age = age;
}

public Test058() {
this.name = "钱五";
this.age = 21;
}

public String toString() {
return "名字:" + name + ",年龄:" + age;
}

public static void main(String[] args) throws Exception {
// 显式创建:使用new关键字
Test058 t1 = new Test058("张三", 20);
System.out.println(t1);

// 显式创建:调用.Class或.reflect.Constuctor类的newInstance()实例方法
// 使用Class类的newInstance()方法创建对象时,会调用类的默认(无参)构造方法
// 注意:Class.forName()需要使用完整类名,如:java.Test058(主类包含包名)
Class c = Class.forName("Test058");
Test058 t2 = (Test058) c.newInstance();
System.out.println(t2);

// 显式创建:调用对象的clone()方法
Test058 t3 = (Test058) t2.clone();
System.out.println(t3);

// 显式创建:调用java.io.ObjectInputStream对象的readObject()方法
// 利用Java的序列化机制来恢复对象的过程
// 通过将对象写入文件再从字节流中读取,实现“隐式创建”对象
// 先序列化t1
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("test.ser"))) {
oos.writeObject(t1);
}
// 再反序列化创建对象t4
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test.ser"))) {
Test058 t4 = (Test058) ois.readObject();
System.out.println(t4);
}

// 隐含地创建对象,值就是一个String对象,由Java虚拟机隐含地创建
String str1 = "名字:孙静,";
String str2 = "年龄:29";
String str3 = str1 + str2;
System.out.println(str3);
// 当Java虚拟机加载一个类时,会隐含地创建描述这个类的Class实例
}
}

(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
public class Test059 {
/**
* 若一个对象只需使用唯一一次,就可使用匿名对象
* 匿名对象还可以作为实际参数进行传递
* 没有明确给出名称的对象,是对象的一种简写形式
* 匿名对象只在堆内存中开辟空间,不存在栈内存的引用
*/
public String name;
public int age;

// 定义构造方法,为属性初始化
public Test059(String name, int age) {
this.name = name;
this.age = age;
}

// 获取信息的方法
public void tell() {
System.out.println("姓名:" + name + ",年龄:" + age);
}

public static void main(String[] args) {
// 使用一次之后就等待被GC(垃圾收集机制)回收
new Test059("刘备", 30).tell();
}
}

(2) 访问对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Test060 {
// 引用对象的属性和行为,需要使用点操作符进行访问
// 对象名在点左边,成员变量名或成员方法名在点右边
public String name;
public int age;

public static void main(String[] args) {
// 定义Test060类,创建该类的对象s,并对对象的属性赋值
Test060 s = new Test060();
s.name = "赵六";
s.age = 25;
System.out.println(s.name);
}
}

(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
public class Test061 {
/**
* 对象的清除是指释放对象占用的内存
* 创建对象时必须使用new操作符为对象分配内存
* 清除对象时由系统自动进行内存回收,不需额外处理
* Java的内存自动回收称为垃圾回收机制,简称GC
*/

// 对象被当作垃圾回收的情况:对象的引用超过其作用范围
{
Object o1 = new Object();
System.out.println(o1);
}

// 对象被当作垃圾回收的情况:对象被赋值为null
{
Object o2 = new Object();
o2 = null;
System.out.println(o2);
}

/**
* 在Java的Object类中还提供了一个protected类型的finalize()方法
* 任何Java类都可覆盖该方法,在该方法中进行释放对象所占用相关资源的操作
* Java虚拟机的堆区中,每个对象都可能处于三种状态之一
*** 可触及状态:对象被创建后,只要程序中还有引用变量,那么就始终处于该状态
*** 可复活状态:当程序不再有任何引用变量引用该对象时,该对象就进入可复活状态
*** 不可触及状态:当Java虚拟机执行完所有可复活对象的finalize()方法后
*** 若这些方法都没有使该对象转到可触及状态,垃圾回收器才会真正回收占用的内存
*/
public static void main(String[] args) {
System.out.println();
}
}

(4) 用户类操作

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
import java.util.Scanner;

// 定义一个用户类,一个.java文件中可以包含多个类
// 最多只有一个public类,并且该类名必须与文件名相同
// 其他类不能声明为public,访问权限默认为包内可见
class Member {
private String username;
private 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;
}

public Member(String username, String password) {
this.username = username;
this.password = password;
}

public String toString() {
return "账户:" + username + "\n密码:" + password;
}
}

public class Test062 {
// 创建一个测试类,调用用户类
public static void main(String[] args) {
Member admin = new Member("admin.", "123456");
Scanner input = new Scanner(System.in);
System.out.println("请输入原密码:");
String pwd = input.next();
if (pwd.equals(admin.getPassword())) {
System.out.println("请输入新密码:");
admin.setPassword(input.next());
} else {
System.out.println("输入密码错误!");
}
System.out.println("--用户信息--\n" + admin);
}
}

4-3 类方法注释

  • 类方法注释
    • 多行注释的内容不能用于生成一个开发者文档,但文档注释可以。
    • 文档注释提供了类、方法和变量的解释,也可以称之为帮助文档。

(1) 类注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* 以@开头的标签为Javadoc标记,由@和标记类型组成,缺一不可
* 没有必要在每一行的开始使用*,只留首尾,中间的*可以省略不写
* @projectName:项目名称
* @package:包
* @className:类名称
* @description:类描述(一句话描述该类的功能,必须)
* @author:创建人(必须)
* @createDate:创建时间(必须)
* @updateUser:修改人
* @updateDate:修改时间
* @updateRemark:修改备注(说明本次修改的内容)
* @version:版本
*/

(2) 方法注释

1
2
3
4
5
6
7
/**
* 方法注释必须紧靠方法定义前,主要声明方法参数、返回值、异常等信息
* 除了可以使用通用标签外,还可以使用下列的以@开始的标签
* @param:变量描述,一个方法的所有@param标记必须全放一起
* @return:返回类型描述
* @throws:异常类型描述
*/

(3) 字段注释

1
2
3
/** 
* 字段注释在定义字段前,用来描述字段的含义
*/

4-4 访问控制符

  • 访问控制符
    • 信息隐藏是OOP最重要的功能之一,也是使用访问修饰符的原因。
    • 访问控制符是一组限定类、属性或方法是否可被程序里的其他部分访问和调用的修饰符。
    • 类的访问控制符只能是空或者public,而方法和属性的访问控制符有四个。
    • 分别是public、private、protected、friendly(未定义专门的访问控制符)。
    • public
      • 一个类被声明为public时就具有了被其他包中类访问的可能性,可使用import引用。
      • 每个Java程序的主类必须是public类,被设定为主类的方法是该类对外的接口部分。
    • private
      • 修饰的类成员只能被该类自身的方法访问和修改,不能被其他类,包括子类访问和引用。
      • private具最高保护级别,例如:PhoneCard电话卡类设有密码,密码域声明为私有成员。
    • friendly
      • 如果一个类没有访问控制符,那么说明这个类具有默认的访问控制特性。
      • 规定该类只能被同一个包中的类访问和引用,不能被其他包中的类使用。
      • 即使其他包中有该类的子类,这种访问特性又称为包访问性(package private)。
    • protected
      • 类成员可被三种类访问:该类自身、与其在同个包中的其他类、其他包中的该类子类。
      • 作用:允许其他包中该类子类访问父类的特定属性和方法,否则可用默认访问控制符。
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
class Student {
// 访问权限为默认friendly
String name;

// 定义私有变量
private String idNumber;

// 定义受保护变量
protected String no;

// 定义共有变量
public String email;

// 定义共有方法
public String info() {
return "姓名:" + name + "\n身份:" + idNumber
+ "\n学号:" + no + "\n邮箱:" + email;
}
}

public class Test063 {
public static void main(String[] args) {
// 创建Student类对象
Student stu = new Student();
// 向类中对象的属性赋值
stu.name = "张三";

// 私有变量,不可见
// stu.idNumber = "1111";

stu.no = "1111";
stu.email = "test@qq.com";
System.out.println(stu.info());
}
}

4-5 static关键字

  • static关键字
    • 在类中,使用static修饰符修饰的属性(即成员变量)称之为静态变量,也可以叫类变量。
    • 常量称为静态常量,方法称为静态方法或类方法,它们都统称为静态成员,全归整个类所有。
    • static修饰的方法或变量不需要依赖对象进行访问,只要类被加载,虚拟机就能根据类名找到。
    • 修饰的成员变量和方法从属于类,普通变量和方法从属于对象,静态方法不能调用非静态成员。

(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
public class Test064 {
/**
* 类的成员变量:静态变量、实例变量
* 静态变量:又叫类变量,指被static修饰的成员变量
*** 运行时Java虚拟机只为其分配一次内存,在加载类的过程中完成内存分配
*** 在类的内部,可以在任何方法内直接访问静态变量
*** 在其他类中,可以通过类名访问该类中的静态变量
* 实例变量:指没有被static修饰的成员变量
*** 每创建一个实例,Java虚拟机就会为实例变量分配一次内存
*** 在类的内部,可以在非静态方法中直接访问实例变量
*** 在本类的静态方法或其他类中,需要通过类的实例对象进行访问
* 静态变量是被多个实例所共享的
*/
public static String str1 = "Hello";

public static void main(String[] args) {
String str2 = "world!";

// 直接访问str1
String a1 = str1 + " " + str2;
System.out.println("第1次访问:" + a1);

// 通过类名访问str1
String a2 = Test064.str1 + " " + str2;
System.out.println("第2次访问:" + a2);

// 通过对象s1访问str1
Test064 s1 = new Test064();
s1.str1 = s1.str1 + " " + str2;
String a3 = s1.str1;
System.out.println("第3次访问:" + a3);

// 通过对象s2访问str1
Test064 s2 = new Test064();
String a4 = s2.str1 + " " + str2;
System.out.println("第4次访问:" + a4);
}
}

(2) 静态方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class Test065 {
/**
* 成员方法:静态方法、实例方法
* 静态方法:又叫类方法,指被static修饰的成员方法
*** 不需要通过所属类的任何实例就可以被调用,因此在静态方法中不能使用this关键字
*** 不能直接访问所属类的实例变量和实例方法,可直接访问所属类的静态变量和静态方法
*** 和this一样,super也与类的特定实例相关,所以在静态方法中也不能使用super关键字
* 实例方法:指没有被static修饰的成员方法
*** 可以直接访问所属类的静态变量、静态方法、实例变量和实例方法
* 在访问非静态方法时,需要通过实例对象来访问
* 在访问静态方法时,可直接访问,也可通过类名访问,还可通过实例化对象访问
*/
// 定义静态变量count
public static int count = 1;

// 实例方法m1
public int m1() {
// 访问静态变量count并赋值
count++;
return count;
}

// 静态方法m2
public static int m2() {
// 访问静态变量count并赋值
count += count;
return count;
}

// 静态方法printCount
public static void printCount() {
count += 2;
System.out.println(count);
}

public static void main(String[] args) {
Test065 s = new Test065();

// 通过实例对象调用实例方法
System.out.println(s.m1());

// 直接调用静态方法
System.out.println(m2());

// 通过类名调用静态方法,打印count
Test065.printCount();
}
}

(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
public class Test066 {
/**
* 静态代码块:指Java类中的static{ }代码块
* 主要用于初始化类,为类的静态变量赋初始值,提升程序性能
* 虚拟机加载类时执行静态代码块,会将一些只需进行一次的初始化操作都放在static块中
* 若类中包含多个静态代码块,则按出现顺序依次执行,每个静态代码块只会被执行一次
* 与静态方法一样,不能直接访问类的实例变量和实例方法,需通过类的实例对象来访问
*/
public static int count = 0;
// 非静态代码块,在创建对象时自动执行的代码,不创建对象不执行该类的非静态代码块
{
count++;
System.out.println(count);
}
static {
count++;
System.out.println(count);
}
static {
count++;
System.out.println(count);
}

public static void main(String[] args) {
Test066 s1 = new Test066();
Test066 s2 = new Test066();
}
}

(4) 静态导入法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// JDK1.5后增加了静态导入语法
// 用于导入指定类的某个静态成员变量、方法或全部的静态成员变量、方法
// 如果一个类中的方法全部是使用static声明的静态方法
// 则在导入时就可以直接使用import static的方式导入
import static java.lang.Math.*;
import static java.lang.System.*;

public class Test067 {
public static void main(String[] args) {
// out是java.lang.System类的静态成员变量
// 直接调用Math类的sqrt静态方法,返回256的正平方根
out.println(sqrt(256));
}
}

5 final修饰符

  • final修饰符
    • final表示对象是最终形态,不可改变的。
    • 应用于类、方法和变量时意义不同,本质一样,都表示不可改变。
    • 用在变量前面,表示变量的值不可以改变,此时该变量称为常量。
    • 用在方法前面,表示方法不可以被重写。
    • 用在类的前面,表示该类不能有子类,即该类不可以被继承。

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
41
42
43
44
45
46
47
public class Test068 {
/**
* final修饰的变量即称为常量,只能赋值一次
* final修饰的局部变量必须使用之前被赋值一次才能使用
* final修饰的成员变量在声明时没有赋值的叫“空白final变量”
* 空白final变量必须在构造方法或静态代码块中初始化
*/
void doSth() {
// 没有在声明的同时赋值
final int a;
a = 100;
System.out.println(a);

// 声明的同时赋值
final int b = 200;
System.out.println(b);
}

// 实例常量,直接赋值
final int c = 300;
// 空白final变量
final int d;

// 静态常量,直接赋值
final static int e = 400;
// 空白final变量
final static int f;

// 静态代码块
static {
// 初始化静态变量
f = 500;
}

// 构造方法
Test068() {
// 初始化实例变量
d = 600;

// 第二次赋值会编译错误
// d = 666;
}

public static void main(String[] args) {
System.out.println();
}
}

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import java.util.Arrays;

class Person {
private int age;

public Person() {
}

// 有参数的构造器
public Person(int age) {
this.age = age;
}

// age的setter和getter方法
public void setAge(int age) {
this.age = age;
}

public int getAge() {
return age;
}
}

public class Test069 {
/**
* 使用final修饰基本类型变量时不能对基本类型变量重新赋值,因此基本类型变量不能被改变
* 引用类型变量所保存的仅是一个引用,final只保证这个引用类型变量所引用的地址不会改变
* 即一直引用同一对象,但该对象完全可以发生改变,使用final声明变量时要求全部字母大写
*/
public static void main(String[] args) {
// final修饰数组变量,iArr是一个引用变量
final int[] iArr = { 1, 7, 3, 5 };
System.out.println(Arrays.toString(iArr));

// 对数组元素进行排序,合法
Arrays.sort(iArr);
System.out.println(Arrays.toString(iArr));

// 对数组元素赋值,合法
iArr[2] = 6;
System.out.println(Arrays.toString(iArr));

// 对引用变量重新赋值,非法
// iArr = null;

// final修饰Person变量,p是一个引用变量
final Person p = new Person(45);

// 改变Person对象的age实例变量,合法
p.setAge(27);
System.out.println(p.getAge());

// 对引用变量P重新赋值,非法
// p =null;
}
}

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 Test070 {
/**
* final修饰的方法不可被重写,若不希望子类重写父类的某个方法,可用该方法
* final修饰一个private访问权限的方法,依然可在子类中定义与该方法一样的新方法
* final修饰的方法仅仅是不能被重写,并不是不能被重载
*/
public final void t1() {
}

private final void t2() {
}

// final修饰的方法,可以被重载
public final void t1(String arg) {
}

public static void main(String[] args) {
System.out.println();
}
}

class Sub extends Test070 {
// 方法定义将出现编译错误,不能重写final方法
// public void t1() {}

// 定义了一个同名同参同返回值类型的新方法,非重写
public void t2() {
}
}

5-4 final修饰类

1
2
3
4
5
6
7
8
9
10
11
12
13
final class Test071 {
/**
* 子类继承父类时可访问父类内部数据,并通过重写父类方法改变父类方法的实现细节
* final修饰的类不能被继承,为了保证某个类不可被继承,可使用final修饰这个类
*/
public static void main(String[] args) {
System.out.println();
}
}

// 编译错误,final修饰的类不可被继承
// class SubClass extends Test071 {
// }

6 main()方法

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 Test072 {
/**
* main()方法的访问控制权是共有的public
* main()方法是静态的
*** 在main()方法调用本类中的其他方法,则该方法也必须是静态的
*** 否则需要先创建本类的实例对象,然后再通过对象调用成员方法
* main()方法没有返回值,只能使用void
* 一个类只能有一个main()方法,这是一个常用于对类进行单元测试的技巧
*/
public void Speak1() {
System.out.println("你好!");
}

public static void Speak2() {
System.out.println("我好!");
}

public static void main(String[] args) {
// 错误调用
// Speak1();

// 可直接调用静态方法
Speak2();

// 调用非静态方法,需要通过类的对象来调用
Test072 t = new Test072();
t.Speak1();
}
}

6-1 接收参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Test073 {
/**
* main()方法具有一个字符串数组参数
* 用来接收执行Java程序的命令行参数
* 实现程序执行时统计传递参数的数量及每个参数值
*/
public static void main(String[] args) {
// 获取参数数量
int n = args.length;
System.out.println("一共有 " + n + " 个参数!");
if (n > 0) {
// 判断参数个数是否大于0
for (int i = 0; i < n; i++) {
System.out.println(args[i]);
}
}
}
}

// javac Test073.java
// java Test073 one two three
// main()可以以字符串的形式接收命令行参数,然后在方法体内进行处理

6-2 可变参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Test074 {
/**
* 方法中参数的个数不确定时使用,可变参数必须定义在参数列表的最后
*/

// 定义输出人数和姓名的方法
public void print(String... names) {
// 获取总个数
int count = names.length;
System.out.println("总共 " + count + " 人!");

for (int i = 0; i < names.length; i++) {
System.out.println(names[i]);
}
}

public static void main(String[] args) {
Test074 t = new Test074();
t.print("孙钱", "赵隶");
t.print("张三", "李四", "王五");
}
}

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class Test075 {
/**
* 构造方法:类的特殊方法,用来初始化类的一新对象,创建对象后自动调用
* Java中的每个类都有一个默认的构造方法,并且可以有一个以上的构造方法
* 特点
*** 方法名必须与类名相同,可以有0个或多个参数,无返回值
*** 默认返回类型即对象类型本身,只能与new运算符结合使用
* 构造方法不能被static、final、synchronized、abstract和native修饰
*/

// 定义私有变量
private int a;

// 定义无参的构造方法,也叫Nullary构造方法
Test075() {
a = 0;
}

// 定义有参的构造方法
Test075(int a) {
this.a = a;
}

// 在一个类中定义多个具有不同参数的同名方法,这就是方法的重载
// 若类中未定义任何构造方法,Java会自动为该类生成一默认的构造方法
// 默认的构造方法不包含任何参数,并且方法体为空
public String name;
private int age;

// 定义带有一个参数的构造方法,并未指定age属性值,程序默认0
public Test075(String name) {
this.name = name;
}

// 定义带有两个参数的构造方法
public Test075(String name, int age) {
this.name = name;
this.age = age;
}

public String toString() {
return "我叫" + name + ",今年" + age + "岁啦~";
}

public static void main(String[] args) {
// 调用一个参数的构造方法
Test075 t1 = new Test075("张三");
System.out.println(t1);

// 调用两个参数的构造方法
Test075 t2 = new Test075("王五", 9);
System.out.println(t2);
}
}

6-4 查询信息

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 Test076 {
private String name;
private int age;
private String sex;
private String birthday;
private String constellation;

public Test076(String name, int age, String sex,
String birthday, String constellation) {
this.name = name;
this.age = age;
this.sex = sex;
this.birthday = birthday;
this.constellation = constellation;
}

public String intro() {
return "姓名:" + name + "\n年龄:" + age + "\n性别:" + sex
+ "\n生日:" + birthday + "\n星座:" + constellation;
}

public static void main(String[] args) {
Test076 t = new Test076("钱三", 28, "男", "0221", "双鱼座");
String intro = t.intro();
System.out.println(intro);
}
}

6-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
public class Test077 {
/**
* 析构方法与构造方法相反,当对象脱离其作用域时,系统自动执行析构方法
* 在Java的Object类中,还提供了一个protected类型的finalize()方法
* 任何Java类都可覆盖该方法,在该方法中进行释放对象所占用的相关资源操作
*/

// 计数器
private static int count = 0;

public Test077() {
// 创建实例时增加值
this.count++;
}

public int getCount() {
// 获取计数器的值
return this.count;
}

// 析构方法
protected void finalize() {
this.count--;
System.out.println("对象销毁");
}

public static void main(String[] args) {
// 创建实例1
Test077 c1 = new Test077();
System.out.println(c1.getCount());

// 创建实例2
Test077 c2 = new Test077();
System.out.println(c2.getCount());

// 销毁实例2
c2 = null;

try {
// 清理内存,调用System.gc()或Runtime.gc()
// 提示垃圾回收器尽快执行垃圾回收操作
System.gc();
// 延时1000毫秒
Thread.currentThread().sleep(1000);
// 输出
System.out.println(c1.getCount());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

6-6 package包

  • package包
    • 包允许将类组合成较小的单元,基本上隐藏了类,并避免了名称冲突。
    • 作用:区分相同名称的类,能够较好地管理大量的类,控制访问范围。
    • 包定义:package语句放在源文件首行,每个源文件只能有一个包定义语句。
    • 包导入:如果使用不同包中的其他类,需要使用到这个类的全名(包名+类名)。
    • 系统包:java.lang、java.io、java.util、java.awt、java.net、java.sql、java.rmi等。

(1) 自定义包

1
2
3
4
5
6
src
└── com
├── test
│ └── Test.java
└── info
└── Student.java

(2) Test.java

1
2
3
4
5
6
7
8
9
10
11
package com.test;

import com.info.Student;

public class Test {
public static void main(String[] args) {
for (String str : Student.GetAll()) {
System.out.println(str);
}
}
}

(3) Student.java

1
2
3
4
5
6
7
package com.info;

public class Student {
public static String[] GetAll() {
return new String[] { "张三", "李四", "王五", "赵六", "孙七", "周八" };
}
}

(4) VSCode报错

1
2
3
4
5
# 编译
javac .\com\dao\Student.java .\com\test\Test.java

# 执行
java com.test.Test

6-7 递归算法

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 Test078 {
/**
* 程序调用自身的编程技巧称为递归,典型例子是数字阶乘
*/
int fact(int n) {
int result;
if (n == 1) {
return 1;
}
result = fact(n - 1) * n;
return result;
}

public Test078() {
}

int values[];

Test078(int i) {
values = new int[i];
}

void printArray(int i) {
if (i == 0) {
return;
} else {
printArray(i - 1);
}
System.out.println("数组第【" + (i - 1) + "】个元素:" + values[i - 1]);
}

public static void main(String[] args) {
Test078 f1 = new Test078();
System.out.println("3的阶乘:" + f1.fact(3));
System.out.println("4的阶乘:" + f1.fact(4));
System.out.println("5的阶乘:" + f1.fact(5));

Test078 f2 = new Test078(3);
int i;
for (i = 0; i < 3; i++) {
f2.values[i] = i;
}
f2.printArray(3);
}
}

Java 基础(二)
https://stitch-top.github.io/2025/06/13/java/java02-java-ji-chu-er/
作者
Dr.626
发布于
2025年6月13日 23:50:30
许可协议