Hi Everyone,
I m running SonarQube on an my AEM project, and the rule “Methods should not have high Cognitive Complexity” (java:S3776) keeps failing for this real utility method, even after I refactored parts into private helpers:
public List<Page> filterAndSortPages(List<Page> pages, Predicate<Page> filter) {
List<Page> result = new ArrayList<>();
for (Page page : pages) {
if (page != null && page.isValid()) {
if (page.getProperties().get("status", "draft").equals("published")) {
ValueMap vm = page.getProperties();
if (vm.containsKey("priority")) {
int priority = vm.get("priority", 0);
if (priority > 5) {
result.add(page);
}
}
}
}
}
result.sort(Comparator.comparingInt(p -> p.getProperties().get("priority", 0)).reversed());
return result;
}
I tried splitting the nested ifs into private methods, but didn't help, can someone help me here?
Solved! Go to Solution.
Hi @PriyaNair1,
Can you try this?
public List<Page> filterAndSortPages(List<Page> pages, Predicate<Page> filter) {
if (pages == null || pages.isEmpty()) {
return Collections.emptyList();
}
return pages.stream()
.filter(Objects::nonNull)
.filter(Page::isValid)
.filter(page -> "published".equals(page.getProperties().get("status", "draft")))
.filter(this::isHighPriority)
.filter(filter) // optional external filter
.sorted(Comparator.comparingInt(p -> p.getProperties().get("priority", 0)).reversed())
.collect(Collectors.toList());
}
private boolean isHighPriority(Page page) {
ValueMap vm = page.getProperties();
return vm.get("priority", 0) > 5;
}
Hi @PriyaNair1,
Can you try this?
public List<Page> filterAndSortPages(List<Page> pages, Predicate<Page> filter) {
if (pages == null || pages.isEmpty()) {
return Collections.emptyList();
}
return pages.stream()
.filter(Objects::nonNull)
.filter(Page::isValid)
.filter(page -> "published".equals(page.getProperties().get("status", "draft")))
.filter(this::isHighPriority)
.filter(filter) // optional external filter
.sorted(Comparator.comparingInt(p -> p.getProperties().get("priority", 0)).reversed())
.collect(Collectors.toList());
}
private boolean isHighPriority(Page page) {
ValueMap vm = page.getProperties();
return vm.get("priority", 0) > 5;
}
Hi @PriyaNair1 ,
Option A: Early Exit (continue)
Flatten logic, avoid deep nesting:
for (Page page : pages) {
if (page == null || !page.isValid()) continue;
if (!"published".equals(page.getProperties().get("status", "draft"))) continue;
if (!page.getProperties().containsKey("priority")) continue;
int priority = page.getProperties().get("priority", 0);
if (priority <= 5) continue;
result.add(page);
}
Simpler, fewer nested blocks → lower complexity.
Option B: Streams
Make conditions declarative:
return pages.stream()
.filter(Objects::nonNull)
.filter(Page::isValid)
.filter(filter)
.filter(p -> "published".equals(p.getProperties().get("status", "draft")))
.filter(p -> p.getProperties().containsKey("priority"))
.filter(p -> p.getProperties().get("priority", 0) > 5)
.sorted(Comparator.comparingInt(p -> p.getProperties().get("priority", 0)).reversed())
.toList();
No nesting, Sonar-friendly, cleaner.
Thanks & Regards,
Vishal
Views
Likes
Replies