将字符串解析为映射的最有效方法是什么?

时间:2013-03-19 14:00:01

标签: java parsing csv map

我正在查看的代码是一个URL调用,它返回一个用于绘制图表的点组成的字符串。[14.1(point),1363649400(UTC中的时间戳将在稍后转换)]

String = [14.1,1363649400],[14.4,1363650300],[14.6,1363651200],[15.1,1363652100],[14.3,1363653000],[14.2,1363653900],[14.8,1363654800]................

最好的方法似乎是删除方括号,然后使用String.split()。

所以想知道是否有人对如何将此字符串转换为地图有更好的想法,比如说。

4 个答案:

答案 0 :(得分:1)

像这样:

points[] = string.substring(1, string.length()-1).split("],[");

会产生一个

数组
"1,3", "3,4"

答案 1 :(得分:1)

这将负责解析和构建地图。地图也将按时间戳排序。

final Matcher m = Pattern.compile("\\[(.*?),(.*?)\\]").matcher(input);
final Map<Long, Double> points = new TreeMap<>();
while (m.find()) 
  points.put(Long.parseLong(m.group(2), Double.parseDouble(m.group(1)));

答案 2 :(得分:1)

创建一个用于保存数据对象的类:

private static final class Data {

    private final BigDecimal point;
    private final Date date;

    public Data(final String point, final String date) {
        this.point = new BigDecimal(point);
        this.date = new Date(Long.parseLong(date));
    }

    @Override
    public String toString() {
        return "Data{" + "point=" + point + ", date=" + date + '}';
    }
}

现在使用正则表达式模式解析字符串,随时构建Data个对象。我使用了占有匹配器,因为String可能很长,你不希望快速引擎反复试图匹配。

此处Data甚至可以将单个String解析为真实数据类型。

public static void main(String[] args) {
    final String s = "[14.1,1363649400],[14.4,1363650300],[14.6,1363651200],[15.1,1363652100],[14.3,1363653000],[14.2,1363653900],[14.8,1363654800]";
    final Pattern p = Pattern.compile("\\[([^,]++),(\\d++)\\]");
    final Matcher matcher = p.matcher(s);
    final Collection<Data> datas = new LinkedList<Data>();
    while (matcher.find()) {
        datas.add(new Data(matcher.group(1), matcher.group(2)));
    }
    for (final Data data : datas) {
        System.out.println(data);
    }
}

输出:

Data{point=14.1, date=Fri Jan 16 19:47:29 GMT 1970}
Data{point=14.4, date=Fri Jan 16 19:47:30 GMT 1970}
Data{point=14.6, date=Fri Jan 16 19:47:31 GMT 1970}
Data{point=15.1, date=Fri Jan 16 19:47:32 GMT 1970}
Data{point=14.3, date=Fri Jan 16 19:47:33 GMT 1970}
Data{point=14.2, date=Fri Jan 16 19:47:33 GMT 1970}
Data{point=14.8, date=Fri Jan 16 19:47:34 GMT 1970}

显然,您可以将Data放入MapSet或适合您的任何内容。

答案 3 :(得分:0)

使用正则表达式似乎不是最好的方法,至少对我而言。说实话,java中正则表达式的表现非常糟糕。我自己编写一个解析器,只需要O(n) n作为字符串的长度。

我是怎么做到的:

public void splitSequence(String str) {
                List<Double> lstPoint = new ArrayList<>();
    List<Long> lstTime = new ArrayList<>();
    char[] buf = new char[128];
    int i=0;
    boolean isPoint = true;
    for(Character c : str.toCharArray()) {
        if(c == ',') {
            if(isPoint) {
                lstPoint.add(new Double(new String(buf,0,i)));
                isPoint = false;
            }
            else {
                lstTime.add(Long.parseLong(new String(buf,0,i)));
                isPoint = true;
            }
            buf = new char[128];
            i=0;
        } else if(!(c == '[' || c == ']')) {
            buf [i++] = c;
        }
    }
    }
//usage
splitSequence("[14.1,1363649400],[14.4,1363650300],[14.6,1363651200],[15.1,1363652100],[14.3,1363653000],[14.2,1363653900],[14.8,1363654800]");