My task is:
In this challenge, write a function CountLOC.count to count the lines of code in a Java source file. A line of code is defined as any line in the source which contains at least one character of executable code. This excludes comments and whitespace. All input will be valid Java code in string format.
CountLOC.count(text) Parameters text: String - A stringified valid Java source file
Return Value int - A count of the number of lines of executable code in the source file
I need help to refactor the logic for the program as:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class CountLOC {
public static void main(String[] args) {
// write your code here
System.out.println("Hello world");
}
public static int count(String text) {
boolean currentlyInComment = false;
int lines = 0;
try (BufferedReader reader = new BufferedReader(new FileReader(text))) {
while (reader.readLine() != null) lines++;
text = text.replace(" ", "");
String line = reader.readLine();
if (line.trim().startsWith("/*")) {
currentlyInComment = true;
}
if (!currentlyInComment && !line.trim().startsWith("//")) {
// Do your algorithmic stuff with line
System.out.println(line);
}
if (line.trim().startsWith("*/") && currentlyInComment) {
currentlyInComment = false;
}
if (line.trim().startsWith("/**") && currentlyInComment) {
currentlyInComment = false;
}
line = reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return lines;
}
}
Specifically for passing tests below:
import java.io.*;
import java.nio.file.*;
import org.junit.Test;
import static org.junit.Assert.*;
public class ExampleTest {
@Test
public void shouldHandleBasicCode() throws IOException {
String path = "./java_src_files/Example1.java";
String code = new String(Files.readAllBytes(Paths.get(path)));
assertEquals(5, CountLOC.count(code));
}
@Test
public void shouldHandleABlankLineWIthOneLineComment() throws IOException {
String path = "./java_src_files/Example2.java";
String code = new String(Files.readAllBytes(Paths.get(path)));
assertEquals(5, CountLOC.count(code));
}
@Test
public void shouldHandleAnInlineComment() throws IOException {
String path = "./java_src_files/Example3.java";
String code = new String(Files.readAllBytes(Paths.get(path)));
assertEquals(5, CountLOC.count(code));
}
@Test
public void shouldHandleMultilineCommentsAndQuotes() throws IOException {
String path = "./java_src_files/Example4.java";
String code = new String(Files.readAllBytes(Paths.get(path)));
assertEquals(5, CountLOC.count(code));
}
@Test
public void shouldHandleAComplexExample() throws IOException {
String path = "./java_src_files/Example5.java";
String code = new String(Files.readAllBytes(Paths.get(path)));
assertEquals(6, CountLOC.count(code));
}
}
I've tried to combine several snippets of the code based on:
- https://mkyong.com/java/how-to-get-the-total-number-of-lines-of-a-file-in-java/
- https://stackoverflow.com/a/47243579/8370915
- https://stackoverflow.com/a/64959634/8370915
But I need to improve it if it possible.
Can someone help me with it, please?
Thank you a lot in advance.
UPD #1:
import java.io.*;
public class CountLOC {
public static void main(String[] args) {
// write your code here
System.out.println("Hello world");
}
public static int count(String text) {
int codeLineCount = 0;
try {
BufferedReader reader = new BufferedReader(new FileReader(text));
String line = reader.readLine();
while (line != null) {
if (!isCommentLine(line)) {
codeLineCount++;
}
line = reader.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}
return codeLineCount;
}
public static boolean isCommentLine(String line) {
line = line.trim();
return line.isEmpty() || line.startsWith("//") || line.startsWith("/*")
|| line.startsWith("*") || line.startsWith("*/");
}
}
I'm trying to understand how to split the input at the newLine character to get the individual lines and rewrite code to use a string and a loop instead of a reader.
UPD #2:
public class CountLOC {
public static int count(String text) {
String[] lines = text.split(System.lineSeparator());
return Arrays.stream(lines).filter(CountLOC::isCode).count();
}
public static boolean isCode(String line) {
line = line.trim();
return !line.isEmpty() && !line.startsWith("//") && !line.startsWith("/*")
&& !line.startsWith("*") && !line.startsWith("*/");
}
}
BufferedReader
readLine
method reads up to and includes the new line characters. \$\endgroup\$