【问题标题】:Write ArrayList of Object that contain ArrayList to CSV将包含 ArrayList 的对象的 ArrayList 写入 CSV
【发布时间】:2020-04-13 04:14:38
【问题描述】:

我的任务是从网页中抓取数据并将它们与其他信息一起写入 CSV。目前我使用 JSoup 来抓取网站,但我的问题是不知道如何将它们写入 CSV。

我将每个抓取页面的数据存储在一个对象调用 CSVObject 中:

public class CSVObject {
    String name;
    String title;
    String description;
    String ArrayList<String> color;
    String ArrayList<String> size;
    String ArrayList<float> price;
}

我将这些对象存储在ArrayList&lt;CSVObject&gt;

名称、标题、描述来自抓取的数据,但颜色、尺寸和价格来自用户输入。他们可以选择多个,它将​​添加到Object中的ArrayList中。

所需的文件输出是这样的:

Name         Title           Description         Color         Size         Price
Shirt        Holiday Shirt   Shirt Description   Black         S            15.99
Shirt                                            Black         M            19.99
Shirt                                            Black         L            24.99
Shirt                                            Green         S            15.99
Shirt                                            Green         M            19.99
Shirt                                            Green         L            24.99
Pants        Movie Pants     Pants Description   Red           S            17.99
...

我做了一些挖掘,发现How to serialize object to CSV file? 中的Java CSV Library 可以帮助将文件写入 CSV,但我不确定如何将其格式化为所需的输出。那么我应该怎么做才能按预期写入文件呢?

【问题讨论】:

    标签: java csv arraylist


    【解决方案1】:

    这是一个又快又脏的方法,它假定您的颜色、价格和尺寸列表始终具有相同的长度

    interface CSVObject {
        String name();
        String title();
        String description();
        List<String> color();
        List<String> size();
        List<Double> price();
    }
    
    List<CSVObject> data = List.of();
    
    String csv =data.stream()
                .flatMap(co->IntStream.range(0,co.color().size())
                        .mapToObj(i->new String[]{co.name(),co.title(),co.description(),co.color().get(i),co.size().get(i),co.price().get(i).toString()} ))
                        .map(sa-> Arrays.stream(sa).collect(Collectors.joining(",")))
                        .collect(Collectors.joining("\n"));
    

    【讨论】:

      【解决方案2】:

      平面文件

      Comma-Separated Values (CSV)Tab-Delimited 格式适用于平面文件,每个格式都有一个表。这意味着一组行都共享同一组列。

      要导出示例数据中的数据,请重复您已隐藏的第一列中的值。然后,您将拥有一组共享同一组列的行。

      层次结构

      根据您的 Java 类,您有一个 hierarchy of data。这不适合 CSV 格式。方钉,圆孔。

      要匹配 Java 类的结构,您应该以分层格式(例如 XML 或 JSON)序列化数据。

      不是真正的 CSV

      如果你坚持使用你展示的那种不是真正的 CSV 格式,你需要嵌套循环。

      循环你的一组对象。对于每个对象,循环其中包含的列表。

      在第一次浏览列表时,写出所有列。对于内部循环中的后续时间,抑制这些值,仅写入一个逗号字符以保持列数。

      直截了当的逻辑,没有什么棘手的,遵循与将这些值手写到纸上相同的步骤。

      当然,任何包含分隔符(COMMA 等)的字段值都必须用引号引起来。或者只是将所有字段括在引号中。

      【讨论】:

      • 我明白这一点。但要求是 CSV 文件,因为它用于导入 Shopify 网站。文件的格式是这样的,所以我无法更改。
      • @user3417256 我添加了最后一节。
      • 感谢您的回答,但我仍然可以清楚地描绘出来。因此,对于最外面的循环,我循环 CSVObject Arraylist 中的对象数量,在里面我循环颜色 ArrayList,在那个循环中我循环大小等等?
      • @user3417256 是的。两个循环,嵌套。外循环基于对象的数量。内循环基于任何列表的大小(三个列表的大小相同)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-10
      相关资源
      最近更新 更多