从Java中的文本文件逐行比较

时间:2016-05-09 14:24:27

标签: java file

我正在尝试比较Java中的文本文件中的行。 例如,有一个包含以下行的文本文件:

  

temp1 am 32.5 pm 33.5
temp2 am 33.5 pm 33.5
temp3 am 32.5 pm   33.5
temp4 am 31.5 pm 35

a b c d e

a 是该行的名称, b 是常量(am), < em> c 是变量, d 是常量(pm), e 是另一个变量。

它只会比较变量 - &gt; temp1(c)到temp2(c),temp1(e)到temp2(e)等。

当有两行或多行具有相同的c(s)和e(s)时,它将抛出FormatException。

从上面的示例文本文件中,因为temp1的c与temp3的c相同,而temps1的e与temp3的相同,所以它会抛出FormatException。

这是我到目前为止:

public static Temp read(String file) throws FormatException {
        String line = "";
        FileReader fr = new FileReader(fileName);
        Scanner scanner = new Scanner(fr);

        while(scanner.hasNextLine()) {
            String line = scanner.nextLine();
            System.out.println(line);
        }
        scanner.close();

        if () {
            throw new FormatException("Error.");

我该怎么做?

4 个答案:

答案 0 :(得分:3)

您需要拆分行以提取变量,然后选择Set以检查重复项:

Set<String> ceValues = new HashSet<>();
while(scanner.hasNextLine()) {
    String line = scanner.nextLine();
    String[] values = line.split(" ");
    if (!ceValues.add(String.format("%s %s", values[2], values[4]))) {
        // The value has already been added so we throw an exception
        throw new FormatException("Error.");
    }
}

答案 1 :(得分:1)

由于我不想为你做功课,让我帮你解决一下:

while(scanner.hasNextLine()) {
    String line = scanner.nextLine();
    String[] partials = line.split(" ");

    String a = partials[0]; 
    //...
    String e = partials[4];    
}

我将这条线拆分为space,因为在您的情况下,这是唯一要拆分的内容。这给了我们5个单独的字符串(a到e)。您需要将它们保存在String[][]中以供日后分析,但您应该能够自己弄清楚如何执行此操作。

尝试使用此功能,如果您仍然卡住,请更新您的问题。

答案 2 :(得分:0)

这里有一个基本包含的例子:

首先,我会制作一个代表行信息的简单POJO:

public class LineInfo {
    private String lineName;
    private String am;
    private String pm;

    public LineInfo(String lineName, String am, String pm) {
        this.lineName = lineName;
        this.am = am;
        this.pm = pm;
    }

    // getters and setters
}

其次,我需要一种模式来验证每一行并从中提取数据:

//                                   group 1         group 2  group3           group 4  group 5
//                                        v               v    v                    v    v
private static final String LINE_REGEX = "(\\w+)\\s+am\\s+(\\d+(\\.\\d+)?)\\s+pm\\s+(\\d+(\\.\\d+)?)";
private static final Pattern LINE_PATTERN = Pattern.compile(LINE_REGEX);

第三,我会像这样重写read方法(为简单起见,我返回void):

public static void read(String fileName) throws FormatException {
    // collect your lines (or better the information your lines provide) in some data structure, like a List
    final List<LineInfo> lines = new ArrayList<>();

    // with this syntax your FileReader and Scanner will be closed automatically
    try (FileReader fr = new FileReader(fileName); Scanner scanner = new Scanner(fr)) {

        while (scanner.hasNextLine()) {
            final String line = scanner.nextLine();
            final Matcher matcher = LINE_PATTERN.matcher(line);

            if (matcher.find()) {
                lines.add(new LineInfo(matcher.group(1), matcher.group(2), matcher.group(4)));
            } else {
                throw new FormatException("Line \"" + line + "\" is not valid.");
            }
        }

        // recursive method
        compareLines(lines, 0);
    } catch (final IOException e) {
        e.printStackTrace();
        // or handle it in some way
    }
}

private static void compareLines(List<LineInfo> lines, int index) throws FormatException {
    // if there are no more lines return
    if (index == lines.size()) {
        return;
    }

    final LineInfo line = lines.get(index);
    for (int i = index + 1; i < lines.size(); i++) {
        final LineInfo other = lines.get(i);
        // do the check
        if (line.getAm().equals(other.getAm()) && line.getPm().equals(other.getPm())) {
            throw new FormatException(String.format("Lines #%d (%s) and #%d (%s) does not meet the requirements.",
                    index, line.getLineName(), i, other.getLineName()));
        }
    }

    // do the same thing with the next line
    compareLines(lines, index + 1);
}

答案 3 :(得分:0)

如果我的问题是正确的,那么您需要逐行检查,以便使用c和e作为标准查找重复项

这意味着,必须将行n与所有其他行进行比较,如果重复,那么异常......

建议如下:

定义一个表示每行的元素c和e的类......

class LinePojo {

    private String c;
    private String e;
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((c == null) ? 0 : c.hashCode());
        result = prime * result + ((e == null) ? 0 : e.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        LinePojo other = (LinePojo) obj;
        if (c == null) {
            if (other.c != null)
                return false;
        } else if (!c.equals(other.c))
            return false;
        if (e == null) {
            if (other.e != null)
                return false;
        } else if (!e.equals(other.e))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "(c=" + c + ", e=" + e + ")";
    }

    public LinePojo(String c, String e) {
        this.c = c;
        this.e = e;
    }
}

然后是该类的列表,其中每行将被插入和/或检查元素是否存在..

List<LinePojo> myList = new ArrayList<LinePojo>();

然后逐行迭代

while(scanner.hasNextLine()) {
    String line = scanner.nextLine();
    String[] lineInfo = line.split(" ");
    LinePojo lp = new LinePojo(lineInfo[2], lineInfo[4]);
    if (myList.contains(lp)) {
        throw new IllegalArgumentException("there is a duplicate element");
    } else {
        myList.add(lp);
    }    
}