如何从java中读取CSV文件返回的矩阵中检索特定行

如何从java中读取CSV文件返回的矩阵中检索特定行,java,Java,我想检索二维数组的一些行 示例:我有一个名为“data.csv”的文件,其中包含 age sex zipcode classtype 21 m 23423 1 12 f 23133 2 23 m 32323 2 23 f 23211 1 下面提到的代码将给出如下输出: {age=[21,12,23,23],sex=[m,f,m,f],zipcode=[23423,23133,32323,23211

我想检索二维数组的一些行

示例:我有一个名为“data.csv”的文件,其中包含

age   sex  zipcode   classtype

21     m     23423   1

12     f     23133   2

23     m     32323   2

23     f     23211   1
下面提到的代码将给出如下输出:

{age=[21,12,23,23],sex=[m,f,m,f],zipcode=[23423,23133,32323,23211],classtype=[1,2,2,1]}
现在我想检索类类型为1的行,并将这些值存储在一个新的2d数组中

partition1={{21,m,23423,1},{23,f,23211,1}

    public class CsvParser {
        public static void main(String[] args) {
            try {
                FileReader fr = new FileReader((args.length > 0) ? args[0] : "data.csv");
                Map<String, List<String>> values = parseCsv(fr, " ", true);
                System.out.println(values);
                List<List<String>> partition1 = new ArrayList<>(25);
                List<String> classTypes = values.get("classtype");
                for (int row = 0; row < classTypes.size(); row++) {
                     String classType = classTypes.get(row);
                     if ("1".equals(classType)) {
                     List<String> data = new ArrayList<>(25);
                     data.add(values.get("age").get(row));
                     data.add(values.get("sex").get(row));
                     data.add(values.get("zipcode").get(row));
                     data.add(values.get("classtype").get(row));
                     partition1.add(data);
                  }
           }

                 System.out.println(partition1);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    public static Map<String, List<String>> parseCsv(Reader reader, String separator, boolean hasHeader) throws IOException {
        Map<String, List<String>> values = new LinkedHashMap<String, List<String>>();
        List<String> columnNames = new LinkedList<String>();
        BufferedReader br = null;
        br = new BufferedReader(reader);
        String line;
        int numLines = 0;
        while ((line = br.readLine()) != null) {
            if (StringUtils.isNotBlank(line)) {
                if (!line.startsWith("#")) {
                    String[] tokens = line.split(separator);
                    if (tokens != null) {
                        for (int i = 0; i < tokens.length; ++i) {
                            if (numLines == 0) {
                                columnNames.add(hasHeader ? tokens[i] : ("row_"+i));
                            } else {
                                List<String> column = values.get(columnNames.get(i));
                                if (column == null) {
                                    column = new LinkedList<String>();
                                }
                                column.add(tokens[i]);
                                values.put(columnNames.get(i), column);
                            }
                        }
                    }
                    ++numLines;
                }
            }
        }
        return values;
    }
}
公共类CsvParser{
公共静态void main(字符串[]args){
试一试{
FileReader fr=新的FileReader((args.length>0)?args[0]:“data.csv”);
映射值=parseCsv(fr,“,true);
System.out.println(值);
列表分区1=新的ArrayList(25);
List classTypes=values.get(“classtype”);
对于(int row=0;row
CSV文件必须是基于逗号分割的,一旦我更改了
Map values=parseCsv(fr,\\s,,,true),它应该是有效的
映射值=parseCsv(fr,“,true)我能够以正确的格式获取数据

从这里开始,只需通读
类类型的每一行,当我找到一个与
1
匹配的值时,我会取出给定行的每个属性,并将其添加到
列表中,形成一行。然后将其添加到另一个
列表
,该列表将维护所有匹配的行,例如

List<List<String>> partition1 = new ArrayList<>(25);
List<String> classTypes = values.get("classtype");
for (int row = 0; row < classTypes.size(); row++) {
    String classType = classTypes.get(row);
    if ("1".equals(classType)) {
        List<String> data = new ArrayList<>(25);
        data.add(values.get("age").get(row));
        data.add(values.get("sex").get(row));
        data.add(values.get("zipcode").get(row));
        data.add(values.get("classtype").get(row));
        partition1.add(data);
    }
}

System.out.println(partition1);
List<Map<String, String>> partition1 = new ArrayList<>(25);
List<String> classTypes = values.get("classtype");
for (int row = 0; row < classTypes.size(); row++) {
    String classType = classTypes.get(row);
    if ("1".equals(classType)) {
        Map<String, String> data = new HashMap<>(25);
        for (String key : values.keySet()) {
            data.put(key, values.get(key).get(row));                        
        }
        partition1.add(data);
    }
}

System.out.println(partition1);
如果您正在寻找一种更自动化的方法,那么恐怕您运气不好,因为
Map
无法保证密钥的存储、迭代顺序

当然,您可以使用维护每个值的键的
列表,而不是使用
列表
,例如

List<List<String>> partition1 = new ArrayList<>(25);
List<String> classTypes = values.get("classtype");
for (int row = 0; row < classTypes.size(); row++) {
    String classType = classTypes.get(row);
    if ("1".equals(classType)) {
        List<String> data = new ArrayList<>(25);
        data.add(values.get("age").get(row));
        data.add(values.get("sex").get(row));
        data.add(values.get("zipcode").get(row));
        data.add(values.get("classtype").get(row));
        partition1.add(data);
    }
}

System.out.println(partition1);
List<Map<String, String>> partition1 = new ArrayList<>(25);
List<String> classTypes = values.get("classtype");
for (int row = 0; row < classTypes.size(); row++) {
    String classType = classTypes.get(row);
    if ("1".equals(classType)) {
        Map<String, String> data = new HashMap<>(25);
        for (String key : values.keySet()) {
            data.put(key, values.get(key).get(row));                        
        }
        partition1.add(data);
    }
}

System.out.println(partition1);

您眼前的问题是,
Map
无法保证钥匙的维护顺序。实际上,您最好使用
列表
,其中第一个条目是
标题
…请注意,如果可以的话,我会使用一个预先存在的CSV库…我无法让您的代码满足您的基本期望…这如何回答OP的问题?这是如何从基于
类类型的矩阵中生成所需的2D数组的?它给出了一个错误,例如:找不到符号符号:类ArrayList位置:类CsvParser,是否导入了java.util.ArrayList
?当有n个类类型时,如何获得n个分区。到目前为止,我得到了一个根据ClassTPye1的分区。如果你想得到每个分区,你需要知道每个类型。您可以使用
Set
,这将允许您迭代
classtype
值,将每个值添加到其中,并确保没有重复的值,在had中,您只需迭代集合并用
集合中的值替换
“1”
…我尝试了集合概念,但是我不明白这个意思,我是java新手。请再闪几盏灯。这将非常有帮助。
[{sex=m, classtype=1, zipcode=23423, age=21}, {sex=f, classtype=1, zipcode=23211, age=23}]