java学习笔记基础篇
注释
// /* … */
8种基础数据类型
- Integral types:
byte,short,int,long - Floating-point types:
float,double - The
booleandata type - The
chardata type
变量类型
- 局部变量
- 成员变量(实例变量) - 默认权限
default或声明权限public、protected、private - 静态变量(类变量) - 可以通过类名访问
default权限可以同包访问
常用input与output
Output:
System.out.print("Hello, "); // 不换行
System.out.println("World!"); // 换行
System.out.printf("My name is %s, and I am %d years old.\n", "Alice", 25); // 格式化输出
| 格式符 | 说明 |
|---|---|
| %d | 整数(int, long) |
| %f | 浮点数(float, double) |
| %s | 字符串(String) |
| %c | 字符(char) |
| %b | 布尔值(boolean) |
Input:
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine(); // 读取一行,以按下Enter结束
int num = scanner.nextInt(); // 读取返回整数,空格或Enter结束
double number = scanner.nextDouble(); // 读取返回浮点数,空格或Enter结束
char ch = scanner.next().charAt(0); // 读取返回字符串,空格或Enter结束,并取字符串第一个字符
scanner.close() // 建议,关闭System.in输入流,释放内存
条件语句
if … else if … else …(a > b) ? a : bswitch … case … default …||和&&
如果
case中没有break也会出现“贯穿”(fall-through)
循环语句
whiledo … while …for
控制关键字:
breakcontinue
Java5引入遍历数组的增强for:
for(声明语句 : 表达式)
{
//代码句子
}
例子:
public class Test {
public static void main(String[] args){
int [] numbers = {10, 20, 30, 40, 50};
for(int x : numbers ){
System.out.print( x );
System.out.print(",");
}
System.out.print("\n");
String [] names ={"James", "Larry", "Tom", "Lacy"};
for( String name : names ) {
System.out.print( name );
System.out.print(",");
}
}
}
Java Number & Math 类
Number和Math类属于java.lang包,无需import
Java Number 类
所有的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类 Number 的子类。
| 包装类 | 基本数据类型 |
|---|---|
| Boolean | boolean |
| Byte | byte |
| Short | short |
| Integer | int |
| Long | long |
| Character | char |
| Float | float |
| Double | double |
这种由编译器特别支持的包装称为装箱,所以当内置数据类型被当作对象使用的时候,编译器会把内置类型装箱为包装类。相似的,编译器也可以把一个对象拆箱为内置类型。
| 方法 | 返回类型 | 说明 |
|---|---|---|
| 类型转换方法 | ||
byteValue() |
byte |
以 byte 类型返回数值 |
shortValue() |
short |
以 short 类型返回数值 |
intValue() |
int |
以 int 类型返回数值 |
longValue() |
long |
以 long 类型返回数值 |
floatValue() |
float |
以 float 类型返回数值 |
doubleValue() |
double |
以 double 类型返回数值 |
| 其他方法 | ||
toString() |
String |
返回数值的字符串形式(继承自 Object) |
equals(Object obj) |
boolean |
判断两个 Number 对象是否相等(继承自 Object) |
hashCode() |
int |
返回 Number 对象的哈希码(继承自 Object) |
示例:
public class NumberExample {
public static void main(String[] args) {
// 创建不同类型的 Number 对象
Integer intObj = 100;
Double doubleObj = 99.99;
Float floatObj = 12.5f;
Long longObj = 100000L;
// 类型转换方法
System.out.println("Integer 转换为 double: " + intObj.doubleValue());
System.out.println("Double 转换为 int: " + doubleObj.intValue());
System.out.println("Float 转换为 long: " + floatObj.longValue());
// 获取 Number 的哈希值
System.out.println("Integer 哈希值: " + intObj.hashCode());
System.out.println("Double 哈希值: " + doubleObj.hashCode());
// Number 的 equals 方法
System.out.println("intObj 和 longObj 是否相等: " + intObj.equals(longObj));
System.out.println("doubleObj 和 new Double(99.99) 是否相等: " + doubleObj.equals(new Double(99.99)));
}
}
Java Math 类
Java 的 Math 包含了用于执行基本数学运算的属性和方法,如初等指数、对数、平方根和三角函数。
Math 的方法都被定义为 static 形式,通过 Math 类可以在主函数中直接调用。
| 方法 | 说明 |
|---|---|
| 取整操作 | |
Math.ceil(double a) |
返回大于等于 a 的最小整数(向上取整) |
Math.floor(double a) |
返回小于等于 a 的最大整数(向下取整) |
Math.round(float a) |
四舍五入,返回 long 或 int |
Math.abs(x) |
取绝对值,x 可为 int、long、float、double |
| 最大值/最小值 | |
Math.max(x, y) |
返回 x 和 y 中的较大值 |
Math.min(x, y) |
返回 x 和 y 中的较小值 |
| 幂运算与根号 | |
Math.pow(a, b) |
计算 a^b(a 的 b 次幂) |
Math.sqrt(x) |
计算 √x(平方根) |
Math.cbrt(x) |
计算 ³√x(立方根) |
| 指数与对数 | |
Math.exp(x) |
计算 e^x(自然指数函数) |
Math.log(x) |
计算 ln(x)(自然对数) |
Math.log10(x) |
计算 log₁₀(x)(以 10 为底的对数) |
| 三角函数 | |
Math.sin(x) |
计算 x 的正弦(x 以弧度为单位) |
Math.cos(x) |
计算 x 的余弦 |
Math.tan(x) |
计算 x 的正切 |
Math.asin(x) |
计算 x 的反正弦 |
Math.acos(x) |
计算 x 的反余弦 |
Math.atan(x) |
计算 x 的反正切 |
| 角度与弧度转换 | |
Math.toRadians(deg) |
角度转弧度 |
Math.toDegrees(rad) |
弧度转角度 |
| 随机数 | |
Math.random() |
返回 [0.0, 1.0) 范围的随机数 |
round()方法的算法为Math.floor(x+0.5),遇到负数如Math.round(-11.5)的结果为 -11
示例:
public class MathExample {
public static void main(String[] args) {
// 1. 基本数学运算
System.out.println("绝对值: " + Math.abs(-10));
System.out.println("最大值: " + Math.max(10, 20));
System.out.println("最小值: " + Math.min(10, 20));
// 2. 幂运算
System.out.println("2 的 3 次方: " + Math.pow(2, 3));
System.out.println("平方根: " + Math.sqrt(16));
System.out.println("立方根: " + Math.cbrt(27));
// 3. 取整
System.out.println("向上取整: " + Math.ceil(4.3));
System.out.println("向下取整: " + Math.floor(4.9));
System.out.println("四舍五入: " + Math.round(4.5));
// 4. 三角函数
System.out.println("sin(30°): " + Math.sin(Math.toRadians(30)));
System.out.println("cos(60°): " + Math.cos(Math.toRadians(60)));
System.out.println("tan(45°): " + Math.tan(Math.toRadians(45)));
// 5. 随机数
System.out.println("随机数 (0~1): " + Math.random());
System.out.println("随机整数 (1~100): " + (int) (Math.random() * 100 + 1));
// 6. 对数与指数
System.out.println("自然对数 log(10): " + Math.log(10));
System.out.println("以 10 为底的对数 log10(1000): " + Math.log10(1000));
System.out.println("e 的 2 次方: " + Math.exp(2));
}
}
Java数组、Arrays类与ArrayList
数组
声明数组变量
dataType[] arrayRefVar; // 首选的方法
dataType arrayRefVar[]; // 效果相同,但不是首选方法
创建数组
Java语言使用new操作符来创建数组
dataType[] arrayRefVar = new dataType[arraySize];
// 或者指定初始化时的值
dataType[] arrayRefVar = {value0, value1, ..., valuek};
Arrays类
| 方法 | 说明 |
|---|---|
| 数组输出 | |
Arrays.toString(array) |
以字符串形式返回一维数组内容 |
Arrays.deepToString(array) |
以字符串形式返回多维数组内容 |
| 数组排序 | |
Arrays.sort(array) |
对数组进行升序排序 |
Arrays.sort(array, Comparator c) |
使用指定比较器对对象数组排序 |
Arrays.parallelSort(array) |
并行排序,适用于大数组,提升性能 |
| 数组搜索 | |
Arrays.binarySearch(array, key) |
在 排序后的数组 中查找 key,返回索引(找不到返回负值) |
| 数组填充 | |
Arrays.fill(array, value) |
用 value 填充整个数组 |
Arrays.fill(array, from, to, value) |
用 value 填充 [from, to) 范围的元素 |
| 数组复制 | |
Arrays.copyOf(array, newLength) |
复制数组,并调整长度 |
Arrays.copyOfRange(array, from, to) |
复制数组的 [from, to) 子范围 |
| 数组比较 | |
Arrays.equals(array1, array2) |
判断两个 一维数组 是否相等 |
Arrays.deepEquals(array1, array2) |
判断两个 多维数组 是否相等 |
| 数组转换 | |
Arrays.asList(array) |
将数组转换为 List(适用于对象数组) |
| 流操作(Java 8+) | |
Arrays.stream(array) |
将数组转换为 Stream 流,以便使用流操作 |
Arrays.parallelPrefix(array, operator) |
计算并行前缀操作 |
示例:
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
public class ArraysExample {
public static void main(String[] args) {
// 1. 数组输出
int[] numbers = {5, 3, 8, 1, 2};
System.out.println("原始数组: " + Arrays.toString(numbers));
// 2. 数组排序
Arrays.sort(numbers);
System.out.println("排序后: " + Arrays.toString(numbers));
// 3. 二分查找 (必须先排序)
int index = Arrays.binarySearch(numbers, 3);
System.out.println("数字 3 的索引: " + index);
// 4. 数组填充
int[] filledArray = new int[5];
Arrays.fill(filledArray, 7);
System.out.println("填充后: " + Arrays.toString(filledArray));
// 5. 部分填充
int[] partialFilled = {1, 2, 3, 4, 5};
Arrays.fill(partialFilled, 1, 4, 9); // 填充索引 [1, 4) 的元素
System.out.println("部分填充后: " + Arrays.toString(partialFilled));
// 6. 数组复制
int[] copiedArray = Arrays.copyOf(numbers, 7); // 长度变为 7
System.out.println("复制后: " + Arrays.toString(copiedArray));
int[] copiedRange = Arrays.copyOfRange(numbers, 1, 4); // 复制索引 [1, 4)
System.out.println("复制范围: " + Arrays.toString(copiedRange));
// 7. 数组比较
int[] array1 = {1, 2, 3};
int[] array2 = {1, 2, 3};
int[] array3 = {1, 2, 4};
System.out.println("数组是否相等 (array1 和 array2): " + Arrays.equals(array1, array2));
System.out.println("数组是否相等 (array1 和 array3): " + Arrays.equals(array1, array3));
// 8. 将数组转换为 List
String[] strArray = {"Alice", "Bob", "Charlie"};
List<String> strList = Arrays.asList(strArray);
System.out.println("转换为 List: " + strList);
// 9. 使用流(Java 8+)
int sum = Arrays.stream(numbers).sum();
System.out.println("数组元素总和: " + sum);
// 10. 并行排序(适用于大数组)
int[] largeArray = {10, 5, 8, 2, 7};
Arrays.parallelSort(largeArray);
System.out.println("并行排序后: " + Arrays.toString(largeArray));
// 11. 多维数组的深度输出
int[][] matrix = {
{1, 2, 3},
{4, 5, 6}
};
System.out.println("二维数组: " + Arrays.deepToString(matrix));
// 12. 深度比较多维数组
int[][] matrix2 = {
{1, 2, 3},
{4, 5, 6}
};
System.out.println("二维数组是否相等: " + Arrays.deepEquals(matrix, matrix2));
}
}
ArrayList
ArrayList 是 Java 集合框架(Java Collections Framework)中的一个类,实现了 List 接口,位于 java.util 包下。它提供了动态数组的实现,能够根据需要自动调整大小。ArrayList 是非同步的(不是线程安全的)。
ArrayList 的主要特点:
- 基于动态数组实现,自动扩容
- 实现了 List 接口,拥有 List 的所有功能
- 允许存储任何类型的对象,包括 null
- 提供随机访问(通过索引)功能,访问元素的时间复杂度为 O(1)
- 插入和删除操作可能需要移动元素,时间复杂度为 O(n)
ArrayList 与数组比较
| 特性 | ArrayList | 数组 |
|---|---|---|
| 大小 | 动态,可以自动增长或缩小 | 固定,创建时必须指定大小且不可改变 |
| 类型安全 | 使用泛型可以确保类型安全 | 只能存储同一类型元素 |
| 存储类型 | 只能存储对象,不能存储基本数据类型 | 可以存储基本数据类型和对象 |
| API | 提供丰富的方法(add, remove, contains等) | 仅提供基本操作和length属性 |
| 性能 | 需要额外的方法调用和类型检查,性能略低 | 访问元素更直接,性能较高 |
| 内存使用 | 由于需要存储对象,会有额外的开销 | 更加紧凑,特别是对基本类型 |
| 便利性 | 提供更多便利功能,如动态调整大小 | 需要手动处理扩容、缩容等操作 |
| 线程安全 | 不是线程安全的 | 不是线程安全的 |
| 迭代器 | 提供迭代器和增强for循环支持 | 只能使用索引或增强for循环 |
ArrayList 的创建
// 创建不指定类型的ArrayList(不推荐)
ArrayList list1 = new ArrayList();
// 使用泛型创建指定类型的ArrayList
ArrayList<String> list2 = new ArrayList<String>();
// 使用Java 7引入的钻石操作符
ArrayList<String> list3 = new ArrayList<>();
// 创建时指定初始容量
ArrayList<Integer> list4 = new ArrayList<>(20);
// 通过其他集合创建ArrayList
ArrayList<Integer> list5 = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
添加元素
ArrayList<String> fruits = new ArrayList<>();
// 在末尾添加元素
fruits.add("苹果");
fruits.add("香蕉");
fruits.add("橙子");
// 在指定位置添加元素
fruits.add(1, "葡萄"); // ["苹果", "葡萄", "香蕉", "橙子"]
// 添加多个元素(集合)
List<String> moreFruits = Arrays.asList("西瓜", "芒果");
fruits.addAll(moreFruits); // ["苹果", "葡萄", "香蕉", "橙子", "西瓜", "芒果"]
// 在指定位置添加多个元素
fruits.addAll(2, Arrays.asList("梨", "樱桃")); // ["苹果", "葡萄", "梨", "樱桃", "香蕉", "橙子", "西瓜", "芒果"]
访问元素
ArrayList<String> fruits = new ArrayList<>(Arrays.asList("苹果", "香蕉", "橙子"));
// 通过索引访问元素
String firstFruit = fruits.get(0); // "苹果"
// 获取列表大小
int size = fruits.size(); // 3
// 检查元素是否存在
boolean hasApple = fruits.contains("苹果"); // true
boolean hasGrape = fruits.contains("葡萄"); // false
// 查找元素索引
int index = fruits.indexOf("香蕉"); // 1
int lastIndex = fruits.lastIndexOf("香蕉"); // 查找最后一次出现的索引
// 检查列表是否为空
boolean isEmpty = fruits.isEmpty(); // false
修改元素
ArrayList<String> fruits = new ArrayList<>(Arrays.asList("苹果", "香蕉", "橙子"));
// 修改指定索引的元素
fruits.set(1, "葡萄"); // ["苹果", "葡萄", "橙子"]
删除元素
ArrayList<String> fruits = new ArrayList<>(Arrays.asList("苹果", "香蕉", "橙子", "香蕉"));
// 删除第一次出现的指定元素
fruits.remove("香蕉"); // ["苹果", "橙子", "香蕉"]
// 删除指定索引的元素
fruits.remove(0); // ["橙子", "香蕉"]
// 删除满足条件的元素(Java 8+)
fruits.removeIf(fruit -> fruit.equals("香蕉")); // ["橙子"]
// 清空列表
fruits.clear(); // []
遍历元素
ArrayList<String> fruits = new ArrayList<>(Arrays.asList("苹果", "香蕉", "橙子"));
// 使用for循环
for (int i = 0; i < fruits.size(); i++) {
System.out.println(fruits.get(i));
}
// 使用增强for循环
for (String fruit : fruits) {
System.out.println(fruit);
}
// 使用Iterator迭代器
Iterator<String> iterator = fruits.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// 使用Java 8的forEach方法和Lambda表达式
fruits.forEach(fruit -> System.out.println(fruit));
// 更简洁的方法引用形式
fruits.forEach(System.out::println);
排序
ArrayList<String> fruits = new ArrayList<>(Arrays.asList("橙子", "苹果", "香蕉"));
// 使用Collections.sort()进行自然排序
Collections.sort(fruits); // ["苹果", "橙子", "香蕉"]
// 使用自定义比较器
Collections.sort(fruits, Collections.reverseOrder()); // ["香蕉", "橙子", "苹果"]
// Java 8+ 使用ArrayList的sort方法
fruits.sort(Comparator.naturalOrder()); // ["苹果", "橙子", "香蕉"]
fruits.sort(Comparator.reverseOrder()); // ["香蕉", "橙子", "苹果"]
// 使用自定义比较器(按字符串长度排序)
fruits.sort(Comparator.comparingInt(String::length));
转换为数组
ArrayList<String> fruits = new ArrayList<>(Arrays.asList("苹果", "香蕉", "橙子"));
// 转换为Object数组
Object[] objectArray = fruits.toArray();
// 转换为指定类型的数组
String[] stringArray1 = fruits.toArray(new String[0]);
String[] stringArray2 = fruits.toArray(new String[fruits.size()]);
// Java 11+更简洁的方式
String[] stringArray3 = fruits.toArray(String[]::new);
性能注意事项
- 随机访问:ArrayList的随机访问性能很好,时间复杂度为O(1)
- 添加元素:在末尾添加元素通常很快O(1),但可能会触发扩容操作
- 插入/删除元素:在中间插入或删除元素需要移动后面的元素,时间复杂度为O(n)
- 初始容量:如果预先知道大致元素数量,指定初始容量可以减少扩容操作
- 迭代:迭代过程中修改列表(add/remove)会导致
ConcurrentModificationException
适用场景
ArrayList适合以下场景:
- 需要频繁随机访问元素
- 主要在列表末尾添加/删除元素
- 对存储空间要求不高
- 不需要频繁在列表中间插入/删除元素
- 不需要线程安全
不适合的场景(考虑使用LinkedList):
- 频繁在列表中间或开头插入/删除元素
- 需要高效的栈、队列或双端队列操作
Java 异常处理
try{
// 可能抛出异常的代码
}catch(异常类型1 异常的变量名1){
// 异常处理代码1
}catch(异常类型2 异常的变量名2){
// (可选)异常处理代码2
}finally{
// (可选)无论是否异常都运行的代码
}
或者
public void readFile() throws IOException {
// 可能会抛出IOException的代码
}
Java 方法
方法的定义
修饰符 返回值类型 方法名(参数类型 参数名){
...
方法体
...
return 返回值;
}
方法命名应使用小驼峰如
addTest
- 修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了 该方法的访问类型。
- 返回值类型 :方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void。
- 方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
- 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
- 方法体:方法体包含具体的语句,定义该方法的功能。
方法重载
重载的方法必须拥有不同的参数列表。你不能仅仅依据修饰符或者返回类型的不同来重载方法。
构造方法
构造方法(Constructor)是用于创建类的对象的特殊方法。当使用 new 关键字创建对象时,构造方法会自动调用,用来初始化对象的属性。
构造方法特点:
- 方法名与类名相同:构造方法的名字必须和类名一致。
- 没有返回类型:构造方法没有返回类型,连 void 也不能写。
- 在创建对象时自动调用:每次使用 new 创建对象时,都会自动调用构造方法。
- 可以重载:可以为同一个类定义多个构造方法,但这些构造方法的参数列表必须不同(即构成重载)。
不管你是否自定义构造方法,所有的类都有构造方法,因为 Java 自动提供了一个默认构造方法,默认构造方法的访问修饰符和类的访问修饰符相同(类为 public,构造函数也为 public;类改为 protected,构造函数也改为 protected),一旦你定义了自己的构造方法,默认构造方法就会失效。
示例:
// 一个简单的构造函数
class MyClass {
int x;
// 以下是构造函数
MyClass(int i ) {
x = i;
}
}
构造方法中的this关键字:
- 引用当前对象的属性或方法
- 调用另一个构造方法
示例:
public Person(String name) {
this(name, 0); // 调用另一个双参数的构造方法
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
可变参数
可变参数允许程序员定义一个方法,该方法可以接受零个或多个相同类型的参数。
声明:
returnType methodName(dataType... parameterName) {
// 方法体
}
- 可变参数必须是方法的最后一个参数
- 一个方法中只能有一个可变参数
示例:
public class VarargsWithArrayExample {
// 声明一个带有可变参数的方法
public static int sum(int... numbers) {
int total = 0;
for (int num : numbers) {
total += num;
}
return total;
}
public static void main(String[] args) {
// 直接传递多个值给可变参数方法
int result1 = sum(1, 2, 3, 4, 5);
System.out.println("Sum of individual elements: " + result1); // 15
// 将整个数组直接传递给可变参数方法
int[] myArray = {1, 2, 3, 4, 5};
int result = sum(myArray);
System.out.println("Sum of array elements: " + result); // 15
}
}
参数默认值
Java方法的参数没有默认值,但可以通过其他方法来实现类似的功能
- 方法重载
public class DefaultValueExample {
public void display(String name, int age, String city) {
System.out.println("Name: " + name);
System.out.println("Age: " + age);
System.out.println("City: " + city);
}
// 带有"默认"city参数的重载方法
public void display(String name, int age) {
display(name, age, "Beijing"); // 使用"北京"作为city的默认值
}
// 带有"默认"age和city参数的重载方法
public void display(String name) {
display(name, 18, "Beijing"); // 使用18作为age的默认值,"北京"作为city的默认值
}
public static void main(String[] args) {
DefaultValueExample example = new DefaultValueExample();
example.display("Zhang San", 25, "Shanghai"); // 全部指定参数
example.display("Li Si", 30); // city使用默认值
example.display("Wang Wu"); // age和city使用默认值
}
}
- 可变参数
public class OptionalParamExample {
public void process(String name, Object... options) {
int age = (options.length > 0 && options[0] != null) ? (int) options[0] : 18;
String city = (options.length > 1 && options[1] != null) ? (String) options[1] : "Beijing";
System.out.println("Name: " + name);
System.out.println("Age: " + age);
System.out.println("City: " + city);
}
public static void main(String[] args) {
OptionalParamExample example = new OptionalParamExample();
example.process("Zhang San", 25, "Shanghai"); // 全部指定参数
example.process("Li Si", 30); // city使用默认值
example.process("Wang Wu"); // age和city使用默认值
}
}
- Java8中的Option类
public class OptionalExample {
public void greet(String name, Optional<Integer> age, Optional<String> city) {
System.out.println("Name: " + name);
System.out.println("Age: " + age.orElse(18)); // 如果age存在则使用它,否则使用默认值18
System.out.println("City: " + city.orElse("Beijing")); // 如果city存在则使用它,否则使用默认值"北京"
}
public static void main(String[] args) {
OptionalExample example = new OptionalExample();
example.greet("Zhang San", Optional.of(25), Optional.of("Shanghai")); // 全部指定参数
example.greet("Li Si", Optional.of(30), Optional.empty()); // city使用默认值
example.greet("Wang Wu", Optional.empty(), Optional.empty()); // age和city使用默认值
}
}
Java 面向对象
Java 作为一种面向对象的编程语言,支持以下基本概念:
- 类(Class)
- 对象(Object)
- 封装(Encapsulation)
- 继承(Inheritance)
- 多态(Polymorphism)
- 抽象(Abstraction)
- 接口(Interface)
- 方法(Method)
- 方法重载(Method Overloading)
Java 类与对象
类是定义对象的蓝图,包括属性和方法
对象是类的实例,具有状态和行为
示例:
public class Dog {
String name;
int size;
String colour;
int age;
void eat() {
}
void run() {
}
void sleep(){
}
void name(){
}
}
访问实例变量和方法:
// 创建对象
Object referenceVariable = new Constructor();
// 访问类中的变量
referenceVariable.variableName;
// 访问类中的方法
referenceVariable.methodName();
封装
将对象的状态(字段)私有化,通过公共方法访问
示例:
public class Puppy {
private int age;
private String name;
// 构造器
public Puppy(String name) {
this.name = name;
System.out.println("小狗的名字是 : " + name);
}
// 设置 age 的值
public void setAge(int age) {
this.age = age;
}
// 获取 age 的值
public int getAge() {
return age;
}
// 获取 name 的值
public String getName() {
return name;
}
// 主方法
public static void main(String[] args) {
// 创建对象
Puppy myPuppy = new Puppy("Tommy");
// 通过方法来设定 age
myPuppy.setAge(2);
// 调用另一个方法获取 age
int age = myPuppy.getAge();
System.out.println("小狗的年龄为 : " + age);
// 也可以直接访问成员变量(通过 getter 方法)
System.out.println("变量值 : " + myPuppy.getAge());
}
}
多态
Java包
源文件声明规则:
当在一个源文件中定义多个类,并且还有 import 语句和 package 语句时,要特别注意这些规则。
- 一个源文件中只能有一个
public类 - 一个源文件可以有多个非
public类 - 源文件的名称应该和
public类的类名保持一致 - 如果一个类定义在某个包中,那么
package语句应该在源文件的首行。 - 如果源文件包含
import语句,那么应该放在package语句和类定义之间。如果没有package语句,那么import语句应该在源文件中最前面 import语句和package语句对源文件中定义的所有类都有效。在同一源文件中,不能给不同的类不同的包声明
package关键字:
package pkg1[.pkg2[.pkg3…]];
示例:
package net.java.util;
public class Something{
...
}
那么它的路径应该是net/java/util/Something.java这样保存的。 包的作用是把不同的 java 程序分类保存,更方便的被其他 java 程序调用
import关键字:
import package1[.package2…].(classname|*);
import语句应位于package语句之后
示例:
package com.example;
import java.util.ArrayList; // 引入 java.util 包中的 ArrayList 类
import java.util.*; // 引入 java.util 包中的所有类
```## 注释
`//` `/* … */`
## 8种基础数据类型
* Integral types: `byte`, `short`, `int`, `long`
* Floating-point types: `float`, `double`
* The `boolean` data type
* The `char` data type
## 变量类型
* 局部变量
* 成员变量(实例变量) - 默认权限`default`或声明权限`public`、`protected`、`private`
* 静态变量(类变量) - 可以通过类名访问
> `default`权限可以同包访问
## 常用input与output
**Output:**
```Java
System.out.print("Hello, "); // 不换行
System.out.println("World!"); // 换行
System.out.printf("My name is %s, and I am %d years old.\n", "Alice", 25); // 格式化输出
| 格式符 | 说明 |
|---|---|
| %d | 整数(int, long) |
| %f | 浮点数(float, double) |
| %s | 字符串(String) |
| %c | 字符(char) |
| %b | 布尔值(boolean) |
Input:
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine(); // 读取一行,以按下Enter结束
int num = scanner.nextInt(); // 读取返回整数,空格或Enter结束
double number = scanner.nextDouble(); // 读取返回浮点数,空格或Enter结束
char ch = scanner.next().charAt(0); // 读取返回字符串,空格或Enter结束,并取字符串第一个字符
scanner.close() // 建议,关闭System.in输入流,释放内存
条件语句
if … else if … else …(a > b) ? a : bswitch … case … default …||和&&
如果
case中没有break也会出现“贯穿”(fall-through)
循环语句
whiledo … while …for
控制关键字:
breakcontinue
Java5引入遍历数组的增强for:
for(声明语句 : 表达式)
{
//代码句子
}
例子:
public class Test {
public static void main(String[] args){
int [] numbers = {10, 20, 30, 40, 50};
for(int x : numbers ){
System.out.print( x );
System.out.print(",");
}
System.out.print("\n");
String [] names ={"James", "Larry", "Tom", "Lacy"};
for( String name : names ) {
System.out.print( name );
System.out.print(",");
}
}
}
Java Number & Math 类
Number和Math类属于java.lang包,无需import
Java Number 类
所有的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类 Number 的子类。
| 包装类 | 基本数据类型 |
|---|---|
| Boolean | boolean |
| Byte | byte |
| Short | short |
| Integer | int |
| Long | long |
| Character | char |
| Float | float |
| Double | double |
这种由编译器特别支持的包装称为装箱,所以当内置数据类型被当作对象使用的时候,编译器会把内置类型装箱为包装类。相似的,编译器也可以把一个对象拆箱为内置类型。
| 方法 | 返回类型 | 说明 |
|---|---|---|
| 类型转换方法 | ||
byteValue() |
byte |
以 byte 类型返回数值 |
shortValue() |
short |
以 short 类型返回数值 |
intValue() |
int |
以 int 类型返回数值 |
longValue() |
long |
以 long 类型返回数值 |
floatValue() |
float |
以 float 类型返回数值 |
doubleValue() |
double |
以 double 类型返回数值 |
| 其他方法 | ||
toString() |
String |
返回数值的字符串形式(继承自 Object) |
equals(Object obj) |
boolean |
判断两个 Number 对象是否相等(继承自 Object) |
hashCode() |
int |
返回 Number 对象的哈希码(继承自 Object) |
示例:
public class NumberExample {
public static void main(String[] args) {
// 创建不同类型的 Number 对象
Integer intObj = 100;
Double doubleObj = 99.99;
Float floatObj = 12.5f;
Long longObj = 100000L;
// 类型转换方法
System.out.println("Integer 转换为 double: " + intObj.doubleValue());
System.out.println("Double 转换为 int: " + doubleObj.intValue());
System.out.println("Float 转换为 long: " + floatObj.longValue());
// 获取 Number 的哈希值
System.out.println("Integer 哈希值: " + intObj.hashCode());
System.out.println("Double 哈希值: " + doubleObj.hashCode());
// Number 的 equals 方法
System.out.println("intObj 和 longObj 是否相等: " + intObj.equals(longObj));
System.out.println("doubleObj 和 new Double(99.99) 是否相等: " + doubleObj.equals(new Double(99.99)));
}
}
Java Math 类
Java 的 Math 包含了用于执行基本数学运算的属性和方法,如初等指数、对数、平方根和三角函数。
Math 的方法都被定义为 static 形式,通过 Math 类可以在主函数中直接调用。
| 方法 | 说明 |
|---|---|
| 取整操作 | |
Math.ceil(double a) |
返回大于等于 a 的最小整数(向上取整) |
Math.floor(double a) |
返回小于等于 a 的最大整数(向下取整) |
Math.round(float a) |
四舍五入,返回 long 或 int |
Math.abs(x) |
取绝对值,x 可为 int、long、float、double |
| 最大值/最小值 | |
Math.max(x, y) |
返回 x 和 y 中的较大值 |
Math.min(x, y) |
返回 x 和 y 中的较小值 |
| 幂运算与根号 | |
Math.pow(a, b) |
计算 a^b(a 的 b 次幂) |
Math.sqrt(x) |
计算 √x(平方根) |
Math.cbrt(x) |
计算 ³√x(立方根) |
| 指数与对数 | |
Math.exp(x) |
计算 e^x(自然指数函数) |
Math.log(x) |
计算 ln(x)(自然对数) |
Math.log10(x) |
计算 log₁₀(x)(以 10 为底的对数) |
| 三角函数 | |
Math.sin(x) |
计算 x 的正弦(x 以弧度为单位) |
Math.cos(x) |
计算 x 的余弦 |
Math.tan(x) |
计算 x 的正切 |
Math.asin(x) |
计算 x 的反正弦 |
Math.acos(x) |
计算 x 的反余弦 |
Math.atan(x) |
计算 x 的反正切 |
| 角度与弧度转换 | |
Math.toRadians(deg) |
角度转弧度 |
Math.toDegrees(rad) |
弧度转角度 |
| 随机数 | |
Math.random() |
返回 [0.0, 1.0) 范围的随机数 |
round()方法的算法为Math.floor(x+0.5),遇到负数如Math.round(-11.5)的结果为 -11
示例:
public class MathExample {
public static void main(String[] args) {
// 1. 基本数学运算
System.out.println("绝对值: " + Math.abs(-10));
System.out.println("最大值: " + Math.max(10, 20));
System.out.println("最小值: " + Math.min(10, 20));
// 2. 幂运算
System.out.println("2 的 3 次方: " + Math.pow(2, 3));
System.out.println("平方根: " + Math.sqrt(16));
System.out.println("立方根: " + Math.cbrt(27));
// 3. 取整
System.out.println("向上取整: " + Math.ceil(4.3));
System.out.println("向下取整: " + Math.floor(4.9));
System.out.println("四舍五入: " + Math.round(4.5));
// 4. 三角函数
System.out.println("sin(30°): " + Math.sin(Math.toRadians(30)));
System.out.println("cos(60°): " + Math.cos(Math.toRadians(60)));
System.out.println("tan(45°): " + Math.tan(Math.toRadians(45)));
// 5. 随机数
System.out.println("随机数 (0~1): " + Math.random());
System.out.println("随机整数 (1~100): " + (int) (Math.random() * 100 + 1));
// 6. 对数与指数
System.out.println("自然对数 log(10): " + Math.log(10));
System.out.println("以 10 为底的对数 log10(1000): " + Math.log10(1000));
System.out.println("e 的 2 次方: " + Math.exp(2));
}
}
Java数组、Arrays类与ArrayList
数组
声明数组变量
dataType[] arrayRefVar; // 首选的方法
dataType arrayRefVar[]; // 效果相同,但不是首选方法
创建数组
Java语言使用new操作符来创建数组
dataType[] arrayRefVar = new dataType[arraySize];
// 或者指定初始化时的值
dataType[] arrayRefVar = {value0, value1, ..., valuek};
Arrays类
| 方法 | 说明 |
|---|---|
| 数组输出 | |
Arrays.toString(array) |
以字符串形式返回一维数组内容 |
Arrays.deepToString(array) |
以字符串形式返回多维数组内容 |
| 数组排序 | |
Arrays.sort(array) |
对数组进行升序排序 |
Arrays.sort(array, Comparator c) |
使用指定比较器对对象数组排序 |
Arrays.parallelSort(array) |
并行排序,适用于大数组,提升性能 |
| 数组搜索 | |
Arrays.binarySearch(array, key) |
在 排序后的数组 中查找 key,返回索引(找不到返回负值) |
| 数组填充 | |
Arrays.fill(array, value) |
用 value 填充整个数组 |
Arrays.fill(array, from, to, value) |
用 value 填充 [from, to) 范围的元素 |
| 数组复制 | |
Arrays.copyOf(array, newLength) |
复制数组,并调整长度 |
Arrays.copyOfRange(array, from, to) |
复制数组的 [from, to) 子范围 |
| 数组比较 | |
Arrays.equals(array1, array2) |
判断两个 一维数组 是否相等 |
Arrays.deepEquals(array1, array2) |
判断两个 多维数组 是否相等 |
| 数组转换 | |
Arrays.asList(array) |
将数组转换为 List(适用于对象数组) |
| 流操作(Java 8+) | |
Arrays.stream(array) |
将数组转换为 Stream 流,以便使用流操作 |
Arrays.parallelPrefix(array, operator) |
计算并行前缀操作 |
示例:
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
public class ArraysExample {
public static void main(String[] args) {
// 1. 数组输出
int[] numbers = {5, 3, 8, 1, 2};
System.out.println("原始数组: " + Arrays.toString(numbers));
// 2. 数组排序
Arrays.sort(numbers);
System.out.println("排序后: " + Arrays.toString(numbers));
// 3. 二分查找 (必须先排序)
int index = Arrays.binarySearch(numbers, 3);
System.out.println("数字 3 的索引: " + index);
// 4. 数组填充
int[] filledArray = new int[5];
Arrays.fill(filledArray, 7);
System.out.println("填充后: " + Arrays.toString(filledArray));
// 5. 部分填充
int[] partialFilled = {1, 2, 3, 4, 5};
Arrays.fill(partialFilled, 1, 4, 9); // 填充索引 [1, 4) 的元素
System.out.println("部分填充后: " + Arrays.toString(partialFilled));
// 6. 数组复制
int[] copiedArray = Arrays.copyOf(numbers, 7); // 长度变为 7
System.out.println("复制后: " + Arrays.toString(copiedArray));
int[] copiedRange = Arrays.copyOfRange(numbers, 1, 4); // 复制索引 [1, 4)
System.out.println("复制范围: " + Arrays.toString(copiedRange));
// 7. 数组比较
int[] array1 = {1, 2, 3};
int[] array2 = {1, 2, 3};
int[] array3 = {1, 2, 4};
System.out.println("数组是否相等 (array1 和 array2): " + Arrays.equals(array1, array2));
System.out.println("数组是否相等 (array1 和 array3): " + Arrays.equals(array1, array3));
// 8. 将数组转换为 List
String[] strArray = {"Alice", "Bob", "Charlie"};
List<String> strList = Arrays.asList(strArray);
System.out.println("转换为 List: " + strList);
// 9. 使用流(Java 8+)
int sum = Arrays.stream(numbers).sum();
System.out.println("数组元素总和: " + sum);
// 10. 并行排序(适用于大数组)
int[] largeArray = {10, 5, 8, 2, 7};
Arrays.parallelSort(largeArray);
System.out.println("并行排序后: " + Arrays.toString(largeArray));
// 11. 多维数组的深度输出
int[][] matrix = {
{1, 2, 3},
{4, 5, 6}
};
System.out.println("二维数组: " + Arrays.deepToString(matrix));
// 12. 深度比较多维数组
int[][] matrix2 = {
{1, 2, 3},
{4, 5, 6}
};
System.out.println("二维数组是否相等: " + Arrays.deepEquals(matrix, matrix2));
}
}
ArrayList
ArrayList 是 Java 集合框架(Java Collections Framework)中的一个类,实现了 List 接口,位于 java.util 包下。它提供了动态数组的实现,能够根据需要自动调整大小。ArrayList 是非同步的(不是线程安全的)。
ArrayList 的主要特点:
- 基于动态数组实现,自动扩容
- 实现了 List 接口,拥有 List 的所有功能
- 允许存储任何类型的对象,包括 null
- 提供随机访问(通过索引)功能,访问元素的时间复杂度为 O(1)
- 插入和删除操作可能需要移动元素,时间复杂度为 O(n)
ArrayList 与数组比较
| 特性 | ArrayList | 数组 |
|---|---|---|
| 大小 | 动态,可以自动增长或缩小 | 固定,创建时必须指定大小且不可改变 |
| 类型安全 | 使用泛型可以确保类型安全 | 只能存储同一类型元素 |
| 存储类型 | 只能存储对象,不能存储基本数据类型 | 可以存储基本数据类型和对象 |
| API | 提供丰富的方法(add, remove, contains等) | 仅提供基本操作和length属性 |
| 性能 | 需要额外的方法调用和类型检查,性能略低 | 访问元素更直接,性能较高 |
| 内存使用 | 由于需要存储对象,会有额外的开销 | 更加紧凑,特别是对基本类型 |
| 便利性 | 提供更多便利功能,如动态调整大小 | 需要手动处理扩容、缩容等操作 |
| 线程安全 | 不是线程安全的 | 不是线程安全的 |
| 迭代器 | 提供迭代器和增强for循环支持 | 只能使用索引或增强for循环 |
ArrayList 的创建
// 创建不指定类型的ArrayList(不推荐)
ArrayList list1 = new ArrayList();
// 使用泛型创建指定类型的ArrayList
ArrayList<String> list2 = new ArrayList<String>();
// 使用Java 7引入的钻石操作符
ArrayList<String> list3 = new ArrayList<>();
// 创建时指定初始容量
ArrayList<Integer> list4 = new ArrayList<>(20);
// 通过其他集合创建ArrayList
ArrayList<Integer> list5 = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
添加元素
ArrayList<String> fruits = new ArrayList<>();
// 在末尾添加元素
fruits.add("苹果");
fruits.add("香蕉");
fruits.add("橙子");
// 在指定位置添加元素
fruits.add(1, "葡萄"); // ["苹果", "葡萄", "香蕉", "橙子"]
// 添加多个元素(集合)
List<String> moreFruits = Arrays.asList("西瓜", "芒果");
fruits.addAll(moreFruits); // ["苹果", "葡萄", "香蕉", "橙子", "西瓜", "芒果"]
// 在指定位置添加多个元素
fruits.addAll(2, Arrays.asList("梨", "樱桃")); // ["苹果", "葡萄", "梨", "樱桃", "香蕉", "橙子", "西瓜", "芒果"]
访问元素
ArrayList<String> fruits = new ArrayList<>(Arrays.asList("苹果", "香蕉", "橙子"));
// 通过索引访问元素
String firstFruit = fruits.get(0); // "苹果"
// 获取列表大小
int size = fruits.size(); // 3
// 检查元素是否存在
boolean hasApple = fruits.contains("苹果"); // true
boolean hasGrape = fruits.contains("葡萄"); // false
// 查找元素索引
int index = fruits.indexOf("香蕉"); // 1
int lastIndex = fruits.lastIndexOf("香蕉"); // 查找最后一次出现的索引
// 检查列表是否为空
boolean isEmpty = fruits.isEmpty(); // false
修改元素
ArrayList<String> fruits = new ArrayList<>(Arrays.asList("苹果", "香蕉", "橙子"));
// 修改指定索引的元素
fruits.set(1, "葡萄"); // ["苹果", "葡萄", "橙子"]
删除元素
ArrayList<String> fruits = new ArrayList<>(Arrays.asList("苹果", "香蕉", "橙子", "香蕉"));
// 删除第一次出现的指定元素
fruits.remove("香蕉"); // ["苹果", "橙子", "香蕉"]
// 删除指定索引的元素
fruits.remove(0); // ["橙子", "香蕉"]
// 删除满足条件的元素(Java 8+)
fruits.removeIf(fruit -> fruit.equals("香蕉")); // ["橙子"]
// 清空列表
fruits.clear(); // []
遍历元素
ArrayList<String> fruits = new ArrayList<>(Arrays.asList("苹果", "香蕉", "橙子"));
// 使用for循环
for (int i = 0; i < fruits.size(); i++) {
System.out.println(fruits.get(i));
}
// 使用增强for循环
for (String fruit : fruits) {
System.out.println(fruit);
}
// 使用Iterator迭代器
Iterator<String> iterator = fruits.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// 使用Java 8的forEach方法和Lambda表达式
fruits.forEach(fruit -> System.out.println(fruit));
// 更简洁的方法引用形式
fruits.forEach(System.out::println);
排序
ArrayList<String> fruits = new ArrayList<>(Arrays.asList("橙子", "苹果", "香蕉"));
// 使用Collections.sort()进行自然排序
Collections.sort(fruits); // ["苹果", "橙子", "香蕉"]
// 使用自定义比较器
Collections.sort(fruits, Collections.reverseOrder()); // ["香蕉", "橙子", "苹果"]
// Java 8+ 使用ArrayList的sort方法
fruits.sort(Comparator.naturalOrder()); // ["苹果", "橙子", "香蕉"]
fruits.sort(Comparator.reverseOrder()); // ["香蕉", "橙子", "苹果"]
// 使用自定义比较器(按字符串长度排序)
fruits.sort(Comparator.comparingInt(String::length));
转换为数组
ArrayList<String> fruits = new ArrayList<>(Arrays.asList("苹果", "香蕉", "橙子"));
// 转换为Object数组
Object[] objectArray = fruits.toArray();
// 转换为指定类型的数组
String[] stringArray1 = fruits.toArray(new String[0]);
String[] stringArray2 = fruits.toArray(new String[fruits.size()]);
// Java 11+更简洁的方式
String[] stringArray3 = fruits.toArray(String[]::new);
性能注意事项
- 随机访问:ArrayList的随机访问性能很好,时间复杂度为O(1)
- 添加元素:在末尾添加元素通常很快O(1),但可能会触发扩容操作
- 插入/删除元素:在中间插入或删除元素需要移动后面的元素,时间复杂度为O(n)
- 初始容量:如果预先知道大致元素数量,指定初始容量可以减少扩容操作
- 迭代:迭代过程中修改列表(add/remove)会导致
ConcurrentModificationException
适用场景
ArrayList适合以下场景:
- 需要频繁随机访问元素
- 主要在列表末尾添加/删除元素
- 对存储空间要求不高
- 不需要频繁在列表中间插入/删除元素
- 不需要线程安全
不适合的场景(考虑使用LinkedList):
- 频繁在列表中间或开头插入/删除元素
- 需要高效的栈、队列或双端队列操作
Java 异常处理
try{
// 可能抛出异常的代码
}catch(异常类型1 异常的变量名1){
// 异常处理代码1
}catch(异常类型2 异常的变量名2){
// (可选)异常处理代码2
}finally{
// (可选)无论是否异常都运行的代码
}
或者
public void readFile() throws IOException {
// 可能会抛出IOException的代码
}
Java 方法
方法的定义
修饰符 返回值类型 方法名(参数类型 参数名){
...
方法体
...
return 返回值;
}
方法命名应使用小驼峰如
addTest
- 修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了 该方法的访问类型。
- 返回值类型 :方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void。
- 方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
- 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
- 方法体:方法体包含具体的语句,定义该方法的功能。
方法重载
重载的方法必须拥有不同的参数列表。你不能仅仅依据修饰符或者返回类型的不同来重载方法。
构造方法
构造方法(Constructor)是用于创建类的对象的特殊方法。当使用 new 关键字创建对象时,构造方法会自动调用,用来初始化对象的属性。
构造方法特点:
- 方法名与类名相同:构造方法的名字必须和类名一致。
- 没有返回类型:构造方法没有返回类型,连 void 也不能写。
- 在创建对象时自动调用:每次使用 new 创建对象时,都会自动调用构造方法。
- 可以重载:可以为同一个类定义多个构造方法,但这些构造方法的参数列表必须不同(即构成重载)。
不管你是否自定义构造方法,所有的类都有构造方法,因为 Java 自动提供了一个默认构造方法,默认构造方法的访问修饰符和类的访问修饰符相同(类为 public,构造函数也为 public;类改为 protected,构造函数也改为 protected),一旦你定义了自己的构造方法,默认构造方法就会失效。
示例:
// 一个简单的构造函数
class MyClass {
int x;
// 以下是构造函数
MyClass(int i ) {
x = i;
}
}
构造方法中的this关键字:
- 引用当前对象的属性或方法
- 调用另一个构造方法
示例:
public Person(String name) {
this(name, 0); // 调用另一个双参数的构造方法
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
可变参数
可变参数允许程序员定义一个方法,该方法可以接受零个或多个相同类型的参数。
声明:
returnType methodName(dataType... parameterName) {
// 方法体
}
- 可变参数必须是方法的最后一个参数
- 一个方法中只能有一个可变参数
示例:
public class VarargsWithArrayExample {
// 声明一个带有可变参数的方法
public static int sum(int... numbers) {
int total = 0;
for (int num : numbers) {
total += num;
}
return total;
}
public static void main(String[] args) {
// 直接传递多个值给可变参数方法
int result1 = sum(1, 2, 3, 4, 5);
System.out.println("Sum of individual elements: " + result1); // 15
// 将整个数组直接传递给可变参数方法
int[] myArray = {1, 2, 3, 4, 5};
int result = sum(myArray);
System.out.println("Sum of array elements: " + result); // 15
}
}
参数默认值
Java方法的参数没有默认值,但可以通过其他方法来实现类似的功能
- 方法重载
public class DefaultValueExample {
public void display(String name, int age, String city) {
System.out.println("Name: " + name);
System.out.println("Age: " + age);
System.out.println("City: " + city);
}
// 带有"默认"city参数的重载方法
public void display(String name, int age) {
display(name, age, "Beijing"); // 使用"北京"作为city的默认值
}
// 带有"默认"age和city参数的重载方法
public void display(String name) {
display(name, 18, "Beijing"); // 使用18作为age的默认值,"北京"作为city的默认值
}
public static void main(String[] args) {
DefaultValueExample example = new DefaultValueExample();
example.display("Zhang San", 25, "Shanghai"); // 全部指定参数
example.display("Li Si", 30); // city使用默认值
example.display("Wang Wu"); // age和city使用默认值
}
}
- 可变参数
public class OptionalParamExample {
public void process(String name, Object... options) {
int age = (options.length > 0 && options[0] != null) ? (int) options[0] : 18;
String city = (options.length > 1 && options[1] != null) ? (String) options[1] : "Beijing";
System.out.println("Name: " + name);
System.out.println("Age: " + age);
System.out.println("City: " + city);
}
public static void main(String[] args) {
OptionalParamExample example = new OptionalParamExample();
example.process("Zhang San", 25, "Shanghai"); // 全部指定参数
example.process("Li Si", 30); // city使用默认值
example.process("Wang Wu"); // age和city使用默认值
}
}
- Java8中的Option类
public class OptionalExample {
public void greet(String name, Optional<Integer> age, Optional<String> city) {
System.out.println("Name: " + name);
System.out.println("Age: " + age.orElse(18)); // 如果age存在则使用它,否则使用默认值18
System.out.println("City: " + city.orElse("Beijing")); // 如果city存在则使用它,否则使用默认值"北京"
}
public static void main(String[] args) {
OptionalExample example = new OptionalExample();
example.greet("Zhang San", Optional.of(25), Optional.of("Shanghai")); // 全部指定参数
example.greet("Li Si", Optional.of(30), Optional.empty()); // city使用默认值
example.greet("Wang Wu", Optional.empty(), Optional.empty()); // age和city使用默认值
}
}
Java 面向对象
Java 作为一种面向对象的编程语言,支持以下基本概念:
- 类(Class)
- 对象(Object)
- 封装(Encapsulation)
- 继承(Inheritance)
- 多态(Polymorphism)
- 抽象(Abstraction)
- 接口(Interface)
- 方法(Method)
- 方法重载(Method Overloading)
Java 类与对象
类是定义对象的蓝图,包括属性和方法
对象是类的实例,具有状态和行为
示例:
public class Dog {
String name;
int size;
String colour;
int age;
void eat() {
}
void run() {
}
void sleep(){
}
void name(){
}
}
访问实例变量和方法:
// 创建对象
Object referenceVariable = new Constructor();
// 访问类中的变量
referenceVariable.variableName;
// 访问类中的方法
referenceVariable.methodName();
封装
将对象的状态(字段)私有化,通过公共方法访问
示例:
public class Puppy {
private int age;
private String name;
// 构造器
public Puppy(String name) {
this.name = name;
System.out.println("小狗的名字是 : " + name);
}
// 设置 age 的值
public void setAge(int age) {
this.age = age;
}
// 获取 age 的值
public int getAge() {
return age;
}
// 获取 name 的值
public String getName() {
return name;
}
// 主方法
public static void main(String[] args) {
// 创建对象
Puppy myPuppy = new Puppy("Tommy");
// 通过方法来设定 age
myPuppy.setAge(2);
// 调用另一个方法获取 age
int age = myPuppy.getAge();
System.out.println("小狗的年龄为 : " + age);
// 也可以直接访问成员变量(通过 getter 方法)
System.out.println("变量值 : " + myPuppy.getAge());
}
}
多态
Java包
源文件声明规则:
当在一个源文件中定义多个类,并且还有 import 语句和 package 语句时,要特别注意这些规则。
- 一个源文件中只能有一个
public类 - 一个源文件可以有多个非
public类 - 源文件的名称应该和
public类的类名保持一致 - 如果一个类定义在某个包中,那么
package语句应该在源文件的首行。 - 如果源文件包含
import语句,那么应该放在package语句和类定义之间。如果没有package语句,那么import语句应该在源文件中最前面 import语句和package语句对源文件中定义的所有类都有效。在同一源文件中,不能给不同的类不同的包声明
package关键字:
package pkg1[.pkg2[.pkg3…]];
示例:
package net.java.util;
public class Something{
...
}
那么它的路径应该是net/java/util/Something.java这样保存的。 包的作用是把不同的 java 程序分类保存,更方便的被其他 java 程序调用
import关键字:
import package1[.package2…].(classname|*);
import语句应位于package语句之后
示例:
package com.example;
import java.util.ArrayList; // 引入 java.util 包中的 ArrayList 类
import java.util.*; // 引入 java.util 包中的所有类

浙公网安备 33010602011771号