From dd8279ade8c51a38ef10ef391814ed9e3d294e8c Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Wed, 26 Aug 2026 17:24:32 -0400 Subject: [PATCH] Add comparator factories pattern Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../collection-bulk-operations.yaml | 2 +- content/collections/comparator-factories.yaml | 51 +++++++++++++++++++ proof/collections/ComparatorFactories.java | 17 +++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 content/collections/comparator-factories.yaml create mode 100644 proof/collections/ComparatorFactories.java diff --git a/content/collections/collection-bulk-operations.yaml b/content/collections/collection-bulk-operations.yaml index b96f66e..c6183db 100644 --- a/content/collections/collection-bulk-operations.yaml +++ b/content/collections/collection-bulk-operations.yaml @@ -33,7 +33,7 @@ support: state: "available" description: "Available since JDK 8 (March 2014)" prev: "collections/stack-to-deque" -next: null +next: "collections/comparator-factories" related: - "collections/reverse-list-iteration" - "collections/copying-collections-immutably" diff --git a/content/collections/comparator-factories.yaml b/content/collections/comparator-factories.yaml new file mode 100644 index 0000000..b4b80ba --- /dev/null +++ b/content/collections/comparator-factories.yaml @@ -0,0 +1,51 @@ +--- +id: a1ac8e52-14cf-49be-a22a-be72de7caa4e +slug: "comparator-factories" +title: "Comparator factories and fluent ordering" +category: "collections" +difficulty: "beginner" +jdkVersion: "8" +oldLabel: "Anonymous comparator" +modernLabel: "Java 8+" +oldApproach: "Anonymous Comparator" +modernApproach: "Comparator factories" +oldCode: |- + people.sort(new Comparator() { + @Override + public int compare(Person a, Person b) { + int byName = a.name().compareTo(b.name()); + return byName != 0 ? byName : Integer.compare(a.age(), b.age()); + } + }); +modernCode: |- + people.sort(Comparator.comparing(Person::name) + .thenComparingInt(Person::age)); +summary: "Build readable, composable ordering rules with Comparator factory methods." +explanation: "Comparator factories express ordering declaratively and compose primary and secondary keys without handwritten branching." +whyModernWins: +- icon: "🧩" + title: "Composable" + desc: "Ordering rules chain naturally." +- icon: "👁" + title: "Easier to review" + desc: "Sort keys and priority are explicit." +- icon: "🐛" + title: "Safer comparisons" + desc: "Specialized helpers avoid error-prone arithmetic comparators." +support: + state: "available" + description: "Available since JDK 8 (March 2014)" +prev: "collections/collection-bulk-operations" +next: null +related: +- "collections/collection-bulk-operations" +- "collections/reverse-list-iteration" +- "language/static-methods-in-interfaces" +tags: +- collections +- functional +docs: +- title: "Comparator.comparing()" + href: "https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/Comparator.html#comparing(java.util.function.Function)" +- title: "Comparator.thenComparingInt()" + href: "https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/Comparator.html#thenComparingInt(java.util.function.ToIntFunction)" diff --git a/proof/collections/ComparatorFactories.java b/proof/collections/ComparatorFactories.java new file mode 100644 index 0000000..dc25f25 --- /dev/null +++ b/proof/collections/ComparatorFactories.java @@ -0,0 +1,17 @@ +///usr/bin/env jbang "$0" "$@" ; exit $? +//JAVA 25+ +import java.util.*; + +/// Proof: comparator-factories +/// Source: content/collections/comparator-factories.yaml +void main() { + record Person(String name, int age) {} + + var people = new ArrayList<>(List.of( + new Person("Ada", 36), + new Person("Ada", 28), + new Person("Grace", 40))); + + people.sort(Comparator.comparing(Person::name) + .thenComparingInt(Person::age)); +}