【问题标题】:Get csv and compare lines. ArrayList? Java获取 csv 并比较行。数组列表?爪哇
【发布时间】:2010-11-21 23:26:59
【问题描述】:

我不经常使用 java,现在我遇到了一些问题。 我想读取这样的 CSV 文件:

A、B、C、D
A,B,F,K
E,F,S,A
A,B,C,S
A,C,C,S

Java 不知道动态数组,所以我选择了一个 ArrayList。到目前为止,这有效。问题是: 如何存储 ArrayList?我认为另一个 ArrayList 会有所帮助。 这就是我得到的:

    BufferedReader reader = new BufferedReader(
            new InputStreamReader(this.getClass().getResourceAsStream(
                    "../data/" + filename + ".csv")));

    List rows = new ArrayList(); 

    String line;
    while ((line = reader.readLine()) != null) {

        rows.add(Arrays.asList(line.split(",")));

    }

现在我得到一个大小为 5 的 rows.size() 的 ArrayList。 例如,我如何获得 row[0][0] ?

我想做什么?问题是我想找到除了最后一列之外的同一行。 例如,我想找到第 0 行和第 3 行。 非常感谢你

谢谢大家!你帮了我很多。 =) 也许 Java 和我会成为朋友 =) 谢谢!

【问题讨论】:

  • 您可以逐行读取 csv,并将每个条目(不包括最后一列)存储在 HashSet 中。然后,如果你读到一个新行,你可以检查 HashSet 是否已经包含相同的条目(使用 contains() 方法)。

标签: java csv arraylist


【解决方案1】:

不需要提前知道行大小,String.split()返回一个String数组:

List<String[]> rows = new ArrayList<String[]>(); 

String line = null;
while((line = reader.readLine()) != null)
    rows.add(line.split(",", -1));

访问特定行:

int len = rows.get(0).length;
String val = rows.get(0)[0];

另外,除了最后一列之外,您是否总是按整行进行比较?您可以只取最后一个值 (line.replaceFirst(",.*?$", "")) 并将行作为字符串进行比较(当然,必须注意空格和其他格式)。

稍微不同的方式:

Set<String> rows = new HashSet<String>(); 

String line = null;
while((line = reader.readLine()) != null){
    if(!rows.add(line.substring(0, line.lastIndexOf(','))))
        System.out.println("duplicate found: " + line);
}

当然,如果您确实需要捕获匹配行,请根据需要进行修改。

【讨论】:

  • 等等。 “rows”是“String[]”的列表,但您添加的是“String”行。除非我遗漏了什么,否则您的代码将无法编译!
  • line.split() 是否返回一个字符串数组?
  • 我在添加line.split()的结果,即String[](字符串数组)
  • rows.get(0).get(0) 在您的代码中不起作用的原因是您没有为List rows 指定类型,因此rows 的内容被视为Object。应该是:List&lt;List&lt;String&gt;&gt; rows(如果你真的想使用列表,我更喜欢我的方式)。
  • 按照你的方式,我现在运行了。我可以按行和列访问每个元素。现在比较部分...
【解决方案2】:

您需要声明一个数组的 ArrayList。假设 csv 文件具有已知数量的列,这里唯一需要的动态列表是“表”的“行”,由数组 char[](列)的 ArrayList(rows) 形成。 (如果不是,那么 ArrayList 的 ArrayList 就可以了)。

它就像任何其他语言中的 2D 表:一个数组数组。只是在这种情况下,其中一个数组需要是动态的。

要读取文件,您需要两个循环。一个读取每一行,就像你正在做的那样,另一个读取每个字符的字符。

简单说明:如果您要声明这样的数组:

char[] row = new char[5];

然后将每一行添加到 ArrayList 中,如下所示:

yourList.add(row);

您将拥有一个列表,其中包含指向同一数组的指针。您需要像这样使用 .clone() 方法:

yourList.add(row.clone());

要像 table[1][2] 那样访问它,你需要使用 arraylist.get(1).get(2);

【讨论】:

  • csv 的每一行在同一个 csv 中的列数相同。但是不同的csv文件有不同的列数。
  • 然后使用另一个 ArrayList,但请记住 .clone() 方法。仍然需要它。顺便说一句,要像 table[1][2] 那样访问它,你需要使用 arraylist.get(1).get(2);
  • 我试图找出列数: rows.get(0).size() 但这不起作用。 .clone() 方法是什么意思?为什么我需要这个?
  • 另外,在声明它们时不要忘记声明要放入 List 的东西:List 或 List
  • @user515466:如果需要,可以使用 arraylist 的 arraylist。您需要 clone() 方法,因为在我的示例中,行只是一个指向数组的指针。如果您将“行”添加到列表中,那么您将拥有一个指针列表,并且所有指针都指向您使用“new char [5]”声明的同一内存块。为了避免这种情况,你必须克隆指针,这样你添加的是指针指向的内存内容,而不是指针本身。
猜你喜欢
  • 1970-01-01
  • 2011-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多