Java 基础 - API

news/2025/1/19 22:46:45/文章来源:https://www.cnblogs.com/wxgmjfhy/p/18679819

API

API: 应用程序编程接口, 即已经写好的东西, 可以直接使用

String

  • 字符串的内容是不会更改的
String name = "abc";
name = "def";// name = "def" 是创建了一个新的字符串, 然后把引用赋给了 name
  • 构建方法
String s = "abc"; // 直接赋值String s = new String(); // 创建一个空字符串String s = new String("abc"); // 根据传递的字符串内容构建一个新字符串char[] chs = {'a', 'b', 'c'};
String s = new String(chs); // 根据字符数组byte[] bytes = {97, 98, 99, 100};
String s = new String(bytes); // 根据字节数组
  • 使用双引号直接赋值时, 如果该字符串在串池中已存在, 会复用字符串
String s1 = "abc";
String s2 = "abc";// s1, s2 指向同一个串池中的地址
  • 使用 new 创建时, 每次 new 会在堆内存中开辟一个新空间, 不会 复用
char[] chs = {'a', 'b', 'c'};
String s1 = new String(chs);
String s2 = new String(chs);// s1, s2 指向不同的堆内存中的地址
  • 字符串比较

    • == 比较基本数据类型时, 比较数据值; 比较引用数据类型时, 比较地址值
      因此对于 String, 比较的是 地址值

    • s1.equals(s2) 比较内容, 完全一样才是 true

    • s1.equalsIgnoreCase(s2) 比较内容, 忽略大小写

  • 访问字符 s1.charAt(i)

  • 转成字符数组 char[] chs = s1.toCharArray();

StringBuilder

可以看成一个容器, 创建之后里面的内容可以改变
因此拼接字符串时, 不会每次产生一个新的字符串, 提高效率

StringBuilder s = new StringBuilder("abc");s.append("def");s.reverse();int len = s.length();String str = s.toString();

StringJoiner

StringJoiner s = new StringJoiner(间隔符号, 开始符号, 结束符号);e.g. StringJoiner s = new StringJoiner("---", "(", ")");s.add("abc"); // 应该是在中间添加数据int len = s.length();String str = s.toString();

System

System.exit(0); // 虚拟机正常停止, 非 0 是异常停止long l = System.currentTimeMillis(); // 从时间原点到运行这行代码的时间毫秒值形式
// 可以两行代码之间相减检查中间代码的运行时间System.arraycopy(arr1, 0, arr2, 0, 10);
// System.arraycopy(数据源数组(被拷贝), 从数据源第几个索引开始拷贝, 目的地数组, 目的地索引, 拷贝的个数);
// 若 arr1, arr2 都是基本数据类型, 则类型需要一样
// 若 arr1, arr2 都是引用数据类型, 则子类数组可以把地址值拷贝给父类数组

Runtime

Runtime r1 = Runtime.getRuntime(); // 获取 Runtime 对象, 地址值固定(final)r1.exit(0); // 停止虚拟机int cpuProcessors = r1.availableProcessors(); // 获取 CPU 的线程数long maxM = r1.maxMemory(); // JVM 能从系统获取总内存大小(单位 byte)long totM = r1.totalMemory(); // JVM 已从系统获取总内存大小(单位 byte)long freeM = r1.freeMemory(); // JVM 剩余内存(单位 byte)r1.exac("写 cmd 命令");

Object

toString

Student stu = new Student();
String s = stu.toString(); // 返回对象的字符串表示形式(地址值)
sout(s); // 等同于 sout(stu);// 可以重写 toString 方法以打印对象的属性信息

equals

Student s1 = new Student();
Student s2 = new Student();
boolean result = s1.equals(s2); // 比较地址值, 为 false// 可以重写 equals 方法以比较对象的属性信息// String.equals() 先判断参数是否为字符串, 是字符串再比较内容
// StringBuilder.equals() 继承 Object 的, 比较地址值

clone

clone 需要重写, 并让类实现 Cloneable 接口

  • [[D:/java_code/user/User.java|e.g.User]]

    public class User implements Cloneable { // 注意 Cloneable...@Overridepublic String toString() {return name + ", " + id;}@Overrideprotected Object clone() throws CloneNotSupportedException { // 注意 throws CloneNotSupportedException// 调用父类中的 clone 方法return super.clone();}
    }
    
  • Cloneable 这个接口中没有抽象方法, 表示当前接口是一个标记行接口

  • 实现 Cloneable 表示当前类的对象可以被克隆

  • [[D:/java_code/user/Test.java|e.g.Test]]

    public static void main(String[] args) throws CloneNotSupportedException { // 注意 throws CloneNotSupportedExceptionUser u1 = new User("zhangsan", "123");User u2 = (User)u1.clone(); // 注意强转// 会调用重写的 toStringSystem.out.println(u1);System.out.println(u2);
    }
    
  • 浅克隆

    • 基本数据类型: 完全拷贝数据值
    • 引用数据类型: 完全拷贝地址值
    • Object.clone() 是浅克隆
  • 深克隆

    • 基本数据类型: 完全拷贝数据值
    • 字符串: 复用
    • 引用数据类型: 重新创建新的
    • 重写 clone 以深克隆 e.g.
    // 假设 User 中有一个成员为 data 数组
    @Override
    protected Object clone() throws CloneNotSupportedException {int[] data = this.data;int[] newData = new int[data.length];for (int i = 0; i < data.length; i++) {newData[i] = data[i];}User u = (User)super.clone(); // 浅克隆u.data = newData; // 对引用数据类型的成员特别处理return u;
    }
    
    • 实际开发中, 一般使用序列化再反序列化
    • 使用第三方工具如 Jackson 或者 Gson, 将对象转换为 JSON 字符串, 再从 JSON 字符串重建新的对象

Objects

一个对象工具类, 注意不是 Object, 因为有 s

boolean flag = Objects.isNull(对象);
boolean flag = Objects.nonNull(对象);
boolean flag = Objects.equals(对象1, 对象2);
  • isNullnonNull 相反
  • equals 会先作非空判断, 再比较两个对象

BigInteger

BigInteger 是 Java 提供的高精度计算类, 可以很方便地解决高精度问题。

初始化

import java.io.PrintWriter;
import java.math.BigInteger;class Main {static PrintWriter out = new PrintWriter(System.out);public static void main(String[] args) {// 将字符串以十进制的形式创建 BigInteger 对象BigInteger a = new BigInteger("12345678910");out.println(a); // 12345678910 // 将字符串以指定进制的形式创建 BigInteger 对象BigInteger b = new BigInteger("1E", 16);out.println(b); // 30 // 获取一个范围为 0 ~ 2^31-1 的随机数BigInteger c = new BigInteger(31, new Random()); out.println(c); // 一个范围为 0 ~ 2^31-1 的随机数// 参数不超过 long, 静态方法获取对象, 内部有优化// 会将 -16 ~ 16 先创建好 BigInteger 对象, 多次获取不会重新创建BigInteger d = BigInteger.valueOf(100); out.println(d); // 100out.close();}
}

对象一旦创建, 内部记录的值不能发生改变

基本运算

以下均用 this 代替当前 BigIntger :

函数名 功能
abs() 返回 this 的绝对值
negate() 返回 - this
add(BigInteger val) 返回 this + val
subtract(BigInteger val) 返回 this - val
multiply(BigInteger val) 返回 this * val
divide(BigInteger val) 返回 this / val
remainder(BigInteger val) 返回 this % val
divideAndRemainder(BigInteger val) 返回一个数组, 包含 this / val 和 this % val
mod(BigInteger val) 返回 this mod val
pow(int e) 返回 this^e
and(BigInteger val) 返回 this & val
or(BigInteger val) 返回 this
not() 返回 ~ this
xor(BigInteger val) 返回 this ^ val
shiftLeft(int n) 返回 this << n
shiftRight(int n) 返回 this >> n
max(BigInteger val) 返回 this 与 val 的较大值
min(BigInteger val) 返回 this 与 val 的较小值
bitCount() 返回 this 的二进制中不包括符号位的 1 的个数
bitLength() 返回 this 的二进制中不包括符号位的长度
getLowestSetBit() 返回 this 的二进制中最右边的位置
compareTo(BigInteger val) 比较 this 和 val 值大小
toString() 返回 this 的 10 进制字符串表示形式
toString(int radix) 返回 this 的 raidx 进制字符串表示形式
intValue(BigInteger val) 转为 int 类型, 超出范围数据出错

BigDecima

  • 用于小数的精确运算
  • 用来表示很大的小数

正则表达式

  • 校验字符串是否满足规则
  • 在一段文本中查找满足要求的内容

如何书写

字符类

代码 范围
[abc] a,b,c
[^abc] 除 a,b,c
[a-zA-z] a-z, A-Z
[a-d[m-p]] a-d, m-p
[a-z&&[def]] d,e,f
[a-z&&[^bc]] a, d-z
[a-z&&[^m-p]] a-l, q-z

预定义字符(只匹配一个字符)

字符 范围
. 任意字符
\d 数字
\D 非数字
\s 一个空白字符
\S 非空白字符
\w 英文, 数字, 下划线
\W 一个非单词字符(非"英文, 数字, 下划线")

[[D:/java_code/regex/Test.java|e.g.]]

插件

any-rule, 支持 idea, vscode

爬虫

[[D:/java_code/regex/Find.java|基础爬取和有条件的爬取]]

贪婪爬取与非贪婪爬取

暂略

捕获分组和非捕获分组

暂略

时间相关类

暂略

包装类

用一个对象, 把基础数据类型包起来

byte -> Byte
short -> Short
char -> Character
int -> Integer
long -> Long
float -> Float
double -> Double
boolean -> Boolean

创建

public static void main(String[] args) {Integer i1 = new Integer(1);Integer i2 = new Integer("1");Integer i3 = Integer.valueOf(123);Integer i4 = Integer.valueOf("123");Integer i5 = Integer.valueOf("123", 8);sout(i5); // 8 进制的 123 -> 10 进制的 83// valueOf 会获取提前创建的 -128 ~ 127 的对象Integer i6 = Integer.valueOf(127);Integer i7 = Integer.valueOf(127);sout(i6 == i7); // true
}

JDK5 以后可以自动装箱, 自动拆箱, 赋值和运算直接写即可

Integer i1 = 10;
Integer i2 = 20;
Integer i3 = i1 + i2;
int i4 = i1;

Integer 成员方法

String str1 = Integer.toBinaryString(100); // 把整数转成 2 进制
String str2 = Integer.toOctalString(100); // 把整数转成 8 进制
String str3 = Integer.toHexString(100); // 把整数转成 16 进制int i = Integer.parseInt("123"); // 字符串类型的整数转成 int
// (8 种包装类, 除 Character 都有对应的 parseXxx 方法)

操作数组的工具类 Arrays

int[] a = {1, 2, 3};String s = Arrays.toString(a); // 数组拼接成字符串
int pos = Arrays.binarySearch(a, 2); // 二分查找
int[] b = Arrays.copyOf(a, 10); // 拷贝数组(原数组, 新数组长度)
int[] c = Arrays.copyOfRange(a, 1, 2); // 拷贝数组, 指定范围
Arrays.fill(a, 0); // 填充数组
Arrays.sort(a); // 默认方式排序数组
Arrays.sort(a, cmp); // 指定方式排序数组

cmp 举例

Integer[] arr = {2, 3, 1, 5, 6, 7, 8, 4, 9};// 底层原理:
// 插入排序 + 二分查找
// 认为前面有序, 后面无序
// 遍历无序序列, 记当前遍历元素为 o1
// 向有序序列中插入 o1, 先利用二分查找确定 o1 的插入点
// 比较 o1 与当前二分到的插入点的元素 o2 的规则为 compare
Arrays.sort(arr, new Comparator<Integer>(){@Overridepublic int compare(Integer o1, Integer o2) {return o1 - o2; // 升序排序}// 返回值:// 负数: 表示当前要插入的元素是"小"的, 放在前面// 正数: 表示当前要插入的元素是"大"的, 放在前面// 0 : 表示当前要插入的元素和现在的元素一样, 也会放在后面
});

Lambda 表达式

Arrays.sort(arr, (Integer o1, Integer o2) -> {return o1 - o2;
});

函数式编程

面向对象: 先找对象, 让对象做事情

函数式编程: 忽略面向对象的复杂语法, 强调做什么, 而不是谁去做

格式

() -> {}

  • 可以简化匿名内部类的书写

  • 只能简化函数式接口的匿名内部类的书写

    • 函数式接口: 有且仅有一个抽象方法的接口, 接口上方可以加 @FunctionalInterface
    • 若不止一个, 则不清楚是替代哪个方法, 接口上方也不能加 @FunctionalInterface
  • 省略格式
    可以(从对应的函数式接口)推导得到的东西可以省略不写

    • 参数类型可以省略
    Arrays.sort(arr, (o1, o2) -> {return o1 - o2;
    });
    
    • 如果只有一个参数, () 可以省略
    • 如果只有一行, 大括号, 分号, return 可以省略, 需要同时省略
    Arrays.sort(arr, (o1, o2) -> o1 - o2);
    

Java 集合对应 C++ STL

集合类不能直接存储基础数据类型, 因为其设计用于存储对象, 只能存储对应的包装类

List<Integer> a = new ArrayList<>(); // vector
List<Integer> a = new LinkedList<>(); // list
Set<Integer> s = new HashSet<>(); // unordered_set
Set<Integer> s = new TreeSet<>(); // set
Map<String, Interger> mp = new HashMap<>(); // unordered_map
Map<String, Interger> mp = new TreeMap<>(); // map
Stack<Integer> st = new Stack<>(); // stack
Queue<Integer> q = new LinkedList<>(); // queue
Deque<Integer> q = new ArrayDeque<>(); // deque
PriorityQueue<Integer> q = new PriorityQueue<>(); // priority_queue

集合

单列集合: Collection, 双列集合: Map

Collection

单列集合的祖宗接口(是个接口, 不能直接创建其对象, 只能创建实现类的对象)

Collection<String> coll = new ArrayList<>();
coll.add("123"); // 向 set 中添加元素, 元素已存在时返回 false
coll.clear();
coll.remove("123"); // 删除成功返回 true
bool flag1 = coll.contains("123"); // 底层依赖 equals 进行判断, 如果集合存储自定义对象, 需要重写 equals 以比较对象属性而非地址值
bool flag2 = coll.isempty();
int size = coll.size();

迭代器

Collection<String> coll = new ArrayList<>();
Iterator<String> it = coll.iterator(); // 默认指向 0 索引对应的位置
while(it.hasNext()) {String str = it.next(); // it.next() 可以大概理解为 C++ 中 *(it++), 返回当前对应的元素, 并移动指针sout(str);
}
  • 迭代器遍历时, 不能使用集合的增加或删除操作, 但可以 it.remove() 在遍历时删除元素

增强 for 遍历

for(String s : coll) {s = "xxx";
}// 修改增强 for 中的变量, 不会改变集合中原本的数据

Lambda 遍历

// 匿名内部类
// 底层遍历每一个元素, 传递给 accept 方法coll.forEach(new Consumer<String>() {@Overridepublic void accept(String s) {sout(s);}
});
// Lambdacoll.forEach(s -> sout(s));

List

List<Integer> list = new ArrayList<>();list.add(1);list.remove(0); // 移除 0 索引元素Integer i = Integer.valueOf(1);
list.remove(i); // 移除元素 1// 上面两个 remove, 本质是方法调用时如果有重载现象, 优先调用实参和形参一致的那个方法
List<String> list = new ArrayList<>();
list.add("abc");
String s = list.set(0, "123"); // 返回被修改的元素 abc, 并修改 0 索引上元素为 123
s = list.get(0); // 123
  • 列表迭代器: 可以遍历集合时添加元素
    ListIterator<String> it = list.listIterator(); // 默认指向 0 索引
    while(it.hasNext()) {String s = it.next();if ("bbb".equals(s)) {it.add("qqq");}
    }
    

泛型

泛型: 可以在编译阶段约束操作的数据类型, 并进行检查
格式: <数据类型>
注意: 泛型只支持引用数据类型

  • 如果没有泛型, 可以给集合添加任意类型的元素, 默认为 Object, 不能使用类的特有行为
  • Java 的泛型是伪泛型
  • 指定泛型的具体类型后, 可以传入其子类类型

泛型类

编写一个类, 如果不确定类型, 可以定义为泛型类

修饰符 class 类名<类型> {}

比如

// E 表示类型不确定, 可以写成 T, K, Vpublic class MyArrayList<E> {Object[] obj = new Object[10];int size;public boolean add(E e) {obj[size] = e;size++;return true;}public E get(int index) {return (E)obj[index];}@Overridepublic String toString() {return Arrays.toString(obj);}
}

泛型方法

修饰符 <类型> 返回值类型 方法名(类型 变量名) {}

比如

public static <E> void addAll(ArrayList<E> list1, ArrayList<E> list2) {if (list2 == null) {return;}list2.forEach(e -> list1.add(e));
}
public static <E> void addAll(ArrayList<E> list, E...e) {for (E element : e) {list.add(element);}
}

泛型接口

修饰符 interface 接口名<类型> {}

比如

public interface List<E> extends Collection<E> {}
  • 两种使用方式
    • 实现类给出具体类型
    public class MyArrayList implements List<String> {}
    
    • 实现类延续泛型, 创建实现类对象时再确定泛型
    public class MyArrayList implements List<E> {}
    

注意

泛型不具备继承性, 但是数据具备继承性
(泛型里面写什么类型, 那么只能传递什么类型的数据)

通配符

如何不确定类型, 但又想限定类型的一定 范围, 需要使用通配符

// 可以传入继承 xxx 类的数据(包括 xxx)
public static void method(ArrayList<? extends xxx> list) {}// 可以传入是 xxx 类父类的数据(包括 xxx)
public static void method(ArrayList<? super xxx> list) {}

Hash

hashCode

  • 哈希值是根据 Objrct.hashCode() 计算得到的 int 类型整数
  • 默认使用地址值计算
  • 一般要重写 hashCode, 使用对象内部的属性值计算哈希值
@Override
public int hashCode() {return Objects.hash(name, age);
}
  • 哈希表存储自定义对象要重写 equalshashCode

LinkedHashSet

相较 HashSet, 可以保证数据存取有序(底层使用双链表记录添加顺序)

Tree

默认排序

  • 默认排序/自然排序: Javabean 类实现 Comparable 接口, 重写里面的抽象方法, 指定比较规则
public class Student implements Comparable<Student> {private int age;public Student() {}public Student(int age) {this.age = age;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic iint compareTo(Student o) {return this.getAge() - o.getAge();// 只看年龄, 升序排序}// this 表示当前要添加的元素// o 表示当前比较的已经在红黑树存在的元素// 返回值:// 负数: 要添加元素"小", 存左边// 正数: 要添加元素"大", 存右边// 0: 要添加元素已经存在, 去重舍弃 
}

比较器排序

  • 比较器排序: 创建 TreeSet 对象时, 传递比较器 Comparator 指定规则
// 当前需求: 先按长度排序, 再按字典序排序
// String 自带的字典序排序方法不满足当前需求, 采用比较器排序
TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {int diff = o1.length() - o2.length();return diff == 0 ? o1.compareTo(o2) : diff;}
});// Comparator 是一个函数式接口, 可以 Lambda
TreeSet<String> ts = new TreeSet<>((o1, o2) -> {int diff = o1.length() - o2.length();return diff == 0 ? o1.compareTo(o2) : diff;
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/871894.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[JavaScript] 深入理解流程控制结构

在编程中,流程控制是指控制代码执行顺序的机制。通过流程控制结构,我们可以根据不同的条件执行不同的代码块,实现逻辑判断、循环遍历和跳出循环等功能。常见的流程控制语句有:if-else、switch-case、for、while,以及控制语句break和continue。本文将详细讲解这些控制结构的…

ELF2开发板(rk3588飞凌)

ELF2开发板(飞凌嵌入式) 开箱包裹内容打开包装,你可以看到以下物品一个绿联的usb3.0读卡器、sandisk的32g内存卡(太好了) rk3588 4g+32g emmc版本ELF2开发板 输出为12v 3A的电源适配器(和ipad的充电器外观好像)图1 外包装盒图2 开箱物品内容图3 ELF2开发板正面图4 ELF2开发…

抗沙箱方式列举

前言 研究过免杀的朋友们一定会碰到过自己的🐎今天还能用,明天就被秒的情况。这种情况大多数是被上传到沙箱然后被沙箱检测和分析发现是🐎,进而记录特征让咱们花好几天写的🐎直接废了。为了提高🐎的存活周期,咱们就需要抗沙箱这门技术。 未加抗沙箱 首先,作为演示我…

K-D树及其应用

K-D树及其应用 简介 在单个维度的范围搜索场景下,如:搜索创建时间最靠近某个日期的商品信息。可以通过遍历所有的商品信息,计算每个商品的创建日期的差值,得到差值最小的商品即可,这样每次查询的时间复杂度为 \(O(n)\);或者通过构造一个 BST,通过日期进行比较查询,这样…

基础动态规划讲解

(标题就叫这个吧,我也没什么主意了) 动态规划,要给这个这个东西下个定义,确实不太好下,他是一种基于状态来思考问题的算法思想 用来表示状态的话,那就是dp,(这么说好抽象),就直接说涉及动态规划的题目怎么处理吧 ,这个还是有步骤可行的,就按如下步骤操作 1.寻找子…

遗传算法个人入门笔记

先举一个简单的求解例子: 变量x,y 函数f(x,y) = (x-5)^2 + (y+3)^2 - 5 求最小值。 def test(x,y):return (x - 5)**2 + (y - 3)**2 - 5显然,这个函数在x=5,y=3时取最小值-5。现在我们尝试用遗传算法解决之。 遗传算法主要是模拟生物进化的过程,将每一个值视作一个生物,有…

excel快速定位到某一行

左上角输入框输入:A100定位到第100行

2024秋季学期 电子技术基础期末复习笔记

这期末也太难了吧,15*2,俩超级难的电路,直接给我算麻了电路分析模拟电路

【牛客训练记录】牛客周赛 Round 77

训练情况赛后反思 打一半吃饭去了,C题看到 ax+by=k 的问题,简单的扩欧exgcd没反应过来,简单数论还是不熟悉TAT,D题DSU计算联通块大小时 \(i\) 打成 \(a_i\) 疯狂 RE 被硬控了十几分钟 A题 输出题目所述的第几个字符串即可 #include <bits/stdc++.h> // #define int l…

LIS于LCS

LIS与LCS是动态规划中最常见的两种情况,LIS也就是最长上升子序列,而LCS是最长公共子序列。 在解决这个问题之前,先要明白为什么是序列,举个例子来说明,在数组 [1,2,3,4,5,6]中,[2,3,5]就是其子序列,也就是说,子序列其实就是数组中存在先后顺序,但不强调连续的子数组。…

层次分析法:数学建模

今天学习了层次分析法和数学建模,这里就简单写一下自己的学习新的,参考的资料是B站上的免费网课,老师讲的不错,可以去围观,学习,希望可以拿个奖。https://www.bilibili.com/video/BV1p14y1U7Nr/?spm_id_from=333.337.search-card.all.click 上面这里是链接。本文的大部分…

那些年我在 HL 集训做的题【某人别催了!】

某人别催了!!!Day 0 1.16 下午到 HL,居然还写了一道题? P8855 [POI2002] 商务旅行 LCA 板子。不理解当时为啥要写这个东东,可能是为了热热身吧。 Day 1 讲整体二分,但是没听懂。貌似是魔改版 CDQ...不管它。但是我似乎发现了一片新天地,一切的一切都从下面的一道题说起…