首页 > 解决方案 > 在 csv 上使用 Scanner,每次调用方法时都进行迭代

问题描述

我正在尝试解析具有发行说明并获取特定说明的文本文档。为此,我有一个带有所需发行说明键的 csv。我想扫描 csv 并使用每个键找到发行说明的匹配部分,并打印下面的描述。

我想使用 Scanner 类来练习它。

csv 看起来像:

foobar-123,foobar-127,foobar-129

发行说明文本文档如下所示:

foobar-123: ewkjhlq kghlhrekgh

foobar-124: lkjhfgrelgkj nberg

foobar-127: ljdfgl kjwneglkjn fdg

foobar-129: lguwlrkguj gwrlekgj werlktj

我遇到的问题是遍历 csv。我似乎一直在抓取 csv 中的第一个字符串。我试图弄清楚如何在 csv 中保存我的位置,所以每次调用该方法时,它都会转到下一个字符串。

我想我可以创建一个变量来保存最后找到的字符串,然后使用扫描仪找到它,然后抓取下一个字符串。但这需要每次我想进步时都扫描 csv,这似乎效率不高。使用 Scanner 类遍历 csv 的最佳方法是什么?

这是我到目前为止的代码:

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;

public class ReleaseNotesScan {
    public static void main(String[] args) {

        //Open csv file with issue keys
        Scanner getIssueKeys = null;
        try {
            getIssueKeys = new Scanner(new FileReader("resources/Issues.txt"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }


        //Open release notes
        Scanner releaseNotes = null;
        try {
            releaseNotes = new Scanner(new FileReader("resources/Release notes text.txt"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        //Get issue key from csv
        String issueKey = Finders.issueKey(getIssueKeys);

        //The below three lines are just for testing if I am iterating through the csv
        System.out.println(issueKey);
        Finders.issueKey(getIssueKeys);
        System.out.println(issueKey);




        //Get issue key and description
        String description = Finders.sectionContent(releaseNotes, issueKey);
        System.out.println(issueKey + ": " + description);

        //Close csv
        getIssueKeys.close();

        //Close release notes
        releaseNotes.close();
    }

}

我的查找器类:

import java.util.Scanner;

public class Finders {
    //parse csv
    public static String issueKey(Scanner findIssues) {
        findIssues.useDelimiter(",");
        String issue = findIssues.next();

        return issue;
    }

    public static String sectionContent(Scanner releaseNotes, String heading) {
        while (releaseNotes.hasNextLine()){
            String found = releaseNotes.findInLine(heading);
            if (found != null){
                releaseNotes.findInLine(": ");
                String grabIt = releaseNotes.nextLine();
                return grabIt;
            }
            releaseNotes.nextLine();
        }
        releaseNotes.close();
        return "Not found";
    }
}

标签: javacsvparsingjava.util.scanner

解决方案


下面是一些示例代码,用于演示如何构建应用程序。我做了一些假设,输入文件“发出”为字符串(为简洁起见,而不是文件)。这些问题存储在一个数组中,并在HashMap集合中发布说明。从文件中读取发行说明,将其标记化(以“:”作为分隔符)作为问题及其发行说明文本。问题是关键,发行说明是地图中的价值。

最后,迭代每个问题并从地图中获取相应的发行说明。

示例代码:

import java.util.*;
import java.io.*;
public class MatchIssues {
    private static String [] issues;
    private static Map<String,String> releseNotes = new HashMap<>();
    public static void main(String [] args)
            throws IOException {
        getIssues();
        getReleaseNotes();
        for(String issue : issues) {
            // Match release notes for the issue
            System.out.println(releseNotes.get(issue));
        }
    }
    private static void getIssues() {
        String s = "foobar-123,foobar-127,foobar-129"; // use string for demo
        issues = s.split(",");
        System.out.println(Arrays.toString(issues));
    }
    private static void getReleaseNotes()
            throws IOException {
        BufferedReader reader =
                new BufferedReader(new FileReader("release_notes.txt"));
        String line = null;
        while ((line = reader.readLine()) != null) {
            String [] tokens = line.split(":");
            releseNotes.put(tokens[0].trim(), tokens[1].trim());
        }
        System.out.println(releseNotes);
    }
}

release_notes.txt

foobar-123: aa ewk jhlq kghlhrekgh aa
foobar-124: bb lkjh fgrelgkj nberg bb
foobar-127: yy ljdfgl kjw neglkjn fdg yy
foobar-129: zz lgu wlrkguj gw rlekgj werlktj zz

推荐阅读