Posted 寮€鍙戣€呮妧鏈墠绾?/a>
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了相关的知识,希望对你有一定的参考价值。
鐐瑰嚮鈥?/span>寮€鍙戣€呮妧鏈墠绾?/span>鈥濓紝閫夋嫨鈥滄槦鏍囸煍濃€?/span>
鍦ㄧ湅|鏄熸爣|鐣欒█, 鐪熺埍
绗?05鏈熷師鍒涘垎浜?/span>
澶у濂斤紝鎴戞槸hub鍝ワ紝鍙堝埌浜嗘湰鏈熷垎浜€傝繖鏈熸垜浠潵鑱婅亰Java涓В鏋怞SON鐨勪笁涓富娴佺被搴?span>锛?/strong>
FastJSON銆?span>Gson鍜?span>Jackson銆?/span>
鍏堟潵鐪嬩笅杩欎笁璐у湪Github涓婄殑鍩烘湰鏁版嵁锛?/span>
鐮佸弸浠杩欎笁璐у悇鏂归潰涔熶竴鐩翠簤璁笉鏂紝澶у鍏冲績鐨勶紝杩樻槸鎬ц兘浠ュ強绋冲畾鎬с€傛湰鏂囦富娴嬫€ц兘锛涘浜庤繖涓変釜搴撶殑绠€浠嬩互鍙婄敤娉曪紝灏变笉鍘诲簾璇濅簡锛屼竴涓畝鍗曟槑浜嗙殑娴嬭瘎锛岀洿鎺ヤ笂锛?/span>
涓昏瀵硅繖涓変釜绫诲簱鍦↗SON搴忓垪鍖栧拰鍙嶅簭鍒楀寲鍦ㄩ€熷害鏂归潰鐨勮〃鐜板仛涓€浜涙祴璇勶紝涓轰簡闃叉鐢变簬鍐呭瓨瀵艰嚧娴嬭瘯缁撴灉鍑虹幇鍋忓樊锛屾祴璇曚腑瀵笿VM鍐呭瓨閰嶇疆-Xmx4g -Xms4g銆?/span>
娴嬭瘯浠g爜宸茬粡璐村埌浜嗘枃绔犳湯灏俱€?/span>
JSON搴忓垪鍖?Object => JSON)
娴嬭瘯鏍锋湰鏁伴噺涓?00000涓紝涓轰簡淇濊瘉姣忎釜绫诲簱鍦ㄦ祴璇曚腑閮借兘澶勭悊鍚屼竴涓牱鏈紝鍏堟妸鏍锋湰Java瀵硅薄淇濆瓨鍦ㄦ枃浠朵腑銆傛瘡涓被搴撴祴璇?娆★紝姣忔寰幆娴嬭瘯10閬嶏紝鍘绘帀鏈€蹇€熷害鍜屾渶鎱㈤€熷害锛屽鍓╀笅鐨?閬嶆眰骞冲潎鍊间綔涓烘渶缁堢殑閫熷害锛屽彇5娆℃祴璇曚腑鏈€濂界殑骞冲潎閫熷害浣滀负鏈€缁堢殑娴嬭瘯鏁版嵁銆?/span>
娴嬭瘯缁撴灉锛?/span>
浠庢祴璇曟暟鎹彲浠ョ湅鍑猴紝Jackson鏄渶蹇殑锛堣€楁椂姣擥son灏戜簡澶х害700姣锛夛紝Gson鑰楁椂鏈€涔?/span>銆?/span>
JSON鍙嶅簭鍒楀寲(JSON => Object)
鍚屾牱锛屾祴璇曟牱鏈暟閲忎负100000涓紝涓轰簡淇濊瘉姣忎釜绫诲簱鍦ㄦ祴璇曚腑閮借兘澶勭悊鍚屼竴涓牱鏈紝鍏堟妸鏍锋湰JSON瀵硅薄淇濆瓨鍦ㄦ枃浠朵腑銆傛瘡涓被搴撴祴璇?娆★紝姣忔寰幆娴嬭瘯10閬嶏紝鍘绘帀鏈€蹇€熷害鍜屾渶鎱㈤€熷害锛屽鍓╀笅鐨?閬嶆眰骞冲潎鍊间綔涓烘渶缁堢殑閫燂紝鍙?娆℃祴璇曚腑鏈€濂界殑骞冲潎閫熷害浣滀负鏈€缁堢殑娴嬭瘯鏁版嵁銆?/span>
娴嬭瘯缁撴灉锛?/span>
浠庢祴璇曟暟鎹彲浠ョ湅鍑猴紝鍦ㄥ弽搴忓垪鍖栦笂鎬ц兘 FastJson鏈€蹇紝涓嶈繃涓嶫ackson宸窛骞朵笉鏄庢樉锛孏son鑰楁椂鏈€涔?/span>
鍙锛屼笉绠℃槸搴忓垪鍖栬繕鏄弽搴忓垪鍖栵紝閫熷害鏂归潰棣栧厛闃典骸鐨勶紝鏄疓son锛?/span>
閭h繕鍓╀笅FastJson鍜孞ackson
FastJson鍦ㄦ煇浜涙柟闈㈢‘瀹炲揩涓€浜涳紝浣嗘槸鍜?span class="mq-98">Jackson 鐨勫樊璺濅笉澶э紝浼樺娍骞舵病鏈夊お鏄庢樉銆侸ackson杩樺彲浠ュ姞涓夾fterBurner鏉ヤ娇鐢╞yte generation锛岃繖鏍峰拰FastJson鐨勫樊璺濆氨鏇村皬浜嗐€?/span>
闄や簡鍦ㄥ弽搴忓垪鍖栫殑閫熷害鑳滃嚭澶栵紝FastJson鐩告瘮杈?Jackson 鏈変笉灏戠煭鏉匡紝鎴戜滑鍙互浠庝互涓?鏂归潰瀵规瘮锛?/span>
1. 鍙畾鍒舵€?/strong>
Jackson鏈夌伒娲荤殑API锛屽彲浠ュ緢瀹规槗杩涜鎵╁睍鍜屽畾鍒讹紝鑰屼笖寰堝鏃跺€欓渶瑕佺殑妯″潡閮藉凡缁忔湁浜烘彁渚涗簡銆傛瘮濡俫uava涓畾涔夌殑鏁版嵁绫诲瀷锛屾瘮濡俴otlin璇█Immutable鐨勭被鍨嬬瓑锛屾瘮濡俲ava8 寮曞叆鐨勬柊鏃ユ湡鏃堕棿绫诲瀷鍜孫ptional閮藉凡缁忔湁鏀寔鐨勬ā鍧椼€?br>
FastJson鍙湁涓€涓?绠€闄?鐨凷erializeFilter鏈哄埗鐢ㄦ潵瀹氬埗搴忓垪鍖栵紝ParseProcess鏈哄埗鐢ㄦ潵瀹氬埗鍙嶅簭鍒楀寲锛屾瘡娆¤皟鐢ㄥ簭鍒楀寲/鍙嶅簭鍒楀寲鐨勭殑鏃跺€欓兘瑕佽嚜宸变紶filter鎴栬€匬rocess杩欎釜鍙傛暟杩囧幓锛孞ackson鍜?Gson閮芥槸鐩存帴娉ㄥ唽妯″潡灏卞彲浠ヤ簡锛孞ackson杩樺彲浠ヤ娇鐢⊿PI鏉ヨ嚜鍔ㄥ彂鐜板拰娉ㄥ唽妯″潡銆?/span>
2. 浠g爜璐ㄩ噺
鍏徃鏈変竴浜涢」鐩娇鐢ㄤ簡Fastjson锛屽湪浣跨敤Fastjson鐨勯」鐩噷闈㈡浘纰板埌杩囩殑涓や釜浣庣骇bug:
1. 纰板埌鍦?28~255 鐨勫瓧绗︾洿鎺ュ紓甯革紝杩欎簺涓昏鏄タ娆ц瑷€鐨勫瓧绗︼紝鍥犱负浠栫敤涓€涓暟缁勬潵璁板綍 杞箟鍚庣殑瀛楃琛ㄧず锛屼絾鏄暟缁勯暱搴﹀彧鏈?28...
2. 鍐呭瓨鍗犵敤杩囧銆侳astjson涓轰簡鎬ц兘锛屽湪ThreadLocal涓紦瀛樹簡char[] buffer锛岃繖鏍烽伩鍏嶅垎閰嶅唴瀛樺拰gc鐨勫紑閿€銆備絾鏄鏋滅鍒颁簡澶х殑json(姣斿10M杩欐牱鐨?锛屽氨浼氬崰鐢ㄥぇ閲忕殑鍐呭瓨锛岃€屼笖浠ュ悗閮芥槸澶勭悊灏廕SON浜嗗唴瀛樺崰鐢ㄤ篃鍥炰笉鏉ャ€?br>杩欎簺闂铏界劧鍚庢潵鐨勭増鏈兘淇浜嗭紝浣嗘槸涔熷弽鏄犲嚭Fastjson浠g爜璐ㄩ噺涓婅姹備笉澶熶弗鏍笺€傝€孞ackson杩欎箞澶氬勾鏉ヤ娇鐢ㄤ笂杩樻病鏈夌鍒拌繃杩欐牱鐨凚ug.
3. 鏂囨。
鐩告瘮Jackson, Fastjson鑻辨枃鏂囨。灏辨樉寰楁瘮杈冩瑺缂猴紝宸叉湁鐨勪篃涓嶈鑼冿紝杩欐牱灏辨洿娌℃硶鎸囨湜鑰佸鐢ㄤ簡锛岀浉瀵硅繕鏄浗鍐呭紑鍙戣€呭崰澶у鏁?/span>
杩欎箞鏉ョ湅锛屾渶缁堢粨鏋滃緢鏄庢樉浜嗭細
瑙傜偣
JSON浠庡彂鏄庡埌鐜板湪涔嬫墍浠ユ祦琛岋紝骞朵笉鏄洜涓簀son蹇殑鍘熷洜锛堟瘮json蹇笖灏忓阀鐨勬牸寮忓拰绫诲簱涓€澶ф妸锛夛紝鑰屾槸鍥犱负json鍜寃eb缁撳悎鐨勬椂鍊欐洿鏄撲簬浣跨敤锛屽寮€鍙戜汉鍛樻槗浜庣悊瑙c€傚緢澶氫汉鎷縁astJson鍜孞ackson姣旓紝灏卞儚鎷块潪鏅鸿兘鏈哄拰iphone姣斿緟鏈烘椂闂达紝鍏跺姛鑳芥€т笉涓€鏍凤紝Jackson鐨勫緢澶氬姛鑳紽astJson骞舵病鏈夊疄鐜帮紝鎵€浠ヨ繖绉嶅姣斾篃涓嶅瑙傘€侳astJson涔嬫墍浠ユ病鍦ㄥ浗闄呬笂娴佽璧锋潵锛屾渶涓昏鐨勫師鍥犲簲璇ユ槸寮€鍙戣€呯殑鎬濊矾鍏ㄦ斁鍒扳€滃揩鈥濅笂鍘讳簡锛岃€屽亸绂讳簡鈥滄爣鍑嗏€濆強鍔熻兘鎬э紝璐ㄩ噺涔熶笉澶熷ソ锛屾湁鐐光€滆垗鏈€愭湯鈥濈殑鍛抽亾銆?/span>
褰撶劧鍦ㄧ洰鍓嶇殑鐜涓嬶紝鍥戒骇杞欢鑳借笍瀹炵殑蹇冩€佸仛濂藉紑婧愮殑涓嶅锛孎astJson鍥㈤槦鑳借繖涔堝揩鐨勫弽棣堝苟淇闂锛岃繖绉嶇簿绁炶繕鏄€煎緱绉拌禐鐨勩€傚笇鏈涘浗鍐呯殑鎶€鏈粠涓氳€呰兘鏇撮噸瑙嗏€滄妧鏈殑鍘熷闇€姹傗€濄€?/span>
娴嬭瘯浠g爜锛?/span>
鏍锋湰瀵硅薄鍖呮嫭Boolean銆両nt銆丩ong銆丏ouble銆丏ate銆丼tring銆丩ist鍜孧ap瀛楁锛屽叾涓璍ist闀垮害鍜孧ap鐨凨ey鏁伴噺鍙互鏍规嵁闇€瑕佹敼鍙樸€?/span>
/**
* 鏍锋湰鏁版嵁宸ュ巶 鎻愪緵鍚勭被鍏冩暟鎹牱鏈?/span>
*/
public class DataFactory {
private static final String[] chars = new String[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b",
"c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
"x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
"S", "T", "U", "V", "W", "X", "Y", "Z" };
// 閰嶇疆鍚勯」闀垮害/鏁伴噺
private static final int charNum = 62;
private static final int maxStrLength = 120;
private static final int defaultStrLength = 50;
private static final int maxListSize = 120;
private static final int defaultListSize = 20;
private static final int maxMapSize = 120;
private static final int defaultMapSize = 20;
private static final String[] types = new String[] { "string", "int", "long", "double", "boolean", "date"};
private static final int typeNum = 6;
private static final Random random = new Random();
/**
* 鐢熸垚闅忔満闀垮害鐨勫瓧绗︿覆
* @return 瀛楃涓?/span>
*/
public static String randomString(){
return randomString(random.nextInt(maxStrLength));
}
/**
* 鐢熸垚鎸囧畾闀垮害瀛楃涓?/span>
* @param len 瀛楃涓查暱搴?/span>
*/
public static String randomString(int len) {
if (len < 1 || len > maxStrLength) {
len = defaultStrLength;
}
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
sb.append(chars[random.nextInt(charNum)]);
}
return sb.toString();
}
/**
* 鐢熸垚List锛屽厓绱犵殑鏁伴噺闅忔満
* @return
*/
public static List<String> randomStringList() {
return randomStringList(random.nextInt(maxListSize));
}
/**
* 鐢熸垚List鏍锋湰
* @param size 鍏冪礌鐨勬暟閲?
* @return
*/
public static List<String> randomStringList(int size) {
if (size < 1 || size > maxListSize) {
size = defaultListSize;
}
List<String> list = new ArrayList<String>();
for (int i = 0; i < size; i++) {
list.add(randomString(random.nextInt(maxStrLength)));
}
return list;
}
/**
* 鐢熸垚闅忔満Map鏍锋湰,key鐨勬暟閲忛殢鏈?/span>
* @return
*/
public static Map<String, Object> randomMap() {
return randomMap(random.nextInt(maxMapSize));
}
/**
* 鐢熸垚闅忔満Map鏍锋湰
* @param size key鐨勬暟閲?/span>
* @return
*/
public static Map<String, Object> randomMap(int size) {
if (size < 1 || size > maxMapSize) {
size = defaultMapSize;
}
Map<String, Object> map = new HashMap<String, Object>();
for (int i = 0; i < size; i++) {
String type = types[random.nextInt(typeNum)];
if ("boolean".equals(type)) {
map.put("key" + i, random.nextBoolean());
} else if ("int".equals(type)) {
map.put("key" + i, random.nextInt());
} else if ("long".equals(type)) {
map.put("key" + i, random.nextLong());
} else if ("double".equals(type)) {
map.put("key" + i, random.nextDouble());
} else if ("date".equals(type)) {
map.put("key" + i, new Date());
} else if ("string".equals(type)) {
map.put("key" + i, randomString(random.nextInt(maxStrLength)));
}
}
return map;
}
}
/**
* 鏍锋湰瀵硅薄
*/
public class TestEntity implements Serializable {
private Double dataDouble;
private Date dataDate;
private String dataStr;
private Boolean dataBoolean;
private Integer dataInt;
private Long dataLong;
private List<String> dataList;
private Map<String, Object> dataMap;
public TestEntity() {
Random random = new Random();
dataBoolean = random.nextBoolean();
dataInt = random.nextInt();
dataLong = random.nextLong();
dataDouble = random.nextDouble();
dataDate = new Date();
dataStr = DataFactory.randomString();
dataList = DataFactory.randomStringList(defaultListSize);
dataMap = DataFactory.randomMap(mapKeyNum);
}
/**
* 鎸囧畾鍏冪礌鏁伴噺鐨勬牱鏈?/span>
*/
public TestEntity(int listSize, int mapKeyNum) {
Random random = new Random();
dataBoolean = random.nextBoolean();
dataInt = random.nextInt();
dataLong = random.nextLong();
dataDouble = random.nextDouble();
dataDate = new Date();
dataStr = DataFactory.randomString();
dataList = DataFactory.randomStringList(listSize);
dataMap = DataFactory.randomMap(defaultMapSize);
}
// get and set
// ......
}
/**
* 娴嬭瘯鍏ュ彛
*/
public class TestBuilder {
public static void main(String[] args) {
int testSize = 100000;
String jsonDataPath = "d:\test_json.dat";
String objectDataPath = "d:\test_object.dat";
buildJson(testSize, 10, 10, jsonDataPath);
buildObject(testSize, 10, 10, objectDataPath);
}
public static List<String> loadJSON(String filePath) {
List<String> list = new LinkedList<String>();
File file = new File(filePath);
if (!file.exists()) {
return list;
}
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(file));
String line = br.readLine();
while(line != null){
list.add(line);
line = br.readLine();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != br) {
try {
br.close();
} catch (IOException e) {
}
}
}
return list;
}
@SuppressWarnings("unchecked")
public static List<TestEntity> loadTests(String filePath) {
List<TestEntity> list = new LinkedList<TestEntity>();
File file = new File(filePath);
if (!file.exists()) {
return list;
}
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream(file));
list = (List<TestEntity>) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != ois) {
try {
ois.close();
} catch (IOException e) {
}
}
}
return list;
}
/**
* 鍒涘缓鏍锋湰
*
* @param testSize 鏍锋湰鏁伴噺
* @param listSize 鏍锋湰List闀垮害
* @param mapKeyNum 鏍锋湰Map鐨凨ey鏁伴噺
* @return 鏍锋湰List
*/
public static List<TestEntity> buildTest(int testSize, int listSize, int mapKeyNum) {
List<TestEntity> list = new LinkedList<TestEntity>();
for (int i = 0; i < testSize; i++) {
list.add(new TestEntity(listSize, mapKeyNum));
}
return list;
}
/**
* 鍒涘缓榛樿鏍锋湰
*/
public static List<TestEntity> buildTest(int testSize) {
List<TestEntity> list = new LinkedList<TestEntity>();
for (int i = 0; i < testSize; i++) {
list.add(new TestEntity());
}
return list;
}
/**
* 鍒涘缓鏍锋湰锛屽苟鎶婃牱鏈琂SON搴忓垪鍖栵紝淇濆瓨鍒版枃浠朵腑銆?/span>
*
* @param testSize 鏍锋湰鏁伴噺
* @param listSize 鏍锋湰List闀垮害
* @param mapKeyNum 鏍锋湰Map涓璌ey鐨勬暟閲?/span>
* @param filePath 鏍锋湰杈撳嚭鐨勬枃浠惰矾寰?/span>
*/
public static void buildJson(int testSize, int listSize, int mapKeyNum, String filePath) {
File file = new File(filePath);
File parent = file.getParentFile();
if (!parent.exists()) {
parent.mkdirs();
}
if (file.exists()) {
file.delete();
}
List<TestEntity> list = buildTest(testSize, listSize, mapKeyNum);
StringBuilder sb = new StringBuilder();
for (TestEntity item : list) {
sb.append(JSON.toJSONString(item));
sb.append(" ");
}
BufferedWriter bw = null;
try {
file.createNewFile();
bw = new BufferedWriter(new FileWriter(file));
bw.write(sb.toString());
bw.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != bw) {
try {
bw.close();
} catch (IOException e) {
}
}
}
}
public static void buildJson(int testSize, String filePath) {
File file = new File(filePath);
File parent = file.getParentFile();
if (!parent.exists()) {
parent.mkdirs();
}
if (file.exists()) {
file.delete();
}
List<TestEntity> list = buildTest(testSize);
StringBuilder sb = new StringBuilder();
for (TestEntity item : list) {
sb.append(JSON.toJSONString(item));
sb.append(" ");
}
BufferedWriter bw = null;
try {
file.createNewFile();
bw = new BufferedWriter(new FileWriter(file));
bw.write(sb.toString());
bw.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != bw) {
try {
bw.close();
} catch (IOException e) {
}TestEntity
}
}
}
public static void buildObject(int testSize, String filePath) {
List<TestEntity> list = buildTest(testSize);
File file = new File(filePath);
File parent = file.getParentFile();
if (!parent.exists()) {
parent.mkdirs();
}
if (file.exists()) {
file.delete();
}
ObjectOutputStream oos = null;
try {
file.createNewFile();
oos = new ObjectOutputStream(new FileOutputStream(file));
oos.writeObject(list);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != oos) {
try {
oos.close();
} catch (IOException e) {
}
}
}
}
/**
* 鐢熸垚鏍锋湰瀵硅薄锛屽苟淇濆瓨鍒版寚瀹氭枃浠?/span>
*
* @param testSize 鏍锋湰澶у皬
* @param listSize 鏍锋湰涓璍ist瀛楁闀垮害
* @param mapKeyNum 鏍锋湰涓璏ap瀵硅薄Key鏁伴噺
* @param filePath 鏍锋湰杈撳嚭鐨勮矾寰?/span>
*/
public static void buildObject(int testSize, int listSize, int mapKeyNum, String filePath) {
List<TestEntity> list = buildTest(testSize, listSize, mapKeyNum);
File file = new File(filePath);
File parent = file.getParentFile();
if (!parent.exists()) {
parent.mkdirs();
}
if (file.exists()) {
file.delete();
}
ObjectOutputStream oos = null;
try {
file.createNewFile();
oos = new ObjectOutputStream(new FileOutputStream(file));
oos.writeObject(list);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != oos) {
try {
oos.close();
} catch (IOException e) {
}
}
}
}
}
以上是关于的主要内容,如果未能解决你的问题,请参考以下文章