Why isn’t my foreach cycle printing anything?

Asked

Viewed 88 times

3

public static Iterable<String> select(Iterable<String> it, Predicate<String> pred) { 
    ((Collection<String>) it).removeIf(pred);
    return it;
}

public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    list.add("a");
    list.add("");
    list.add("b");
    list.add("");
    list.add("c");
    Iterable<String> nonEmpty = select(list, s -> !s.isEmpty());
    for(String s : nonEmpty) {
        System.out.println(s);
    }
}

I want through function select filter the contents (where the filter is given through the Predicate) of an object that is eternal. I tried to touch several things, one of them was to do the cast to use the removeIf but when I test, no print comes out.

2 answers

8

The problem is in this lambda:

s -> !s.isEmpty()

He returns true when the string nay is empty. And the method removeIf removes the elements for which the predicate is true.

That is, the code is removing the non-empty strings, and in the end only the empty strings remain. You can check this if you print something before each element:

Iterable<String> nonEmpty = select(list, s -> !s.isEmpty());
for (String s : nonEmpty) {
    System.out.println("- " + s);
}

The exit is:

- 
- 

That is, at the end left the two empty strings.


If you want to remove the empty strings, simply remove the ! of lambda:

Iterable<String> nonEmpty = select(list, s -> s.isEmpty());
for (String s : nonEmpty) {
    System.out.println("- " + s);
}

So he returns true when the string is empty, and removeIf removes empty strings. The output is:

- a
- b
- c

But you need to use a Predicate? You can use a loop simple if you want:

for (Iterator<String> it = list.iterator(); it.hasNext();) {
    if (it.next().isEmpty()) {
        it.remove();
    }
}

Or, if you really want to wear one Predicate, can turn the list into a stream and filter the empty strings:

List<String> naoVazios = list.stream()
                             .filter(s -> !s.isEmpty())
                             .collect(Collectors.toList());

In that case I used !s.isEmpty(), because I want to filter strings that are not empty.

The above code creates another list, containing only non-empty strings. But if you just want to print the elements, for example, you can do:

list.stream()
    .filter(s -> !s.isEmpty())
    .forEach(System.out::println);

Or more generally:

list.stream()
    .filter(s -> !s.isEmpty())
    .forEach(s -> {
    // fazer o que quiser com a String s
    });

4


From what I understand your code is removing what it is other than empty and must be printing things blank.

Switch to select(list, String::isEmpty); that will work

Browser other questions tagged

You are not signed in. Login or sign up in order to post.