解析文件分为逗号和等号

时间:2015-01-26 19:39:00

标签: java string parsing

我有一个如下所示的文件

name=helium,sign=he,number=2  
name=lithium,sign=li
name=gold,sign=au,number=79  

名称,标志和数字是地图中的键。如果未列出某些密钥,则应将其变为“未识别”值。现在我想解析这个逗号/等号分隔文件,但我不会成为我需要的结果,无法找到并改善错误。

这是我到目前为止所拥有的:

static Map<Table, String> periodicTable = new LinkedHashMap<Table, String>();
String[] list = fileToString(args[0]); // fileToString is to become the file content as a String array, where in the first field of the array is saved the first line of the file, in the second field - the second line and so on.
for (int i = 0; i < list.length; i++) {
    String[] element = list[i].split(",");

    for (int j = 0; j < element.length; j++) {
        String[] feature = element[j].split("=");
        if (feature[0].equals("name") 
             || feature[0].equals("sign") || feature[0].equals("number")) {
            feature[1] = periodicTable.get(feature[0]);
        } else {
            feature[1] = "unspecified";
        }
    }
}


public class Table {
private String name;
private String number;
private String sign;

public Table(String name, String number, String sign) {
    this.name = name;
    if (Integer.parseInt(number) >= 1 && Integer.parseInt(number) <= 118) {
        this.number = number;
    }
    this.sign = sign;
    }
}

如果有人可以帮我解决这个问题,那将会很棒。提前谢谢!

2 个答案:

答案 0 :(得分:0)

不是解决方案,而是对您的代码提出一些意见:

  1. 您解析文件的代码不在主要方法之内,我认为您错过了某处

  2. 使用StringTokenizer而不是split:

    StringTokenizer tokenizer = new StringTokenizer(line,&#34;,&#34;); while(tokenizer.hasMoreTokens()){       String element = tokenizer.nextToken(); }

  3. 使用foreach样式而不是索引:

    for(String line:list){      // foo在线 }

  4. 尝试使用&#34; equals&#34;常量字符串而不是变量的方法:

    if(&#34; name&#34; .equals(feature [0])){ }

    因为变量可以为null,这可能会破坏您的代码。

答案 1 :(得分:0)

使方法更简洁的一种相对标准的方法是将元素属性封装在enum中。这样,您可以非常轻松地扩展存储的属性。它还避免了你丑陋的if陈述。我已将Table更改为Element,因为Table列出Element似乎更自然。

public class Element {
    enum Attribute {
        NAME ("name", Element::setName),
        ATOMIC_NUMBER("number", Element::setNumber),
        SIGN("sign", Element::setSign);

        private final String attributeName;
        private final ValueSetter valueSetter;

        Attribute(String elementName, Element.ValueSetter valueSetter) {
            this.elementName = elementName;
            this.valueSetter = valueSetter;
        }

        public static void setElementValue(Element element, String attributeValue) {
            String[] attributeValuePair = attributeValue.split("=");
            String attributeName = attributeValuePair[0];
            String value = attributeValuePair[1];
            values().stream().filter(attributeName::equals)
                .forEach(attr -> attr.valueSetter.setValue(element, value));
        }
    }

    interface ValueSetter {
        void setValue(Element element, String value);
    }

    private Element() {
        // set default vaues
    }

    private static setName(Element element, String name) {
        element.name = name;
    }

    private static setSign(Element element, String sign) {
        element.sign = sign;
    }

    private static setNumber(Element element, String number) {
        element.number = Integer.parseInt(number);
    }

    public static Element readFromLine(String line) {
        Element element = new Element();
        line.split(",").stream()
            .forEach(attrVal -> Attribute.setElementValue(element, attrVal));
    }

    // same for setNumber, setSign
}

然后你的阅读行代码可能会有点整洁:

List<Element> table = lines.stream()
    .map(Element::readFromLine)
    .collect(Collectors.toList());

我在这里跳过了很多错误检查,但希望你能得到这个想法。