Is there a better way to achieve the following in java 8?
String regex = "^SACHI";
for (String temp : personalNames ) {
if (temp.matches(regex)){
personalNames.remove(temp);
}
}
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.
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());
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With