在Java中使用列表列表

我正在尝试将CS​​V文件读入列表(string)列表中,将其传递到从数据库中获取数据,构build新数据列表的新列表,然后传递该列表以便它可以写入一个新的CSV文件。 我已经看遍了所有,我似乎无法find如何做到这一点的例子

我宁愿不使用简单的数组,因为文件的大小会有所不同,我不知道如何使用数组的维度。 我没有处理这些文件的问题。 我只是不知道如何处理列表清单。

我发现的大多数例子都会创buildmultidimensional array或者在循环内部执行一些从文件中读取数据的操作。 我知道我可以做到这一点,但我想写面向对象的代码。 如果你可以提供一些示例代码或者指向一个引用,那就太棒了。

ArrayList<ArrayList<String>> listOLists = new ArrayList<ArrayList<String>>(); ArrayList<String> singleList = new ArrayList<String>(); singleList.add("hello"); singleList.add("world"); listOLists.add(singleList); ArrayList<String> anotherList = new ArrayList<String>(); anotherList.add("this is another list"); listOLists.add(anotherList); 

如果您真的想知道如何在Java中完美处理CSV文件,那么尝试自己实现CSV读写器并不好。 下面检查出来。

http://opencsv.sourceforge.net/

当您的CSV文件包含双引号或换行符时,您将面临困难。

首先学习面向对象的方法,看看其他的实现(Java)会帮助你。 我认为这不是pipe理List中的一行的好方法。 CSV不允许你有不同的列大小。

以下是一个将CSVstring列表读入列表列表,然后循环显示列表列表并将CSVstring输出回控制台的示例。

 import java.util.ArrayList; import java.util.List; public class ListExample { public static void main(final String[] args) { //sample CSV strings...pretend they came from a file String[] csvStrings = new String[] { "abc,def,ghi,jkl,mno", "pqr,stu,vwx,yz", "123,345,678,90" }; List<List<String>> csvList = new ArrayList<List<String>>(); //pretend you're looping through lines in a file here for(String line : csvStrings) { String[] linePieces = line.split(","); List<String> csvPieces = new ArrayList<String>(linePieces.length); for(String piece : linePieces) { csvPieces.add(piece); } csvList.add(csvPieces); } //write the CSV back out to the console for(List<String> csv : csvList) { //dumb logic to place the commas correctly if(!csv.isEmpty()) { System.out.print(csv.get(0)); for(int i=1; i < csv.size(); i++) { System.out.print("," + csv.get(i)); } } System.out.print("\n"); } } } 

我觉得很简单。 只是几点要注意:

  1. build议在创build列表对象时使用“List”而不是“ArrayList”。 最好是传递接口“List”,因为如果以后你需要改变使用像Vector这样的东西(比如你现在需要同步列表),你只需要用“new”语句来改变行。 无论您使用的列表是什么,例如Vector或ArrayList,您仍然只是传递List<String>

  2. 在ArrayList构造函数中,可以将列表保留为空,并且默认为一定大小,然后根据需要dynamic增长。 但是如果你知道你的名单有多大,你可以节省一些performance。 例如,如果你知道你的文件总是会有500行,那么你可以这样做:

List<List<String>> csvList = new ArrayList<List<String>>(500);

这样你永远不会浪费处理时间,等待你的列表dynamic增长。 这就是为什么我将“linePieces.length”传递给构造函数。 通常不是什么大事,但有时候会有所帮助。

希望有所帮助!

@tster提供的示例显示了如何创build列表的列表。 我将提供一个迭代这个列表的例子。

 Iterator<List<String>> iter = listOlist.iterator(); while(iter.hasNext()){ Iterator<String> siter = iter.next().iterator(); while(siter.hasNext()){ String s = siter.next(); System.out.println(s); } } 

像这样的东西将工作阅读:

 String filename = "something.csv"; BufferedReader input = null; List<List<String>> csvData = new ArrayList<List<String>>(); try { input = new BufferedReader(new FileReader(filename)); String line = null; while (( line = input.readLine()) != null) { String[] data = line.split(","); csvData.add(Arrays.toList(data)); } } catch (Exception ex) { ex.printStackTrace(); } finally { if(input != null) { input.close(); } } 

我会再次说什么xrath – 你最好使用现有的库来处理读取/写入CSV。

如果你打算自己制作框架,我还build议不要使用List<List<String>>作为你的实现 – 你可能会更好的实现CSVDocumentCSVRow类(可以在内部使用List<CSVRow>List<String> ),但对于用户而言,只暴露一个不可变的List或一个数组。

简单地使用List<List<String>>留下太多未经检查的边缘情况,并依赖于实现细节 – 比如是否与数据分开存储标题? 或者他们在List<List<String>>的第一行? 如果我想通过列标题而不是按索引访问数据呢?

当你打电话给你时会发生什么:

 // reads CSV data, 5 rows, 5 columns List<List<String>> csvData = readCSVData(); csvData.get(1).add("extraDataAfterColumn"); // now row 1 has a value in (nonexistant) column 6 csvData.get(2).remove(3); // values in columns 4 and 5 moved to columns 3 and 4, // attempting to access column 5 now throws an IndexOutOfBoundsException. 

在写出CSV文件时,您可以尝试validation所有这些,这在某些情况下可能会有效…但在其他情况下,您将提醒用户远离发生错误更改的地方,导致难以debugging。

这也是如何使用高级for循环打印List列表的一个例子:

 public static void main(String[] args){ int[] a={1,3, 7, 8, 3, 9, 2, 4, 10}; List<List<Integer>> triplets; triplets=sumOfThreeNaive(a, 13); for (List<Integer> list : triplets){ for (int triplet: list){ System.out.print(triplet+" "); } System.out.println(); } }