Java之函数式接口
函数式接口只包含一个抽象方法的接口,称为函数式接口。
你可以通过 Lambda 表达式来创建该接口的对象。(若 Lambda 表达式抛出一个受检异常(即:非运行时异常),那么该异常需要在目标接口的抽象方法上进行声明)。
我们可以在一个接口上使用 @FunctionalInterface注解,这样做可以检查它是否是一个函数式接口。同时 javadoc 也会包含一条声明,说明这个接口是一个函数式接口。
在java.util.function包下定义了Java 8 的丰富的函数式接口
我们查看Comparator接口源码。发现了一些矛盾的地方。
我们发现了该接口中不止包含了一个方法,还存在大量的default和static方法。这和上文的定义是矛盾的!!
在jdk8之前,interface之中可以定义变量和方法,变量必须是public、static、final的,方法必须是public、abstract的。由于这些修饰符都是默认的,JDK8及以后,允许我们在接口中定义static方法和default方法。
JDK8接口中的静态方法和默认方法,都不算是抽象方法。。接口默认继承java.l ...
Java之Lambda表达式
简介Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。使用它可以写出更简洁、更 灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了 提升。
使用条件该类为函数式接口
语法Lambda 表达式:在Java 8 语言中引入的一种新的语法元素和操 作符。这个操作符为 “->” , 该操作符被称为 Lambda 操作符 或箭头操作符。它将 Lambda 分为两个部分:
左侧:指定了 Lambda 表达式需要的参数列表
右侧:指定了 Lambda 体,是抽象方法的实现逻辑,也即 Lambda 表达式要执行的功能。
1234567891011121314151617181920//语法格式一:无参,无返回值Runnable r1 = ()->{ System.out.println("Hello Lambda!"); };//语法格式二:Lambda 需要一个参数,但是没有返回值。Consumer<String> con1 = (Str ...
JUC并发编程
JUC介绍在 java 5.0 提供了 java.util.concurrent (简称JUC )包,在此包中增加了在并发编程中很常用的实用工具类,用于定义类似于线程的自定义子系统,包括线程池、异步 IO 和轻量级任务框架。提供可调的、灵活的线程池。还提供了设计用于多线程上下文中的 Collection 实现等。
程序进程线程
在操作系统中运行的程序就是进程。一个进程可以有多个线程,如视频中同时听声音,看图像,看弹幕等等。
程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念。
进程则是执行程序的一次执行过程,是一个动态的概念。是系统资源分配的单位。通常一个进程中可以包含若干个线程,一个进程中至少有一个线程(main线程)。线程是CPU调度和执行的单位。
线程状态在java中查看Thread.State可知线程的状态
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364public ...
SpringBoot整合RabbitMQ
环境搭建创建一个SpringBoot项目rabbitmq_springboot
可以选择导入依赖
也可以使用坐标导入依赖
1234<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId></dependency>
配置文件配置RabbitMQ
123456789spring: application: name: rabbitmq-springboot rabbitmq: host: localhost port: 5672 username: ems password: 123 virtual-host: /ems
Hello World 模型生产者在测试类中注入RabbitMQTemplate,使用convertAndSend()方法
1234567891011121314@SpringBootT ...
RabbitMQ五种消息模型
RabbitMQ支持的消息模型https://www.rabbitmq.com/getstarted.html
环境搭建创建一个Maven项目导入RabbitMQ依赖
123456<!--引入rabbitmq--><dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client</artifactId> <version>5.7.2</version></dependency>
创建ems用户,密码为123,创建VirtualHost /ems
Hello World 模型
在上图的模型中,有以下概念:
P:生产者,也就是要发送消息的程序
C:消费者:消息的接受者,会一直等待消息到来。
queue:消息队列,图中红色部分。类似一个邮箱,可以缓存消息;生产者向其中投递消息,消费者从其中取出消息。
生产者创建生产者Provider类,通过连接工厂对象获取连接,创建通道channel
...
LeetCode链表题解
面试题 02.03. 删除中间节点
可以删除链表至少为二的头节点,不能删除尾节点。
237. 删除链表中的节点
这与上题一摸一样。。
160. 相交链表
要求时间复杂度为 O(N),空间复杂度为 O(1)。如果不存在交点则返回 null。
设 A 的长度为 a + c,B 的长度为 b + c,其中 c 为尾部公共部分长度,可知 a + c + b = b + c + a。
当访问 A 链表的指针访问到链表尾部时,令它从链表 B 的头部开始访问链表 B;同样地,当访问 B 链表的指针访问到链表尾部时,令它从链表 A 的头部开始访问链表 A。这样就能控制访问 A 和 B 两个链表的指针能同时访问到交点。
如果不存在交点,那么 a + b = b + a,以下实现代码中 l1 和 l2 会同时为 null,从而退出循环。
21. 合并两个有序链表
思路很简单,创建一个新的节点,while循环遍历l1和l2并且比较大小,谁小添加谁。按照题意如果某一条链表先遍历完了,另一条没有遍历完成,那么剩下的直接添加就行。最后返回头节点head.next
也可以使用迭代。
数据结构之双向链表
简介双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
单向链表与双向链表单向链表,查找的方向只能是一个方向,而双向链 表可以向前或者向后查找。也就是可以直接从逆序遍历
单向链表不能自我删除,需要靠辅助节点 ,而双向 链表,则可以自我删除不需要借助其他节点,而前面我们单链表删除时节点,总是找到temp,temp是待删除节点的前一个节点。
单链表删除节点
双向链表删除节点
代码实现这和单链表没啥大区别。不过是多了个直接前驱指针。同样是上文单链表的例子,也定义了一个单独的头节点。
节点初始化12345678910111213141516171819202122// 定义HeroNode2 , 每个HeroNode 对象就是一个节点class HeroNode2 { public int no; public String name; public String nickname; public Her ...
数据结构之单链表
简介概念介绍单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
以“结点的序列”表示线性表称作线性链表(单链表),单链表是链式存取的结构。
链接存储方法链接方式存储的线性表简称为链表(Linked List)。
链表的具体存储表示为:
① 用一组任意的存储单元来存放线性表的结点(这组存储单元既可以是连续的,也可以是不连续的)
② 链表中结点的逻辑次序和物理次序不一定相同。为了能正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其后继结点的地址(或位置)信息(称为指针(pointer)或链(link))
链式存储是最常用的存储方式之一,它不仅可用来表示线性表,而且可用来表示各种非线性的数据结构。
结点结构┌───┬───┐
│ data│next |
└───┴───┘
data域–存放结点值的数据域
next域–存放结点的直接后继的地址(位置)的指针域(链域)
链表通过每个 ...
数据结构之队列
简介队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。
顺序队列建立顺序队列结构必须为其静态分配或动态申请一片连续的存储空间,并设置两个指针进行管理。一个是队头指针front,它指向队头元素;另一个是队尾指针rear,它指向下一个入队元素的存储位置。
每次在队尾插入一个元素是,rear增1;每次在队头删除一个元素时,front增1。随着插入和删除操作的进行,队列元素的个数不断变化,队列所占的存储空间也在为队列结构所分配的连续空间中移动。当front=rear时,队列中没有任何元素,称为空队列。当rear增加到指向分配的连续空间之外时,队 ...
数据结构之稀疏数组
介绍当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方法是:
1)记录数组一共有几行几列,有多少个不同的值
2)把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
二维数组
索引
0
1
2
3
4
5
6
0
0
0
0
22
0
0
15
1
0
11
0
0
0
17
0
2
0
0
0
-6
0
0
0
3
0
0
0
0
0
39
0
4
91
0
0
0
0
0
0
5
0
0
28
0
0
0
0
稀疏数组
行(row)
列(col)
值(value)
[0]
6
7
8
[1]
0
3
22
[2]
0
6
15
[3]
1
1
11
[4]
1
15
17
[5]
2
3
-6
[6]
3
5
39
[7]
4
0
91
[8]
5
2
28
第一行记录原二维数组的大小,和拥有值的个数
应用实例使用稀疏数组,来保留类似前面的二维数组(棋盘、地图等等),把稀疏数组存盘,并且可以从新恢复原来的二维数组数。(棋盘保存复 ...