书接上回
常用JavaAPI
API – Application Programming Interface,应用程序编程接口,是Java写好的标准库函数,即官方给你的工具包,用于快速方便地实现特定功能。
字符串相关常用API类 – StringBuilder、StringJoiner、StringBuffer
三者都是用于对字符串的增删改查系列操作,特别地,StringBuffer由于其线程安全特性,一般用于多线程操作。
数组工具类 – Arrays
其提供的方法,专用于对数组的增删改查。
时间日期工具类 – Date
Date对象本身是一个按“周序 月 日 时:分:秒 CST(中央标准时) 年”的格式化时间数据,表示当前时间,它的方法与时间操作有关,其中较常用的方法有:
getTime(); // 获取时间对象自世界标准时间原点以来所过去的毫秒值
setTime(Long time); // 设置/修改毫秒值
public static void main(String[] args) {
Date d = new Date();
System.out.println(d.getTime()); // 1691674264262
System.out.println(d); // Thu Aug 10 21:31:04 CST 2023
d.setTime(465497646378L);
System.out.println(d); // Tue Oct 02 00:54:06 CST 1984
}
值得注意的是,许多涉及到日历对象Calendar的计算时,方法底层是将时间中的纪元,年,月,日,时,分,秒,周序等等都放入到一个数组中。其中,特别地,月份(0~11)与周序(0~6)的数据比实际时间数据少1(大部分的编程语言都是这样)。
数学计算工具类 – Math
其提供的方法多应用于非整数取整、幂次方等运算,其中的random()方法获取随机数使用最多,返回值为[0.0,1.0)内的随机double值。
正则表达式 – Regex
正则表达式用于检验字符串是否满足某规则,或者查找一段文本中满足要求的内容,这个规则或者说要求即是正则表达式。正则表达式多用于文本爬取。
// 校验用户名(大小写字母 数字 下划线共4——16位)
String regex6 = "\\w{4,16}";
System.out.println("zhangsan".matches(regex6));//true
System.out.println("lisi".matches(regex6));//true
System.out.println("S1121".matches(regex6));//true
// 判断一字符串是否首尾一致 只考虑一个字符
String regex1="(.).+\\1";
System.out.println("a125611a".matches(regex1));//t
System.out.println("7kde_7".matches(regex1));//t
System.out.println("&qwhq &".matches(regex1));//t
System.out.println("1wh12b".matches(regex1));//f
“优雅永不过时!” – Lambda表达式
匿名内部类
在调用一个方法时,若方法的形参是一个接口,我们在传递接口的实现类对象时使用匿名内部类可以简化代码,尤其是对于一次性使用的简单类或接口的实例化。
如下是一个经常使用到的匿名内部类例子
// 匿名内部类:
Integer[]arr={2,3,4,5,6,9,4,8};
Arrays.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1-o2;
}
});
System.out.println(Arrays.toString(arr));//[2, 3, 4, 4, 5, 6, 8, 9]
函数式编程
为简化方法中面向对象的复杂语法,专注于方法逻辑而诞生的编程思想。
Lambda表达式就是对此思想的体现。
特点:
- Lambda表达式可用于简化匿名内部类的书写
- Lambda表达式只能简化函数式接口的匿名内部类写法(函数式接口:有且仅有一个抽象方法的接口)
// lambda:
Arrays.sort(arr, (Integer o1, Integer o2) -> {
return o1 - o2;
}
);
System.out.println(Arrays.toString(arr));//[2, 3, 4, 4, 5, 6, 8, 9]
进一步省略的规则:
- 参数类型可以不写
- 若仅有一个参数,参数类型可省略,同时()也可以省略
- 若lambda表达式方法体只有一行,大括号 分号 return均可省略,但要同时省略
// lambda进一步省略:
Arrays.sort(arr, (o1,o2)->o1-o2);
System.out.println(Arrays.toString(arr));//[2, 3, 4, 4, 5, 6, 8, 9]
常见算法
算法是解决问题的一系列步骤或指令的集合
查找
在给定的数据集合中寻找目标元素的过程
基本查找/顺序查找
从0索引开始依次向后遍历
二分查找/折半查找
每次排除一半的查找范围
区块查找
块内无序,块间有序
- 1 将所有数据分为若干数组(块)
- 2 查找目标数据属于哪一块
- 3 单独遍历此数据块
排序
将一组数据按特定的顺序要求重新排列的过程
冒泡排序
原理(从小到大):
- 1 相邻元素两两比较,大的放右边,小的放左边
- 2 第一轮比较完毕后,得到了最大值,第二轮则少循环一次,后面同理
- 3 数组有n个数据,则执行步骤1共n-1次
//外循环:表示要执行多少轮
for (int i = 0; i < arr.length-1; i++) {
//内循环:每一轮中如何比较数据并找到当前最大值 -1防止索引越界 -i提高效率
for (int j = 0; j < arr.length - 1-i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
插入排序
原理:
将0索引的元素到N索引的元素看作有序,将N+1索引元素到最后一个看作无序
遍历无序数据,将遍历到的元素插入有序序列中适当位置,如遇相同数据,插在后面
N的范围:0~最大索引
for (int i = 1; i < arr.length; i++) {
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
快速排序
原理:
第一轮:以0索引数字为基准数,先确定基准数在数组中的位置
比基准数小的全在左边,大的在右边 以此类推
if (low < high) {
int pivotIndex = partition(arr, low, high);
quickSort(arr, low, pivotIndex - 1);
quickSort(arr, pivotIndex + 1, high);
}
public int partition(int[] arr, int low, int high) {
int pivot = arr[high];
int i = low - 1;
for (int j = low; j < high; j++) {
if (arr[j] < pivot) {
i++;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
int temp = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = temp;
return i + 1;
}
选择排序
原理:
- 从0索引开始,与后面的元素一一比较,小的放前,大的放后
- 第一轮循环后,得到最小值
- 第二轮循环从1索引开始,后面以此类推
for (int i = 0; i < arr.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
递归 – “你就说优不优雅吧!”
将大问题分解为小问题而最终解决的过程
核心:“大事化小” “方法自己调用自己” “寻找循环出口”
// 现欲利用递归求1~100的和
//大事化小
//1~100的和 =100+(1~99的和)
//1~99的和 =99+(1~98的和)
//1~98的和 =98+(1~97的和)
//。。。
//1~1的和 =1(递归的出口)
System.out.println(getSum(100));//5050
}
public static int getSum(int x) {
if (x == 1) return 1;
return x + getSum(x - 1);
}
集合进阶
介于集合进阶内容多且相当重要,我将在另一篇文章上对此内容做更详细的总结阐述,链接如下。
泛型
在编译阶段约束操作的数据类型,并进行检查
格式:
<数据类型> (泛型仅支持引用数据类型)
例:
ArrayList<Integer> list = new ArrayList<> ();
泛型在使用上体现:
- 泛型类 在类名后面定义泛型,创建该类对象时,确定类型
- 泛型方法 在修饰符后面定义方法,调用该方法的时候,确定类型
- 泛型接口 在接口名后面定义泛型,实现类确定类型,实现类延续泛型