Java使用对象来保持状态似乎不起作用

Java使用对象来保持状态似乎不起作用,java,oop,Java,Oop,我正在编写一个实用程序类,它应该能够解析分隔文件(逗号、管道、冒号分隔文件)。它读取特定行,需要提取该行中最常用的分隔符。但这似乎并不像预期的那样有效。当我在主方法调用方类中调用getHeader()方法时,似乎唯一被确认的分隔符是行中的逗号。我认为是我的java和oop能力不足,使我无法理解这个问题。请给我一些建议。先谢谢你。下面是我的代码: public class Parser { // sample line of data String line = "Ther

我正在编写一个实用程序类,它应该能够解析分隔文件(逗号、管道、冒号分隔文件)。它读取特定行,需要提取该行中最常用的分隔符。但这似乎并不像预期的那样有效。当我在主方法调用方类中调用
getHeader()
方法时,似乎唯一被确认的分隔符是行中的逗号。我认为是我的java和oop能力不足,使我无法理解这个问题。请给我一些建议。先谢谢你。下面是我的代码:

    public class Parser {
    // sample line of data
    String line = "There|is|data,in,this:file|hause";

    private static class Delimiters {
        static char DEFAULT = ',';
        static char COMMA = ',';
        static char SEMI = ';';
        static char PIPE = '|';
        static char COLON = ':';
    };

    public String[] getHeader() {
        char delim = findDelimiter(line);
        System.out.println("Header delim: " + delim);
        String[] columns = line.split(String.valueOf(delim));
        return columns;
    }

    // figure out the delimiter of the file. This method
    // gets called on lines of file data
    public char findDelimiter(String line) {
        Delimiter dim = new Delimiter();
        for (int i = 0; i < line.length(); i++) {
            for (char delim : Arrays.asList(Delimiters.COLON, Delimiters.COMMA,
                    Delimiters.PIPE, Delimiters.SEMI)) {
                if (delim == line.charAt(i)) {
                    dim.increaseDelimiterCnt(delim);
                }
            }
        }

        final char theLinesDelimiter = dim.mostCommonDelimiter();
        return theLinesDelimiter;
    }

    private class Delimiter {
        Map<Character, Integer> delimiterCounts = new HashMap<Character, Integer>();

        private void increaseDelimiterCnt(char delim) {
            System.out.println(delim);

            int value = (delimiterCounts.containsKey(delim) ? delimiterCounts
                    .get(delim) : 0);
            delimiterCounts.put(delim, value++);
            System.out.println(getDelimiterCounts());
        }

        private Map<Character, Integer> getDelimiterCounts() {
            return delimiterCounts;
        }

        /**
         * Gets the delimiter based on greatest frequency of first line in file.
         * 
         * @return String
         */
        private char mostCommonDelimiter() {
            char theDelimiter = ',';
            System.out.println(delimiterCounts);
            int maxValueInMap = (Collections.max(delimiterCounts.values()));
            for (Map.Entry<Character, Integer> entry : delimiterCounts
                    .entrySet()) {
                if (entry.getValue().equals(maxValueInMap)) {
                    theDelimiter = entry.getKey();
                }
            }
            return theDelimiter;
        }
    }

}
公共类解析器{
//数据样本行
String line=“There | is | data,in,this:file | hause”;
私有静态类分隔符{
静态字符默认值=',';
静态字符逗号=',';
静态字符半=';';
静态字符管道=“|”;
静态字符冒号=':';
};
公共字符串[]getHeader(){
char delim=finddelimitor(行);
System.out.println(“标题delim:+delim”);
String[]columns=line.split(String.valueOf(delim));
返回列;
}
//找出文件的分隔符。此方法
//在文件数据行上调用
公共字符findDelimiter(字符串行){
Delimiter dim=新的分隔符();
对于(int i=0;i
错误在这一行:

            delimiterCounts.put(delim, value++);
变量名后的
++
是一个后增量,因此尽管
值+++
增量
,但其计算结果仍然是原始值。因此,上述内容相当于:

            delimiterCounts.put(delim, value);
            value = value + 1; // pointless, since we never use value again
相反,你应该写:

            delimiterCounts.put(delim, value + 1);
您的调试输出实际上应该足以告诉您这一点;它显示
delimiterCounts
中的每个分隔符都映射为零

我建议你读一读。你可能会发现它对未来很有用

(注意:解决上述问题后,您将遇到另一个问题。您的程序现在将正确地将
|
识别为分隔符,但
行。拆分(|)并不是您想要的。要解决这个问题,您需要使用
模式。请引用
。我会让您了解详细信息。)


编辑添加:既然您对OOP有顾虑,我也应该谈谈总体设计。通过使用枚举,您可以创建更健壮、更高效的设计:

public enum Delimiter {
    COMMA(','), SEMI(';'), PIPE('|'), COLON(':');

    public final char c;
    public final Pattern pattern;

    private DelimiterChar(final char c) {
        this.c = c;
        this.pattern = Pattern.compile(Pattern.quote(Character.toString(c)));
    }
}
然后,当需要枚举可能的分隔符时,可以使用
Delimiter.values()
,并可以使用
EnumSet
按分隔符存储计数


请注意,我使用了名称
分隔符
来表示与您非常不同的内容。您的
Delimiter
类可能应该被称为
DelimiterCounter
,因为它的实例计数的是分隔符,而不是它们自己分隔任何东西。

错误在这一行:

            delimiterCounts.put(delim, value++);
变量名后的
++
是一个后增量,因此尽管
值+++
增量
,但其计算结果仍然是原始值。因此,上述内容相当于:

            delimiterCounts.put(delim, value);
            value = value + 1; // pointless, since we never use value again
相反,你应该写:

            delimiterCounts.put(delim, value + 1);
您的调试输出实际上应该足以告诉您这一点;它显示
delimiterCounts
中的每个分隔符都映射为零

我建议你读一读。你可能会发现它对未来很有用

(注意:解决上述问题后,您将遇到另一个问题。您的程序现在将正确地将
|
识别为分隔符,但
行。拆分(|)并不是您想要的。要解决这个问题,您需要使用
模式。请引用
。我会让您了解详细信息。)


编辑添加:既然您对OOP有顾虑,我也应该谈谈总体设计。通过使用枚举,您可以创建更健壮、更高效的设计:

public enum Delimiter {
    COMMA(','), SEMI(';'), PIPE('|'), COLON(':');

    public final char c;
    public final Pattern pattern;

    private DelimiterChar(final char c) {
        this.c = c;
        this.pattern = Pattern.compile(Pattern.quote(Character.toString(c)));
    }
}
然后,当需要枚举可能的分隔符时,可以使用
Delimiter.values()
,并可以使用
EnumSet
按分隔符存储计数


请注意,我使用了名称
分隔符
来表示与您非常不同的内容。您的
Delimiter
类可能应该被称为
DelimiterCounter
,因为它的实例计数的是分隔符,而不是它们自己分隔任何东西。

错误在这一行:

            delimiterCounts.put(delim, value++);
++
之后