Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate value of text from a dictionary of words in Java 8

I'm having trouble transforming my algo in a Java 8 view.

I have an arrayList composed of Articles

ArrayList<Article> listArticles = new ArrayList<>();

With an Article composed like this

public class Article {
    private String titleArticle;
    private String abstractArticle;
    private String textArticle;
    private Long value;
}

and on the other side I have map of words with each one a value associated

HashMap<String, Long> dictionary = new HashMap<>();

I want to get the value of an article. The value of an article is calculated based on the words in the title, abstract and text (all added up together)

In Java 7 I would do something like this (I hope I didn't make any mistake here)

for(Article article : dataArticles){
    double valueArticle = 0;

    for(Map.Entry<String, Long> word : dataDictionary.entrySet()){

         //looping through the words in the title
         for(String text : article.getTitle().split(" ")){
            if(text.equalsIgnoreCase(word.getKey())){
                valueArticle += word.getValue();
            }
         }
         //looping through the words in the abstract
         for(String text : article.getAbstractText().split(" ")){
            if(text.equalsIgnoreCase(word.getKey())){
                valueArticle += word.getValue();
            }
         }
         //looping through the words in the abstract
         for(String text : article.getText().split(" ")){
            if(text.equalsIgnoreCase(word.getKey())){
                valueArticle += word.getValue();
            }
         }
    }

    article.setValue(valueArticle);
}

How can I calculate the value of each article inside the Array by reducing the time process?
I was thinking of using lambdas but maybe it's a bad approach.
I'm new to Java 8 and trying to learn it.

After some developing

Still looking around how to make my ArrayList using streams. In the meantime I wanted, as well, to sort out the list from greatest article value to lowest article value. I imagined that it would be something like this

Comparator<Article> byArticleValue = (a1, a2) ->
Integer.compare(a1.getValue(), a2.getValue());
dataArticles.stream()
        .sorted(byArticleValue);

But my list comes out unsorted. What am I doing wrong in this case ?

like image 501
kanadianDri3 Avatar asked Dec 14 '25 18:12

kanadianDri3


1 Answers

The hash map can do very fast lookups. If you reorganize your code a bit, you can get huge runtime savings.

long getValueOfText(String text) {
    long value = 0;
    for(String word : text.split(" ")) {
        Long v = dataDictionary.get(word);
        if (v != null) {
            value += v;
        }
    }
    return value;
}

That call to get is almost free. No matter how many words you store in your map, it will take a constant time to look one up.

EDIT: it looks a bit nicer as a Java 8 stream

long getValueOfText(String text) {
    return Arrays.stream(text.split(" "))
                .map(word -> dataDictionary.get(word))
                .filter(v -> v != null)
                .reduce(Long::sum).get();
}
like image 84
Neal Ehardt Avatar answered Dec 16 '25 07:12

Neal Ehardt