Java代码精简之道-10条代码精简方案

场景

一、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开发手册中为什么禁止使用ApacheBeanutils进行属性的复制copy以及使用SpringBeanUtils、CglibBeanCopier、AapchePropertyUtils进行属_霸道流氓气质的博客-CSDN博客

六、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中为什么禁止把SimpleDateFormat定位为static变量以及如果非要使用static定位SimpleDateFormat时在多线程环境下的几种使用方式_霸道流氓气质的博客-CSDN博客

八、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);

猜你喜欢

转载自blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/131224868