jdk1.8+如何判斷hashmap中的value是否爲LocalDateTime類型
喜歡用jvm新特性的你一定知道since1.8的LocalDateTime相比於Date的各種好處(格式化時併發安全),但是當你嘗試序列化LocalDateTime卻不想爲其指定對象,只希望使用json這種通用的信息傳遞格式傳遞LocalDateTime傳遞值時,你就會發現這個LocalDateTime怎麼這麼難轉json。
從源碼定義可以看出它是繼承了序列化接口的,說明我們用對象接收,經過包裝發送接收解析後它是能夠被還原的,請注意這是建立在對象之上的。如果我們不使用對象接收和發送LocalDateTime類型的值。直接使用json做轉換傳輸,比如使用jackson包的 objectMapper.writeValueAsString方法將其轉化再讀取出來的話會報錯 Cannot construct instance of java.time.LocalDateTime
指定類型**ObjectWriter s = new ObjectMapper().writerFor(LocalDateTime.class);**和上邊報的錯誤一致
然後我使用fastjson來讀取jackson轉化之後的json,結果如下
讀取成功,雖然排序不同,但是結果一致。
那麼這兩個json包結合使用是可行的
然後我們來嘗試map的轉換
這個結果倒是能看 ,我們確實是可以以這種
{“dayOfWeek”:“SATURDAY”,“hour”:17,“month”:“APRIL”,“dayOfMonth”:4,“dayOfYear”:95,“year”:2020,“monthValue”:4,“nano”:928000000,“chronology”:{“calendarType”:“iso8601”,“id”:“ISO”},“minute”:24,“second”:20}
時間描述的形式傳遞和轉換的,但是顯然這種方式很坑!
就正常開發思路來講,我們接收到時間類型的數據想要存儲到任何數據庫中時間的格式應該是如下的:
2020-04-04T17:27:16.649
這樣的格式才能被數據庫正常識別爲date類型,從而正常存儲。
那麼我們傳遞時怎麼把LocalDateTime轉化成這種格式呢?
很簡單,使用toString即可
emm,看起來很好解決是吧,那你看一個細節,我的Map泛型是<String,Object>,你覺得我的Object會只裝一個LocalDateTime嗎?答案當然是否定的,我還要裝HashMap,還要放一個ArryList,還要·····,你能想到的我可能都會放,如果代碼寫成這樣
你可能會問:確定要這樣玩嗎?hhhh測試代碼別當真,造出來的數據格式和我在生產上見過的差不多。
不知道你發現圖中的問題了沒有 我hashmap toString之後,鍵值對中的 : 變成了 = 。= 號分割的鍵值對當然無法很容易的轉化爲hashmap,硬要通過string的方法轉化那麼時間複雜度可想而知,是那這樣問題就來了,轉換後的數據無法被識別爲轉換前的數據。這能愉快的玩耍嗎?顯然不能。
這時聰明的你可能會想到我只轉化LocalDateTime,別的不用理會, 用 instanceOf判斷一下,是LocalDateTime類型的就轉換一下,如果有嵌套的collection,遞歸一下即可,我們來試試
這樣是可以的,代碼如下
package starter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import java.time.LocalDateTime;
import java.util.*;
/**
* @ClassName jsonTest
* @Description //TODO
* @Author geyunpeng
* @Date 2020/4/4 17:05
* @Version 1.0
**/
public class jsonTest {
@SneakyThrows
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now();
Map<String, Object> map = new HashMap<>();
map.put("Time",now);
map.put("List",new ArrayList(Arrays.asList(new HashMap(map),new HashMap(map),new HashMap(map),new HashMap(map))));
map.put("HashMap",new HashMap(map));
localDateTimeToString(map);
String s = new ObjectMapper().writeValueAsString(map);
System.out.println(s);
JSONObject jsonObject = JSON.parseObject(s);
System.out.println(jsonObject);
}
private static void localDateTimeToString(Map<String, Object> map) {
map.forEach((k, v) -> {
if (v instanceof Map) {
localDateTimeToString((Map<String, Object>) v);
return;
}
if (v instanceof List) {
((List) v).stream().filter(element -> element instanceof Map).forEach(element -> localDateTimeToString((Map<String, Object>) element));
return;
}
if (v instanceof LocalDateTime) {
System.out.println(k + v);
map.replace(k, map.get(k).toString());
}
});
}
}
如果直接是前端傳過來的時間類型數據用 v instanceof LocalDateTime判斷判斷不出來的話,需要這麼寫
body.forEach((k, v) -> {
if (v.getClass().getName().equals("org.joda.time.LocalDateTime")) {
body.replace(k, body.get(k).toString());
}
});
經驗交流到此結束,如有錯誤敬請高手指點