I'm trying to filter a resource and exclude some elements based on a field. To exclude I have a set (that contains a id that needs to be excluded) and a list (it contains multiple range of ids that needs to be excluded). I wrote the below logic and I'm not satisfied with the 2nd filter logic. Is there any better way we can do it with Java 8? I need to do the same for including ranges as well.
Set<String> extensionsToExclude = new HashSet<>(Arrays.asList("20","25","60","900"));
List<String> rangesToExclude = new ArrayList<>(Arrays.asList("1-10","20-25","50-70","1000-1000000"));
return directoryRecords.stream()
.filter((directoryRecord) -> !extensionsToExclude.contains(directoryRecord.getExtensionNumber()))
.filter((directoryRecord -> {
Boolean include = true;
for(String s : rangesToExclude) {
String [] rangeArray = s.split("-");
Integer extension = Integer.parseInt(directoryRecord.getExtensionNumber());
if(extension <= Integer.parseInt(rangeArray[0]) && extension >= Integer.parseInt(rangeArray[1])) {
include = false;
}
}
return include;
}))
.collect(Collectors.toList());
Thanks :)
I would do it with a custom Range
class, something like:
class Range {
private long start;
private long end;
Range(String start, String end) {
this.start = Long.parseLong(start);
this.end = Long.parseLong(end);
}
Range(String range) {
this(range.split("-")[0], range.split("-")[1]);
}
boolean inRange(long n) {
returns start <= n && n <= end;
}
}
Which will make something like this possible:
List<Range> ranges = rangesToExclude.stream()
.map(Range::new).collect(Collectors.toList());
return directoryRecords.stream()
.filter((directoryRecord) -> !extensionsToExclude
.contains(directoryRecord.getExtensionNumber()))
.filter(directoryRecord -> ranges.stream()
.noneMatch(r -> r.isInRange(directoryRecord)))
.collect(Collectors.toList());
I personally find your first filter good enough to be preserved as is.
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