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++);
++
之后