使用java解析csv,然后保存在2D数组中
好的,我正在开发一个基于java的交易卡游戏的游戏。我将所有游戏peice的“信息”刮到一个csv文件中,其中每一行都是游戏peice,每一列都是该peice的一种属性。我花了好几个小时用缓冲读取器等编写代码,试图将csv文件中的信息提取到2d数组中,但没有成功。我的csv文件链接在这里:我有一年的计算机科学经验,但我仍然不知道如何做到这一点使用java解析csv,然后保存在2D数组中,java,arrays,csv,multidimensional-array,Java,Arrays,Csv,Multidimensional Array,好的,我正在开发一个基于java的交易卡游戏的游戏。我将所有游戏peice的“信息”刮到一个csv文件中,其中每一行都是游戏peice,每一列都是该peice的一种属性。我花了好几个小时用缓冲读取器等编写代码,试图将csv文件中的信息提取到2d数组中,但没有成功。我的csv文件链接在这里:我有一年的计算机科学经验,但我仍然不知道如何做到这一点 因此,我的主要问题是如何将其放入2D数组中,以便保留行和列?我正在研究一个类似的问题,以便在机器学习中使用,因此,让我分享一下我在这个主题上所做的工作 1
因此,我的主要问题是如何将其放入2D数组中,以便保留行和列?我正在研究一个类似的问题,以便在机器学习中使用,因此,让我分享一下我在这个主题上所做的工作 1) 如果您在开始解析行之前知道(无论它是硬编码到您的程序中的还是您的文件中是否有提供此信息的头文件(强烈建议)-每行将有多少个属性,您可以用逗号合理地拆分它,例如,第一个属性将是RowString.substring(0,RowString.indexOf(',')),第二个属性将是从第一个逗号到下一个逗号的子字符串(编写一个函数来查找逗号的第n个实例,或者在遍历时简单地切掉字符串的一些位,应该是相当简单的),最后一个属性将是RowString.substring(RowString.lastIndexOf(',')),RowString.length())。字符串类的方法在这里是您的朋友 2) 如果无法区分用于分隔值的逗号和作为字符串格式属性一部分的逗号,则(如果文件足够小,可以手动重新格式化)执行Java所做的操作—用“\”表示字符串中具有特殊含义的字符,而不只是“,”。这样,您就可以搜索“,”而不是“\”的索引,这样您就有了一些区分字符的方法 3) 作为2)的替代方案,CSV(在我看来)不适合字符串,因为字符串通常包含逗号。CSV没有真正的通用格式,所以为什么不让它们使用冒号分隔的值、破折号分隔的值,甚至三个安培和分隔的值呢?用逗号分隔值的目的是使它们易于区分,如果逗号不起作用,就没有理由保留它们。同样,这仅适用于文件小到可以手动编辑的情况 4) 查看您的文件不仅仅是查看格式,很明显您无法手动完成。此外,有些字符串似乎被三个双引号(“字符串”)包围,有些字符串被单双引号(“字符串”)包围。如果我不得不猜测的话,我会说引号中包含的任何内容都是单个属性——例如,没有以一个属性开头、以另一个属性结尾的引号对。所以我想说你可以: 使用一个方法创建一个类,将字符串拆分为每个逗号分隔的字段。
编写该方法,使其忽略前面带有奇数个双引号的逗号(这样,如果引号对尚未关闭,则它知道它位于字符串内部,并且逗号不是值分隔符)。但是,如果文件的创建者使用双引号(““string”)将一些字符串括起来,则此策略将失败,因此您可能需要更全面的方法。正如前面提到的,您的一些字符串包含逗号,因此最初您的起点不好,但我有一个解决方案,它是这样的:
- 它的工作原理是传入一个字符串和一个分隔符(在本例中,分隔符是“,”),并输出所有由逗号分隔的子字符串。如果您从一开始就知道总共有多少块,那么可以在开始时实例化一个2D数组,只需插入StringTokenizer提供给您的每一行。如果不这样做,也没关系,因为可以使用ArrayList。ArrayList很好,因为它是数组的高级抽象,可以自动请求更多内存,这样您就可以继续添加到它中,并且知道检索时间始终是恒定的。但是,如果您计划动态添加片段,并且这样做的频率比检索片段的频率更高,那么您可能希望使用LinkedList,因为它具有线性检索时间,但是对于添加-删除时间,它的关系比ArrayList好得多。或者,如果你很棒的话,你可以用一个技工来代替。我不知道它们是否默认用Java实现,但它们非常棒。不过,这是一个公平的警告;可再生能源的速度成本
R1C1|R1C2|R1C3|R1C4|R1C5|R1C6|R1C7|R1C8 R2C1|R2C2|R2C3|R2C4|R2C5|R2C6|R2C7|R3C8 R3C1|R3C2|R3C3|R3C4|R3C5|R3C6|R3C7|R3C8 R4C1|R4C2|R4C3|R4C4|R4C5|R4C6|R4C7|R4C8 A/D Changer|DREV-EN005|Effect Monster|Light|Warrior|100|100|You can remove from play this card in your Graveyard to select 1 monster on the field. Change its battle position.
BufferedReader br = new BufferedReader(new FileReader(new File("MonstersFinal.csv"))); String line = ""; ArrayList<String[]> cardList = new ArrayList<String[]>(); // Use an arraylist because we might not know how many cards we need to parse. while((line = br.readLine()) != null) { // Read a single line from the file until there are no more lines to read StringTokenizer st = new StringTokenizer(line, "|"); // "|" is the delimiter of our input file. String[] card = new String[8]; // Each card has 8 fields, so we need room for the 8 tokens. for(int i = 0; i < 8; i++) { // For each token in the line that we've read: String value = st.nextToken(); // Read the token card[i] = value; // Place the token into the ith "column" } cardList.add(card); // Add the card's info to the list of cards. } for(int i = 0; i < cardList.size(); i++) { for(int x = 0; x < cardList.get(i).length; x++) { System.out.printf("card[%d][%d]: ", i, x); System.out.println(cardList.get(i)[x]); } }
card[0][0]: R1C1 card[0][1]: R1C2 card[0][2]: R1C3 card[0][3]: R1C4 card[0][4]: R1C5 card[0][5]: R1C6 card[0][6]: R1C7 card[0][7]: R1C8 card[1][0]: R2C1 card[1][1]: R2C2 card[1][2]: R2C3 card[1][3]: R2C4 card[1][4]: R2C5 card[1][5]: R2C6 card[1][6]: R2C7 card[1][7]: R3C8 card[2][0]: R3C1 card[2][1]: R3C2 card[2][2]: R3C3 card[2][3]: R3C4 card[2][4]: R3C5 card[2][5]: R3C6 card[2][6]: R3C7 card[2][7]: R4C8 card[3][0]: R4C1 card[3][1]: R4C2 card[3][2]: R4C3 card[3][3]: R4C4 card[3][4]: R4C5 card[3][5]: R4C6 card[3][6]: R4C7 card[3][7]: R4C8 card[4][0]: A/D Changer card[4][1]: DREV-EN005 card[4][2]: Effect Monster card[4][3]: Light card[4][4]: Warrior card[4][5]: 100 card[4][6]: 100 card[4][7]: You can remove from play this card in your Graveyard to select 1 monster on the field. Change its battle position.