Create a file named dictionary.txt with the following contents:
a as an b bat ball
Here we have: Count of words starting with "a": 3
Count of words starting with "b": 3
Total word count: 6
Now execute the following program as: java WordCount test_dictionary.txt 10
public class WordCount { String fileName; public WordCount(String fileName) { this.fileName = fileName; } public void process() throws Exception { long start = Instant.now().toEpochMilli(); LongAdder totalWords = new LongAdder(); //Map<Character, LongAdder> wordCounts = Collections.synchronizedMap(new HashMap<Character, LongAdder>()); ConcurrentHashMap<Character, LongAdder> wordCounts = new ConcurrentHashMap<Character, LongAdder>(); Files.readAllLines(Paths.get(fileName)) .parallelStream() .map(line -> line.split("\\s+")) .flatMap(Arrays::stream) .parallel() .map(String::toLowerCase) .forEach(word -> { totalWords.increment(); char c = word.charAt(0); if (!wordCounts.containsKey(c)) { wordCounts.put(c, new LongAdder()); } wordCounts.get(c).increment(); }); System.out.println(wordCounts); System.out.println("Total word count: " + totalWords); long end = Instant.now().toEpochMilli(); System.out.println(String.format("Completed in %d milliseconds", (end - start))); } public static void main(String[] args) throws Exception { for (int r = 0; r < Integer.parseInt(args[1]); r++) { new WordCount(args[0]).process(); } }
}
You would see counts vary as shown below:
{a=2, b=3}
Total word count: 6
Completed in 77 milliseconds
{a=3, b=3}
Total word count: 6
Now comment out ConcurrentHashMap at line 13, uncomment the line above it and run the program again.
You would see deterministic counts.