簡體   English   中英

從Java中的文本文件逐行比較

[英]Compare line by line from a text file in Java

我正在嘗試比較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

ABCDE

a是行的名稱, b是常數(am), c是變量, d是常數(pm), e是另一個變量。

它只會比較變量-> temp1(c)與temp2(c),temp1(e)與temp2(e)等。

當有兩行或多行具有相同的c和e時,它將拋出FormatException。

在上面的示例文本文件中,由於temp1的c與temp3的c相同,而temps1的e與temp3的e相同,因此它將引發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.");

我該怎么做?

您將需要拆分行以提取變量,然后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.");
    }
}

因為我不想為您做作業,所以讓我開始吧:

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

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

我將行分割成一個space因為這是您情況下唯一要分割的東西。 這給了我們5個獨立的字符串(a到e)。 您將需要將它們保存在String[][]以便以后進行分析,但是您應該可以自己弄清楚該怎么做。

嘗試解決這個問題,如果仍然遇到問題,請更新您的問題。

在這里,您得到的示例基本上包括:

首先,我將制作一個簡單的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);
}

如果我的問題沒問題,那么您需要逐行檢查,以便使用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);
    }    
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM