我正在尝试将CSV文件读入列表(字符串列表),传递它以从数据库获取一些数据,构建新数据列表列表,然后传递列表列表,它可以写入新的CSV文件。 我看了一遍,我似乎无法找到一个如何做的例子。
我宁愿不使用简单数组,因为文件的大小会有所不同,我不知道如何使用数组的维度。我没有处理文件的问题。我只是不确定如何处理列表清单。
我发现的大多数示例都将创建多维数组或在循环内执行从文件中读取数据的操作。我知道我可以这样做,但我想编写面向对象的代码。如果您可以提供一些示例代码或指向我的参考,那就太棒了。
答案 0 :(得分:126)
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);
答案 1 :(得分:15)
如果您真的想知道在Java中完美地处理CSV文件,那么尝试自己实现CSV读取器/写入器并不好。检查下面。
http://opencsv.sourceforge.net/
当您的CSV文档包含双引号或换行符时,您将面临困难。
首先要学习面向对象的方法,看看其他实现(通过Java)会对你有所帮助。而且我认为管理List中的一行并不好。 CSV不允许您具有不同的列大小。
答案 2 :(得分:10)
这是一个示例,它将CSV字符串列表读入列表列表,然后遍历该列表列表并将CSV字符串打印回控制台。
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");
}
}
}
我认为非常直截了当。只有几点需要注意:
我建议在创建列表对象时在左侧使用“List”而不是“ArrayList”。传递“List”界面会更好,因为如果以后你需要更改为使用像Vector这样的东西(例如你现在需要同步列表),你只需要用“new”语句来改变这一行。无论您使用哪种列表实现,例如Vector或ArrayList,你仍然只是传递List<String>
。
在ArrayList构造函数中,您可以将列表保留为空,它将默认为特定大小,然后根据需要动态增长。但是如果你知道你的列表有多大,你有时可以节省一些性能。例如,如果您知道文件中总会有500行,那么您可以这样做:
List<List<String>> csvList = new ArrayList<List<String>>(500);
这样你就不会浪费处理时间等待你的列表增长动态增长。这就是我将“linePieces.length”传递给构造函数的原因。通常不是什么大问题,但有时也很有帮助。
希望有所帮助!
答案 3 :(得分:5)
@tster提供的示例显示了如何创建列表列表。我将提供一个迭代这样一个列表的例子。
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);
}
}
答案 4 :(得分:3)
这样的东西可以用于阅读:
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();
}
}
答案 5 :(得分:2)
我是第二个xrath说的 - 你最好使用现有的库来处理读/写CSV。
如果你计划推出自己的框架,我还建议不要使用List<List<String>>
作为你的实现 - 你可能最好不要实现CSVDocument
和CSVRow
类(虽然对于用户来说,可能在内部分别使用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文件时尝试验证所有这些,这可能在某些情况下有效......但在其他情况下,您将提醒用户远离错误更改的位置的例外情况,导致调试困难。
答案 6 :(得分:0)
这也是如何使用高级for循环打印列表列表的示例:
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();
}
}
答案 7 :(得分:0)
public class TEst {
public static void main(String[] args) {
List<Integer> ls=new ArrayList<>();
ls.add(1);
ls.add(2);
List<Integer> ls1=new ArrayList<>();
ls1.add(3);
ls1.add(4);
List<List<Integer>> ls2=new ArrayList<>();
ls2.add(ls);
ls2.add(ls1);
List<List<List<Integer>>> ls3=new ArrayList<>();
ls3.add(ls2);
methodRecursion(ls3);
}
private static void methodRecursion(List ls3) {
for(Object ls4:ls3)
{
if(ls4 instanceof List)
{
methodRecursion((List)ls4);
}else {
System.out.print(ls4);
}
}
}
}