Java – description of this lambda expression

I'm creating a word comparison class that also counts the number of occurrences of words (this is Java)

This is my original method:

/**
 * @param map The map of words to search
 * @param num The number of words you want printed
 * @return list of words
 */
public static List<String> findMaxOccurrence(Map<String,Integer> map,int num) {
    List<WordComparable> l = new ArrayList<>();
    for (Map.Entry<String,Integer> entry : map.entrySet())
        l.add(new WordComparable(entry.getKey(),entry.getValue()));

My ide suggests that loop and list allocation can be replaced by "collect calls": "stream API calls"

Where this code is generated:

List<WordComparable> l =
            map.entrySet().stream()
                    .map(entry -> new WordComparable
                            (entry.getKey(),entry.getValue())).collect(Collectors.toList());

I'm confused about how lambda mathematics works If my memory is normal, then – > is every loop, but the other calls are completely confusing

My ide can also extend the code to these two fragments:

List<WordComparable> l =
            map.entrySet().stream()
                    .map(entry -> {
                        return new WordComparable
                                (entry.getKey(),entry.getValue());
                    }).collect(Collectors.toList());

and

List<WordComparable> l =
            map.entrySet().stream()
                    .map(new Function<Map.Entry<String,Integer>,WordComparable>() {
                        @Override
                        public WordComparable apply(Map.Entry<String,Integer> entry) {
                            return new WordComparable
                                    (entry.getKey(),entry.getValue());
                        }
                    }).collect(Collectors.toList());

Any light will be great

Solution

Let's look at the for loop and see how we write it functionally:

List<WordComparable> l = new ArrayList<>();
for (Map.Entry<String,Integer> entry : map.entrySet())
    l.add(new WordComparable(entry.getKey(),entry.getValue()));

If we read the code in simple English, we might say "for each item of my map, let's convert it to wordcomparable and add it to the list"

Now, we can change the sentence to "for each item of my map, let's convert it to wordcomparable. When we convert it all, let's make a list from it"

Using this sentence, we see that we need to create a function: a function that takes map entries and converts them into wordcomparable So let's build one! Java 8 introduces a new type called function, which has an important method: apply This method takes an input, transforms it, and returns an output

Because function is an interface, we can implement it to write our conversion code:

public class EntryConverter implements Function<Map.Entry<String,WordComparable> {

    public WordComparable apply(Map.Entry<String,Integer> entry) {
        return new WordComparable(entry.getKey(),entry.getValue());
    }

}

Now that we have this converter, we need to use it on all items Java 8 also introduces the concept of stream, that is, a series of elements (note that this sequence can be infinite) Using this sequence, we can finally write what we said before, that is, "for each item, let's convert it to wordcomparable" We use the map method, whose goal is to apply the method on each element of the stream

We have a method: entryconverter. We use the stream method to build our item stream

Therefore, we get:

map.entrySet().stream().map(new EntryConverter());

The rest is the last part of the sentence: "make a list from it", that is, collect all elements into a list This is done using the collect method This method takes collector as a parameter, that is, it can reduce the flow to the object of the final container Java 8 comes with many pre built collectors; One of them is collectors toList().

Finally, we get:

map.entrySet().stream().map(new EntryConverter()).collect(Collectors.toList());

Now, if we delete the temporary class entryconverter and make it anonymous, we will get your ide advice:

List<WordComparable> l = map.entrySet()
                            .stream() //make a Stream of our entries
                            .map(new Function<Map.Entry<String,WordComparable>() {
                                 @Override
                                 public WordComparable apply(Map.Entry<String,Integer> entry) {
                                     return new WordComparable(entry.getKey(),entry.getValue());
                                 }
                             }) //let's convert each entry to a WordComparable
                             .collect(Collectors.toList()); //and make a List out of it

Now, writing all the code is a bit cumbersome, especially the declaration of anonymous classes Java 8 brings a new – > operator This operator allows you to create functions more easily than before: the left corresponds to the parameters of the function and the right corresponds to the results This is called lambda expression

In our example, we get:

entry -> new WordComparable(entry.getKey(),entry.getValue())

You can also write this lambda expression using blocks and return statements:

entry -> {
    return new WordComparable(entry.getKey(),entry.getValue());
}

Please note that this corresponds to what we wrote earlier in entryconverter

This means that we can refactor the code to:

List<WordComparable> l = map.entrySet()
                            .stream()
                            .map(entry -> new WordComparable(entry.getKey(),entry.getValue()))
                            .collect(Collectors.toList());

It is more readable and is proposed by your ide

You can find more information about lambda expressions on the Oracle site

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>