我正在尝试计算以下csv文件中的r,t和c的数量。
我当前正在返回值4 c的0 r和3 t的值,这不是准确的结果。有人可以帮助我识别代码中的错误吗?
public static int getCount ( String fileName, String letter )
{
int count = 0;
String line;
String[] lineArray new String[3];
Scanner sc = new Scanner (System.in);
try
{
BufferedReader br = new BufferedReader(new FileReader(fileName));
count = 0;
while (br.readLine() != null)
{
line = br.readLine();
lineArray = line.split(",");
for (int i = 0; i < lineArray.length; i++)
{
(lineArray[0].equals(letter))count++;
}
}
br.close();
}
return count;
}
我正在读取一个csv文件。
r,21.2,12.2
c,50
t,23.4,56.8
t,15.3,12.2
c,32
t,32.3,23.5
答案 0 :(得分:2)
发布的代码无法编译,但此行:
while (br.readLine() != null)
读取一行,但未将其分配给变量,因此该值会丢失。
然后在循环中显示以下行:
line = br.readLine();
读取下一行,并将其分配给变量。因此,每次迭代实质上都会跳过一行。
将循环条件更改为:
while ((line = br.readLine()) != null)
因此将读取行分配给变量。并在循环中删除它:
line = br.readLine();
为避免跳过一行。
也可以考虑使用Map<String, Integer>
而不是数组来跟踪计数。
答案 1 :(得分:1)
由于您的代码无法编译,因此很难说出问题所在。 这是您问题的替代解决方案:
public static void main(String[] args) {
try {
Map<String, Long> csvOccurences = Files.readAllLines(Paths.get("text.csv"))
.stream()
.map(csvLine -> csvLine.split(",")[0])
.collect(Collectors.groupingBy(csvLine -> csvLine, Collectors.counting()));
System.out.println("c occurence -> " + csvOccurences.getOrDefault("c", 0L));
System.out.println("t occurence -> " + csvOccurences.getOrDefault("t", 0L));
System.out.println("z occurence -> " + csvOccurences.getOrDefault("z", 0L));
} catch (Exception exception) {
System.err.print("Unable to elaborate the csv");
exception.printStackTrace();
}
}
代码输出:
c occurence -> 2
t occurence -> 3
z occurence -> 0
我们很乐意为您提供帮助,但可以使您的代码可编译,因此我们可以帮助您进行调试。
编辑: 代码的故障安全版本
Map<String, Long> csvOccurences =
Files.readAllLines(Paths.get("text.csv")) // Read the files and get all the lines
.stream() // Iterate all the lines
.map(csvLine -> csvLine.split(",")) // Split the line into tokens (split by ',')
.filter(csvTokens -> csvTokens.length >= 1) // Filter out all the lines that don't have at least 2 tokens
.map(csvTokens -> csvTokens[0]) // Map the stream to only the first token
.map(String::trim) // Trim the string (remove the space at start and at the end)
.filter(csvToken -> csvToken.length() == 1) // Filter out all the token that have more than one letter (is this necessary?)
.collect(Collectors.groupingBy(csvLine -> csvLine, Collectors.counting())); // Count the occurence of each letter and map them Map<Letter, Occurence>
编辑2,您的方法已修复并重构:
public static int getCount(String fileName, String letter) throws Exception {
// Put the stream inside the try/catch so they get closed automatically
try (FileReader fileReader = new FileReader(fileName);
BufferedReader bufferReader = new BufferedReader(fileReader)) {
// Initialized the counter to 0
int letterCount = 0;
// Declare a line buffer
String lineBuffer;
// While readLine is not returning null put the line inside lineBuffer
while ((lineBuffer = bufferReader.readLine()) != null) {
// Split the line buffer into tokens
String[] lineTokens = lineBuffer.split(",");
// If the tokens are more than 0 and the first token is equal to the letter
if (lineTokens.length > 0 && lineTokens[0].equals(letter)) {
// Increment the letter count
letterCount++;
}
}
// Return the letter count
return letterCount;
}
}
已采取的措施:
Scanner sc = new Scanner (System.in);
没用lineTokens.length > 0
长度的检查答案 2 :(得分:0)
假设您的代码是一种将letter
作为字符串传递的方法,那么计算字母的行必须是
if (lineArray[0].equals(letter)) count++;
但是,代码的问题和错误是环绕的for循环:在这里,您将字母的每次出现计数三遍。删除这些for循环,因为您不需要它。
答案 3 :(得分:0)
您的代码中存在多个问题:
Scanner
或BufferedReader
,而不要同时使用两者。 do-while
循环,否则第一行将被跳过。在这里,我们阅读每一行,然后继续阅读下一行。for-loop
==代码==
public static int findCount(String fileName) {
int count = 0;
String[] lineArray = new String[3];
try {
Scanner br = new Scanner(new FileReader(fileName));
do {
lineArray = br.nextLine().split(",");
if (lineArray[0].matches("c|r|t")) {
count++;
}
} while (br.hasNextLine());
br.close();
} catch (Exception e) {
// handle exception
e.printStackTrace();
}
return count;
}
使用Java-8,我们可以在一行中完成整个操作。
public static long getCount(String fileName) {
try {
return Files.readAllLines(Paths.get(fileName)).stream().map(line -> line.split(",")[0])
.filter(str -> str.matches("c|r|t")).count();
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}