Use "constructor chaining" in WordArrayList
, and TextAnalyzer
. That is, call one constructor from another. For example,
public TextAnalyzer(String text)
for (String str : splitTextArray)
Map words = new HashMap(); for (String str : splitTextArray)
Overall the current classes you have seems to do what they are supposed to do, and the result is correct. Good job.
Источник
How to count rows – count (*) and Java
The SQL Count() function returns the number of rows in a table. Using this you can get the number of rows in a table.
select count(*) from TABLE_NAME;
Let us create a table with name cricketers_data in MySQL database using CREATE statement as shown below −
CREATE TABLE cricketers_data( First_Name VARCHAR(255), Last_Name VARCHAR(255), Date_Of_Birth date, Place_Of_Birth VARCHAR(255), Country VARCHAR(255), );
Now, we will insert 5 records in cricketers_data table using INSERT statements −
insert into cricketers_data values('Shikhar', 'Dhawan', DATE('1981-12-05'), 'Delhi', 'India'); insert into cricketers_data values('Jonathan', 'Trott', DATE('1981-04-22'), 'CapeTown', 'SouthAfrica'); insert into cricketers_data values('Kumara', 'Sangakkara', DATE('1977-10-27'), 'Matale', 'Srilanka'); insert into cricketers_data values('Virat', 'Kohli', DATE('1988-11-05'), 'Delhi', 'India'); insert into cricketers_data values('Rohit', 'Sharma', DATE('1987-04-30'), 'Nagpur', 'India');
Following JDBC program establishes connection with MySQL and displays the number of rows in the table named cricketers_data.
Example
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class Count_Example < public static void main(String args[]) throws Exception < //Registering the Driver DriverManager.registerDriver(new com.mysql.jdbc.Driver()); //Getting the connection String mysqlUrl = "jdbc:mysql://localhost/mydatabase"; Connection con = DriverManager.getConnection(mysqlUrl, "root", "password"); System.out.println("Connection established. "); //Creating the Statement object Statement stmt = con.createStatement(); //Query to get the number of rows in a table String query = "select count(*) from Cricketers_Data"; //Executing the query ResultSet rs = stmt.executeQuery(query); //Retrieving the result rs.next(); int count = rs.getInt(1); System.out.println("Number of records in the cricketers_data table: "+count); >>
Output
Connection established. Number of records in the cricketers_data table: 5
Источник
Refactoring count Lines of Java code
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
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; > >
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)); >>
But I need to improve it if it possible.
Can someone help me with it, please?
Thank you a lot in advance.
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.
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("*/"); >>
\$\begingroup\$ Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers. \$\endgroup\$
\$\begingroup\$ Ordinarily I'd rollback the edits made after the answer was posted, but while the answer was helpful to you, I'm not convinced it's a review of your code. Considering this site is Code Review, that's important. \$\endgroup\$
\$\begingroup\$ The BufferedReader readLine method reads up to and includes the new line characters. \$\endgroup\$
3 Answers 3
Prefer try-with-resources
try (BufferedReader reader = new BufferedReader(new FileReader(text)))
This seems like a mistake. The try-with-resources (first form) is superior. It ensures that the BufferedReader gets closed properly regardless of whether there is an exception or not. The second form doesn't close it at all, so you're guaranteed it won't get closed until the method ends and garbage collection runs. Still consistent, but consistently wrong.
Comments are hard
return line.isEmpty() || line.startsWith("//") || line.startsWith("/*") || line.startsWith("*") || line.startsWith("*/");
This is incorrect. Consider the following input
The first should be two lines of code (by the definition in the problem). The second should be zero lines of code. But you'd count both as one line of code. Or
/* Comment followed by code */ int product = 5 * 3;
That should be one line of code, but you'd count it as zero lines of code.
If you allow /* */ style comments, then you have to do a lot more parsing and maintain state across lines. Because such comments can appear on lines with executable code or prevent execution of what otherwise would be executable code. You need something like
if (commentOpenFromPreviousLine) < int location = line.indexOf("*/"); if (location >= 0) < line = line.substring(location + "*/".length()); commentOpenFromPreviousLine = false; >>
Note that this is an incomplete solution. For example, it never sets commentOpenFromPreviousLine to true.
Another test case to handle:
String s = """ /* This is a string, not a comment */ """;
That should count as three lines of code.
int product = 5 * 3; /* This is a comment */
int product /* Comment */ = 5 * 3;
int product /* Comment */ = 5 * 3; /* Comment */ int sum = 5 + 3;
Note: please don't use comments like this in real programs. They're horrible. But they're syntactically allowed.
It is best to split your code into smaller pieces of code, that do only one thing and to it "right".
@gilbert made your method a bit nicer by having parameter of File type and is improvement, but it can be done even better. One method shouldn't contain bot IO handling (reading from the file) and your logic what you actually want to do.
- Moving even further, you may want to have a method, that accepts the source code text directly. That way you can parse the code provided by other means. If someone wants to use your code, they currently have to provide files.
- All the used methods reading contents from files don't specify encoding and by default if the encoding is not specified, platform encoding is used. I believe that java files are utf-8 encoded so it's better to specify that explicitly when loading from them. It's unlikely this would every cause trouble, but I wouldn't take the chance.
- Exception handling is done poorly. Exceptions are hard to learn, but I would say it's in general better to add throw to the signature or rethrow as RuntimeException . Anything but catching exception and "logging it" and removing something "empty" and not very meaningless In this case just 0 . I can't know if it's because of an error, or because the file actually contains 0 lines of meaningful code. If someone wants to use your method and know, if everything went wrong, they don't have a chance.
- @gilbert's solution doesn't take into consideration multiline comments as your solutions tried to do using currentlyInComment flag. You want to take that into consideration. It is even more complicated. You can have lines, that contain both code and comments. You may want to handle that too, imagine those lines:
System.out.println("I am code" /* comment */); System.out.println("I am code"); //I comment System.out.println("I am code"); /* Start of multiline comment */ System.out.println("I am code"); /* another piece of comment */ Your code would consider those as comments and not count them.
- One way to go is to create regular expressions for all those possibilities and then match each line of code against regexes to determine, if it's code, comment or both. Some examples:
EMPTY = Pattern.compile("\\s*") BLOCK_COMMENT_ONLY = Pattern.compile("\\s*/[*][^*][*]/\\s*"
You can then use it as EMPTY.matches(line) and handle accordingly by excluding the line or not and determining if you keep being inside the comment or not.
- Going further, you can create a tokenizer, that handles possible comment starts and endings. Or use regular expressions to detect those.
Источник