java 开发笔记(1)

写在前面

一直从事java开发,下面这些是我日常工作总结出来的小经验。

1、字符串、数值操作相关

1.1、 判断字符串相等

不推荐使用的方式:

String str = null;

// 会报空指针异常
if (str.equals("abc123")) {
  ... } else {  .. }

推荐使用的两种方式:

"abc123".equals(str);// false 

Objects.equals(str,"abc123");// false

1.2、 判断字符串为空

StringUtils.isEmpty(str1)、StringUtils.isNotBlank(str1)

判断字符串为空可以用工具类StringUtils

<dependency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.6</version>
</dependency>

1.3、基本数据类型转字符串用.toString()

把一个基本数据类型转为字符串,基本数据类型.toString()是最快的方式、String.valueOf(数据)次之、数据+””最慢

1.4、判断包装类的数值不要用 ==

所有整型包装类对象值的比较必须使用equals方法。

Integer -128~127之间是存的值,其他值是存的地址

1.5、浮点数之间的等值判断用BigDecimal

浮点数之间的等值判断,基本数据类型不能用==来比较,包装数据类型不能用 equals 来判断。

float a = 1.0f - 0.9f;
float b = 0.9f - 0.8f;
System.out.println(a);// 0.100000024
System.out.println(b);// 0.099999964
System.out.println(a == b);// false

使用 BigDecimal 来定义浮点数的值,再进行浮点数的运算操作。

BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("0.9");
BigDecimal c = new BigDecimal("0.8");

BigDecimal x = a.subtract(b); 
BigDecimal y = b.subtract(c); 

System.out.println(x); /* 0.1 */
System.out.println(y); /* 0.1 */
System.out.println(Objects.equals(x, y)); /* true */

1.6、基本数据类型与包装数据类型的使用标准

Reference:《阿里巴巴Java开发手册》

【强制】所有的 POJO 类属性必须使用包装数据类型。
【强制】RPC 方法的返回值和参数必须使用包装数据类型。
【推荐】所有的局部变量使用基本数据类型。

比如我们如果自定义了一个Student类,其中有一个属性是成绩score,如果用Integer而不用int定义,一次考试,学生可能没考,值是null,也可能考了,但考了0分,值是0,这两个表达的状态明显不一样

2、for循环相关

2.1、在for循环外面定义变量

	String str = "";
	List<String> list = new ArrayList<>();
	for(int i=0;i<1000;i++){
		str = "第 " + i + " 个";
		list.add(str);
	}

如上str的定义,如果放在for里面,就会造成1000个变量在内存中出现,只有当当前方法结束,才可能被释放

2.2、List被for出来的对象改变,List也会改变

	List<String> list = new ArrayList<>();
	for(String s:list){
		s = s + “abc”;
	}

如上代码,list循环完之后里面的值已经发生了改变(每个对象的地址不会变),不用再new一个list往里面添加

2.3、减少重复计算

例如下面的操作:

for (int i = 0; i < list.size(); i++)
{...}

建议替换为:

for (int i = 0, int length = list.size(); i < length; i++)
{...}

2.4、try…catch…应该放在循环外面

不要在循环中使用try…catch…,应该把其放在最外层

3、集合、对象、程序结构

3.1、检查Map里面是否有某个key

containskey(keyName)

3.2、对象深拷贝

BeanUtils.copyProperties(param,param1);

这个工具类是org.springframework.beans.BeanUtils.copyProperties提供的,可以代替字段一个一个的get、set

3.3、一个对象在需要的时候再去创建

例如:

String str = "aaa";
if (i == 1){
	list.add(str);
}

建议替换为:

if (i == 1){
	String str = "aaa";
	list.add(str);
}

3.4、在适当的时候使用System.gc()

如果某个对象所占内存较大,或者当前对象数量很多,我们可以使用System.gc(),及时释放内存,一般用在一个方法体末尾。

调用gc()函数表明Java虚拟机花费了很多精力来回收未使用的对象,以使它们当前占用的内存可用于快速重用。当控制从方法调用返回时,Java虚拟机已尽最大努力从所有丢弃的对象中回收空间。在注释中也明确的说明了,调用System.gc()等同于调用Runtime.getRuntime().gc()。

gc()也不能保证一定进行回收(如果-XX:+DisableExplicitGC设置成true,则不会进行回收)。

3.5、apache的FileUtils

做文件操作的时候,自己去些FileUtils比较麻烦,可以使用apache的FileUtils。如下写入List并指定编码到文件中:

import org.apache.commons.io.FileUtils;

File f = new File(fileName);
FileUtils.writeLines(f, "GBK", list);

3.6、能估计到内容长度,为底层以数组方式实现的集合、工具类指定初始长度

比如ArrayList、LinkedLlist、StringBuilder、StringBuffer、HashMap、HashSet等等,以StringBuilder为例:

(1)StringBuilder() // 默认分配16个字符的空间

(2)StringBuilder(int size) // 默认分配size个字符的空间

(3)StringBuilder(String str) // 默认分配16个字符+str.length()个字符空间

3.7、复制大量数据时,使用System.arraycopy()

如下例:

public class SsytemArrayCopy {  
    public static void main(String[] args) {  
       User [] users=new User[]{new User(1,"admin","admin@qq.com"),new User(2,"maco","maco@qq,com"),new User(3,"kitty","kitty@qq,com")};//初始化对象数组  
       User [] target=new User[users.length];//新建一个目标对象数组  
       System.arraycopy(users, 0, target, 0, users.length);//实现复制  
       System.out.println("源对象与目标对象的物理地址是否一样:"+(users[0] == target[0]?"浅复制":"深复制"));  
       target[0].setEmail("admin@sina.com");  
       System.out.println("修改目标对象的属性值后源对象users:");  
       for (User user : users){  
           System.out.println(user);  
       }           
    }  
}  
class User{  
    private Integer id;  
    private String username;  
    private String email;  
    //无参构造函数  
    public User() { }  
    //有参的构造函数  
    public User(Integer id, String username, String email) {  
        super();  
        this.id = id;  
        this.username = username;  
        this.email = email;  
    }  
    public Integer getId() {  
        return id;  
    }  
    public void setId(Integer id) {  
        this.id = id;  
    }  
    public String getUsername() {  
        return username;  
    }  
    public void setUsername(String username) {  
        this.username = username;  
    }  
    public String getEmail() {  
        return email;  
    }  
    public void setEmail(String email) {  
        this.email = email;  
    }  
    @Override  
    public String toString() {  
        return "User [id=" + id + ", username=" + username + ", email=" + email  
                + "]";  
    }  
}

3.8、遍历Map最快的方式

HashMap<String, String> hm = new HashMap<String, String>();
hm.put("111", "222");
Set<Map.Entry<String, String>> entrySet = hm.entrySet();
Iterator<Map.Entry<String, String>> iter = entrySet.iterator(); 
while (iter.hasNext()){
	Map.Entry<String, String> entry = iter.next();
	System.out.println(entry.getKey() + "	" + entry.getValue());
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值