我有这个 CSV 文件:
id,name,mark
20203923380,Lisa Hatfield,62
20200705173,Jessica Johnson,59
20205415333,Adam Harper,41
20203326467,Logan Nolan,77
我正在尝试用这段代码来处理它:
try (Stream<String> stream = Files.lines(Paths.get(String.valueOf(csvPath)))) {
DoubleSummaryStatistics statistics = stream
.map(s -> s.split(",")[index]).skip(1)
.mapToDouble(Double::valueOf)
.summaryStatistics();
} catch (IOException e) // more code
我想通过名称获取列。
我想我需要验证 index 是用户作为整数输入的列的索引,如下所示:
int index = Arrays.stream(stream).indexOf(columnNS);
但这不起作用。
流应该具有以下值,例如:
专栏:
"mark"
62、59、41、77
我需要验证索引是用户作为整数输入的列的索引......但它不起作用。
Arrays.stream(stream).indexOf(columnNS)
Stream IPA 中没有方法
indexOf
。我不确定你所说的 stream(stream)
是什么意思,但这种方法是错误的。
为了获取有效索引,您需要列的名称。根据 name,您必须分析从文件中检索到的第一行。就像在列名称为“mark”的示例中一样,您需要找出该名称是否出现在第一行中及其索引是什么。
我想要的是通过名称获取列......流应该......
流的目的是“有状态”。它们在 Java 中引入是为了提供富有表现力和清晰的代码结构方式。即使您设法将有状态的条件逻辑塞入流中,您也会失去这种优势,并最终得到性能不如普通循环清晰的复杂代码(余下的:迭代解决方案几乎总是表现更好)。 因此,您想保持代码整洁,您可以选择:使用迭代方法解决此问题,或者放弃在流内动态确定列索引的要求。
这就是如何通过循环解决基于列名动态读取文件数据的任务:
public static List<String> readFile(Path path, String columnName) {
List<String> result = new ArrayList<>();
try(var reader = Files.newBufferedReader(path)) {
int index = -1;
String line;
while ((line = reader.readLine()) != null) {
String[] arr = line.split("\\p{Punct}");
if (index == -1) {
index = getIndex(arr, columnName);
continue; // skipping the first line
}
result.add(arr[index]);
}
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
// validation logic resides here
public static int getIndex(String[] arr, String columnName) {
int index = Arrays.asList(arr).indexOf(columnName);
if (index == -1) {
throw new IllegalArgumentException("Given column name '" + columnName + "' wasn't found");
}
return index;
}
// extracting statistics from the file data
public static DoubleSummaryStatistics getStat(List<String> list) {
return list.stream()
.mapToDouble(Double::parseDouble)
.summaryStatistics();
}
public static void main(String[] args) {
DoubleSummaryStatistics stat = getStat(readFile(Path.of("test.txt"), "mark"));
}