String ——(不空、“+”、值比较、String.format())
Sting是在工作总遇到的最多的一种类型,所以不管在什么样的业务环境下,理解String的用法,和巧妙用String类型可以解决很多问题。
一、判断一个字符串String不为空的方法有:
-
str != null; (使用最多)
优点:代码比较直观,方便理解
缺点:效率不高
-
" ".equals(str);(最少使用)
-
str.length() != 0;
效率最高
二、"+"连接符的实现字符串连接的原理和效率:
在某些环境下,比如:电子票的序列号自动生成,uuid不能够满足我们业务有序且唯一的需求,所以我们需要经常进行字符串的拼接和累加的操作,所以我就对"+"字符产生了一些兴趣。
//以下两者是等价的
String a = "";
String i = "";
a = i + "";
a = String.valueOf(i);
//进入底层可以发现是默认的toString方法。
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
--------------------------------------------------------
//以下两者也是等价的
a = "123" + i;
a = new StringBuilder("123").append(i).toString();
//进入底层一样可以发现
@Override
public StringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
//Java中使用"+"连接字符串对象时,会创建一个StringBuilder()对象,并调用append()方法将数据拼接,最后调用toString()方法返回拼接好的字符串。
--------------------------------------------------------
String a = "123";
for (int i=0; i<10000; i++) {
a += "123";
//a = (new StringBuilder()).append(a).append("123").toString(); 等价上一行
}
//可以发现每次进行累加都是会创建新StringBuilder的对象的,这样会在堆内存中填充大量的的空间,拖慢效率。
三、String类型值比较 "=="VS “equals()”:
“双等于”判断的是堆内存的地址值,equals()方法判断的是内容。
equals()是平时使用的最多了,也是比较安全的,如果equals()的结果为true,那么他们的hashCode()也相同。所以还是用equals() 香!
java规定
如果两个对象的hashCode()相等,那么他们的equals()不一定相等。
如果两个对象的equals()相等,那么他们的hashCode()必定相等。
重写equals()方法时候一定要重写hashCode()方法
这里对算法有兴趣的小伙伴可以看看
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
// key.hashCode() ^ (key.hashCode() >>> 16)
//这个巧妙的扰动算法
//==============================源码哈希Code==========================
final Node<K,V> getNode(int hash, Object key) {
Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
if ((tab = table) != null && (n = tab.length) > 0 &&
(first = tab[(n - 1) & hash]) != null) {
if (first.hash == hash && // always check first node
((k = first.key) == key || (key != null && key.equals(k))))
return first;
if ((e = first.next) != null) {
if (first instanceof TreeNode)
return ((TreeNode<K,V>)first).getTreeNode(hash, key);
do {
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
} while ((e = e.next) != null);
}
}
return null;
}
四、String.format()使用:
这里放一个工作的实例:需求是生成唯一的电子序列号,由字母开头+日期+7位的数字生成唯一的序列号:我的方案是,当天的累加,每次生成一个从数据库取最大值,不是当天的则从0重新计数(类似条件计数器)
public synchronized int generateSerial () {
//这是查询数据库,如果库中有最行的电子序列号则取出进行拆解操作,提取出后7位数字
String findnewszph = sewageWaterFeeReceiveGDDao.findnewszph();
if (findnewszph != null) {
//取出中间的日期:20170607
String sqlDate = findnewszph.substring(8, 14);
//取出后七位的数字eg:0000001
String sevenNumber = findnewszph.substring(15);
//削0操作
int num = Integer.parseInt(sevenNumber);
SimpleDateFormat df = new SimpleDateFormat("yyMMdd");//设置日期格式
//获得最行的日期
String format = df.format(new Date());
//判断是否是今天
if (sqlDate.equals(format)) {
num++;
} else {
num = 0;
}
return num;
}
return 0;
}
public String seqNo(){
String A ="";
String seqno = "GD04";
SimpleDateFormat df = new SimpleDateFormat("yyMMdd");//设置日期格式
String seqno1 = seqno + "01" + df.format(new Date());
//查询数据库的最后一条,如果得到的日期日期不是今天的日期则重置后7位从0开始
A = seqno1 + String.format("%07d",generateSerial());
// System.out.println("seqNo报文序列号为:"+A);//验证函数是否正确
return A;
}