Java 8 removing an item from array/array list based on regex

You can use

personalNames.removeIf(Pattern.compile("^SACHI").asPredicate());

You could also use the simpler

personalNames.removeIf(s -> s.matches("^SACHI"));

but it will perform Pattern.compile("^SACHI") under the hood, for every element in the worst case. Note that the Pattern created by compile is immutable and can be shared, hence, you could also create it only once, like

static final Pattern REMOVAL_PATTERN = Pattern.compile("^SACHI");

and use it like

personalNames.removeIf(REMOVAL_PATTERN.asPredicate());

asPredicate() uses find() instead of matches(), but since your pattern has the ^ anchor, it makes no difference. The method asMatchPredicate() for getting a predicate using matches() has been added in JDK 11.


If all you want, is to match a literal string at the beginning, you can also use

personalNames.removeIf(s -> s.startsWith("SACHI"));

which does not have the regex initialization overhead.


It depends did you need to modify existing list, or you need just get list without elements. In first case, you can use stream to filter non matching objects and remove them from list

personalNames.removeAll(
        personalNames
                .stream()
                .filter(x -> !x.matches(regex))
                .collect(Collectors.toList())
);

In other case, you can just return new list with only matching objects

final List<String> matchingElements = personalNames.stream()
        .filter(x -> x.matches(regex))
        .collect(Collectors.toList());

also, this code

for (String temp : personalNames ) {
    if (temp.matches(regex)){
        personalNames.remove(temp);
    }
}

will throw java.util.ConcurrentModificationException


Adding and/or removing elements from an existing container does not fit in nicely with the concepts of functional programming. More over that behavior is not thread safe in parallel and concurrent environment. Making it thread safe demands more effort too. Therefore prefer steteless lambdas to stateful lambdas as a good engineering practice. You can get the matching names by merely using filter operator. Here's how it looks.

private static final Pattern PATTERN = Pattern.compile("^SACHI");

List<String> validNames = personalNames.stream()
    .filter(PATTERN.asPredicate())
    .collect(Collectors.toList());

Tags:

Java

Java 8