1

I am using a function call is filter on a stream like below -

list.stream()
        .filter(a -> !StringUtils.isEmpty(a.getProp1()))
        .filter(a -> !a.getProp1().matches(“(.*)xyz"))
        .filter(a -> {try {
                        return isValid(a.getProp1());
                    } catch (javax.naming.NamingException e) {
                        logger.error("Error");
                    }
                    })

I referred to the question But I don't want to throw an exception in the catch block. I just want to log it.

I want to retain the records which return true on invoking isValid(a) and then be able to collect it in a HashSet like below --

 //   .collect(Collectors.toCollection(HashSet::new));

It must be obvious from code but I am new to java 8 and still learning concepts. Please pardon any naive code. Thanks for any help.

Stefan Zobel
  • 3,182
  • 7
  • 28
  • 38
maddie
  • 629
  • 10
  • 29
  • in the 3rd filter, when you catch your exception, should be the "a" filtered out or not? Not missing a "return false" or sth like that? – fairtrax Jul 19 '17 at 17:01

1 Answers1

2

As you are filtering, if the isValid method throws a javax.naming.NamingException, apart from logging the exception, you might want to return false:

Set<Whatever> result = list.stream()
    .filter(a -> !StringUtils.isEmpty(a.getProp1()))
    .filter(a -> !a.getProp1().matches("(.*)xyz"))
    .filter(a -> {
        try {
            return isValid(a.getProp1());
        } catch (javax.naming.NamingException e) {
            logger.error("Error");
            return false;
        }})
    .collect(Collectors.toCollection(HashSet::new));

This is because the Predicate argument passed to the Stream.filter method must always return a boolean value, no matter if it has catched an exception or not.

fps
  • 33,623
  • 8
  • 55
  • 110
  • That makes sense, even after adding a `return false`, I am not able to collect the list which is an arraylist into a hashSet. I get a compilation error saying 'Bad return type in method reference. – maddie Jul 19 '17 at 17:05
  • `Set mySet = new HashSet<>(); mySet = list.stream() .filter(a -> !StringUtils.isEmpty(a.getProp1())) .filter(a -> !a.getProp1().matches(“(.*xyz”)) .filter(a -> {try { return isValid(a.getProp1()); } catch (javax.naming.NamingException e) { logger.error("Error"); return false; } }) .collect(Collectors.toCollection(HashSet::new));` This is my final code. – maddie Jul 19 '17 at 17:05
  • @maddie Please check if it works after my last edit. The other strange thing I notice is the use of typographic quotes in the second `filter(...)`... – fps Jul 19 '17 at 17:06
  • @maddie The other problem is the `Set mySet`. Is it really a set of strings? I think it's a set of some object of yours, while `getProp1()` returns an actual string. – fps Jul 19 '17 at 17:10
  • 1
    Yes, you guessed it right, I will fix it. I guess I will reassign the modified list to list itself in that case. Thanks so much. – maddie Jul 19 '17 at 17:12
  • @maddie So you only want to remove elements from the original list? – fps Jul 19 '17 at 17:14
  • 1
    I actually added a `.map(a -> a.getProp1())` after all the filters. i am able to collect it as a HashSet. Thanks! – maddie Jul 19 '17 at 17:14
  • @maddie OK, that makes sense. Cheers! – fps Jul 19 '17 at 17:15
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/149639/discussion-between-federico-peralta-schaffner-and-maddie). – fps Jul 19 '17 at 17:15