自己写JSON解析工具

JSON就是固定格式的字符串,能包含编程世界中的数组和字典两种基本数据结构信息,相对于以前流行的XML的复杂,JSON的解析相对要简单很多(XML解析其实也挺简单的,只是有一堆标准一堆规格,附带的东西太多,比较不自由,没有太多兴趣,有意向的朋友可以自行尝试)。

OK,废话不多说,直接上代码(因为是C#直接翻译过来的,所以可能有些地方不是很符合java最佳编码方案,仅做介绍用,不用纠结这些细节)。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class ToObject {

	private static final char cl_s = '[';
	private static final char cl_e = ']';
	private static final char cd_s = '{';
	private static final char cd_e = '}';
    private static final String Null = "Null";
    
    private int e = 0;
    private String jsonString = null;
    
    public Object toObject(String jsonString) {
        this.jsonString = jsonString;
        return this.toObject(0);
    }
    // 路由
	private Object toObject(int s) {
		char c = this.jsonString.charAt(s);
		if (c == cl_s) {
			return this.toObjectFromCLS(s + 1);
		} else if (c == cd_s) {
			return this.toObjectFromCDS(s + 1);
		} else {
			if (s == 0) {
				return ToObject.Null;
			}
			if (c == '"') {
				return this.toObjectFromString(s);
			} else {
				return this.toObjectFromSimpleType(s);
			}
		}
	}

	// 解析集合
	private Object toObjectFromCLS(int s) {
        List<Object> ret = new ArrayList<Object>();
        char c;
        int l = jsonString.length();
        Object obj;
        for (int i = s; i < l; i++) {
            c = jsonString.charAt(i);
            if (c == ' ' || c == ',') {
                continue;
            }
            if (c == cl_e) {
                e = i;
                return ret;
            }
            obj = this.toObject(i);
            if (ToObject.Null.equals(obj)) {
                break;
            }
            ret.add(obj);
            i = e;
        }
        return null;
	}

	// 解析键值对
	private Object toObjectFromCDS(int s) {
		Map<Object, Object> ret = new HashMap<Object, Object>();
		char c;
		int l = jsonString.length(), step = 0;
		Object key = null, value = null, obj;
		for (int i = s; i < l; i++) {
			c = jsonString.charAt(i);
			if (c == ' ') {
				continue;
			}
			if (c == cd_e) {
				e = i;
				return ret;
			}
			if (c == ',') {
				step = 0;
				key = null;
				continue;
			}
			if (c == ':') {
				step = 1;
				value = null;
				continue;
			}
			obj = this.toObject(i);
			if (ToObject.Null.equals(obj)) {
				break;
			}
			if (step == 0) {
				key = obj;
			} else if (step == 1) {
				value = obj;
				ret.put(key, value);
			}
			i = e;
		}
		return null;
	}

	// 解析字符串
	private Object toObjectFromString(int s) {
		char c = jsonString.charAt(s);
		s++;
		StringBuilder ret = new StringBuilder();
		for (int i = s; i < jsonString.length(); i++) {
			c = jsonString.charAt(i);
			if (c == '"') {
				e = i;
				return ret.toString();
			}
			if (c == '\"') {
				ret.append('"');
				continue;
			}
			if (c == '\\' && jsonString.charAt(i + 1) == '\"') {
				i++;
				ret.append('\"');
				continue;
			}
			ret.append(c);
		}
		return null;
	}

	// 基本类型
	private Object toObjectFromSimpleType(int s) {
		final String t = "true";
		final String f = "false";
		final String n = "null";
		final String u = "undefined";
		if (this.isType(s, t)) {
			e = s + t.length() - 1;
			return true;
		}
		if (this.isType(s, f)) {
			e = s + f.length() - 1;
			return false;
		}
		if (this.isType(s, n)) {
			e = s + n.length() - 1;
			return null;
		}
		if (this.isType(s, u)) {
			e = s + u.length() - 1;
			return null;
		}
		// 数字
		char c = jsonString.charAt(s);
		if ((c >= '0' && c <= '9') || c == '.' || c == '-') {
			boolean hasPoint = false;
			for (int i = s; i < jsonString.length(); i++) {
				c = jsonString.charAt(i);
				switch (c) {
				case '.':
					if (hasPoint)
						return null;
					hasPoint = true;
					break;
				case '0':
				case '1':
				case '2':
				case '3':
				case '4':
				case '5':
				case '6':
				case '7':
				case '8':
				case '9':
				case '-':
					break;
				case 'F':
				case 'f':
					e = i;
					return Float.parseFloat(jsonString.substring(s, i - s));
				case 'L':
				case 'l':
					e = i;
					if (hasPoint)
						return null;
					return Long.parseLong(jsonString.substring(s, i - s));
				default:
					e = i - 1;
					if (hasPoint) {
						return Double.parseDouble(jsonString
								.substring(s, i - s));
					} else {
						return Integer.parseInt(jsonString.substring(s, i - s));
					}
				}
			}
		}
		return null;
	}

	private boolean isType(int s, String type) {
		for (int i = 0; i < type.length(); i++) {
			if (jsonString.charAt(s + i) != type.charAt(i)) {
				return false;
			}
		}
		return true;
	}



整个字符串解析就这些,测试如下:
public static void main(String[] args) {
		String json = "{\"key1\":\"value1\",\"key2\":[\"array1\",\"array2\"]}";
		Object obj = new ToObject().toObject(json);
		Map<Object, Object> map = (Map<Object, Object>)obj;
		Set<Object> keys = map.keySet();
		Object value = null;
		for(Object key : keys) {
			value = map.get(key);
			System.out.print("key=" + key);
			if (value instanceof List) {
				List<Object> array = (List<Object>)value;
				System.out.print("\tvalue=");
				for(Object item : array) {
					System.out.print(item);
				}
				System.out.println();
			} else {
				System.out.println("\tvalue=" + value);
			}
		}
	}


打印结果如下:

再次重申,仅仅做功能展示,给大家扩展思路用,别纠结性能和代码规范啥的。

如果有兴趣的同学可以多交流。

转载于:https://my.oschina.net/5zx1Vm/blog/284771

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值