Arrays、Lambda、方法引用、算法、正则表达式
1 Arrays
1.1 作用
一个用于处理数组的工具类
1.2 常用方法
返回数组的内容: static String toString(数组)
从指定范围拷贝数组内容: static 数组 copyOfRange(数组, 开始索引, 结束索引) 注意: 包前不包后!
拷贝数组: static int[] copyOf(数组,int 长度)
把数组的内容改为新的数据: static void setAll(数组 , IntToDoubleFunction generator);
对数组的内容进行排序: 基本数据类型static void sort(数组), 自定义类型数组不支持直接排序, 需制定规则.
方法一:
//让这个类实现Comparable接口,重写compareTo方法,自己来指定比较规则
public class Student implements Comparable<Student>{
//省略创建类
}
public int compareTo(Student o) {
if(this.height > o.getHeight()){
return 1;// 1 可以理解为换! positive
}
else if (this.height < o.getHeight()){
return -1; // -1可以理解为不换 negative
}else {
if (this.age > o.getAge()){
return -1;
}else if (this.age < o.getAge()){
return 1;
}else {
return 0;
}
}
第二种方法啊:
//在sort方法里面,创建Comparator接口,重写方法,指定比较规则
Arrays.sort(stu, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
// if(o1.getAge() > o2.getAge()){
// return -1;
// }else if(o1.getAge() < o2.getAge()){
// return 1;
// }else{
// return 0;
// }
int i = Double.compare(o1.getAge(),o2.getAge());
// int i2 = Double.compare(o1.getHeight(),o2.getAge());
return i;
}
});
二分查找元素: static int binarySearch(数组, 元素)
2 Lambda 表达式
2.1 作用
简化匿名内部类的格式。这个匿名内部类的接口一定要是一个函数式接口 (里面有且只有一个抽象方法)
2.2 格式
(重写方法的参数)->{
方法体;
}
2.3 方法引用
不在乎实现的过程, 只在乎实现的结果!
2.3.1 静态方法引用
1) 格式: 类名::静态方法
2) 使用场景: 如果某个Lambda表达式里只是调用一个静态方法,并且前后参数的形式一致,就可以使用静态方法引用。
3) 代码: A a2 = MyUtils::getMax;
public interface findMax {
int findMax(int a, int b);
}
public interface findMin {
int findMin(int a, int b);
}
public class MyUtils {
// 静态方法,用于获取两个整数的最大值
public static int getMax(int a, int b) {
return a > b ? a : b;
}
// 实例方法,获取两个数字的最小值
public int getMin(int a, int b) {
return a < b ? a : b;
}
}
public class test {
public static void main(String[] args) {
int a = 14;
int b = 28;
// 之前学过的 (匿名内部类)
findMax max1 = new findMax() {
@Override
public int findMax(int a, int b) {
int c = MyUtils.getMax(a, b );
return c;
}
};
System.out.println(max1.findMax(a,b));
// Lampda
findMax max2 = (int a1, int b1)->{
int c = MyUtils.getMax(a, b );
return c;
};
findMax max3 = MyUtils::getMax;
System.out.println(max3.findMax(a,b));
2.3.2 实例方法的引用
1) 格式: 对象名::实例方法
2) 使用场景: 如果某个Lambda表达式里只是调用一个实例方法,并且前后参数的形式一致,就可以使用实例方法引用。
3) 代码: B b3 = mu::getMin; //写的也是方法的名字就可以了
B b4 = new MyUtils()::getMin; //写的也是方法的名字就可以了
2.3.3 特定类型方法的引用
1) 格式: 类型::方法
2) 使用场景: 如果某个Lambda表达式里只是调用一个实例方法,并且前面参数列表中的第一个参数是作为方法的主调, 后面的所有参数都是作为该实例方法的入参的,则此时就可以使用特定类型的方法引用
3) 代码:
String[] names = new String[]{"baby", "Angela", "about", "eson", "Jack", "jack2", "rose"};
Arrays.sort(names, String::compareToIgnoreCase);
2.3.4 构造器引用
1) 格式: 类名::new
2) 使用场景: 如果某个Lambda表达式里只是在创建对象,并且前后参数情况一致,就可以使用构造器引用。
3) 代码: C c3 = Student::new;
3 算法
3.1 冒泡排序
3.1.1 核心思想
每次从数组中找出最大值放在数组的后面去。
3.1.2 实现步骤
1) 确定总共需要做几轮: 数组的长度-1.
2) 每轮比较几次
3) 当前位置大于后一个位置则交换数据
3.1.3 代码实现
public static void main(String[] args) {
int[] arr = {5, 2, 3, 1};
//外部循环控制执行的次数
/*
第一轮 i = 0 2 3 1 5
第二轮 i = 1 2 1 3 5
第三轮 i = 2 1 2 3 5
*/
for (int i = 0; i < arr.length - 1; i++) {
//内部循环实现获取较大值【两两比较】
for (int j = 0; j < arr.length - i - 1; j++) {
//相邻的两个进行比较 , 如果当前元素值 大于下一个元素的值,则进行位置的交换
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
System.out.println(Arrays.toString(arr));
}
}
}
3.2 选择排序
3.2.1 核心思想
每轮选择当前位置,开始找出后面的较小值与该位置交换
3.2.2 实现步骤
1) 确定总共需要做几轮: 数组的长度-1.
2) 控制每轮从以前位置为基准,与后面元素选择几次。
3) 当前位置大于后一个位置则交换数据
3.2.3 代码实现
public static void main(String[] args) {
int[] arr = {5, 1, 3, 2};
//定义外部循环,代表循环执行的次数
for (int i = 0; i < arr.length - 1; i++) {
System.out.println("第" + (i + 1) + "轮");
//定义内部循环,代表选择的次数
for (int j = i + 1; j < arr.length; j++) {
//用当前的位置的元素和后面的元素进行判断,如果当前位置后面位置的元素大,则交换位置
if (arr[i] > arr[j]) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//可以查看这个程序交换的流程
System.out.println(Arrays.toString(arr));
}
}
System.out.println(Arrays.toString(arr));
}
3.3 二分查找
3.3.1 前提条件
数组中的数据必须是有序的
3.3.2 核心思想
每次排除一半的数据,查询数据的性能明显提高极多!
3.3.3 实现步骤
1) 定义变量记录左边和右边位置。
2) 使用while循环控制二分查询(条件是左边位置<=右边位置)
3) 循环内部获取中间元素索引
4) 判断当前要找的元素如果大于中间元素,左边位置=中间索引+1
5) 判断当前要找的元素如果小于中间元素,右边位置=中间索引-1
6) 判断当前要找的元素如果等于中间元素,返回当前中间元素索引。
3.3.4 代码实现
public static int myBinarySearch(int[] arr, int num) {
//我们首先应该要有两个索引,代表 左边的索引, 以及 右边的索引
int left = 0;
int right = arr.length - 1;
while (left <= right) {
//开始去找中间的索引 = (左边索引 + 右边的索引) / 2
int mid = (left + right) / 2;
//我们用中间索引的元素和 num 进行比较
if (arr[mid] == num) {
// 如果中间元素 和 num 值相等,直接返回索引。代表找到
return mid;
} else if (arr[mid] > num) {
// 中间的元素 > num 大, 改变右边的索引 = 中间索引 - 1
right = mid - 1;
} else if (arr[mid] < num) {
// 中间的元素 < num 小, 改变左边的索引 = 中间索引 + 1
left = mid + 1;
}
}
//返回一个负数 代表找不到
return -1;
}
4 正则表达式
4.1 概念
用来校验数据格式是否合法
4.2 作用
1) 用来校验数据格式是否合法
2) 在一段文本中查找满足要求的内容
4.3 正则规则
4.3.1 字符类【匹配一个字符】
[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到z,除了b和c(等同于[ad-z])
[a-z&&[ ^m-p]] : a到z,除了m到p(等同于[a-lq-z]
4.3.2 预定义字符(只匹配单个字符)
. 任何字符
\d 一个数字: [0-9]
\D 非数字: [ ^0-9]
\s 一个空白字符:
\S 非空白字符: [ ^\s]
\w [a-zA-Z_0-9]
\W [ ^\w] 一个非单词字符
4.3.3 数量词
X? X , 一次或0次
X* X,零次或多次
X+ X , 一次或多次
X {n} X,正好n次
X {n, } X,至少n次
X {n,m} X,至少n但不超过m次
4.3.4 分割/爬取数据
import java.util.Arrays;
public class Demo04 {
public static void main(String[] args) {
String str = "张三asdasdasdasd18dasdasdadasd广州市";
// 把所有的按照分段方式,替换为一个 "," ==> 张三,18,广州
String result = str.replaceAll("[a-z]{1,}", ",");
System.out.println(result);
// 把上面的字符串中个人信息分割出来
String[] ss = str.split("[a-z]{1,}");
System.out.println(Arrays.toString(ss)); // [张三, 18, 广州市]
}
}
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Demo03 {
/*
信息爬取
*/
public static void main(String[] args) {
String data = "来黑马程序员学习Java," +
"电话:18512516758,18512508907" +
"或者联系邮箱:boniu@itcast.com.cn" +
"座机电话:01036517895,010-98951256" +
"邮箱:bozai@itcast.cn," +
"邮箱2:dlei0009@163.com," +
"热线电话:400-618-9090 ,400-618-4000," +
"4006184000,4006189090";
//请把下面文本中的电话,邮箱,座机号码,热线都爬取出来。
String regex = "(1[3-9]\\d{9})|(0\\d{2}-?[1-9]\\d{7})|(400-\\d{3}-\\d{4})|(400\\d{3}\\d{4})|([a-zA-Z0-9]{1,}@[a-zA-Z0-9]{2,8}(\\.[a-z]{2,3}){1,2})";
// 我们先要创建一个Pattern对象,用来封装正则
Pattern pattern = Pattern.compile(regex);
// 指定爬取的数据
Matcher matcher = pattern.matcher(data);
// 拿数据 ==> 1.先判断有没有数据 2.再去拿数据
while (matcher.find()){
String s = matcher.group();
System.out.println(s);
}
}
}