I have to create a word counter program. It is not very difficult logically but I am getting stuck with interfaces. So first I have to create an class which implements the defined interface:
public interface WordFrequency {
String getWord();
int getFrequency();
}
And I have to create another class which implements another interface as defined:
public interface WordFrequencyAnalyzer {
int calculateHighestFrequency(String text);
int calculateFrequencyForWord (String text, String word);
List<WordFrequency> calculateMostFrequentNWords (String text, int n);
}
Now, the third method in this interface returns a list of the previous interface. I will maintain the frequencies of words in a Map. This method requires me to return the words with N highest frequencies in the given text. It would be very easy to just sort the map with descending values and return accordingly, but how do I create a list of this particular interface with the correct values from the map to return in the required format?
Edit: I am using Map<String,Integer> m = new HashMap<String,Integer>()
to store the words and their frequencies. This is what I need to store in List<WordFrequency>
and return.
CodePudding user response:
You can consider this example as a starting point for your use case:
interface
public interface WordFrequency {
String getWord();
int getFrequency();
}
The implementation of above interface
public class WordFreqImpl implements WordFrequency {
final String w;
final Integer f;
public WordFreqImpl(String word, Integer freq) {
w = word;
f = freq;
}
@Override
public String getWord() {
return w;
}
@Override
public int getFrequency() {
return f;
}
@Override
public String toString() {
return ""
"w=" w
", f=" f;
}
}
demo of getting the list per your requirement
public class WordFreqDemo {
public static void main(String[] args) {
Map<String,Integer> m = new HashMap<>();
m.put("k1",1);
m.put("k2",2);
m.put("k3",3);
List<WordFrequency> wordFrequencyList = new ArrayList<>();
for (Map.Entry<String, Integer> entry: m.entrySet()) {
wordFrequencyList.add(new WordFreqImpl(entry.getKey(), entry.getValue()) {
});
}
for (WordFrequency w: wordFrequencyList) {
System.out.println(w);
}
// return wordFrequencyList as per use case
}
}
output
w=k1, f=1
w=k2, f=2
w=k3, f=3
CodePudding user response:
Simply, you must have an concrete object that implements the interface. Then you can add that object to your list because it will now be a WordFrequency object in addition to whatever object it is by default. You will also need an object that implements the WordFrequencyAnalyzer interface as well.
The interface is a contract which guarantees that any object implementing the interface will have certain behaviors. It abstracts the implementation away and allows objects to be more polymorphic.
This is a good resources on interfaces
https://www.geeksforgeeks.org/interfaces-in-java/
CodePudding user response:
Still an answer showing record
as ad-hoc data class, and Stream
-.
The n
highest frequency entries from the map:
record Fr(String word, int frequency) implements WordFrequency {
@Override
public String getWord() {
return word;
}
@Override
public int getFrequency() {
return frequency;
}
}
Map<String,Integer> m = ...
List<WordFrequency> wfs = m.entrySet().stream()
.sorted(e -> Comparator.comparingInt(e.getValue()).reversed()
.thenComparing(e.getKey()))
.limit(n)
.map(e -> new Fr(e.getKey(), e.getValue())
.collect(Collectors.toList()):