java 8 i/o 流应用程序

标签 java lambda java-8 java-stream

我在下面有一个 CSV 文件,我编写了下面的方法来解析该文件。

"PRODUCT_NAME","PRODUCT_CATEGORY","SALES_PRICE"
"Hair Gel","Beauty",6.99 
"Scotch tape","Office Supply",2.99
"Office Chair","Office Supply",134.99

我的代码:

public static void ReadFile(String path, Map<String, List<Double>> db){
    try(BufferedReader br = new BufferedReader(new FileReader(path))){
        String line;
        if((line = br.readLine()) != null){
            //this line is the heading..and needed to be skipped
        }
        while ((line = br.readLine()) != null) {
            String[] keys = line.split(",");
            keys[1] = keys[1].replace("\"", "");
            if(db.containsKey(keys[1])){
                List<Double> list = db.get(keys[1]);
                list.add(Double.valueOf(keys[2]));
                db.put(keys[1], list);
            }
            else{
                List<Double> list = new ArrayList<>();
                list.add(Double.valueOf(keys[2]));
                db.put(keys[1],list);
            }
        }

    }catch(IOException e){}
}

它在解析文件时工作正常,但我的主要问题是如何利用 java8 流和 lambda 功能编写上述方法?

最佳答案

您可以使用 Files.lines(path) 在文件的行上检索流(你可以用 Path 得到一个 Paths.get )。使用 skip(1) 跳过标题行, 然后每行围绕 "," 拆分.

最后,Stream 元素按键的第一个元素分组(删除引号)并将值映射到 Double键的第二个元素的值并收集到 List 中.组操作是用 groupingBy(classifier, downstream) 完成的collector:classifier是一个方法,返回key给group by,下游collector收集所有分组到同一个key的Stream元素;在这种情况下,对于具有相同键的值,我们希望将 Stream 元素映射到 Double值 ( mapping ) 并收集那些 Double进入 List ( toList() )。

您设计中的问题是您的方法采用了 Map<String, List<Double>> db作为参数并在最好让方法返回它时对其进行变异。

public static Map<String, List<Double>> readFile(String path) throws IOException {
    try (Stream<String> stream = Files.lines(Paths.get(path))) {
        return stream.skip(1)
                  .map(l -> l.split(","))
                  .collect(Collectors.groupingBy(
                    keys -> keys[1].replace("\"", ""),
                    Collectors.mapping(keys -> Double.valueOf(keys[2]), Collectors.toList())
                  ));
    }
}

请注意,我还修改了您的代码,让它抛出 IOException而不是捕获它什么都不做。如果您想在方法本身中处理该异常,您仍然可以添加 catch 部分。

关于java 8 i/o 流应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35385554/

相关文章:

java - 使用 foreach 循环数组列表不会执行任何操作

java - Java中动态多态和静态多态有什么区别?

Javafx 使用线程将子项动态添加到 TreeView ?

java - 如何从java中的HttpServletRequest中获取调用了哪个端点操作?

python - 如果匿名,对 python lambda 的调用是什么?

python - 如何在python case语句中运行代码块

lambda - Kotlin:为什么函数不能存储在变量中?

Java 8 奇数计时/内存问题

java - 关于 Stream - IZ0-809 考试中 OCPJP 8 考试主题中提到的不存在的 merge() 方法

java - 使用流而不是嵌套的 for 循环