I have written a code snippet to read a sentence and print the words in the sentence along with their count of occurence.
Example: String = Java is a language. java is easy and i like Java Expected output : Java =3, is=2 a=1, language=1, easy=1, and=1 i=1, like=1
I want to achieve it by using two nested for loops but I am missing something and the code is broken. Here is the snippet
package corejava;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class DuplicateStringOccurence {
public static void main(String[] args) {
// TODO Auto-generated method stub
String myString = " Java is a language. java is easy and i like Java";
String[] wordsInMySentence = getWords(myString);
Map<String, Integer> myMap = new HashMap<String, Integer>();
int countOfOccurence = 1;
// outloop i, innerlop j
for(int i=0;i<wordsInMySentence.length;i ) {
if (myMap.containsKey(wordsInMySentence[i])) {
countOfOccurence=1;
continue;
}
for(int j=i 1;j<wordsInMySentence.length;j )
{
if (wordsInMySentence[i].equalsIgnoreCase(wordsInMySentence[j])) {
// match found
countOfOccurence ;
}
myMap.put(wordsInMySentence[i], countOfOccurence);
}
}
// print the duplicates and counts
for (Entry<String, Integer> entry : myMap.entrySet()) {
System.out.println(entry.getKey() ":" entry.getValue().toString());
}
}
private static String[] getWords(String myString) {
// TODO Auto-generated method stub
String[] wordsInMySentence = myString.replaceAll("[^a-zA-Z ]", "").toLowerCase().split("\\s ");
// create the array of words from the sentence
for (String s:wordsInMySentence) {
// System.out.println(s);
}
return wordsInMySentence;
}
}
I am not getting the expected output. I want to correct this piece of code . Can someone guide what is the mistake here?
CodePudding user response:
Using java8
you can do like below :
First split you string by using regex ("[. ] ")
and store that into List.
Then using Collectors.toMap
,
toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper,BinaryOperator<U> mergeFunction)
It takes below three arguments :
- KeyMapper -
k -> k.toLowerCase()
- ValueMapper -
k -> 1
- MergeFunction - Here
Integer::sum
You can refer doc Collectors.toMap(keyMapper,valueMapper,mergeFunction)
public class WordCount {
public static void main(String[] args) {
String sentense= "Java is a language.java is easy and i like Java";
List<String> list = Stream.of(sentense).map(k -> k.split("[. ] ")).flatMap(Arrays::stream)
.collect(Collectors.toList());
Map<String, Integer> countMap= list.stream()
.collect(Collectors.toMap(k -> k.toLowerCase(), k -> 1, Integer::sum));
System.out.println(countMap);
// Output : {a=1, java=3, like=1, and=1, i=1, language=1, is=2, easy=1}
}
}
CodePudding user response:
With Map data structure you need only one for loop.
Here is one solution using basic for loop:
String sentense= "Java, is a language.java is easy and i like Java";
String[] words = sentense.split("\\W ");
Map<String, Integer> countMap = new HashMap<>();
for(String word : words) {
word = word.toLowerCase();
Integer count = countMap.containsKey(word)? countMap.get(word) 1 : 1;
countMap.put(word, count);
}
System.out.println(countMap);
CodePudding user response:
You can use the handy merge
method to keep track of the sums
private static String[] getWords(String myString) {
return myString.trim().split("\\W ");
}
public static void main(String[] args) {
String myString = "\tJava is a language. java is easy and i like Java ";
Map<String, Integer> myMap = new HashMap();
for (String word : getWords(myString)) {
myMap.merge(word.toLowerCase(), 1, Integer::sum);
}
System.out.println(myMap);
}