Java进阶2 排序查找与Lambda、正则表达式


排序查找与Lambda、正则表达式

  • ● 导图
  • 一、 基础算法
    • 1.排序
      • 1.1 冒泡排序
      • 1.2 选择排序
    • 2. 查找
      • 2.1 基础查找
      • 2.2 二分查找
  • 二、Lambda表达式
    • 1)初识Lambda
    • 2)函数式编程
    • 3).Lambda表达式的标准格式
    • 4)Lambda的注意事项
    • 5)Lambda表达式的省略写法
    • 6)Lambda表达式简化Comparator接口的匿名形式
    • Lambda小结
  • 三、正则表达式
    • ● 正则表达式的使用


● 导图

在这里插入图片描述

一、 基础算法

1.排序

1.1 冒泡排序

冒泡排序: 相邻的数据两两比较,小的放前面,大的放后面。

核心思想:

  1. 相邻的元素两两比较,大的放右边,小的放左边。
  2. 第一轮比较完毕之后,最大值就已经确定,第二轮可以少循环一次,后面以此类推。
  3. 如果数组中有n个数据,总共我们只需要执行n - 1 轮的代码就可以。

冒泡排序的应用

现在有一个数组:{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 4
                if (arr[j] > arr[j + 1]){
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

1.2 选择排序

选择排序:从0索引开始,拿着每一个索引上的元素跟后面的元素依次比较,小的放前面,大的放后面,以此类推。

选择排序的实现:

  1. 从0索引开始,跟后面的元素一一比较。
  2. 小的放前面,大的放后面。
  3. 第一轮循环结束后,最小的数据已经确定。
  4. 第二轮循环从1索引开始以此类推。
  5. 第三轮循环从2索引开始以此类推。
  6. 第四轮循环从3所以开始以此类推。

选择排序的应用

还是以冒泡排序的题为例子:有一个数组:{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;
                }
            }
        }
    }


2. 查找

2.1 基础查找

从索引值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索引开始一个一个往后找,但是如果元素比较多,需要查找的元素比较靠后的话,这样查找的此处就比较多。性能比较差

2.2 二分查找

二分查找的主要特点是,每次查找能排除一半元素,这样效率明显提高。但是二分查找要求比较苛刻,它要求元素必须是有序的,否则不能进行二分查找。

现在有如下一个需求:

定义一个方法利用二分查找,查询某个元素在数组中的索引,数组如下: {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.二分查找的过程

  • min和max表示当前要查找的范围
  • mid是在min和max中间的
  • 如果要查找的元素在mid的左边,缩小范围时,min不变,max等于mid减1
  • 如果要查找的元素在mid的右边,缩小范围时,max不变,min等于mid加1
  • 如果要查找的元素恰好等于mid,那么就返回。

二、Lambda表达式

1)初识Lambda

以下有段代码,使用Arrays中的sort方法来对数组进行排序。

Integer[] arr = {2,3,4,1,5,7,8,9,6};

//使用匿名内部类来实现排序
Arrays.sort(arr,new Comparator<Integer>(){
	@Override
	public int compare(Integer o1,Integer o2){
		return o1 - o2;
	}
});

//使用Lambda表达式来优化这段代码
Arrays.sort(arr, (Integer o1 - Integer o2)->{
	return o1 - o2;
	}
);

2)函数式编程

面向对象:先找对象,让对象做事。
函数式编程:是一种思想特点。
函数式编程思想,是忽略面向对象的复杂语法, 强调做什么,而不是谁去做。 而Lambda表达式就是函数式思想的体现。

3).Lambda表达式的标准格式

() -> {

}
  • () 对应着方法的形参
  • -> 固定格式

4)Lambda的注意事项

  • Lambda表达式可以用来简化匿名内部类的书写
  • Lambda表达式只能简化函数式接口的匿名内部类的写法
  • 函数式接口: 有且仅有一个抽象方法的接口叫做函数式接口,接口上方可以加@Functionallnterface注解

5)Lambda表达式的省略写法

  • 参数类型可以省略不写
  • 如果只有一个参数,参数类型可以省略,同时()也可以省略
  • 如果Lambda表达式的方法只有一行,大括号,分号,return可以省略不写,注意:大括号,分号,return需要同时省略

6)Lambda表达式简化Comparator接口的匿名形式

看以下的一个需求:

定义数组并存储一些字符串,利用Arrays中的sort方法进行排序。

要求:

按照字符串的长度进行排序,短的在前面,长的再后面。(暂时不比较字符串里的内容)

代码实现

String[] arr = {"a","aaaa","aaa","aa"}

//如果要把数组中的数据按照指定的方式进行排序,就需要用到sort方法,而且要指定排序的规则

//匿名内部类解决
//Arrays.sort(arr,new Comparator<String>){
//	@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());

Lambda小结

1.Lambda的基本作用?

简化函数式接口的匿名内部类的写法。

2.Lambda表达式有什么使用前提?

必须是接口的匿名内部类,接口中只能有一个抽象方法。

3.Lambda的好处?

Lambda是一个匿名函数,我们可以把Lambda表达式理解为是一段可以传递的代码,它可以写出更简洁、更灵活的代码,作为一种更紧凑的代码风格,使java语言表达能力得到了提升。

三、正则表达式

正则表达式的规则

字符类(只匹配一个字符)

在这里插入图片描述
预定义字符(只匹配一个字符)

**加粗样式**
数量词

在这里插入图片描述

● 正则表达式的使用

字符类(只匹配一个字符)的使用

public static void main(String[] args) {
        //public boolean matches(String regex);判断是否与正则表达式匹配,匹配则返回true

        //只能是a b c
        System.out.println("-------1-------");
        System.out.println("a".matches("[abc]")); //true  //只能是abc中的一个
        System.out.println("z".matches("[abc]")); //false //z不属于abc
        System.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属于abc
        System.out.println("z".matches("[^abc]")); //true //z不属于abc
        System.out.println("zz".matches("[^abc]")); //false
        System.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-z
        System.out.println("z".matches("[a-zA-z]")); //true //z属于a-z
        System.out.println("aa".matches("[a-zA-z]")); //false //一个[]只能判断一个字符
        System.out.println("zz".matches("[a-zA-z]")); //false
        System.out.println("zz".matches("[a-zA-z][a-zA-Z]")); //true
        System.out.println("0".matches("[a-zA-z]")); //false
        System.out.println("0".matches("[a-zA-Z0-9]")); //true
        System.out.println("0".matches("[0-9]")); //true

        //[a-d[m-p]] a到d,或m到p
        System.out.println("-------4-------");
        System.out.println("a".matches("[a-d[m-p]]")); //true
        System.out.println("d".matches("[a-d[m-p]]")); //true
        System.out.println("m".matches("[a-d[m-p]]")); //true
        System.out.println("p".matches("[a-d[m-p]]")); //true
        System.out.println("e".matches("[a-d[m-p]]")); //false
        System.out.println("0".matches("[a-d[m-p]]")); //false

        //[a-z &&[def]] a-z和def的交集,为:d,e,f
        System.out.println("-------5-------");
        System.out.println("a".matches("[a-z &&[def]]")); //false
        System.out.println("d".matches("[a-z &&[def]]")); //true
        System.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]]")); //true
        System.out.println("b".matches("[a-z &&[^bc]]")); //flase
        System.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]]")); //true
        System.out.println("m".matches("[a-z &&[^m-p]]")); //false
        System.out.println("0".matches("[a-z &&[^m-p]]")); //false
}

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

使用预定义字符正则表达式的时候,先要注意几个点:

  1. 在Java中,\代表转义字符,意义为:改变后面那个字符原本的含义。
  2. " 在Java中表示字符串的开头或者结尾。
  3. "\连用成:\",此时 \ 表示转义字符,改变了后面那个双引号原本的含义,把它变成了一个普普通通的双引号。
  4. 而在Java中想要表示\,则需要在\前再加上一个反斜杠,:\\,改变后面\原本的含义,把它变成一个普普通通的\

预定义字符的使用

public static void main(String[] args) {
        // .表示任意一个字符
        System.out.println("你".matches("..")); //false
        System.out.println("你a".matches(".."));//true

        // \\d只能是任意的一位数字
        //简单来记:\\ 表示 \
        System.out.println("a".matches("\\d")); //false
        System.out.println("3".matches("\\d")); //true
        System.out.println("333".matches("\\d")); //false

        // \\w只能是一位单词字符 [a-zA-Z_0-9]
        System.out.println("z".matches("\\w")); //true
        System.out.println("2".matches("\\w")); //true
        System.out.println("21".matches("\\w\\w")); //true
        System.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,}")); //true
        System.out.println("244f".matches("\\w{6,}")); //false

        //必须是数字和字符 必须是4位
        System.out.println("23dF".matches("[a-zA-Z0-9]{4}")); //true
        System.out.println("23_F".matches("[a-zA-Z0-9]{4}")); //false
        System.out.println("23dF".matches("[\\w &&[^_]]{4}")); //true
        System.out.println("23_F".matches("[\\w &&[^_]]{4}")); //false
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

k8s 1.18.20版本部署

身为k8s初学者&#xff0c;在掌握k8s理论知识的同时&#xff0c;也需要掌握一下实际部署k8s的过程&#xff0c;对于理论的学习起到一定的帮助作用。罗列了一下相关步骤&#xff0c;请各位参考&#xff1a; 一、环境准备 三台虚机&#xff1a; 操作系统&#xff1a; CentOS L…

【计算机组成原理 - 第二章】系统总线(完结)

本章参考王道考研相关课程&#xff1a; 【2019版】6.1.1 总线的概念与分类_哔哩哔哩_bilibili 【2019版】6.1.2 总线的性能指标_哔哩哔哩_bilibili 【2019版】6.2 总线仲裁_哔哩哔哩_bilibili 【2019版】6.3 总线操作和定时_哔哩哔哩_bilibili 【2019版】6.4 总线标准_哔哩哔哩…

Mac 和 Win,到底用哪个系统学编程?

今天来聊一个老生常谈的问题&#xff0c;学编程时到底选择什么操作系统&#xff1f;Mac、Windows&#xff0c;还是别的什么。。 作为一个每种操作系统都用过很多年的程序员&#xff0c;我会结合我自己的经历来给大家一些参考和建议。 接下来先分别聊聊每种操作系统的优点和不…

springCloud学习【2】之Nacnos配置管理Fegin远程调用gateway服务网关

文章目录前言一 Nacos配置管理1.1 统一配置管理1.1.1 nacos中添加配置文件1.1.2 从微服务拉取配置1.2 配置热更新1.2.1 方式一&#xff1a;添加注解RefreshScope1.2.2 方式二&#xff1a;使用ConfigurationProperties注解1.3 配置共享二 搭建Nacos集群2.1 集群结构图2.2 搭建集…

【函数】JavaScript 全栈体系(七)

JavaScript 基础 第十三章 函数 一、为什么需要函数 函数&#xff1a; function&#xff0c;是被设计为执行特定任务的代码块 说明&#xff1a; 函数可以把具有相同或相似逻辑的代码“包裹”起来&#xff0c;通过函数调用执行这些被“包裹”的代码逻辑&#xff0c;这么做…

cv2报错:Unsupported depth of input image

cv2 报错 error: OpenCV(4.6.0) /io/opencv/modules/imgproc/src/color.simd_helpers.hpp:94: error: (-2:Unspecified error) in function ‘cv::impl::{anonymous}::CvtHelper<VScn, VDcn, VDepth, sizePolicy>::CvtHelper(cv::InputArray, cv::OutputArray, int) [wit…

vue后台管理系统——添加i18n国际化功能——技能提升

昨天在写后台管理系统时&#xff0c;遇到一个需求就是需要实现国际化功能。 antd和element-ui这两个框架其实都是有国际化的。 具体展示形式就是如下&#xff1a; 点击右上角头部的语言&#xff0c;切换语言&#xff0c;然后整个系统的文字都改变成对应的语言展示。 切换成…

燕山大学-面向对象程序设计实验-实验7 多态性:函数与运算符重载-实验报告

CSDN的各位友友们你们好,今天千泽为大家带来的是燕山大学-面向对象程序设计实验-实验5 派生与继承&#xff1a;单重派生-实验报告,接下来让我们一起进入c的神奇小世界吧,相信看完你也能写出自己的 实验报告!本系列文章收录在专栏 燕山大学面向对象设计报告中 ,您可以在专栏中找…

【C语言进阶】内存函数

天生我材必有用&#xff0c;千金散尽还复来。 ——李白 目录 前言 一.memcpy函数 ​1.实现memcpy函数 2.模拟实现memcpy函数 二.memmove函数 1.实现memmove函数 2.模拟实现memmove函数 三.memcpy函数和memmove函数的关系 四.memcm…

2023金三银四--我们遇到的那些软件测试面试题【功能/接口/自动化/性能等等】

一、面试技巧题(主观题) 序号面试题1怎么能在技术没有那么合格的前提下给面试官留个好印象&#xff1f;2面试时&#xff0c;如何巧妙地避开不会的问题&#xff1f;面试遇到自己不会的问题如何机智的接话&#xff0c;化被动为主动&#xff1f;3对于了解程度的技能&#xff0c;被…

【Docker】什么是Docker?Docker的安装、加速

文章目录Docker出现的背景解决问题docker理念容器与虚拟机比较容器发展简史传统虚拟机技术容器虚拟化技术Docker安装官方网站安装前提Docker的基本组成镜像容器仓库Docker平台架构图解CentOS7安装Docker确定你是CentOS7及以上版本卸载旧版本yum安装gcc相关安装需要的软件包设置…

用 ChatGPT 辅助学好机器学习

文章目录一、前言二、主要内容&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、前言 探索更高效的学习方法可能是有志者共同的追求&#xff0c;用好 ChatGPT&#xff0c;先行于未来。 作为一个人工智能大语言模型&#xff0c;ChatGPT 可以在帮助初…

Pandas 与 PySpark 强强联手,功能与速度齐飞

Pandas做数据处理可以说是yyds&#xff01;而它的缺点也是非常明显&#xff0c;Pandas 只能单机处理&#xff0c;它不能随数据量线性伸缩。例如&#xff0c;如果 pandas 试图读取的数据集大于一台机器的可用内存&#xff0c;则会因内存不足而失败。 另外 pandas 在处理大型数据…

Linux分文件编程:静态库与动态库的生成和使用

目录 一&#xff0c;Linux库引入之分文件编程 ① 简单说明 ② 分文件编程优点 ③ 操作逻辑 ④ 代码实现说明 二&#xff0c;Linux库的基本说明 三&#xff0c;Linux库之静态库的生成与使用 ① 静态库命名规则 ② 静态库制作步骤 ③ 静态库的使用 四&#xff0c;Linu…

django-celery-beat搭建定时任务

一、创建django项目和app 1、安装定时任务第三方包 pip install django-celery-beat # 插件用来动态配置定时任务,一般会配合 django_celery_results 一起使用&#xff0c;所以一起安装 django_celery_results pip install django_celery_results pip install eventlet # win…

Keil MDK6要来了,将嵌入式软件开发水平带到新高度,支持跨平台(2023-03-11)

注&#xff1a;这个是MDK6&#xff0c;不是MDK5 AC6&#xff0c;属于下一代MDK视频版&#xff1a; https://www.bilibili.com/video/BV16s4y157WF Keil MDK6要来了&#xff0c;将嵌入式软件开发水平带到新高度&#xff0c;支持跨平台一年一度的全球顶级嵌入式会展Embedded Wor…

操作系统(1.3)--习题

一、课堂习题 1、一个作业第一 次执行时用了5min ,而第二次执行时用了6min,这说明了操作系统的( )特点。 A、并发性 B、共享性 C、虚拟性 D、不确定性 D 2、在计算机系统中,操作系统是( )。 A、处于裸机之上的第一层软件 B、处于硬件之下的低层软件 C、处于应用软件之上的系统软…

对象的创建以及数组中常见的属性与方法

&#xff08;一&#xff09;对象创建的三种方法 1、利用对象字面量创建对象 const obj{ name:小开心 } 2、利用new Object创建对象 const obj1new Object({ name:小开心 }) 3、利用构造函数创建对象 构造函数&#xff1a;是一种特殊的函数&#xff0c;主要用来初始化对象&…

Vector的扩容机制

到需要扩容的时候&#xff0c;Vector会根据需要的大小&#xff0c;创建一个新数组&#xff0c;然后把旧数组的元素复制进新数组。 我们可以看到&#xff0c;扩容后&#xff0c;其实是一个新数组&#xff0c;内部元素的地址已经改变了。所以扩容之后&#xff0c;原先的迭代器会…

【Spring事务】声明式事务 使用详解

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ 声明式事务一、编程式事务二、声明式事务&…