冒泡排序: 相邻的数据两两比较,小的放前面,大的放后面。
核心思想:
冒泡排序的应用
现在有一个数组:{2,4,5,3,1};想从小到大排序,这里就可以使用冒泡排序。
代码实现
public static void main(String[] args) {//1.定义数组int[] arr = {2,4,5,3,1};//2.利用冒泡排序将数组中的数据变成 1 2 3 4 5//外循环:表示要执行多少轮,如果有n个数据,那么就执行 n - 1 轮。for (int i = 0; i < arr.length - 1; i++) {//内循环:每一轮循环中比较数据并找到当前的最大值//-1:为了防止索引越界//-i:提高效率,每一轮执行的次数应该比上一轮少一次。for (int j = 0; j < arr.length - 1 - i; j++) {//i 依次表示数组中的每一个索引:0 1 2 3 4if (arr[j] > arr[j + 1]){int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}}
选择排序:从0索引开始,拿着每一个索引上的元素跟后面的元素依次比较,小的放前面,大的放后面,以此类推。
选择排序的实现:
选择排序的应用
还是以冒泡排序的题为例子:有一个数组:{2,4,5,3,1};想从小到大排序。
代码实现
public static void main(String[] args) {//1.定义数组int[] arr = {2,4,5,3,1};//外循环:表示循环几轮//i:表示这一轮中,拿着i索引上的数据跟后面的元素进行比较并交换for (int i = 0; i < arr.length - 1; i++) {//内循环:每一轮拿着i跟i后面的数据进行比较交换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;}}}}
从索引值0开始挨个往后查找,若查到想要的元素值,则停止。
public static void main(String[] args) {int[] arr = {131,127,147,81,103,23,7,79};find(arr,127);}public static int find(int[] arr,int num){for (int i = 0; i < arr.length; i++) {if(num == arr[i]){System.out.println("索引值为:"+i);return 1;}}System.out.println("没有查找到该元素");return 0;}
假设我们要查找的元素是79,如果是基本查找的话,只能从0索引开始一个一个往后找,但是如果元素比较多,需要查找的元素比较靠后的话,这样查找的此处就比较多。性能比较差
二分查找的主要特点是,每次查找能排除一半元素,这样效率明显提高。但是二分查找要求比较苛刻,它要求元素必须是有序的,否则不能进行二分查找。
现在有如下一个需求:
定义一个方法利用二分查找,查询某个元素在数组中的索引,数组如下: {7,23,79,81,103,127,131,147}
代码实现
public static void main(String[] args) {int[] arr = {7,23,79,81,103,127,131,147};System.out.println("查找元素的索引为:"+Index(arr,131));;}public static int Index(int[] arr,int num){//1.定义两个变量记录查找范围int max = arr.length-1;int min = 0;//2.利用循环不断地去找要查找的数据while (true) {if(min > max){return - 1;}//3.找到min和max的中间值int mid = (max + min) / 2;//4.拿着mid指向的元素跟要查找的元素进行比较if(arr[mid] > num){//4.1 num在mid的左边//min不变,max = mid -1;max = mid - 1;}else if(arr[mid] < num){//4.2 num在mid的右边//max不变,min = mid + 1;min = mid + 1;}else{return mid;}}}
二分查找小结:
1.二分查找的优势。
提高查找效率
2.二分查找的前提条件。
数据必须是有序的,如果数据是乱的,先排序再用二分查找得到的索引就没有实际意义,只能确定当前数字在数组中是否存在,因为排序后数字的位置可能会发生改变。
3.二分查找的过程
以下有段代码,使用Arrays中的sort方法来对数组进行排序。
Integer[] arr = {2,3,4,1,5,7,8,9,6};//使用匿名内部类来实现排序
Arrays.sort(arr,new Comparator(){@Overridepublic int compare(Integer o1,Integer o2){return o1 - o2;}
});//使用Lambda表达式来优化这段代码
Arrays.sort(arr, (Integer o1 - Integer o2)->{return o1 - o2;}
);
面向对象:先找对象,让对象做事。
函数式编程:是一种思想特点。
函数式编程思想,是忽略面向对象的复杂语法, 强调做什么,而不是谁去做。 而Lambda表达式就是函数式思想的体现。
() -> {}
看以下的一个需求:
定义数组并存储一些字符串,利用Arrays中的sort方法进行排序。
要求:
按照字符串的长度进行排序,短的在前面,长的再后面。(暂时不比较字符串里的内容)
代码实现
String[] arr = {"a","aaaa","aaa","aa"}//如果要把数组中的数据按照指定的方式进行排序,就需要用到sort方法,而且要指定排序的规则//匿名内部类解决
//Arrays.sort(arr,new Comparator){
// @Override
// public int comapre(String o1,String o2){
// //字符串的长度进行排序
// return o1.length() - o2.length();
// }
//});//打印
System.out.println(Arrays.toString(arr));//Lambda完整格式
Arrays.sort(arr,(String o1,String o2)->{return o1.length() - o2.length();}
);//Lambda简写格式
//小括号:数据类型可以省略,如果参数只有一个,小括号可以省略
//大括号:如果方法体只有一行,return 分号,大括号都可以省略
Arrays.sort(arr,(o1,o2) -> o1.length()-o2.length());
1.Lambda的基本作用?
简化函数式接口的匿名内部类的写法。
2.Lambda表达式有什么使用前提?
必须是接口的匿名内部类,接口中只能有一个抽象方法。
3.Lambda的好处?
Lambda是一个匿名函数,我们可以把Lambda表达式理解为是一段可以传递的代码,它可以写出更简洁、更灵活的代码,作为一种更紧凑的代码风格,使java语言表达能力得到了提升。
正则表达式的规则
字符类(只匹配一个字符)
预定义字符(只匹配一个字符)
数量词
字符类(只匹配一个字符)的使用
public static void main(String[] args) {//public boolean matches(String regex);判断是否与正则表达式匹配,匹配则返回true//只能是a b cSystem.out.println("-------1-------");System.out.println("a".matches("[abc]")); //true //只能是abc中的一个System.out.println("z".matches("[abc]")); //false //z不属于abcSystem.out.println("ab".matches("[abc]"));//false //[]一个中括号只能判断一个字符System.out.println("ab".matches("[abc][abc]")); //true //两个[] 就可以判断两个字符//不能出现a b c(除abc外的其他值)System.out.println("-------2-------");System.out.println("a".matches("[^abc]")); //fase //a属于abcSystem.out.println("z".matches("[^abc]")); //true //z不属于abcSystem.out.println("zz".matches("[^abc]")); //falseSystem.out.println("zz".matches("[^abc][^abc]")); //true//a-z A-z(包括头尾的范围)System.out.println("-------3-------");System.out.println("a".matches("[a-zA-z]")); //true //a属于a-zSystem.out.println("z".matches("[a-zA-z]")); //true //z属于a-zSystem.out.println("aa".matches("[a-zA-z]")); //false //一个[]只能判断一个字符System.out.println("zz".matches("[a-zA-z]")); //falseSystem.out.println("zz".matches("[a-zA-z][a-zA-Z]")); //trueSystem.out.println("0".matches("[a-zA-z]")); //falseSystem.out.println("0".matches("[a-zA-Z0-9]")); //trueSystem.out.println("0".matches("[0-9]")); //true//[a-d[m-p]] a到d,或m到pSystem.out.println("-------4-------");System.out.println("a".matches("[a-d[m-p]]")); //trueSystem.out.println("d".matches("[a-d[m-p]]")); //trueSystem.out.println("m".matches("[a-d[m-p]]")); //trueSystem.out.println("p".matches("[a-d[m-p]]")); //trueSystem.out.println("e".matches("[a-d[m-p]]")); //falseSystem.out.println("0".matches("[a-d[m-p]]")); //false//[a-z &&[def]] a-z和def的交集,为:d,e,fSystem.out.println("-------5-------");System.out.println("a".matches("[a-z &&[def]]")); //falseSystem.out.println("d".matches("[a-z &&[def]]")); //trueSystem.out.println("0".matches("[a-z &&[def]]")); //false//注意:如果要求两个范围的交集,那么需要写符号 &&//如果写成了一个&,那么此时&表示就不是交集了,而是一个简简单单的&符号System.out.println("a".matches("[a-z &&[def]]")); //true//[a-z &&[^bc]] a-z和非bc的交集(等同于[ad-z])System.out.println("-------6-------");System.out.println("a".matches("[a-z &&[^bc]]")); //trueSystem.out.println("b".matches("[a-z &&[^bc]]")); //flaseSystem.out.println("0".matches("[a-z &&[^bc]]")); //false//[a-z &&[^m-p]] a-z 和 非m-p的交集(等同于[a-lq-z])System.out.println("-------7-------");System.out.println("a".matches("[a-z &&[^m-p]]")); //trueSystem.out.println("m".matches("[a-z &&[^m-p]]")); //falseSystem.out.println("0".matches("[a-z &&[^m-p]]")); //false
}
预定义字符(只匹配一个字符)
使用预定义字符正则表达式的时候,先要注意几个点:
\
代表转义字符,意义为:改变后面那个字符原本的含义。"
在Java中表示字符串的开头或者结尾。"
与\
连用成:\"
,此时 \
表示转义字符,改变了后面那个双引号原本的含义,把它变成了一个普普通通的双引号。\
,则需要在\
前再加上一个反斜杠,:\\
,改变后面\
原本的含义,把它变成一个普普通通的\
。预定义字符的使用
public static void main(String[] args) {// .表示任意一个字符System.out.println("你".matches("..")); //falseSystem.out.println("你a".matches(".."));//true// \\d只能是任意的一位数字//简单来记:\\ 表示 \System.out.println("a".matches("\\d")); //falseSystem.out.println("3".matches("\\d")); //trueSystem.out.println("333".matches("\\d")); //false// \\w只能是一位单词字符 [a-zA-Z_0-9]System.out.println("z".matches("\\w")); //trueSystem.out.println("2".matches("\\w")); //trueSystem.out.println("21".matches("\\w\\w")); //trueSystem.out.println("你".matches("\\w")); //false// \\W非单词字符System.out.println("你".matches("\\W")); //true
}
数量词
public static void main(String[] args) {//数量词: 必须都是数字、字母、下划线,至少6位System.out.println("2442fsfsf".matches("\\w{6,}")); //trueSystem.out.println("244f".matches("\\w{6,}")); //false//必须是数字和字符 必须是4位System.out.println("23dF".matches("[a-zA-Z0-9]{4}")); //trueSystem.out.println("23_F".matches("[a-zA-Z0-9]{4}")); //falseSystem.out.println("23dF".matches("[\\w &&[^_]]{4}")); //trueSystem.out.println("23_F".matches("[\\w &&[^_]]{4}")); //false
}