Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

lambda expressions and streams  RSS feed

 
tim ledger
Greenhorn
Posts: 12
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

How do I write a lambda expression, with two variables, as a filter in a stream?

Here is what I am trying to do:

        NavigableMap<Integer, String> mymap = new TreeMap<>();
        mymap.put(90, "Sophia");
        mymap.put(20, "Isabella");
        mymap.put(10, "Emma");
        mymap.put(50, "Olivea");
        mymap.entrySet().stream().filter((Integer i, String s) -> i > 40).

The error that I am getting says: "Incompatible types. Incompatible types in lambda expression"

Thanks

Tim
 
Dave Tolls
Rancher
Posts: 2909
35
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The entrySet() method returns a Set<Map.Entry<K,V>> so the parameter to the lambda is a Map.Entry<Integer, String> in your case.
 
Knute Snortum
Sheriff
Posts: 4070
112
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And if you don't need the String value, you can simplify the code to:
 
tim ledger
Greenhorn
Posts: 12
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Figured it out:

You can get the values andd the keys as in the filter below.

        Map<Integer, String> passed = mymap.entrySet().stream().filter(p -> p.getKey() > 40)
                .collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue()));
        System.out.println("Mark \tName");
        passed.forEach((i, s) -> System.out.printf("%d \t%s\n", i, s));
 
tim ledger
Greenhorn
Posts: 12
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oh, and you collect a new map showing you the result you want.
 
Campbell Ritchie
Marshal
Posts: 55672
161
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Duplicating this discussion in our Java8 forum.

Go through the methods of the Stream interface, and you will find they are described as terminal operations or intermediate operations (gross oversimplification warning ‍). Those labelled intermediate return a Stream, and those called terminal don't return a Stream; they might be void or return something different. Every time you call a method which is an intermediate operation, it creates a reference to a new Stream. That may seem expensive in memory, but it isn't. The Streams are probably created on the stack because you usually create them as local variables and they go out of scope as soon as the statement finishes. There is no point in having a Stream with more scope, becaus you cannot wind it back to its beginning and start again. You need a new Stream. Each Stream reference created will point to an object which executes one part of the action you want. If you execute yoru code on an IDE like Eclipse, hover your mouse over each of the method calls and you will get a popup with the type of Stream, i.e. the type actually returned from each method call. That shou‍ld allow you to see how the different Streams handle the data they are processing.
tim ledger wrote:
Let's reformat that code, with a slightly different indentation convention so all the dots align vertically:-Now, if you have a Map<XYZ, Integer>, and you hover your mouse on the different lines the popups will say something like this:-
  • Line 1: Set<Map.Entry<XYZ, Integer>>
  • Line 2: Stream<Map.Entry<XYZ, Integer>>
  • Line 3: Stream<Map.Entry<XYZ, Integer>> Note the filer method is likely to return a Stream of exactly the same type.
  • Line 4: Map<XYZ, Integer>>
  • You will probably find that sort of information makes it easier to follow what is happening throughout the whole procedure. If you add a peek call anywhere, you will find that nothing happens until the collect method (which is a terminal operation) starts, because Streams use lazy execution.

    If you go back to the Stream documentation, you will find the phrases like intermediate operation are hyperlinks and you will get more information if you click them.

    [edit]I seem to have got the K and V types the wrong way round in what I wrote earlier. I shall leave it to the reader to work out how to correct my error. Sorry.
     
    tim ledger
    Greenhorn
    Posts: 12
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thanks very much for a great explanation. :-)
     
    Campbell Ritchie
    Marshal
    Posts: 55672
    161
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    tim ledger wrote:Thanks very much . . .
    That's a pleasure
     
    It is sorta covered in the JavaRanch Style Guide.
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!