分类 Default 下的文章
Docsify使用文档上线啦~~
很久之前就用Docsify写过一篇java的文档(卒),过了一段时间后再想动手,发现已经不会用Docsify
现在网上使用的类似文档有很多:gitbook、书栈、看云等等,之所以选了Docsify,也是之前学习Vue才知道有这东西,认真看了下,也还不错。
仅仅是为了记录和复习一下,毕竟-->官方文档<--已经写得很清楚了。
下面是鱼某人利用几个晚上时间写的Docsify使用记录文档,肯定还有疏漏的地方,欢迎直接在文档下面留言哟。
不鸽了不鸽了,都在路上
先写完Docsify再到Springsecurity,都在计划内,后续继续写Java基础相关文档、Spring相关的框架文档、云服务和大数据或者其他语言(Rust,Go)的文档,之前的坑会一个个填完的,不填完就--( *・ω・)✄╰ひ╯
Arrays.asList使用和lambda表达式复习 [改]
实际开发中遇到的问题,仅此记录
map中对Arrays.asList的结果集合进行操作无效。 知识点太久没复习,一不小心就掉咧。完整测试代码
一、出现问题
// 需求要删掉map中key值跟数组元素相同的数据。
Integer[] idsInt = {2, 3};
Map<Integer, String> map = HashMap<>();
map.put(1,"hello");
map.put(2,"world");
map.put(3,"go");
map.put(4,"ahead");
map.keySet().removeIf(v -> Arrays.asList(idsInt).contains(v));
// 最后结果应该只有key为1、4的数据。
// 然而结果是所有map原始数据(key1~key4)
二、定位问题
removeIf
这个方法是java8中新增。直接写死参数看结果:map.keySet().removeIf(v -> v==2);
确实key为2的数据被删了,确实是可以删除数据的,pass继续。
Arrays.asList
- 因为用到了lambda表达式,分析的时候有点卡-->lambda表达式复习
v -> Arrays.asList(idsInt).contains(v)
先来分析
->
,这是一个Predicate函数,执行test方法,返回boolean类型。所以完整的v -> Arrays.asList(idsInt).contains(v)
执行流程是:map.keySet().removeIf(new Predicate<Integer>() { @Override public boolean test(Integer v) { return Arrays.asList(idsInt).contains(v); } });
来看看
Arrays.asList
代码@SafeVarargs @SuppressWarnings("varargs") public static <T> List<T> asList(T... a) { return new ArrayList<>(a); }
返回了一个ArrayList数组集合,没毛病。
结合代码,如果key存在于该数组中,就返回true,返回true就执行删除操作。为什么没有删掉呢?
再退回来看map.keySet().removeIf
代码
default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean removed = false;
final Iterator<E> each = iterator();
while (each.hasNext()) {
if (filter.test(each.next())) { // 在此处调用了lambda表达式,如果包含则返回true
each.remove();
removed = true;
}
}
return removed;
}
最终map.keySet().removeIf(v -> Arrays.asList(idsInt).contains(v));
的代码执行流程如下:
removeIf(Predicate<Integer> filter) {
Objects.requireNonNull(filter);
boolean removed = false;
final Iterator<Integer> each = iterator();
while (each.hasNext()) {
// if(filter.test(each.next())) 等于
if (Arrays.asList(idsInt).contains(each.next())) {
// 这里调用了迭代器的remove方法对Arrays.asList的结果集进行了remove操作
// 迭代器使用的注意事项:不能调用集合的remove方法改变集合,否则会ConcurrentModificationException
each.remove();
removed = true;
}
}
return removed;
}
map.keySet().removeIf(Predicate..);
发现问题
- removeIf方法的if语句中
Arrays.asList
返回了一个数组集合,数组集合增删查改应该没问题才对。然鹅,当按住ctrl键点击该ArrayList
类时,并不是跳转到java.util.ArrayList
类!!! 而是跳转到
Arrays
私有的内部类(这个内部类紧接着asList方法,滑稽),其路径为:java.util.Arrays
中的ArrayList
内部类private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable { xxxx //并没有增删方法 }
- 因为该内部类继承了
List
的实现类AbstractList
,所以该内部类ArrayList有List所有定义的方法
可以调用,List中存在remove方法的定义,但是在ArrayList内部类中该定义没有被实现。所以就发生了删不了数据的情况!!
三、解决方法
原来的代码:map.keySet().removeIf(v -> Arrays.asList(idsInt).contains(v));
可修改为下面代码使用:
第一种方法:
map.keySet().removeIf(v -> {
for(int j=0;j<idsInt;j++)
if(j == v) return true;
return false;
});
- 把集合相关的操作都用for循环解决,避免使用
Arrays.asList
第二种方法
map.keySet().removeIf(v -> new ArrayList<Integer>(Arrays.asList(idsInt)).contains(v));
- 还是使用
Arrays.asList
,但是转换成了java.util.ArrayList
类来用
四、效率
long startTime = System.nanoTime();
// 代码(上面两种方法)
long endTime = System.nanoTime();
long duration = endTime - startTime;
System.out.println("use: " + duration / 1000000);
设置2000000条map数据,idsInt = {2000,13000,57000,1000000},每种方法都跑三遍,发现:
- for循环的最高时间为:270毫秒 且三次时间都在200~300毫秒内;
- 集合
Arrays.asList
最高为369秒,300~400毫秒内。
所以建议使用for循环来做。OVER~~~~,搞完睡觉
来一起学SpringSecurity:④面向持久化的用户认证示例-前期准备(搭建项目骨架)
一,项目环境
- SpringBoot2.2.8
- SpringSecurity
- Gradle
- Mysql
随便一说:开发工具用Manjaro
i3wm
下的VSCode
,有点香
二,数据库表字段及建表相关操作
- 用户id,
- 用户名,
- 密码,
- 手机号,
- 账户锁定状态,
- 用户使用状态,
- 用户创建时间,
- 用户最后登录时间
(当前示例还没涉及用户权限相关内容哦,预告)
建库语句
CREATE DATABASE /*!32312 IF NOT EXISTS*/`fisha_demo` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
建表语句
CREATE TABLE fisha_demo.fisha_user (
`user_id` bigint(20) NOT NULL COMMENT '用户id,mybatis_plus雪花算法',
`account` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '用户账号',
`password` varchar(255) DEFAULT NULL COMMENT '用户加密密码',
`phone` varchar(20) DEFAULT NULL COMMENT '手机号码(国际国内)',
`locked` tinyint(2) DEFAULT '1' COMMENT '账户是否被锁定。1没被锁,2被锁(用户登录次数超出限制后会被锁定)',
`deleted` tinyint(2) unsigned DEFAULT '1' COMMENT '账户状态。1正在使用,2被逻辑删除',
`gmt_created` datetime DEFAULT NULL COMMENT '注册时间',
`gmt_modified` datetime DEFAULT NULL COMMENT '最后活跃时间',
PRIMARY KEY (`user_id`) COMMENT '主键索引'
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8
COMMENT='fisha用户实例表';
授权相关
项目使用的数据库用户密码为:java just1508,该用户拥有fisha_demo库所有的操作权限
create user 'java'@'localhost' identified by 'just1508'
grant all privileges on fisha_demo.* to 'java'@'localhost'