使用Stream流完成并集、交集和差集
使用Stream流完成并集、交集和差集
一、介绍
本文将进行介绍使用Stream流的方式,来完成对象集合的并集、交集和差集。
二、代码
先建立一个User.java,一会使用它来创建集合,并重写了它的equals方法
12345678910111213141516171819202122232425262728293031323334package com.banmoon.test;import lombok.AllArgsConstructor;import lombok.Data;import java.util.Objects;/** * @author banmoon */@Data@AllArgsConstructorpublic class User { private Integer id; private String name; @Override public boolean equals(Object o) { if (this == o) return true; if ...
稀疏数组
稀疏数组
一、介绍
稀疏数组可以看作是普通数组的压缩,当一个数组中大部分元素为0或同一个值时,可用稀疏数组来保存该数组。
由此可以发现,当一个数组上出现大量无用的数组时,我们可以使用一些方法将其压缩成稀疏数组进行存储,等到使用的时候再进行解压还原。
最经典的案例便是五子棋了,如果要实现退回,保存当前五子棋进度,加载五子棋进度的时候,原先的数组就会显得臃肿,这时候稀疏数组就可以派上用场了。
稀疏数组的压缩方法:
记录原数组的大小,几行几列,以及有多少个不同的值
记录原数组不同的值的行数和列数,将其保存在一个小的数组之中
二、实现
1)思路分析
如果原始数组是11*11的一个二维数组,里面的有效值个数有三个,
那么转为稀疏数组后,将会变成一个4*3的稀疏数组。
如下图所示
转换前
转换后
那么转换后的稀疏数组代表着什么呢,如下图所示
由此可以分析出来,将二维数组转换成为稀疏数组只需要这么几步就可以成功。
遍历原数组,得到原数组中有效值的个数num
创建一个稀疏数组,大小为(num+1)*3
稀疏数组的第0行存放,原数组的行个数,列个数,以及 ...
openfeign的几种调用方式
openfeign的几种调用方式
一、介绍
先上openfeign的maven依赖,这边注册中心用的是nacos,具体版本看自己的需求
123456789<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2.2.2.RELEASE</version></dependency>
二、示例代码
1)客户端
1234567891011121314 ...
二叉树详解
二叉树详解
一、开始
什么是树,什么又是二叉树?我知道大家都听过,但对于具体的概念,应该还是比较模糊的吧?
一起来看看,什么是树,什么又是二叉树!
二、概念
1)树结构概念
树是一种数据结构,它是由节点相连,带来的一个层次结构的数据集合,且除了根节点以外,其余节点有且只有一个父节点。
与链表不同的是,树的连接关系往往是一对多的关系。
树结构通常表现为下图方式
子节点:一个节点指向下一个节点时,下个节点是上个节点的子节点。上图A节点的子节点是B节点和C节点
父节点、双亲节点:一个节点指向下一个节点时,下个节点是上个节点的子节点。上图B节点的父节点是A节点
兄弟节点:拥有同一个父节点的两个节点,互为兄弟节点。上图如D节点和E节点互为兄弟节点
节点的度:拥有子节点的数量称为节点的度。如D节点的度为3,C节点的度为2
节点的权:代表节点中存的对象。如D节点代表存了D字符
根节点:一颗树最开始的节点,被称为根节点。上图为A节点
叶子节点:没有子节点的节点,也就是度为0的节点。上图为H节点、E节点、F节点等
内部节点、枝节点:除了根节点和叶子节点以外的节点。如B节 ...
排序算法之堆排序
排序算法之堆排序
一、介绍
由于堆排序与以前的排序都不太一样,他是基于顺序存储的二叉树结构来进行的排序,故此拉出来单独做了一张。
以前的排序算法传送门
二、概念
在开始编码之前,我们先要理解下面两个概念
1)顺序存储的二叉树
对于任意一个数组,它都可以转换为一个完全二叉树
如下图,平铺着转换就可以了
对于一个顺序存储的二叉树,它的节点连接定义如下
下标N的左节点:2n+12n+12n+1
下标N的右节点:2n+22n+22n+2
下标N的父节点:n−12\frac{n-1}{2}2n−1
2)大小顶堆
什么是大顶堆,就是父节点永远都比子节点的数要大,故名为大顶堆。如下图
相反,如果一颗二叉树的父节点都比子节点的数要小,那么它就是小顶堆。如下图
三、代码
简单的来说,堆排序就是将持续的将,一个顺序存储的二叉树变成大顶堆或者小顶堆。
升序使用大顶堆,降序使用小顶堆。
步骤如下,这是第一步
从非叶子节点开始前遍历
每一个非叶子节点,都将和自己的左节点、右节点进行判断
根据大小顶堆的需要,来进行替换
直到称为一个大小顶堆
成为了大小顶堆之后,我们将得到了一个最大或者 ...
汉诺塔问题
汉诺塔问题
一、介绍
汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。
大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。介绍来源于百度知道。
我小时候也玩过,但当时就是云里雾里的,不知道怎么去解题,简单的可以完成,难的就不行了。
到了现在,如何用代码解题,依旧是一个不小的难度,反正我是得琢磨一会。
二、解题思路
有三根柱子,分别是起始的柱子,辅助的柱子,目标的柱子,我们需要将圆盘从开始移动到目标。
但由于汉诺塔的这项规则,在小圆盘上不能放大圆盘上,我们就可以将其分为两部分,分为上面一部分,下面一部分。
下面一部分永远比上面一部分要大,所以需要先将上面这一部分移动到辅助的位置。
当上面这部分有多个时,照样看成上下两部分,上面部分移动到辅助位置(最开始的目标位置,现在变成了辅助位置)
如此重复执行,直到完成所有的迁移。
大家可以先试试这个小游戏,找找灵感
代码如下,主要 ...
MySQL触发器详解
MySQL触发器详解
一、介绍
大家应该都听过MySQL的触发器,它的概念如下
它是一种特殊的一种存储过程,当表数据发生了新增、更新、删除时,便触发这个存储过程。
由此,故而名为触发器。下面一起来看看触发器的使用吧!
二、语法
1)语法格式
1234567891011121314-- 删除drop trigger 触发器名;-- 定义结束符号delimiter $$-- 创建create trigger 触发器名 before|after insert|update|delete on 表名 for each rowbegin 执行语句end$$-- 定义结束符号delimiter ;
触发事件类型
insert:有数据新增时触发
update:有数据被修改时触发
delete:有数据被删除时触发
执行顺序
before:在触发事件前执行语句
after:在触发事件后执行语句
在执行语句中,和正常的存储过程差不多,不过触发器多了两个存储过程没有的对象,分别是NEW和OLD;
OLD:代表着更新,删除前的数据,可以通过OLD.字段名来获取以前的值
NEW:代表着新增 ...
SpringBoot中使用注解读取redis缓存
SpringBoot中使用注解读取redis缓存
一、介绍
我们使用redis的时候,一般都是以下这个步骤
查询指定的redis缓存
如果有直接返回,(异步执行查询,更新redis缓存)
如果没有则执行查询,(同时设置redis缓存)
此外,如果是增删改操作,将触发一次设置redis缓存的操作。
上面的一些步骤高度重复,我决定造个轮子,基于注解、切面和反射来完成此项功能。
二、相关代码
1)依赖
处于SpringBoot中,redis、aop等相关依赖不要忘记
123456789101112<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency><dependency> <groupId>org.springframework.boot</groupId> < ...
SpringBoot中的@Conditional注解
SpringBoot中的@Conditional注解
一、介绍
在Spring的应用下,我们希望一些bean可以通过一些条件来判断是否需要实例化,并加载到spring容器中。
所以,@Conditional注解就是为了解决上面这个需求而制定的注解。@Conditional注解是总接口,可以定制逻辑。
二、详情
1)@Conditional
先看源码,此注解需要传入Condition接口的实现类,可以多个
12345678@Target({ElementType.TYPE, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Conditional { Class<? extends Condition>[] value(); }
所以,使用此注解时,我们若是有些高度定制化的一些判断,可以先实现Condition接口,再讲实现类提供给@Conditional注解,使用示例如下。
首先要有一个Condition ...
Java使用NIO实现Socket通信
Java使用NIO实现Socket通信
一、介绍
在上次的博客中,已经了解到NIO当中最为重要的两个对象。分别是缓冲Buffer和通道Channel,也进行了基本的使用,不过使用的是FileChannel,主要用来与文件打交道。
那么,这一次使用NIO实现Socket网络通信,主要是使用到ServerSocketChannel和SocketChannel。
同样,在本次作为NIO的网络通信,建议先了解传统BIO的网络通信,传送门在此。
二、实现
1)服务端
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475package com.banmoon.test;import lombok.extern.slf4j.Slf4j;import java.io.IOException;import java.net.InetSocketAddress;import ja ...