场景
一、Java中利用try-with-resource语句
JDK7 开始新增了对需要关闭资源处理的特殊语法 try-with-resource。
所有实现Closeable接口的“资源”,均可采用try-with-resource进行简化。
例如 InputStream, OutputStream ,Connection, Statement, ResultSet等接口都实现了,
使用 try-with-resource可以不用写finally块,编译器会帮助生成关闭资源的代码。
下面看一个普通实现代码:
BufferedReader reader = null;
try{
reader = new BufferedReader(new FileReader("badao.csv"));
String line;
while ((line = reader.readLine()) != null){
//业务处理
}
}catch (IOException e){
System.out.println(e);
}finally {
if(reader !=null){
try{
reader.close();;
}catch (IOException e){
System.out.println(e);
}
}
}
精简之后的代码:
try(BufferedReader reader1 = new BufferedReader(new FileReader("badao.csv"))){
String line;
while ((line = reader1.readLine())!= null){
//业务处理
}
}catch (IOException e){
System.out.println(e);
}
二、Java中利用泛型进行代码精简
1、泛型接口
在Java没有引入泛型前,都是采用Object标识通用对象,最大的问题就是类型无法强校验并且需要强制类型转换。
普通写法:
新建接口
public interface NormalComparable {
public int compartTo(Object other);
}
接口实现
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Setter
@Getter
@ToString
public class NormalUserVO implements NormalComparable{
private Long id;
@Override
public int compartTo(Object other) {
NormalUserVO user = (NormalUserVO)other;
return Long.compare(this.id,user.id);
}
}
精简写法:
接口
public interface ReduceComparable<T> {
public int compareTo(T other);
}
接口实现
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Setter
@Getter
@ToString
public class ReduceUserVo implements ReduceComparable<ReduceUserVo>{
private Long id;
@Override
public int compareTo(ReduceUserVo other) {
return Long.compare(this.id,other.id);
}
}
2、泛型类
普通写法:
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class DoublePoint {
private Double x;
private Double y;
}
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class IntPoint {
private Integer x;
private Integer y;
}
精简写法:
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class Point <T extends Number>{
private T x;
private T y;
}
3、泛型方法
普通写法:
public static Map<String,Integer> newHashMap(String[] keys,Integer[] values){
//check notnull arg
if(ArrayUtils.isEmpty(keys) || ArrayUtils.isEmpty(values)){
return Collections.emptyMap();
}
//to hashmap
Map<String,Integer> map = new HashMap<>();
int length = Math.min(keys.length, values.length);
for (int i = 0; i < length; i++) {
map.put(keys[i],values[i]);
}
return map;
}
精简写法:
public static <K,V> Map<K,V> newHashMap(K[] keys,V[] values){
//check notnull arg
if(ArrayUtils.isEmpty(keys) || ArrayUtils.isEmpty(values)){
return Collections.emptyMap();
}
//to hashmap
Map<K,V> map = new HashMap<>();
int length = Math.min(keys.length, values.length);
for (int i = 0; i < length; i++) {
map.put(keys[i],values[i]);
}
return map;
}
三、Java中利用自身方法进行代码精简
1、利用Set的add方法
Java中由于Set的add函数有个特性:如果添加的元素已经在集合中存在,则会返回false。
可参考如下:
Java开发技巧-数据结构-使用HashSet判断主键是否存在、使用Pair成对结果返回/Triple三个对象返回_霸道流氓气质的博客-CSDN博客
2、Java中利用Map的computelIfAbsent 方法进行代码精简
利用Map的computeIfAbsent方法,可以保证获取到的对象非空,从而避免了不必要的空判断和重新设置值。
普通写法:
ArrayList<UserDO> userDOS = new ArrayList<UserDO>() {
{
add(new UserDO(1l,"zhangsan"));
add(new UserDO(1l,"lisi"));
add(new UserDO(2l,"wangwu"));
add(new UserDO(1l,"zhaoliu"));
}};
Map<Long, List<UserDO>> roleUserMap = new HashMap<>();
for (UserDO userDO:userDOS) {
Long roleId = userDO.getRoleId();
List<UserDO> userList = roleUserMap.get(roleId);
if(Objects.isNull(userList)){
userList = new ArrayList<>();
roleUserMap.put(roleId,userList);
}
userList.add(userDO);
}
System.out.println(roleUserMap);
Map<Long, List<UserDO>> roleUserMap1 = new HashMap<>();
精简写法:
for (UserDO userDO : userDOS) {
roleUserMap1.computeIfAbsent(userDO.getRoleId(),key->new ArrayList<>()).add(userDO);
}
System.out.println(roleUserMap1);
以上输出结果一致
{1=[UserDO(roleId=1, name=zhangsan), UserDO(roleId=1, name=lisi), UserDO(roleId=1, name= zhaoliu)],2=[UserDO(roleId=2, name= wangwu)]
java中Map的compute,computeIfAbsent,computeIfPresent
compute(计算)
如果指定的键没有对应的值(没有该键或者该键对应的值是空),
那么使用该键计算新的值,并将其添加到 Map 中
computeIfAbsent(不存在时计算)
computeIfPresent ——如果指定的键在 Map 中存在,就计算该键的新值,并将其添加到 Map 中
computeIfPresent(存在时计算)
compute ——使用指定的键计算新的值,并将其存储到 Map 中。
相同:返回值是返回最新的值
不相同:compute是有则覆盖,没则添加;computeIfAbsent是有则不操作,没则添加;computeIfPresent是有则覆盖,没值的时候不操作。
四、Java中利用工具方法进行代码精简
1、避免空值判断
普通:
if(userDOS!=null && !userDOS.isEmpty()){
}
精简:
if(CollectionUtils.isNotEmpty(userDOS)){
}
2、简化赋值语句
Arrays.asList返回的List并不是ArrayList,不支持add等变更操作
List<String> stringList = Arrays.asList("a","b","c");
List<String> stringList1 = ImmutableList.of("a", "b", "c");
五、Java中简化数据拷贝
普通:
UserDO userDO = new UserDO(1l,"zhangsan");
UserVO userVO = new UserVO();
userVO.setRoleId(userDO.getRoleId());
userVO.setName(userDO.getName());
System.out.println(userVO);
精简:
UserVO userVO1 = new UserVO();
org.springframework.beans.BeanUtils.copyProperties(userDO,userVO1);
System.out.println(userVO1);
其他方式可以参考
Java开发手册中为什么禁止使用ApacheBeanutils进行属性的复制copy以及使用SpringBeanUtils、CglibBeanCopier、AapchePropertyUtils进行属性复制:
六、Java中利用容器类进行代码精简
Java不像Python和Go,方法不支持返回多个对象。如果需要返回多个对象,就必须自定义类,或者利用容器类。
常见的容器类有Apache的Pair类和Triple类,Pair类支持返回2个对象,Triple类支持返回3个对象。
Java开发技巧-数据结构-使用HashSet判断主键是否存在、使用Pair成对结果返回/Triple三个对象返回:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/131143345
七、Java中利用ThreadLocal进行代码精简
ThreadLocal提供了线程专有对象,可以在整个线程生命周期中随时取用,极大地方便了一些逻辑的实现。
用ThreadLocal保存线程上下文对象,可以避免不必要的参数传递。
Java中为什么禁止把SimpleDateFormat定位为static变量以及如果非要使用static定位SimpleDateFormat时在多线程环境下的几种使用方式:
八、Java中利用Optional进行代码精简
在Java 8里,引入了一个Optional类,该类是一个可以为null的容器对象
1、 保证值存在
Integer value = null;
Integer integer = Optional.ofNullable(value).orElse(0);
System.out.println(integer);//0
2、保证值合法
Integer integer1 = Optional.ofNullable(value).filter(temp -> temp.compareTo(10) <= 0).orElse(10);
System.out.println(integer1);//10
3、避免空判断
UserVO userVO2 = null;
String name = Optional.ofNullable(userVO2).map(UserVO::getName).orElse("未命名");
System.out.println(name);//未命名
4、Java8中Optional类入门-替代null避免冗杂的非空校验:
Java8中Optional类入门-替代null避免冗杂的非空校验_霸道流氓气质的博客-CSDN博客
九、Java中利用Stream进行代码精简
Java8新特性-Stream对集合进行操作的常用API:
Java8新特性-Stream对集合进行操作的常用API_stream 集合少选_霸道流氓气质的博客-CSDN博客
十、Java中利用非空对象进行代码精简
在比较对象时,交换对象位置,利用非空对象,可以避免空指针判断。
普通写法:
Integer value1 = null;
Boolean result = null;
boolean isMax = (value1!=null && value1.equals(MAX_VALUE));
boolean isTrue = (result !=null && result.equals(Boolean.TRUE));
System.out.println(isMax);
System.out.println(isTrue);
精简写法:
boolean isMax2 = MAX_VALUE.equals(value1);
boolean isTrue2 = Boolean.TRUE.equals(result);
System.out.println(isMax2);
System.out.println(isTrue2);