开发好习惯
1.定义配置文件信息
有时候我们为了统一管理会把一些变量放到 yml 配置文件中
例如:
developer:
name:hugh
website:https://blog.csdn.net/weixin_44994494?spm=1010.2135.3001.5421
qq:2496760580
phone-number:11111111
@Value 单个
@ConfigurationProperties 多个
使用方法:
@Data
// 指定前缀 也就是你yml里面配置的东西
@ConfigurationProperties(prefix = "developer")
@Component
public class DeveloperProperty {
private String name;
private String website;
private String qq;
private String phoneNumber;
}
使用时注入这个bean
@RestController
@RequiredArgsConstructor
public class PropertyController {
final DeveloperProperty developerProperty;
@GetMapping("/property")
public Object index() {
// 直接取到对应的值
return developerProperty.getName();
}
}
2.@RequiredArgsConstructor代替@Autowired
@Autowired 这个注解大家都比较常用
我们都知道注入一个 bean 有三种方式哦(set 注入, 构造器注入, 注解注入),Spring 推荐我们使用构造器的方式注入 Bean
但是==@RequiredArgsConstructor==可能没那么熟悉 简单看一下介绍效果
他的作用其实就是和Autowired一样都是进行依赖注入 但是我们实际项目中一个service 中可能会写很多个Autowired去进行注入
就会有一点乱 所以lombok 就给我提供了同一个管理方法RequiredArgsConstructor注解
依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
使用
使用需要同时注意几点:
1.必须声明的变量为final
2.根据构造器注入的,相当于当容器调用带有一组参数的类构造函数时,基于构造函数的 DI 就完成了,其中每个参数代表一个对其他类的依赖。基于构造方法为属性赋值,容器通过调用类的构造方法将其进行依赖注入
使用当我们需要注入Bean的时候可以直接在类名称上使用。代替了Autowrited注解
// 加上注解
@RequiredArgsConstructor
@RestController
@RequestMapping("/component")
public class ComponentController {
private final ComponentService ComponentService;
}
3.代码模块化
阿里巴巴 Java 开发手册中说到每个方法的代码不要超过 50 行(我没记错的话),在实际的开发中我们要善于拆分自己的接口或方法, 做到一个方法只处理一种逻辑, 说不定以后某个功能就用到了, 拿来即用
就是有两段代码是重复的时候就可以进行方法的封装来提高代码的可用性
idea 快捷键
选中代码块然后组合 CTRL + ALT + M
也可以选中代码块右键
4.抛异常而不是返回
在写业务代码的时候,经常会根据不同的结果返回不同的信息,尽量减少返回,会显得代码比较乱
反例
正例
5.减少不必要的db
尽可能的减少对数据库的查询
反例
正例
6. 不要返回 null
反例
正例
7. if else
这个经常使用但是怎么进行优化美观呢
方案一去除不必要的else
########### 优化前 ##########
if(condition){
//doSomething
}else{
return ;
}
######### 优化后 ##########
if(!condition){
return ;
}
方案二 使用条件三目运算符
前提是判断比较少的 过多三目运算也会很乱
########## 优化前 ##########
int price ;
if(condition){
price = 80;
}else{
price = 100;
}
######## 优化后 #########
int price = condition?80:100;
方案三:使用枚举
########## 优化前 ##########
String OrderStatusDes;
if(orderStatus==0){
OrderStatusDes ="订单未支付";
}else if(OrderStatus==1){
OrderStatusDes ="订单已支付";
}else if(OrderStatus==2){
OrderStatusDes ="已发货";
}
...
######## 优化后 ########
先构建一个枚举类
public enum OrderStatusEnum {
UN_PAID(0,"订单未支付"),PAIDED(1,"订单已支付"),SENDED(2,"已发货"),;
private int index;
private String desc;
public int getIndex() {
return index;
}
public String getDesc() {
return desc;
}
OrderStatusEnum(int index, String desc){
this.index = index;
this.desc =desc;
}
OrderStatusEnum of(int orderStatus) {
for (OrderStatusEnum temp : OrderStatusEnum.values()) {
if (temp.getIndex() == orderStatus) {
return temp;
}
}
return null;
}
}
############# 代码优化后 ############
StringOrderStatusDes= OrderStatusEnum.0f(orderStatus).getDesc();
方案四:合并条件表达式
########## 优化前 ##########
double getVipDiscount() {
if(age<18){
return 0.8;
}
if("深圳".equals(city)){
return 0.8;
}
if(isStudent){
return 0.8;
}
}
######## 优化后 #########
double getVipDiscount(){
if(age<18|| "深圳".equals(city)||isStudent){
return 0.8;
}
}
方案五:使用 Optional
有时候if-else比较多,是因为非空判断导致的,这时候你可以使用java8的Optional进行优化。
########## 优化前 ##########
String str = "jay@huaxiao";
if (str != null) {
System.out.println(str);
} else {
System.out.println("Null");
}
######## 优化后 #########
Optional<String> strOptional = Optional.of("jay@huaxiao");
strOptional.ifPresentOrElse(System.out::println, () -> System.out.println("Null"));
8. 减少controller业务代码
所有的逻辑代码尽量放到service里面 controller 最好不写任何逻辑只返回值
反例:
正例:
9. 利用好Idea
ctrl+z撤回代码
ctrl+shift+z恢复撤回代码
ctrl + Alt + V (返回属性变量)
shift+ctrl+u (大小写的切换)
Ctrl+Alt+L,格式化代码
Ctrl+D 将当前行复制到下一行
Ctrl+Alt+T,可以把代码包在一个块内,例如:try/catch 也可抛错误
抛异常 鼠标放在编译异常的位置 + Alt+Enter
快捷方式一(光标移到该代码行,Alt+Enter),可以异常外抛出,也可以try-catch:
Ctrl+Shift+Space,自动补全代码(提示)
Ctrl+O,重写方法
Ctrl+I,实现方法
itar 生成array for代码块
iter 生成增强for
itli 生成List的遍历
itit 生成iterator 迭代
自定义的注释模板(自定义):M+Tab
自定义的注释方法模板(自定义):r+Tab
ctrl + shift + enter 句末加;
连安两下 shift 查找文件
CtrL +shift +r 全局搜索:
ctrl +r 替换当前页的单词
代码格式化: shfit + G(自定义) //ctrl +alt +L
直接查看和进入接口实现类的快捷键: Ctrl+Alt+鼠标左键
alt+capslk(大小写切换)+鼠标左键 或者:ALT + 鼠标左键 列编辑模式
-对象+.+new +enter +.+var --------------------new 对象
ctrl+shift+enter不只是用来行尾加分号的;
idea进阶快捷键:
查看接口的实现类:Ctrl+Alt+B:
查看一个类中有什么方法:Alt+7 或 点左侧边栏Structure
返回上/下个光标地方:Alt+Ctrl+箭头(向左) 和 Alt+ Ctrl+箭头(向右)---(全键盘)
而本机为:Alt+Ctrl+Pgup和Alt+Ctrl+Down
查看Java方法调用树(被调/主调):Ctrl+Alt+H
查看类继承关系图:Ctrl+Alt+U
查看当前类的继承树:Ctrl+H
10.阅读源码
一定要养成阅读源码的好习惯包括优秀的开源项目GitHub上stars:>1000, 会从中学好好多知识包括其对代码的设计思想以及高级API,面试加分(好多面试官习惯问源码相关的知识)
11. 设计模式
23种设计模式,要尝试代码中运用设计模式思想,写出的代码即规范又美观还高大上哈哈。
23中设计模式
12. 拥抱新知识
像我们这种工作年限少的程序员,我觉得要多学习自己认知之外的知识,不能每天crud,有机会就多用用有点难度的知识,没有机会(项目较传统),可以自己下班多些相关demo练习
13. 基础问题
map遍历
HashMap<String, String> map = new HashMap<>();
map.put("name", "du");
for (String key : map.keySet()) {
String value = map.get(key);
}
map.forEach((k, v) -> {
});
// 推荐
for (Map.Entry<String, String> entry : map.entrySet()) {
}
optional 判空
public List<CatalogueTreeNode> getChild(String pid) {
if (V.isEmpty(pid)) {
pid = BasicDic.TEMPORARY_DIRECTORY_ROOT;
}
CatalogueTreeNode node = treeNodeMap.get(pid);
return Optional.ofNullable(node)
.map(CatalogueTreeNode::getChild)
.orElse(Collections.emptyList());
}
递归
public static void main(String[] args) {
int[] arrays = {2, 3, 4, 5, 1, 5, 2, 9, 5, 6, 8, 3, 1};
bubbleSort(arrays, 0, arrays.length - 1);
System.out.println("公众号:Java3y:" + arrays);
}
public static void bubbleSort(int[] arrays, int L, int R) {
int temp;
//如果只有一个元素了,那什么都不用干
if (L == R) ;
else {
for (int i = L; i < R; i++) {
if (arrays[i] > arrays[i + 1]) {
temp = arrays[i];
arrays[i] = arrays[i + 1];
arrays[i + 1] = temp;
}
}
//第一趟排序后已经将最大值放到数组最后面了
//接下来是排序"整体"的数据了
bubbleSort(arrays, L, R - 1);
}
}
注释
// 单行注释
/*
* 多行注释
* */
/**
* 文档注释
* */
14. 尽量在finally块中释放资源
程序中使用到的资源应当被释放,以避免资源泄漏,这最好在finally块中去做。不管程序执行的结果如何,finally块总是会执行的,以确保资源的正确关闭
15.减少static变量 尽量使用局部变量
全局访问 会造成变量被其他人引用修改造成数据混乱 大量还会造成资源浪费
调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(Stack)中,速度较快;其他变量,如静态变量、实例变量等,都在堆(Heap)中创建,速度较慢
16.写好日志
尽量在代码中写好日志有助于排查错误
17.常用事务
在进行数据库操作的使用需要习惯对事务的使用 来保证数据的一致性
18.第三方工具的使用
hutool 工具可以优雅的进行 集合 变量空值判断
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.6.0</version>
</dependency>
http请求
String result = HttpUtil.post("https://fpdk.beijing.chinatax.gov.cn/NSbsqWW/pltj.do", map);
MD5加密
String sign = SecureUtil.md5(append.toString());
System.out.println(sign);
List集合拆分
List<List<String>> partitionList = Lists.partition(valList, 30);
转换为Int
// 字符串转换为int类型
System.out.println(Convert.toInt("3"));
字符串转为时间
// 转换时间
String date = "2020-05-06";
System.out.println(Convert.toDate(date));
生成二维码
// 生成二维码
QrCodeUtil.generate("https://hutool.cn/", 300, 300, FileUtil.file("d:/qrcode.jpg"));