Commit on 2025/03/26 周三 18:16:04.26
This commit is contained in:
parent
24e284ace3
commit
34e53e1a72
File diff suppressed because it is too large
Load Diff
181
自学/Java笔记本.md
181
自学/Java笔记本.md
@ -81,13 +81,13 @@ IDEA快捷键:
|
||||
|
||||
2. 在 `System.out.println()` 方法中,"ln" 代表 "line",表示换行。因此,`println` 实际上是 "print line" 的缩写。这个方法会在输出文本后自动换行.
|
||||
|
||||
```text
|
||||
```java
|
||||
System.out.println("nihao "+1.3331); #Java 会自动将数值转换为字符串
|
||||
```
|
||||
|
||||
当直接打印一个没有重写 `toString()` 方法的对象时,Java 默认会调用 `Object` 类的 `toString()` 方法,其输出格式通常为:
|
||||
|
||||
```text
|
||||
```java
|
||||
java.lang.Object@15db9742
|
||||
```
|
||||
|
||||
@ -95,7 +95,7 @@ IDEA快捷键:
|
||||
|
||||
当打印重写`toString()` 方法的对象时:
|
||||
|
||||
```text
|
||||
```java
|
||||
class Person {
|
||||
private String name;
|
||||
private int age;
|
||||
@ -120,7 +120,7 @@ IDEA快捷键:
|
||||
|
||||
```
|
||||
|
||||
```text
|
||||
```java
|
||||
Person{name='Alice', age=30}
|
||||
```
|
||||
|
||||
@ -128,7 +128,7 @@ IDEA快捷键:
|
||||
|
||||
3. 一维数组创建:
|
||||
|
||||
```text
|
||||
```java
|
||||
// 方式1:先声明,再指定长度(默认值为0、null等)
|
||||
int[] arr1 = new int[10]; // 创建一个长度为10的int数组
|
||||
|
||||
@ -139,14 +139,13 @@ IDEA快捷键:
|
||||
|
||||
// 方式3:结合new关键字和初始化列表创建数组(常用于明确指定类型时)
|
||||
int[] arr3 = new int[]{1, 2, 3, 4, 5}; // 与方式2效果相同
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
4. 字符串创建
|
||||
|
||||
```text
|
||||
```java
|
||||
String str = "Hello, World!"; //(1)直接赋值
|
||||
|
||||
String str = new String("Hello, World!"); //使用 new 关键字
|
||||
@ -157,6 +156,70 @@ IDEA快捷键:
|
||||
|
||||
|
||||
|
||||
|
||||
#### Java传参方式
|
||||
|
||||
基本数据类型(Primitives)
|
||||
|
||||
- 传递方式:按值传递
|
||||
每次传递的是变量的值的副本,对该值的修改不会影响原变量。例如:`int`、`double`、`boolean` 等类型。
|
||||
|
||||
引用类型(对象)
|
||||
|
||||
- 传递方式:对象引用的副本传递
|
||||
传递的是对象引用的一个副本,指向同一块内存区域。因此,方法内部通过该引用修改对象的状态,会影响到原对象。如数组、集合、String、以及其他所有对象类型。
|
||||
|
||||
|
||||
|
||||
**浅拷贝**
|
||||
|
||||
拷贝对象本身,但内部成员(例如集合中的元素)只是复制引用,新旧对象的内部成员指向同一份内存。如果内部元素是不可变的(如 Integer、String 等),这种拷贝通常足够。如果元素是可变对象,修改其中一个对象**可能会影响**另一个。
|
||||
|
||||
```java
|
||||
List<Integer> list = new ArrayList<>();
|
||||
list.add(1);
|
||||
list.add(2);
|
||||
list.add(3);
|
||||
|
||||
// 浅拷贝:新列表中的元素引用和原列表中的是同一份
|
||||
List<Integer> shallowCopy = new ArrayList<>(list);
|
||||
```
|
||||
|
||||
可变对象,浅拷贝修改对象会出错!
|
||||
|
||||
```java
|
||||
List<Box> list = new ArrayList<>();
|
||||
list.add(new Box(1));
|
||||
list.add(new Box(2));
|
||||
list.add(new Box(3));
|
||||
|
||||
List<Box> shallowCopy = new ArrayList<>(list);
|
||||
shallowCopy.get(0).value = 10; // 修改 shallowCopy 中第一个 Box 的 value
|
||||
|
||||
System.out.println(list); // 输出: [10, 2, 3],因为同一 Box 对象被修改
|
||||
System.out.println(shallowCopy); // 输出: [10, 2, 3]
|
||||
```
|
||||
|
||||
|
||||
|
||||
**深拷贝**
|
||||
|
||||
不仅复制对象本身,还递归地复制其所有内部成员,从而生成一个完全独立的副本。即使内部元素是可变的,修改新对象也不会影响原始对象。
|
||||
|
||||
```java
|
||||
// 深拷贝 List<MyObject> 的例子
|
||||
List<MyObject> originalList = new ArrayList<>();
|
||||
originalList.add(new MyObject(10));
|
||||
originalList.add(new MyObject(20));
|
||||
|
||||
List<MyObject> deepCopy = new ArrayList<>();
|
||||
for (MyObject obj : originalList) {
|
||||
deepCopy.add(new MyObject(obj)); // 每个元素都创建一个新的对象
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### 日期
|
||||
|
||||
在Java中:
|
||||
@ -196,7 +259,7 @@ LocalDateTime.now(),获取当前时间
|
||||
|
||||
|
||||
|
||||
```text
|
||||
```java
|
||||
// 文件:com/example/PrivateExample.java
|
||||
package com.example;
|
||||
|
||||
@ -215,7 +278,7 @@ public class PrivateExample {
|
||||
|
||||
修饰符不仅可以用来修饰成员变量和方法,也可以用来**修饰类**。顶级类只能使用 `public` 或默认(即不写任何修饰符,称为包访问权限)。内部类可以使用所有访问修饰符(`public`、`protected`、`private` 和默认),这使得你可以更灵活地控制嵌套类的访问范围。
|
||||
|
||||
```text
|
||||
```java
|
||||
public class OuterClass {
|
||||
// 内部类使用private,只能在OuterClass内部访问
|
||||
private class InnerPrivateClass {
|
||||
@ -258,7 +321,7 @@ public class OuterClass {
|
||||
|
||||
用途:适用于内部类与外部类关系密切,需要频繁访问外部类成员的情况。
|
||||
|
||||
```text
|
||||
```java
|
||||
public class OuterClass {
|
||||
class InnerClass implements Runnable {
|
||||
// static int count = 0; // 编译错误
|
||||
@ -294,7 +357,7 @@ public class OuterClass {
|
||||
|
||||
用途:适用于只在方法或代码块中使用的类,有助于将实现细节隐藏在方法内部。
|
||||
|
||||
```text
|
||||
```java
|
||||
public class OuterClass {
|
||||
public void startThread() {
|
||||
class LocalInnerClass implements Runnable {
|
||||
@ -327,7 +390,7 @@ public class OuterClass {
|
||||
|
||||
用途:适合当内部类工作不依赖外部类实例时使用,常用于实现与外部类关系不那么密切的帮助类。
|
||||
|
||||
```text
|
||||
```java
|
||||
public class OuterClass {
|
||||
// 外部类的静态成员
|
||||
private static int staticVar = 10;
|
||||
@ -371,7 +434,7 @@ public class OuterClass {
|
||||
|
||||
用途:适用于创建一次性使用的实例,通常用于接口或抽象类的实现。
|
||||
|
||||
```text
|
||||
```java
|
||||
//eg1
|
||||
public class OuterClass {
|
||||
public static void main(String[] args) {
|
||||
@ -413,7 +476,7 @@ public class GUIApp {
|
||||
|
||||
1. 创建`ActionListener`实例
|
||||
|
||||
```text
|
||||
```java
|
||||
new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
System.out.println("Button was clicked!");
|
||||
@ -432,7 +495,7 @@ new ActionListener() {
|
||||
|
||||
2. 将匿名内部类添加为事件监听器
|
||||
|
||||
```text
|
||||
```java
|
||||
button.addActionListener(...);
|
||||
```
|
||||
|
||||
@ -446,7 +509,7 @@ Lambda表达式特别适用于**只有单一抽象方法**的接口(也即**
|
||||
|
||||
**`@FunctionalInterface` 注解**:这是一个可选的注解,用于表示接口是一个函数式接口。虽然不是强制的,但它可以帮助编译器识别意图,并检查接口是否确实只有一个抽象方法。
|
||||
|
||||
```text
|
||||
```java
|
||||
public class LambdaExample {
|
||||
// 定义函数式接口,doSomething 有两个参数
|
||||
@FunctionalInterface
|
||||
@ -479,7 +542,7 @@ public class LambdaExample {
|
||||
可选的大括号:如果主体只有一个语句,可以不使用大括号。
|
||||
可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,使用大括号需显示retrun;如果函数是void则不需要返回值。
|
||||
|
||||
```text
|
||||
```java
|
||||
// 定义一个函数式接口
|
||||
interface Calculator {
|
||||
int add(int a, int b);
|
||||
@ -507,7 +570,7 @@ public class LambdaReturnExample {
|
||||
|
||||
`list.forEach`这个方法接受一个**函数式接口**作为参数。它只有一个抽象方法 `accept(T t)`因此,可以使用 lambda 表达式来**实现**。
|
||||
|
||||
```text
|
||||
```java
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@ -536,7 +599,7 @@ public class Main {
|
||||
|
||||
如果返回正数,则 `a` 应该排在 `b` 的后面。
|
||||
|
||||
```text
|
||||
```java
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -564,7 +627,7 @@ public class Main {
|
||||
|
||||
**1.静态初始化块(Static Initialization Block)**
|
||||
|
||||
```text
|
||||
```java
|
||||
public class MyClass {
|
||||
static int num1, num2;
|
||||
|
||||
@ -590,7 +653,7 @@ public class MyClass {
|
||||
|
||||
输出:
|
||||
|
||||
```text
|
||||
```java
|
||||
静态代码块1执行
|
||||
静态代码块2执行
|
||||
main方法执行
|
||||
@ -603,7 +666,7 @@ main方法执行
|
||||
|
||||
**2.在声明时直接初始化**
|
||||
|
||||
```text
|
||||
```java
|
||||
public class MyClass {
|
||||
// 直接在声明时初始化静态成员变量
|
||||
public static int staticVariable = 42;
|
||||
@ -614,7 +677,7 @@ public class MyClass {
|
||||
|
||||
静态成员变量的访问不需要创建 `MyClass` 的实例,可以直接通过类名访问:
|
||||
|
||||
```text
|
||||
```java
|
||||
int value = MyClass.staticVariable;
|
||||
MyClass obj = new MyClass();
|
||||
System.out.println("obj.num1 = " + obj.staticVariable); #通过示例访问也可以
|
||||
@ -638,7 +701,7 @@ System.out.println("obj.num1 = " + obj.staticVariable); #通过示例访问也
|
||||
- 非静态成员变量。
|
||||
- 非静态方法(必须通过对象实例访问)。
|
||||
|
||||
```text
|
||||
```java
|
||||
public class MyClass {
|
||||
private static int staticVar = 10;
|
||||
private int instanceVar = 20;
|
||||
@ -664,7 +727,7 @@ public class MyClass {
|
||||
|
||||
调用静态方法:
|
||||
|
||||
```text
|
||||
```java
|
||||
MyClass.staticMethod(); // 通过类名直接调用静态方法
|
||||
```
|
||||
|
||||
@ -680,7 +743,7 @@ MyClass.staticMethod(); // 通过类名直接调用静态方法
|
||||
|
||||
因为父类的成员变量和方法都是默认的访问修饰符,可以继承给子类,而子类也定义了同名的xxx,发生了**变量隐藏**(shadowing)。
|
||||
|
||||
```text
|
||||
```java
|
||||
class Parent {
|
||||
int num = 10;
|
||||
void display() {
|
||||
@ -711,7 +774,7 @@ MyClass.staticMethod(); // 通过类名直接调用静态方法
|
||||
|
||||
输出:
|
||||
|
||||
```text
|
||||
```java
|
||||
Child class num: 20
|
||||
Parent class num: 10
|
||||
Parent class method
|
||||
@ -721,7 +784,7 @@ MyClass.staticMethod(); // 通过类名直接调用静态方法
|
||||
|
||||
可以使用 `super` 关键字调用父类的构造方法。这通常在子类的构造方法中使用,用于显式地调用父类的构造方法。
|
||||
|
||||
```text
|
||||
```java
|
||||
class Parent {
|
||||
Parent() {
|
||||
System.out.println("Parent class constructor");
|
||||
@ -745,7 +808,7 @@ public class Main {
|
||||
|
||||
输出:
|
||||
|
||||
```text
|
||||
```java
|
||||
Parent class constructor
|
||||
Child class constructor
|
||||
```
|
||||
@ -771,7 +834,7 @@ final 关键字,意思是最终的、不可修改的,最见不得变化 ,
|
||||
3. **数据类型**:变量的数据类型,如int、String、class等。
|
||||
4. **变量名**:变量的名称。
|
||||
|
||||
```text
|
||||
```java
|
||||
public static final int MAX_COUNT = 100; #定义常量
|
||||
protected static volatile int counter; #定义成员变量
|
||||
```
|
||||
@ -790,7 +853,7 @@ protected static volatile int counter; #定义成员变量
|
||||
|
||||
**继承**
|
||||
|
||||
```text
|
||||
```java
|
||||
[修饰符] class 子类名 extends 父类名{
|
||||
类体部分
|
||||
}
|
||||
@ -820,7 +883,7 @@ Java继承了父类**非私有**的成员变量和成员方法,但是请注意
|
||||
|
||||
2. **向上转型(Upcasting)**:动态多态;子类对象可以赋值给父类引用,这样做可以隐藏对象的真实类型,只能调用**父类中声明的方法**。
|
||||
|
||||
```text
|
||||
```java
|
||||
class Animal {
|
||||
public void makeSound() {
|
||||
System.out.println("Animal makes sound");
|
||||
@ -856,7 +919,7 @@ Java继承了父类**非私有**的成员变量和成员方法,但是请注意
|
||||
- **重载**发生在同一个类中,与继承无关;
|
||||
- **重写**发生在子类中,依赖继承关系,实现运行时多态。
|
||||
|
||||
```text
|
||||
```java
|
||||
class Calculator {
|
||||
int add(int a, int b) {
|
||||
return a + b;
|
||||
@ -879,7 +942,7 @@ class Calculator {
|
||||
**必须实现抽象方法**
|
||||
如果一个子类继承了抽象类,通常必须实现抽象类中的所有抽象方法,否则该子类也必须声明为抽象类。例如:
|
||||
|
||||
```text
|
||||
```java
|
||||
abstract class Animal {
|
||||
// 抽象方法,没有方法体
|
||||
public abstract void makeSound();
|
||||
@ -908,7 +971,7 @@ class Dog extends Animal {
|
||||
1. **定义一个新的子类**
|
||||
创建一个子类继承抽象类并实现所有抽象方法,然后使用子类实例化对象:
|
||||
|
||||
```text
|
||||
```java
|
||||
Animal animal = new Dog();
|
||||
animal.makeSound(); // 输出:Dog barks
|
||||
```
|
||||
@ -916,7 +979,7 @@ class Dog extends Animal {
|
||||
2. **使用匿名内部类**
|
||||
使用匿名内部类实现抽象类相当于临时创建了一个**未命名的子类**,并且立即实例化了这个子类的对象。
|
||||
|
||||
```text
|
||||
```java
|
||||
Animal animal = new Animal() {
|
||||
@Override
|
||||
public void makeSound() {
|
||||
@ -956,7 +1019,7 @@ class Dog extends Animal {
|
||||
- 类可以实现多个接口(多继承)。
|
||||
- 类只能继承一个抽象类(单继承)。
|
||||
|
||||
```text
|
||||
```java
|
||||
// 定义接口
|
||||
interface Flyable {
|
||||
void fly();
|
||||
@ -1009,7 +1072,7 @@ public class Main {
|
||||
- `void clear()`:移除集合中的所有元素。
|
||||
- `boolean isEmpty()`:如果集合为空,则返回 `true`。
|
||||
|
||||
```text
|
||||
```java
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
@ -1051,7 +1114,7 @@ public class CollectionExample {
|
||||
2. `next()`:返回迭代器的下一个元素,并将迭代器移动到下一个位置。
|
||||
3. `remove()`:从迭代器当前位置删除元素。该方法是可选的,不是所有的迭代器都支持。
|
||||
|
||||
```text
|
||||
```java
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
@ -1093,7 +1156,7 @@ public class Main {
|
||||
|
||||

|
||||
|
||||
```text
|
||||
```java
|
||||
// 使用 entrySet() 方法获取 Map 中所有键值对的集合,并使用增强型 for 循环遍历键值对
|
||||
System.out.println("Entries in the map:");
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
@ -1109,7 +1172,7 @@ public class Main {
|
||||
|
||||
默认是小根堆,输出1,2,5,8
|
||||
|
||||
```text
|
||||
```java
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
public class Main {
|
||||
@ -1140,7 +1203,7 @@ public class Main {
|
||||
|
||||
### JAVA异常处理
|
||||
|
||||
```text
|
||||
```java
|
||||
public class ExceptionExample {
|
||||
// 方法声明中添加 throws 关键字,指定可能抛出的异常类型
|
||||
public static void main(String[] args) throws SomeException, AnotherException {
|
||||
@ -1181,7 +1244,7 @@ Arrays.toString()
|
||||
作用:方便地输出数组。
|
||||
这个方法是是用来将数组转换成String类型输出的,入参可以是long,float,double,int,boolean,byte,object 型的数组。
|
||||
|
||||
```text
|
||||
```java
|
||||
import java.util.Arrays;
|
||||
|
||||
public class Main {
|
||||
@ -1211,7 +1274,7 @@ public class Main {
|
||||
|
||||
**类路径**是JVM在运行时用来查找类文件和资源文件的一组目录或JAR包。在许多项目(例如Maven或Gradle项目)中,`src/main/resources`目录下的内容在编译时会被复制到输出目录(如`target/classes`),`src/main/java` 下编译后的 class 文件也会放到这里。
|
||||
|
||||
```text
|
||||
```java
|
||||
MyProject/
|
||||
├── src/
|
||||
│ └── main/
|
||||
@ -1226,7 +1289,7 @@ MyProject/
|
||||
|
||||
```
|
||||
|
||||
```text
|
||||
```java
|
||||
// 获取 resources 根目录下的 emp.xml 文件路径
|
||||
String empFile = this.getClass().getClassLoader().getResource("emp.xml").getFile();
|
||||
|
||||
@ -1261,7 +1324,7 @@ String ttImgPath = resourceUrl != null ? resourceUrl.getFile() : null;
|
||||
|
||||
**1.获取类的字节码(Class对象)**:有三种方法
|
||||
|
||||
```text
|
||||
```java
|
||||
public class Test1Class{
|
||||
public static void main(String[] args){
|
||||
Class c1 = Student.class;
|
||||
@ -1282,7 +1345,7 @@ public class Test1Class{
|
||||
|
||||
**2.获取类的构造器**
|
||||
|
||||
```text
|
||||
```java
|
||||
public class Cat{
|
||||
private String name;
|
||||
private int age;
|
||||
@ -1301,7 +1364,7 @@ public class Cat{
|
||||
|
||||
- 获取构造器列表
|
||||
|
||||
```text
|
||||
```java
|
||||
public class TestConstructor {
|
||||
|
||||
@Test
|
||||
@ -1386,7 +1449,7 @@ public class Test2Constructor(){
|
||||
|
||||
示例:`Cat` 类与测试类
|
||||
|
||||
```text
|
||||
```java
|
||||
public class Cat {
|
||||
private String name;
|
||||
public int age;
|
||||
@ -1406,7 +1469,7 @@ public class Cat {
|
||||
}
|
||||
```
|
||||
|
||||
```text
|
||||
```java
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
@ -1478,7 +1541,7 @@ public class FieldReflectionTest {
|
||||
|
||||

|
||||
|
||||
```text
|
||||
```java
|
||||
@Test
|
||||
public void testListUser(){
|
||||
List<User>list=userMapper.list();
|
||||
@ -1494,7 +1557,7 @@ public class FieldReflectionTest {
|
||||
|
||||
原理可能是:
|
||||
|
||||
```text
|
||||
```java
|
||||
//自定义注解
|
||||
@Retention(RetentionPolicy.RUNTIME) //指定注解在运行时可用,这样才能通过反射获取到该注解。
|
||||
@Target(ElementType.METHOD) //指定注解可用于方法上。
|
||||
@ -1539,7 +1602,7 @@ public class AnnotationTest4 {
|
||||
|
||||
定义:
|
||||
|
||||
```text
|
||||
```java
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@ -1564,7 +1627,7 @@ public @interface MyAnnotation {
|
||||
|
||||
**简化使用**:当注解只有一个元素需要设置时,且该元素的名字是`value`,在使用该注解时可以不用显式地指定元素名
|
||||
|
||||
```text
|
||||
```java
|
||||
@MyAnnotation(5) // 等同于 @MyAnnotation(value = 5)
|
||||
public void someMethod() {
|
||||
// 方法实现
|
||||
@ -1576,7 +1639,7 @@ public void someMethod() {
|
||||
|
||||
如果要同时设置`description`,则不能省略元素名:
|
||||
|
||||
```text
|
||||
```java
|
||||
@MyAnnotation(value = 5, description = "Specific description")
|
||||
public void anotherMethod() {
|
||||
// 方法实现
|
||||
@ -1588,7 +1651,7 @@ public void anotherMethod() {
|
||||
|
||||
**获得注解上的value:**反射
|
||||
|
||||
```text
|
||||
```java
|
||||
public class MyClass {
|
||||
|
||||
@MyAnnotation(value = "specific value")
|
||||
@ -1601,7 +1664,7 @@ public class MyClass {
|
||||
|
||||
|
||||
|
||||
```text
|
||||
```java
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class AnnotationReader {
|
||||
|
199
自学/力扣Hot 100题.md
199
自学/力扣Hot 100题.md
@ -15,7 +15,7 @@
|
||||
|
||||
- 支持多种类型的数组(如 `int[]`、`char[]`、`Object[]` 等)。
|
||||
|
||||
- ```text
|
||||
- ```java
|
||||
int[] arr1 = {1, 2, 3};
|
||||
int[] arr2 = {1, 2, 3};
|
||||
boolean isEqual = Arrays.equals(arr1, arr2); // true
|
||||
@ -24,7 +24,7 @@
|
||||
|
||||
`Collections` 类本身没有直接提供类似 `Arrays.equals` 的方法来比较两个集合的内容是否相等。不过,Java 中的集合类(如 `List`、`Set`、`Map`)已经实现了 `equals` 方法
|
||||
|
||||
- ```text
|
||||
- ```java
|
||||
List<Integer> list1 = Arrays.asList(1, 2, 3);
|
||||
List<Integer> list2 = Arrays.asList(1, 2, 3);
|
||||
List<Integer> list3 = Arrays.asList(3, 2, 1);
|
||||
@ -36,25 +36,20 @@
|
||||
|
||||
**逻辑比较**
|
||||
|
||||
```text
|
||||
```java
|
||||
boolean flag = false;
|
||||
|
||||
if (!flag) { //! 是 Java 中的逻辑非运算符,只能用于对布尔值取反。
|
||||
System.out.println("flag 是 false");
|
||||
}
|
||||
|
||||
|
||||
if (flag == false) { //更常用!
|
||||
System.out.println("flag 是 false");
|
||||
}
|
||||
|
||||
//java中没有 if(not flag) 这种写法!
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 常用数据结构
|
||||
|
||||
#### `String`
|
||||
@ -71,7 +66,7 @@ if (flag == false) { //更常用!
|
||||
|
||||
需要String先转为char [] 数组,排序好之后再转为String类型!!
|
||||
|
||||
```text
|
||||
```java
|
||||
char[] charArray = str.toCharArray();
|
||||
Arrays.sort(charArray);
|
||||
String sortedStr = new String(charArray);
|
||||
@ -92,12 +87,51 @@ String sortedStr = new String(charArray);
|
||||
|
||||
|
||||
|
||||
#### **`HashMap`**
|
||||
#### `StringBuffer`
|
||||
|
||||
`StringBuffer` 是 Java 中用于操作可变字符串的类
|
||||
|
||||
**append**
|
||||
|
||||
```java
|
||||
public class StringBufferExample {
|
||||
public static void main(String[] args) {
|
||||
// 创建初始字符串 "Hello"
|
||||
StringBuffer sb = new StringBuffer("Hello");
|
||||
System.out.println("Initial: " + sb.toString()); // 输出 "Hello"
|
||||
|
||||
// 1. append:在末尾追加 " World"
|
||||
sb.append(" World");
|
||||
System.out.println("After append: " + sb.toString()); // 输出 "Hello World"
|
||||
|
||||
// 2. insert:在索引 5 位置("Hello"后)插入 ", Java"
|
||||
sb.insert(5, ", Java");
|
||||
System.out.println("After insert: " + sb.toString()); // 输出 "Hello, Java World"
|
||||
|
||||
// 3. delete:删除从索引 5 到索引 11(不包含)的子字符串(即删除刚才插入的 ", Java")
|
||||
sb.delete(5, 11);
|
||||
//sb.delete(5, sb.length()); 删除到末尾
|
||||
System.out.println("After delete: " + sb.toString()); // 输出 "Hello World"
|
||||
|
||||
// 4. deleteCharAt:删除索引 5 处的字符(删除空格)
|
||||
sb.deleteCharAt(5);
|
||||
System.out.println("After deleteCharAt: " + sb.toString()); // 输出 "HelloWorld"
|
||||
|
||||
// 5. reverse:反转整个字符串
|
||||
sb.reverse();
|
||||
System.out.println("After reverse: " + sb.toString()); // 输出 "dlroWolleH"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### `HashMap`
|
||||
|
||||
- 基于哈希表实现,查找、插入和删除的平均时间复杂度为 O(1)。
|
||||
- 不保证元素的顺序。
|
||||
|
||||
```text
|
||||
```java
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -137,7 +171,7 @@ public class HashMapExample {
|
||||
|
||||
记录二维数组中某元素是否被访问过,推荐使用:
|
||||
|
||||
```text
|
||||
```java
|
||||
int m = grid.length;
|
||||
int n = grid[0].length;
|
||||
boolean[][] visited = new boolean[m][n];
|
||||
@ -150,13 +184,13 @@ visited[i][j] = true;
|
||||
|
||||
|
||||
|
||||
#### **`HashSet`**
|
||||
#### `HashSet`
|
||||
|
||||
- 基于哈希表实现,查找、插入和删除的平均时间复杂度为 O(1)。
|
||||
|
||||
- 不保证元素的顺序!!因此不太用iterator迭代,而是用contains判断是否有xx元素。
|
||||
|
||||
```text
|
||||
```java
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@ -221,7 +255,7 @@ visited[i][j] = true;
|
||||
6. **`clear()`**:
|
||||
- 清空队列。
|
||||
|
||||
```text
|
||||
```java
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Comparator;
|
||||
|
||||
@ -281,7 +315,7 @@ public class PriorityQueueExample {
|
||||
- 访问元素的时间复杂度为 O(1),在末尾插入和删除的时间复杂度为 O(1)。
|
||||
- 在指定位置插入和删除O(n) `add(int index, E element)` `remove(int index)`
|
||||
|
||||
```text
|
||||
```java
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -324,7 +358,7 @@ public class ArrayListExample {
|
||||
|
||||
**如果事先不知道嵌套列表的大小如何遍历呢?**
|
||||
|
||||
```text
|
||||
```java
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -359,7 +393,7 @@ for (int i = 0; i < list.size(); i++) {
|
||||
- **快速访问**:通过索引访问元素的时间复杂度为 O(1)。
|
||||
- **连续内存**:数组的元素在内存中是连续存储的。
|
||||
|
||||
```text
|
||||
```java
|
||||
public class ArrayExample {
|
||||
public static void main(String[] args) {
|
||||
// 创建数组
|
||||
@ -429,7 +463,7 @@ public class ArrayExample {
|
||||
|
||||
#### `二维数组`
|
||||
|
||||
```text
|
||||
```java
|
||||
int rows = 3;
|
||||
int cols = 3;
|
||||
int[][] array = new int[rows][cols];
|
||||
@ -467,7 +501,7 @@ public void setZeroes(int[][] matrix) {
|
||||
|
||||
队尾插入,队头取!
|
||||
|
||||
```text
|
||||
```java
|
||||
import java.util.Queue;
|
||||
import java.util.LinkedList;
|
||||
|
||||
@ -508,7 +542,7 @@ public class QueueExample {
|
||||
|
||||
**栈**
|
||||
|
||||
```text
|
||||
```java
|
||||
Deque<Integer> stack = new ArrayDeque<>();
|
||||
stack.push(1); // 入栈
|
||||
Integer top1=stack.peek()
|
||||
@ -541,7 +575,7 @@ Integer top = stack.pop(); // 出栈
|
||||
|
||||
*删除或查看元素*:调用 `remove()` 或 `poll()` 时,则是调用 `removeFirst()` 或 `pollFirst()`,即在队头移除元素;同理,`element()` 或 `peek()` 则是查看队头元素。
|
||||
|
||||
```text
|
||||
```java
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedList;
|
||||
|
||||
@ -591,7 +625,7 @@ public class DequeExample {
|
||||
2. `next()`:返回迭代器的下一个元素,并将迭代器移动到下一个位置。
|
||||
3. `remove()`:从迭代器当前位置删除元素。该方法是可选的,不是所有的迭代器都支持。
|
||||
|
||||
```text
|
||||
```java
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
@ -625,7 +659,7 @@ public class Main {
|
||||
|
||||
#### **数组排序**
|
||||
|
||||
```text
|
||||
```java
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ArraySortExample {
|
||||
@ -641,7 +675,7 @@ public class ArraySortExample {
|
||||
|
||||
#### 集合排序
|
||||
|
||||
```text
|
||||
```java
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -678,7 +712,7 @@ public class ListSortExample {
|
||||
- 如果返回零,说明 `o1` 等于 `o2`。
|
||||
- 如果返回正数,说明 `o1` 排在 `o2`后面。
|
||||
|
||||
```text
|
||||
```java
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
@ -725,7 +759,7 @@ public class ComparatorSortExample {
|
||||
|
||||
**自定义比较器排序二维数组** 用Lambda表达式实现`Comparator<int[]>接口`
|
||||
|
||||
```text
|
||||
```java
|
||||
import java.util.Arrays;
|
||||
|
||||
public class IntervalSort {
|
||||
@ -771,18 +805,13 @@ public class IntervalSort {
|
||||
|
||||
#### 双指针
|
||||
|
||||
1. 问题分析:
|
||||
题型:
|
||||
|
||||
- 确定问题是否涉及数组或链表的遍历。
|
||||
- 判断是否需要通过两个指针的协作来缩小搜索范围或比较元素。
|
||||
- 同向双指针:两个指针从同一侧开始移动,通常用于**滑动窗口**或链表问题。
|
||||
- 对向双指针:两个指针从两端向中间移动,通常用于有序数组或回文问题。重点是考虑**移动哪个指针**可能优化结果!!!
|
||||
- 快慢指针:两个指针以不同速度移动,通常用于链表中的环检测或中点查找。
|
||||
|
||||
2. 选择双指针类型:
|
||||
|
||||
- **同向双指针**:两个指针从同一侧开始移动,通常用于**滑动窗口**或链表问题。
|
||||
- **对向双指针**:两个指针从两端向中间移动,通常用于有序数组或回文问题。重点是考虑**移动哪个指针**可能优化结果!!!
|
||||
- **快慢指针**:两个指针以不同速度移动,通常用于链表中的环检测或中点查找。
|
||||
|
||||
3. 适用场景
|
||||
适用场景:
|
||||
|
||||
**有序数组的两数之和**:
|
||||
|
||||
@ -881,7 +910,7 @@ public void inOrderTraversalIterative(TreeNode root, List<Integer> list) {
|
||||
|
||||
*迭代法前序*
|
||||
|
||||
```
|
||||
```java
|
||||
public void preOrderTraversalIterative(TreeNode root, List<Integer> list) {
|
||||
if (root == null) return;
|
||||
|
||||
@ -904,3 +933,97 @@ public void preOrderTraversalIterative(TreeNode root, List<Integer> list) {
|
||||
}
|
||||
```
|
||||
|
||||
层序遍历BFS
|
||||
|
||||
```java
|
||||
public List<List<Integer>> levelOrder(TreeNode root) {
|
||||
List<List<Integer>> result = new ArrayList<>();
|
||||
if (root == null) return result;
|
||||
|
||||
Queue<TreeNode> queue = new LinkedList<>();
|
||||
queue.offer(root);
|
||||
|
||||
while (!queue.isEmpty()) {
|
||||
int levelSize = queue.size();
|
||||
List<Integer> level = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < levelSize; i++) {
|
||||
TreeNode node = queue.poll();
|
||||
level.add(node.val);
|
||||
|
||||
if (node.left != null) {
|
||||
queue.offer(node.left);
|
||||
}
|
||||
if (node.right != null) {
|
||||
queue.offer(node.right);
|
||||
}
|
||||
}
|
||||
result.add(level);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### 回溯法
|
||||
|
||||
回溯算法用于 **搜索一个问题的所有的解** ,即爆搜(暴力解法),通过深度优先遍历的思想实现。核心思想是:
|
||||
|
||||
**1.逐步构建解答:**
|
||||
|
||||
回溯算法通过逐步构造候选解,当构造的部分解满足条件时继续扩展;如果发现当前解不符合要求,则“回溯”到上一步,尝试其他可能性。
|
||||
|
||||
**2.剪枝(Pruning):**
|
||||
|
||||
在构造候选解的过程中,算法会判断当前部分解是否有可能扩展成最终的有效解。如果判断出无论如何扩展都不可能得到正确解,就立即停止继续扩展该分支,从而节省计算资源。
|
||||
|
||||
**3.递归调用**
|
||||
|
||||
回溯通常通过递归来实现。递归函数在**每一层都尝试不同的选择**,并在尝试失败或达到终点时返回上一层重新尝试其他选择。
|
||||
|
||||
**例:以数组 `[1, 2, 3]` 的全排列为例。**
|
||||
|
||||
先写以 1 开头的全排列,它们是:`[1, 2, 3], [1, 3, 2]`,即 `1` + `[2, 3]` 的全排列(注意:递归结构体现在这里);
|
||||
再写以 2 开头的全排列,它们是:`[2, 1, 3]`, `[2, 3, 1]`,即 `2` + `[1, 3]` 的全排列;
|
||||
最后写以 3 开头的全排列,它们是:`[3, 1, 2]`, `[3, 2, 1]`,即 `3` + `[1, 2]` 的全排列。
|
||||
|
||||

|
||||
|
||||
```java
|
||||
public class Permute {
|
||||
public List<List<Integer>> permute(int[] nums) {
|
||||
List<List<Integer>> res = new ArrayList<>();
|
||||
// 用来标记数组中数字是否被使用
|
||||
boolean[] used = new boolean[nums.length];
|
||||
List<Integer> path = new ArrayList<>();
|
||||
backtrack(nums, used, path, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
private void backtrack(int[] nums, boolean[] used, List<Integer> path, List<List<Integer>> res) {
|
||||
// 当path中元素个数等于nums数组的长度时,说明已构造出一个排列
|
||||
if (path.size() == nums.length) {
|
||||
res.add(new ArrayList<>(path));
|
||||
return;
|
||||
}
|
||||
// 遍历数组中的每个数字
|
||||
for (int i = 0; i < nums.length; i++) {
|
||||
// 如果该数字已经在当前排列中使用过,则跳过
|
||||
if (used[i]) {
|
||||
continue;
|
||||
}
|
||||
// 选择数字nums[i]
|
||||
used[i] = true;
|
||||
path.add(nums[i]);
|
||||
// 递归构造剩余的排列
|
||||
backtrack(nums, used, path, res);
|
||||
// 回溯:撤销选择,尝试其他数字
|
||||
path.remove(path.size() - 1);
|
||||
used[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
70
自学/苍穹外卖.md
70
自学/苍穹外卖.md
@ -31,7 +31,25 @@
|
||||
| 10 | orders | 订单表 |
|
||||
| 11 | order_detail | 订单明细表 |
|
||||
|
||||
### @TableName("user")public class User { @TableId private Long id; private String name; private Integer age; @TableField("isMarried") private Boolean isMarried; @TableField("`order`") private String order;}Java
|
||||
```java
|
||||
@TableName("user")
|
||||
public class User {
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
private Integer age;
|
||||
|
||||
@TableField("isMarried")
|
||||
private Boolean isMarried;
|
||||
|
||||
@TableField("`order`")
|
||||
private String order;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
**1.nginx 反向代理的好处:**
|
||||
|
||||
@ -47,7 +65,7 @@
|
||||
|
||||
因为一般后台服务地址不会暴露,所以使用浏览器不能直接访问,可以把nginx作为请求访问的入口,请求到达nginx后转发到具体的服务中,从而保证后端服务的安全。
|
||||
|
||||
```text
|
||||
```java
|
||||
server{
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
@ -62,7 +80,7 @@ server{
|
||||
|
||||
**2.负载均衡配置**(有两个后端服务器)
|
||||
|
||||
```text
|
||||
```java
|
||||
upstream webservers{
|
||||
server 192.168.100.128:8080;
|
||||
server 192.168.100.129:8080;
|
||||
@ -93,7 +111,7 @@ server{
|
||||
|
||||
在pom.xml中添加依赖
|
||||
|
||||
```xml
|
||||
```java
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-spring-boot-starter</artifactId>
|
||||
@ -156,7 +174,7 @@ protected void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
|
||||
EmployeeLoginDTO.java
|
||||
|
||||
```text
|
||||
```java
|
||||
@Data
|
||||
@ApiModel(description = "员工登录时传递的数据模型")
|
||||
public class EmployeeLoginDTO implements Serializable {
|
||||
@ -188,7 +206,7 @@ spring security中提供了一个加密类BCryptPasswordEncoder。
|
||||
|
||||
- 添加依赖
|
||||
|
||||
```text
|
||||
```java
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
@ -197,7 +215,7 @@ spring security中提供了一个加密类BCryptPasswordEncoder。
|
||||
|
||||
- 添加配置
|
||||
|
||||
```text
|
||||
```java
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
@ -218,7 +236,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
- 使用
|
||||
|
||||
```text
|
||||
```java
|
||||
@Autowired
|
||||
private BCryptPasswordEncoder bCryptPasswordEncoder;
|
||||
|
||||
@ -256,7 +274,7 @@ ThreadLocal为**每个线程**提供**单独**一份存储空间,具有线程
|
||||
|
||||
**每次请求代表一个线程**!!!注:请求可以先经过拦截器,再经过controller=>service=>mapper,都是在一个线程里。
|
||||
|
||||
```text
|
||||
```java
|
||||
public class BaseContext {
|
||||
|
||||
public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
|
||||
@ -321,7 +339,7 @@ public class BaseContext {
|
||||
|
||||
JacksonObjectMapper()文件:
|
||||
|
||||
```text
|
||||
```java
|
||||
public class JacksonObjectMapper extends ObjectMapper {
|
||||
|
||||
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
|
||||
@ -373,7 +391,7 @@ public void startOrStop(Integer status, Long id) {
|
||||
|
||||
还有一种:把源对象source的属性值赋给目标**对象**target中与源**对象**source的中有着同属性名的属性
|
||||
|
||||
```text
|
||||
```java
|
||||
BeanUtils.copyProperties(source,target);
|
||||
```
|
||||
|
||||
@ -397,7 +415,7 @@ BeanUtils.copyProperties(source,target);
|
||||
|
||||
在 EmployeeMapper.xml 中编写SQL:
|
||||
|
||||
```sql
|
||||
```java
|
||||
<update id="update" parameterType="Employee">
|
||||
update employee
|
||||
<set>
|
||||
@ -454,7 +472,7 @@ BeanUtils.copyProperties(source,target);
|
||||
|
||||
**1). 导入Spring Data Redis的maven坐标(已完成)**
|
||||
|
||||
```xml
|
||||
```java
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
@ -465,7 +483,7 @@ BeanUtils.copyProperties(source,target);
|
||||
|
||||
在application-dev.yml中添加
|
||||
|
||||
```yaml
|
||||
```java
|
||||
sky:
|
||||
redis:
|
||||
host: localhost
|
||||
@ -482,7 +500,7 @@ database:指定使用Redis的哪个数据库,Redis服务启动后默认有16
|
||||
|
||||
在application.yml中添加读取application-dev.yml中的相关Redis配置
|
||||
|
||||
```yaml
|
||||
```java
|
||||
spring:
|
||||
profiles:
|
||||
active: dev
|
||||
@ -564,7 +582,7 @@ public class SpringDataRedisTest {
|
||||
|
||||
**哈希测试**
|
||||
|
||||
```text
|
||||
```java
|
||||
/**
|
||||
* 操作哈希类型的数据
|
||||
*/
|
||||
@ -723,7 +741,7 @@ public class SpringDataRedisTest {
|
||||
|
||||
|
||||
|
||||
```text
|
||||
```java
|
||||
public static String doGet(String url,Map<String,String> paramMap){
|
||||
// 创建Httpclient对象
|
||||
CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||
@ -798,7 +816,7 @@ public static String doGet(String url,Map<String,String> paramMap){
|
||||
- 每个分类下的菜品保存一份缓存数据
|
||||
- 数据库中菜品数据有**变更时清理缓存数据**
|
||||
|
||||
```text
|
||||
```java
|
||||
@Autowired
|
||||
private RedisTemplate redisTemplate;
|
||||
/**
|
||||
@ -845,7 +863,7 @@ public static String doGet(String url,Map<String,String> paramMap){
|
||||
|
||||
清理缓冲方法:
|
||||
|
||||
```text
|
||||
```java
|
||||
private void cleanCache(String pattern){
|
||||
Set keys = redisTemplate.keys(pattern);
|
||||
redisTemplate.delete(keys);
|
||||
@ -858,7 +876,7 @@ public static String doGet(String url,Map<String,String> paramMap){
|
||||
|
||||
Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。
|
||||
|
||||
```text
|
||||
```java
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-cache</artifactId> <version>2.7.3</version>
|
||||
@ -892,7 +910,7 @@ Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要
|
||||
|
||||
|
||||
|
||||
```text
|
||||
```java
|
||||
@PostMapping
|
||||
@CachePut(value = "userCache", key = "#user.id")//key的生成:userCache::1
|
||||
public User save(@RequestBody User user){
|
||||
@ -915,7 +933,7 @@ Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要
|
||||
|
||||
所以,@Cacheable(cacheNames = "userCache",key="#id")中的#id表示的是函数形参中的id,而不能是返回值中的user.id
|
||||
|
||||
```text
|
||||
```java
|
||||
@GetMapping
|
||||
@Cacheable(cacheNames = "userCache",key="#id")
|
||||
public User getById(Long id){
|
||||
@ -928,7 +946,7 @@ Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要
|
||||
|
||||
作用: 清理指定缓存
|
||||
|
||||
```text
|
||||
```java
|
||||
@DeleteMapping
|
||||
@CacheEvict(cacheNames = "userCache",key = "#id")//删除某个key对应的缓存数据
|
||||
public void deleteById(Long id){
|
||||
@ -990,13 +1008,13 @@ https://pay.weixin.qq.com/static/product/product_index.shtml
|
||||
|
||||
输入代码:
|
||||
|
||||
```text
|
||||
```java
|
||||
cpolar.exe authtoken ZmIwMmQzZDYtZDE2ZS00ZGVjLWE2MTUtOGQ0YTdhOWI2M2Q1
|
||||
```
|
||||
|
||||
3)获取临时域名
|
||||
|
||||
```text
|
||||
```java
|
||||
cpolar.exe http 8080
|
||||
```
|
||||
|
||||
@ -1058,7 +1076,7 @@ cron表达式在线生成器:https://cron.qqe2.com/
|
||||
|
||||
|
||||
|
||||
```text
|
||||
```java
|
||||
@Component
|
||||
@Slf4j
|
||||
public class OrderTask {
|
||||
|
Loading…
x
Reference in New Issue
Block a user