1

I need to run two different tasks based on a whole mess of filters

I'm just now grasping the concept of Lambdas, so I guess my question is, how do you handle multiple "else" conditions containing complicated logic... within a Lambda?

I know I can use filter and map to select certain pieces of data. How does "nesting" work with filters?

Could I do something like:

//Iterate over list of sites
sites.stream()
//Check if current site is active
.map(isActive ? 
//{Do something with site because site is active};
//Set a variable for later user maybe?
:
//{Do something else involving the current site because it's not?};
//Set a different variable maybe?
);

//use variable from first map?

Can someone provide me with some proper syntax and maybe a basic explanation of what I'm doing to my data when I run through these abstract processes that are doing me a bamboozle.

Secondly, if I wanted to run these two map processes in parallel, would I just do this?

sites.stream().parallel()?

As usual, thanks for helping with my ignorance!

4
  • 1
    docs.oracle.com/javase/tutorial/java/javaOO/… ? Commented Mar 31, 2016 at 18:10
  • I think you better stick to traditional programming for these types of tasks. Commented Mar 31, 2016 at 18:11
  • Just so I'm completely clear...if I have two simple program paths, do task 1 if true, do task 2 if false, lambdas aren't really the way to go? Commented Mar 31, 2016 at 18:42
  • 1
    Maybe you should put more logic into your site objects and let them decide what to do, see Tell-Don't-Ask principle. This way you can simply call sites.forEach(Site::doSomething) from outside and put the logic in the Site class. Commented Apr 2, 2016 at 7:27

3 Answers 3

4

Some example of lambda usage:

You can group your sites by active and not active, after that you can perform some logic to both. Put the big logic into a method and then call in the map() function.

You can use filter() as well to get only a part of the stream.

public class Lambda {

    static class Site {

        public boolean isActive;
        public boolean otherCondition;
        public boolean isActive() {
            return isActive;
        }

        public boolean isOtherCondition() {
            return otherCondition;
        }

        public void setProperty(String property) {

        }
    }
    public static Site someOperation(Site site) {

        //some code

        return site;
    }
    public static void main(String[] args) {

        ArrayList<Site> sites = new ArrayList<>();

        Map<Boolean, List<Site>> groupedSites = sites.stream().collect(Collectors.groupingBy(Site::isActive));          
        groupedSites.get(Boolean.TRUE).stream().filter(Site::isOtherCondition).map(Lambda::someOperation).forEach(p -> p.setProperty("something"));

    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you! This is very helpful! I can now leverage multiple processors to work on multiple lists at one time and the code is much less complex. Perhaps a little more confusing, but less complex overall!
You can replace Collectors.groupingBy(Site::isActive) by Collectors.partitioningBy(Site::isActive). Then you will get a map optimized for mapping exactly true and false to a value and it will have an empty list in case there’s no match, so the follow-up groupedSites.get(Boolean.TRUE).stream() won’t throw a NullPointerException in that case. Also, mind that there is an overload that accept a downstream collector to perform operation right when collecting instead of storing everything into a list and perform a stream operation afterwards.
@Holger oh, thank you, I didn't know that method, useful comment.
3

I would put the complex logic into a separate method and reference to it in the map(…).

sites.stream()
    .map(Foo::bar)
    …;

This would use a method in a class Foo that could look like this:

public static String bar(Site site)
{
    return site.toString();
}

Of course you can use arbitrary logic in the method but it should be free of side effects.

And yes, if the method used for mapping is thread safe, you can use parallel() to run the mappings in parallel.

Comments

1

You just use a plain, simple if:

.map(site -> {
   if (isActive) {
     ...whatever...
   } else {
     ...whatever else...
   }
 })
 ...

1 Comment

@TheFunk There isn't. Lambdas and streams aren't always the best solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.