我們先來看一個例子:
public static void main(String[] args) {
try {
Date d1 = str2date("2019-10-20 09:10:00");
Date d2 = str2date("2019-10-20 09:12:00");
Date d3 = str2date("2019-10-20 09:13:00");
long c = System.currentTimeMillis();
Date d4 = new Date(c);
Set<Date> set = new HashSet<>();
set.add(d1);
set.add(d2);
set.add(d3);
set.add(d4);
System.out.println(set);
d2.setTime(c);
System.out.println(set);
}catch (Exception e){
e.printStackTrace();
}
}
public static Date str2date(String dateStr) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.parse(dateStr);
}
以上代碼的執行結果
我們看到Set中居然出現了兩個重複元素,這就破壞了Set的約束規則。
之所以會出現上面的現象,是因爲我們在Set中存儲的元素是可變對象。
可變對象本身是一種不安全的數據結構,我們在平時開發中應儘量使用不可變對象作爲對象的內部組件。比如上面的例子,我們可以用java8之後的新類型LocalDateTime來代替Date。如果是在Java8之前,我們可以用Date.getTime()返回long類型而不是Date對象的引用,這種方式會帶來一些性能損失,但是如果操作的對象數量沒有達到幾千個以上的話,這一般不會成爲性能瓶頸。