Count code in java

Word count program in Java

I am trying to write clean code in Java for reading text of any size and printing the word count in ascending order without using Java collection framework. For example, given the following input text «What is the your name of the name?», it should print:

your 1 of 1 is 1 What 1 name 2 the 2 
public class WordArrayList < private WordData[] words; public void setWords(WordData[] words) < this.words = words; >public WordData[] getWords() < return words; >private int size; public WordData getWord(int index) < return words[index]; >public int getSize() < return size; >private static final int DEFAULT_WORD_ARRAY_SIZE = 10; private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; public WordArrayList() < words = new WordData[DEFAULT_WORD_ARRAY_SIZE]; >public WordArrayList(int initialCapacity) < super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity); words = new WordData[initialCapacity]; >public int insertWord(final String word) < if (checkAndAddExistingWord(word)) < return 0; >checkAndIncreaseCapacity(); words[size] = new WordData(word); size++; return 1; > private boolean checkAndAddExistingWord(String word) < int position = 0; for (position = 0; position < size; position++) < if (words[position].getWord().equals(word)) < words[position].incrementWordCount(); return true; >> return false; > private void checkAndIncreaseCapacity() < if (isWordArrayFull(size)) increaseCapacity(size); >private void increaseCapacity(int size) < int newCapacity = size * 2; if (newCapacity >MAX_ARRAY_SIZE) < newCapacity = Integer.MAX_VALUE; >WordData[] newWords = new WordData[newCapacity]; System.arraycopy(words, 0, newWords, 0, size); > private boolean isWordArrayFull(int wordCount) < return (wordCount - words.length >0); > public void setWord(int i, WordData word) < words[i] = word; >public class TextAnalyzer < private static final String REG_SPLIT_EXP = "\\s+"; private String text; private String textSplitExp; private WordArrayList wordArrayList; public TextAnalyzer(String text, String textSplitExp) < this.textSplitExp = textSplitExp; this.text = text; wordArrayList = new WordArrayList(); >public TextAnalyzer(String text) < this.textSplitExp = REG_SPLIT_EXP; this.text = text; wordArrayList = new WordArrayList(); >private String[] convertToArray() < return text.split(textSplitExp); >public void generateWordArrayList() < String[] splitTextArray = convertToArray(); for (int i = 0; i < splitTextArray.length; i++) < wordArrayList.insertWord(splitTextArray[i]); >> public void printWordArrayList() < for (int i = 0; i < wordArrayList.getSize(); i++) < System.out.println("=" + wordArrayList.getWord(i).getWord() + "= mt24 mb12">
  • java
  • strings
  • array
)" data-controller="se-share-sheet" data-se-share-sheet-title="Share a link to this question" data-se-share-sheet-subtitle="" data-se-share-sheet-post-type="question" data-se-share-sheet-social="facebook twitter " data-se-share-sheet-location="1" data-se-share-sheet-license-url="https%3a%2f%2fcreativecommons.org%2flicenses%2fby-sa%2f3.0%2f" data-se-share-sheet-license-name="CC BY-SA 3.0" data-s-popover-placement="bottom-start">Share
)" title="">Improve this question
)">edited Jan 7, 2014 at 21:14
200_success
143k22 gold badges186 silver badges470 bronze badges
asked Jan 7, 2014 at 16:30
\$\endgroup\$
2
  • \$\begingroup\$Could you include the TextAnalyzerUtil.sort method in your code? That way we could compile the code ourselves and therefore make a better review.\$\endgroup\$
    – Simon Forsberg
    Jan 7, 2014 at 16:41
  • 1
    \$\begingroup\$Nevermind, sorting the word list isn't that important really :)\$\endgroup\$
    – Simon Forsberg
    Jan 7, 2014 at 17:16
Add a comment|

2 Answers 2

Reset to default
13
\$\begingroup\$

There are a couple of things you should think about or fix:

  • Indentation. You're not really consistent in indenting your code. Please follow the Java conventions.

  • No need to call super() inside your constructor, the default empty super constructor is automatically called.

  • 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.

    Источник

    Читайте также:  Python получить размер монитора
Оцените статью