1

I'm working on an assignment which uses Java streams with lambda syntax. The program is supposed to be designed (1) To count a set of files (2) To count the words within those files (3) Print and display the result. This is an example of the output:

Count 11 files:
word length: 1 ==> 80
word length: 2 ==> 321
word length: 3 ==> 643
.....

However, I'm getting this output instead:

primes.txt
word length: 1 ==> hw8.WordCount@5c647e05
constitution.txt
word length: 2 ==> hw8.WordCount@33909752
short.txt
word length: 3 ==> hw8.WordCount@55f96302
.....
Count: 11 files

The program I've written is in two classes - FileCatch, which counts the files and WordCount, which counts the words (In theory). If anyone has any programming tips to help, I would be appreciated.

The FileCatch class

public class FileCatch8 {
    public static void main(String args[]) {
        List<String> fileNames = new ArrayList<>();
        try {
            DirectoryStream<Path> directoryStream = Files.newDirectoryStream
        (Paths.get("files"));
            int fileCounter = 0;
            for (Path path : directoryStream) {
                System.out.println(path.getFileName());
                fileCounter++;
                fileNames.add(path.getFileName().toString());
                WordCount WordCnt = new WordCount();
                System.out.println("word length: " +  fileCounter + " ==> " + WordCnt);
            }
    }catch(IOException ex){
    }
    System.out.println("Count: "+fileNames.size()+ " files");

  }
}

The WordCount class:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.AbstractMap.SimpleEntry;
import java.util.Arrays;
import java.util.Map;
import java.util.TreeMap;
import static java.util.stream.Collectors.counting;
import static java.util.stream.Collectors.groupingBy;
import java.util.stream.Stream;

/**
 *
 * @author GeraldShields
 */
public class WordCount {

    /**
     *
     * @return 
     * @throws IOException
     */
    public Map<String, Long> WordCount()throws IOException {
        Stream<String> lines = Files.lines(Paths.get("constitution.txt"));
        Map<String, Long> wordMap = lines
                .parallel()
                .map(String::toLowerCase)
                .map(line -> line.split("\\W+"))
                .flatMap(line -> Arrays.asList(line).stream())
                .filter(word -> !word.matches("\\d+") && word.trim().length() != 0)
                .map(word -> new SimpleEntry<>(word, 1))
                .collect(groupingBy(SimpleEntry::getKey, counting()));
        new TreeMap(wordMap).forEach((k, v) -> 
                System.out.println(String.format("%s word length: 1 ==> %d", k, v)));
        return wordMap;
    }
}
Eran
  • 387,369
  • 54
  • 702
  • 768
Java Newbie
  • 41
  • 1
  • 6

1 Answers1

0

You are printing an instance of your WordCount class, which makes no sense. You also never call the WordCount() method.

You should create a single instance of WordCount and call the method that performs the word count for each file (I renamed some of the methods and variables to make the code more readable):

WordCount wordCnt = new WordCount();
for (Path path : directoryStream) {
    System.out.println(path.getFileName());
    fileCounter++;
    fileNames.add(path.getFileName().toString()); 
    System.out.println("word length: " +  fileCounter + " ==> " + wordCnt.count(path.getFileName().toString()));
}


public class WordCount {

    /**
     *
     * @return 
     * @throws IOException
     */
    public Map<String, Long> count(String filename) throws IOException {
        Stream<String> lines = Files.lines(Paths.get(filename));
        Map<String, Long> wordMap = lines
                .parallel()
                .map(String::toLowerCase)
                .map(line -> line.split("\\W+"))
                .flatMap(line -> Arrays.asList(line).stream())
                .filter(word -> !word.matches("\\d+") && word.trim().length() != 0)
                .map(word -> new SimpleEntry<>(word, 1))
                .collect(groupingBy(SimpleEntry::getKey, counting()));
        new TreeMap(wordMap).forEach((k, v) -> 
                System.out.println(String.format("%s word length: 1 ==> %d", k, v)));
        return wordMap;
    }
}

Note the your WordCount class seems to count the appearances of each word in a file, not the total number of words in a file, so it doesn't seem to match the expected output you posted at the start of your question.

Eran
  • 387,369
  • 54
  • 702
  • 768
  • @Eren just to check: Did you suggest to create a WordCount method? I'd tried these suggestions, but the complier had a problem with System.out.println("word length: " + fileCounter + " ==> " + wordCnt.count(path.getFileName().toString())); – Java Newbie Dec 01 '17 at 08:46
  • @JavaNewbie No, I renamed your `WordCount` method to `count` and added a `String` argument to it. – Eran Dec 01 '17 at 08:47
  • @JavaNewbie You have to change your `WordCount` class in order for `wordCnt.count(path.getFileName().toString())` to pass compilation. – Eran Dec 01 '17 at 08:55
  • @Eren Okay, but now the program only returns one of the files in the directory (primes.txt Count: 1 files) , nixes the file count And it doesn't do the word count for the file. – Java Newbie Dec 01 '17 at 10:54