You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2022/12/12 16:34:28 UTC

[sis] branch geoapi-4.0 updated (9a73feaadc -> 2c7abea573)

This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a change to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git


    from 9a73feaadc Replace `Collections.singletonMap(…)` by `Map.of(…)` where applicabie. There is two cases where we don't do the replacement: - When the map needs to accept null values. - When the check for null value will be better done (with a better error message) by `IdentifiedObject` constructor.
     new 6b3c47f8e1 Replace more `Collections` method calls by `Map.of`, `List.of` or `Set.of`. The remaining `Collections` calls are intentional for accepting null values.
     new 2c7abea573 Resolve some "TODO" which were waiting for JDK 10 or JDK 11.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../org/apache/sis/console/IdentifierCommand.java  |  1 +
 .../org/apache/sis/console/MetadataCommand.java    |  4 +-
 .../apache/sis/console/ResourcesDownloader.java    |  3 +-
 .../org/apache/sis/console/TransformCommand.java   |  3 +-
 .../main/java/org/apache/sis/gui/DataViewer.java   |  3 +-
 .../main/java/org/apache/sis/gui/RecentFiles.java  |  4 +-
 .../apache/sis/gui/coverage/CoverageControls.java  |  4 +-
 .../apache/sis/gui/dataset/ExpandedFeature.java    |  6 +-
 .../org/apache/sis/gui/dataset/PathAction.java     |  3 +-
 .../apache/sis/gui/referencing/AuthorityCodes.java |  3 +-
 .../org/apache/sis/internal/gui/GUIUtilities.java  |  4 +-
 .../apache/sis/coverage/grid/GridCoverage2D.java   |  3 +-
 .../org/apache/sis/coverage/grid/GridExtent.java   | 15 ++---
 .../apache/sis/coverage/grid/PixelTranslation.java | 23 ++++----
 .../org/apache/sis/feature/AbstractFeature.java    |  5 +-
 .../java/org/apache/sis/feature/LinkOperation.java |  3 +-
 .../sis/feature/builder/FeatureTypeBuilder.java    |  3 +-
 .../org/apache/sis/filter/AssociationValue.java    |  4 +-
 .../java/org/apache/sis/filter/Capabilities.java   |  3 +-
 .../org/apache/sis/filter/IdentifierFilter.java    |  5 +-
 .../java/org/apache/sis/filter/LeafExpression.java |  3 +-
 .../java/org/apache/sis/filter/LogicalFilter.java  |  3 +-
 .../java/org/apache/sis/filter/Optimization.java   |  5 +-
 .../java/org/apache/sis/filter/UnaryFunction.java  |  3 +-
 .../sis/internal/feature/AttributeConvention.java  | 30 ++++------
 .../apache/sis/internal/feature/j2d/Factory.java   |  4 +-
 .../internal/feature/jts/PathIteratorAdapter.java  |  6 +-
 .../sis/internal/filter/GeometryConverter.java     |  3 +-
 .../internal/filter/sqlmm/GeometryConstructor.java |  6 +-
 .../sis/internal/filter/sqlmm/OneGeometry.java     |  4 +-
 .../coverage/grid/BufferedGridCoverageTest.java    |  3 +-
 .../coverage/grid/ConvertedGridCoverageTest.java   | 10 ++--
 .../sis/coverage/grid/GridCoverage2DTest.java      |  7 +--
 .../org/apache/sis/feature/CustomAttribute.java    |  7 +--
 .../apache/sis/feature/PropertySingletonTest.java  |  3 +-
 .../feature/builder/AttributeTypeBuilderTest.java  |  9 ++-
 .../builder/CharacteristicTypeBuilderTest.java     |  6 +-
 .../org/apache/sis/filter/LogicalFilterTest.java   |  4 +-
 .../sis/internal/jaxb/IdentifierMapAdapter.java    |  8 +--
 .../sis/internal/jaxb/NonMarshalledAuthority.java  |  5 +-
 .../apache/sis/internal/metadata/ExcludedSet.java  |  2 -
 .../apache/sis/internal/metadata/NameMeaning.java  | 27 ++++-----
 .../internal/metadata/TransformationAccuracy.java  |  6 +-
 .../apache/sis/metadata/PropertyInformation.java   |  4 +-
 .../java/org/apache/sis/metadata/TreeNode.java     |  4 +-
 .../apache/sis/metadata/sql/MetadataWriter.java    |  5 +-
 .../org/apache/sis/util/iso/DefaultLocalName.java  |  3 +-
 .../org/apache/sis/util/iso/DefaultRecord.java     |  3 +-
 .../main/java/org/apache/sis/xml/Namespaces.java   | 69 ++++++++++------------
 .../org/apache/sis/xml/TransformingReader.java     |  6 +-
 .../org/apache/sis/xml/TransformingWriter.java     |  9 ++-
 .../apache/sis/metadata/MetadataStandardTest.java  |  5 +-
 .../sis/metadata/ModifiableMetadataTest.java       |  8 +--
 .../java/org/apache/sis/metadata/PrunerTest.java   | 12 ++--
 .../java/org/apache/sis/metadata/TreeNodeTest.java |  6 +-
 .../apache/sis/metadata/TreeTableFormatTest.java   |  8 +--
 .../apache/sis/metadata/iso/MarshallingTest.java   | 27 ++++-----
 .../metadata/iso/citation/DefaultCitationTest.java |  4 +-
 .../identification/DefaultCoupledResourceTest.java | 10 ++--
 .../DefaultDataIdentificationTest.java             | 16 ++---
 .../DefaultServiceIdentificationTest.java          | 10 ++--
 .../sis/metadata/sql/MetadataSourceTest.java       |  3 +-
 .../apache/sis/test/xml/DocumentComparator.java    | 26 ++++----
 .../org/apache/sis/internal/map/SEPortrayer.java   |  5 +-
 .../MultiResolutionCoverageLoaderTest.java         |  5 +-
 .../referencing/gazetteer/FinalLocationType.java   |  4 ++
 .../sis/internal/referencing/AxisDirections.java   | 22 +++----
 .../internal/referencing/CoordinateOperations.java |  5 +-
 .../main/java/org/apache/sis/io/wkt/Element.java   |  5 +-
 .../main/java/org/apache/sis/io/wkt/Formatter.java |  5 +-
 .../apache/sis/io/wkt/GeodeticObjectParser.java    |  2 +-
 .../org/apache/sis/io/wkt/MathTransformParser.java |  3 +-
 .../org/apache/sis/io/wkt/SingletonElement.java    |  2 +-
 .../java/org/apache/sis/io/wkt/Transliterator.java | 23 +++-----
 .../main/java/org/apache/sis/io/wkt/WKTFormat.java |  3 +-
 .../parameter/DefaultParameterDescriptorGroup.java |  6 +-
 .../main/java/org/apache/sis/referencing/CRS.java  |  7 +--
 .../sis/referencing/EPSGFactoryFallback.java       |  3 +-
 .../sis/referencing/crs/DefaultCompoundCRS.java    |  5 +-
 .../cs/DefaultCoordinateSystemAxis.java            | 27 ++++-----
 .../referencing/factory/AuthorityFactoryProxy.java | 31 ++++------
 .../factory/GeodeticAuthorityFactory.java          |  5 +-
 .../factory/IdentifiedObjectFinder.java            |  5 +-
 .../factory/MultiAuthoritiesFactory.java           |  2 +-
 .../referencing/factory/sql/EPSGCodeFinder.java    | 15 +++--
 .../referencing/factory/sql/EPSGDataAccess.java    |  7 +--
 .../sis/referencing/factory/sql/EPSGFactory.java   |  3 +-
 .../factory/sql/InstallationScriptProvider.java    |  3 +-
 .../operation/AbstractCoordinateOperation.java     |  5 +-
 .../operation/DefaultConcatenatedOperation.java    |  3 +-
 .../operation/transform/MathTransforms.java        |  5 +-
 .../transform/SpecializableTransform.java          |  7 +--
 .../sis/io/wkt/GeodeticObjectParserTest.java       |  4 +-
 .../referencing/AbstractIdentifiedObjectTest.java  |  5 +-
 .../transform/MathTransformFactoryBase.java        |  3 +-
 .../report/CoordinateOperationMethods.java         |  2 +-
 .../apache/sis/internal/util/DefinitionURI.java    |  8 ++-
 .../org/apache/sis/internal/util/Numerics.java     | 11 +++-
 .../org/apache/sis/measure/AbstractConverter.java  |  3 +-
 .../java/org/apache/sis/measure/UnitDimension.java |  7 ++-
 .../java/org/apache/sis/measure/UnitFormat.java    |  8 ++-
 .../apache/sis/setup/OptionalInstallations.java    |  3 +-
 .../java/org/apache/sis/util/resources/Loader.java |  3 +-
 .../org/apache/sis/internal/util/NumericsTest.java | 35 ++++++++++-
 .../profile/fra/DirectReferenceSystemTest.java     |  6 +-
 .../apache/sis/internal/earth/netcdf/GCOM_C.java   | 33 +++++------
 .../apache/sis/internal/earth/netcdf/GCOM_W.java   | 32 ++++------
 .../apache/sis/internal/storage/inflater/ZIP.java  | 31 +---------
 .../internal/storage/inflater/package-info.java    |  2 +-
 .../org/apache/sis/internal/netcdf/Convention.java |  5 +-
 .../sis/internal/netcdf/impl/ChannelDecoder.java   |  6 +-
 .../sis/internal/netcdf/ucar/DecoderWrapper.java   |  6 +-
 .../apache/sis/storage/netcdf/MetadataReader.java  | 12 ++--
 .../sis/internal/sql/feature/PrimaryKey.java       |  3 +-
 .../sis/internal/storage/io/ChannelFactory.java    |  3 +-
 .../sis/internal/storage/xml/AbstractProvider.java |  2 +-
 .../java/org/apache/sis/storage/FeatureNaming.java |  6 +-
 .../apache/sis/storage/GridCoverageResource.java   |  5 +-
 .../org/apache/sis/storage/StorageConnector.java   |  7 ++-
 .../storage/aggregate/AggregatedFeatureSet.java    |  2 +-
 .../sis/storage/aggregate/GroupBySample.java       |  2 +-
 .../sis/internal/storage/MetadataBuilderTest.java  |  7 +--
 .../apache/sis/internal/storage/csv/StoreTest.java |  7 +--
 .../org/apache/sis/storage/GridResourceMock.java   |  3 +-
 124 files changed, 452 insertions(+), 547 deletions(-)


[sis] 01/02: Replace more `Collections` method calls by `Map.of`, `List.of` or `Set.of`. The remaining `Collections` calls are intentional for accepting null values.

Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 6b3c47f8e1ca784b6c83d63b0956921c80cec440
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Mon Dec 12 14:56:16 2022 +0100

    Replace more `Collections` method calls by `Map.of`, `List.of` or `Set.of`.
    The remaining `Collections` calls are intentional for accepting null values.
---
 .../org/apache/sis/console/IdentifierCommand.java  |  1 +
 .../org/apache/sis/console/MetadataCommand.java    |  4 +-
 .../apache/sis/console/ResourcesDownloader.java    |  3 +-
 .../org/apache/sis/console/TransformCommand.java   |  3 +-
 .../main/java/org/apache/sis/gui/DataViewer.java   |  3 +-
 .../main/java/org/apache/sis/gui/RecentFiles.java  |  4 +-
 .../apache/sis/gui/coverage/CoverageControls.java  |  4 +-
 .../apache/sis/gui/dataset/ExpandedFeature.java    |  6 +-
 .../org/apache/sis/gui/dataset/PathAction.java     |  3 +-
 .../apache/sis/gui/referencing/AuthorityCodes.java |  3 +-
 .../org/apache/sis/internal/gui/GUIUtilities.java  |  4 +-
 .../apache/sis/coverage/grid/GridCoverage2D.java   |  3 +-
 .../org/apache/sis/coverage/grid/GridExtent.java   | 15 ++---
 .../apache/sis/coverage/grid/PixelTranslation.java | 23 ++++----
 .../org/apache/sis/feature/AbstractFeature.java    |  5 +-
 .../java/org/apache/sis/feature/LinkOperation.java |  3 +-
 .../sis/feature/builder/FeatureTypeBuilder.java    |  3 +-
 .../org/apache/sis/filter/AssociationValue.java    |  4 +-
 .../java/org/apache/sis/filter/Capabilities.java   |  3 +-
 .../org/apache/sis/filter/IdentifierFilter.java    |  5 +-
 .../java/org/apache/sis/filter/LeafExpression.java |  3 +-
 .../java/org/apache/sis/filter/LogicalFilter.java  |  3 +-
 .../java/org/apache/sis/filter/Optimization.java   |  5 +-
 .../java/org/apache/sis/filter/UnaryFunction.java  |  3 +-
 .../sis/internal/feature/AttributeConvention.java  | 30 ++++------
 .../internal/feature/jts/PathIteratorAdapter.java  |  6 +-
 .../sis/internal/filter/GeometryConverter.java     |  3 +-
 .../internal/filter/sqlmm/GeometryConstructor.java |  6 +-
 .../sis/internal/filter/sqlmm/OneGeometry.java     |  4 +-
 .../coverage/grid/BufferedGridCoverageTest.java    |  3 +-
 .../coverage/grid/ConvertedGridCoverageTest.java   | 10 ++--
 .../sis/coverage/grid/GridCoverage2DTest.java      |  7 +--
 .../org/apache/sis/feature/CustomAttribute.java    |  7 +--
 .../apache/sis/feature/PropertySingletonTest.java  |  3 +-
 .../feature/builder/AttributeTypeBuilderTest.java  |  9 ++-
 .../builder/CharacteristicTypeBuilderTest.java     |  6 +-
 .../org/apache/sis/filter/LogicalFilterTest.java   |  4 +-
 .../sis/internal/jaxb/IdentifierMapAdapter.java    |  3 +-
 .../sis/internal/jaxb/NonMarshalledAuthority.java  |  5 +-
 .../apache/sis/internal/metadata/ExcludedSet.java  |  2 -
 .../apache/sis/internal/metadata/NameMeaning.java  | 27 ++++-----
 .../internal/metadata/TransformationAccuracy.java  |  6 +-
 .../apache/sis/metadata/PropertyInformation.java   |  4 +-
 .../java/org/apache/sis/metadata/TreeNode.java     |  4 +-
 .../apache/sis/metadata/sql/MetadataWriter.java    |  5 +-
 .../org/apache/sis/util/iso/DefaultLocalName.java  |  3 +-
 .../org/apache/sis/util/iso/DefaultRecord.java     |  3 +-
 .../main/java/org/apache/sis/xml/Namespaces.java   | 69 ++++++++++------------
 .../org/apache/sis/xml/TransformingReader.java     |  5 +-
 .../org/apache/sis/xml/TransformingWriter.java     |  9 ++-
 .../apache/sis/metadata/MetadataStandardTest.java  |  5 +-
 .../sis/metadata/ModifiableMetadataTest.java       |  8 +--
 .../java/org/apache/sis/metadata/PrunerTest.java   | 12 ++--
 .../java/org/apache/sis/metadata/TreeNodeTest.java |  6 +-
 .../apache/sis/metadata/TreeTableFormatTest.java   |  8 +--
 .../apache/sis/metadata/iso/MarshallingTest.java   | 27 ++++-----
 .../metadata/iso/citation/DefaultCitationTest.java |  4 +-
 .../identification/DefaultCoupledResourceTest.java | 10 ++--
 .../DefaultDataIdentificationTest.java             | 16 ++---
 .../DefaultServiceIdentificationTest.java          | 10 ++--
 .../sis/metadata/sql/MetadataSourceTest.java       |  3 +-
 .../apache/sis/test/xml/DocumentComparator.java    | 26 ++++----
 .../org/apache/sis/internal/map/SEPortrayer.java   |  5 +-
 .../MultiResolutionCoverageLoaderTest.java         |  5 +-
 .../referencing/gazetteer/FinalLocationType.java   |  4 ++
 .../sis/internal/referencing/AxisDirections.java   | 22 +++----
 .../internal/referencing/CoordinateOperations.java |  5 +-
 .../main/java/org/apache/sis/io/wkt/Element.java   |  5 +-
 .../main/java/org/apache/sis/io/wkt/Formatter.java |  5 +-
 .../apache/sis/io/wkt/GeodeticObjectParser.java    |  2 +-
 .../org/apache/sis/io/wkt/MathTransformParser.java |  3 +-
 .../org/apache/sis/io/wkt/SingletonElement.java    |  2 +-
 .../java/org/apache/sis/io/wkt/Transliterator.java | 23 +++-----
 .../main/java/org/apache/sis/io/wkt/WKTFormat.java |  3 +-
 .../parameter/DefaultParameterDescriptorGroup.java |  6 +-
 .../main/java/org/apache/sis/referencing/CRS.java  |  7 +--
 .../sis/referencing/EPSGFactoryFallback.java       |  3 +-
 .../sis/referencing/crs/DefaultCompoundCRS.java    |  5 +-
 .../cs/DefaultCoordinateSystemAxis.java            | 27 ++++-----
 .../referencing/factory/AuthorityFactoryProxy.java | 31 ++++------
 .../factory/GeodeticAuthorityFactory.java          |  5 +-
 .../factory/IdentifiedObjectFinder.java            |  5 +-
 .../factory/MultiAuthoritiesFactory.java           |  2 +-
 .../referencing/factory/sql/EPSGCodeFinder.java    | 15 +++--
 .../referencing/factory/sql/EPSGDataAccess.java    |  7 +--
 .../sis/referencing/factory/sql/EPSGFactory.java   |  3 +-
 .../factory/sql/InstallationScriptProvider.java    |  3 +-
 .../operation/AbstractCoordinateOperation.java     |  5 +-
 .../operation/DefaultConcatenatedOperation.java    |  3 +-
 .../operation/transform/MathTransforms.java        |  5 +-
 .../transform/SpecializableTransform.java          |  7 +--
 .../sis/io/wkt/GeodeticObjectParserTest.java       |  4 +-
 .../referencing/AbstractIdentifiedObjectTest.java  |  5 +-
 .../transform/MathTransformFactoryBase.java        |  3 +-
 .../report/CoordinateOperationMethods.java         |  2 +-
 .../apache/sis/internal/util/DefinitionURI.java    |  8 ++-
 .../org/apache/sis/measure/AbstractConverter.java  |  3 +-
 .../java/org/apache/sis/measure/UnitDimension.java |  7 ++-
 .../java/org/apache/sis/measure/UnitFormat.java    |  8 ++-
 .../apache/sis/setup/OptionalInstallations.java    |  3 +-
 .../java/org/apache/sis/util/resources/Loader.java |  3 +-
 .../profile/fra/DirectReferenceSystemTest.java     |  6 +-
 .../apache/sis/internal/earth/netcdf/GCOM_C.java   | 33 +++++------
 .../apache/sis/internal/earth/netcdf/GCOM_W.java   | 32 ++++------
 .../org/apache/sis/internal/netcdf/Convention.java |  5 +-
 .../sis/internal/netcdf/impl/ChannelDecoder.java   |  6 +-
 .../sis/internal/netcdf/ucar/DecoderWrapper.java   |  6 +-
 .../apache/sis/storage/netcdf/MetadataReader.java  | 12 ++--
 .../sis/internal/sql/feature/PrimaryKey.java       |  3 +-
 .../sis/internal/storage/io/ChannelFactory.java    |  3 +-
 .../java/org/apache/sis/storage/FeatureNaming.java |  6 +-
 .../apache/sis/storage/GridCoverageResource.java   |  5 +-
 .../org/apache/sis/storage/StorageConnector.java   |  7 ++-
 .../sis/internal/storage/MetadataBuilderTest.java  |  7 +--
 .../apache/sis/internal/storage/csv/StoreTest.java |  7 +--
 .../org/apache/sis/storage/GridResourceMock.java   |  3 +-
 116 files changed, 398 insertions(+), 506 deletions(-)

diff --git a/application/sis-console/src/main/java/org/apache/sis/console/IdentifierCommand.java b/application/sis-console/src/main/java/org/apache/sis/console/IdentifierCommand.java
index 1d0a2399ba..a02b52de4d 100644
--- a/application/sis-console/src/main/java/org/apache/sis/console/IdentifierCommand.java
+++ b/application/sis-console/src/main/java/org/apache/sis/console/IdentifierCommand.java
@@ -136,6 +136,7 @@ final class IdentifierCommand extends FormattedOutputCommand {
                     rows.add(create(rs));
                 }
             } else {
+                // This list may contain a null element.
                 rows = Collections.singletonList(create((ReferenceSystem) metadata));
             }
             print(rows);
diff --git a/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java b/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java
index d9c540f078..6c678516fd 100644
--- a/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java
+++ b/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java
@@ -16,7 +16,7 @@
  */
 package org.apache.sis.console;
 
-import java.util.Collections;
+import java.util.Set;
 import java.util.EnumSet;
 import java.util.function.Predicate;
 import org.opengis.metadata.Metadata;
@@ -72,7 +72,7 @@ final class MetadataCommand extends FormattedOutputCommand {
         if (metadata != null) {
             if (!(metadata instanceof Metadata)) {
                 final DefaultMetadata md = new DefaultMetadata();
-                md.setReferenceSystemInfo(Collections.singleton((ReferenceSystem) metadata));
+                md.setReferenceSystemInfo(Set.of((ReferenceSystem) metadata));
                 metadata = md;
             }
             format(metadata);
diff --git a/application/sis-console/src/main/java/org/apache/sis/console/ResourcesDownloader.java b/application/sis-console/src/main/java/org/apache/sis/console/ResourcesDownloader.java
index d43f2c728b..6d7d067006 100644
--- a/application/sis-console/src/main/java/org/apache/sis/console/ResourcesDownloader.java
+++ b/application/sis-console/src/main/java/org/apache/sis/console/ResourcesDownloader.java
@@ -19,7 +19,6 @@ package org.apache.sis.console;
 import java.util.Set;
 import java.util.Map;
 import java.util.HashMap;
-import java.util.Collections;
 import java.util.Locale;
 import java.util.ResourceBundle;
 import java.io.Console;
@@ -102,7 +101,7 @@ public class ResourcesDownloader extends OptionalInstallations {
      */
     @Override
     public Set<String> getAuthorities() {
-        return (console != null) ? super.getAuthorities() : Collections.emptySet();
+        return (console != null) ? super.getAuthorities() : Set.of();
     }
 
     /**
diff --git a/application/sis-console/src/main/java/org/apache/sis/console/TransformCommand.java b/application/sis-console/src/main/java/org/apache/sis/console/TransformCommand.java
index bd45c0d9ce..4ec5e735e6 100644
--- a/application/sis-console/src/main/java/org/apache/sis/console/TransformCommand.java
+++ b/application/sis-console/src/main/java/org/apache/sis/console/TransformCommand.java
@@ -18,7 +18,6 @@ package org.apache.sis.console;
 
 import java.util.List;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.EnumSet;
 import java.util.Locale;
 import java.io.IOException;
@@ -202,7 +201,7 @@ final class TransformCommand extends FormattedOutputCommand {
          * This will be used when searching for a coordinate operation.
          */
         GeographicBoundingBox areaOfInterest = null;
-        List<double[]> points = Collections.emptyList();
+        List<double[]> points = List.of();
         final boolean useStandardInput = useStandardInput();
         if (useStandardInput || !files.isEmpty()) {
             if (useStandardInput) {
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/DataViewer.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/DataViewer.java
index 286ae234c7..d6468d774a 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/DataViewer.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/DataViewer.java
@@ -20,7 +20,6 @@ import java.io.File;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
@@ -329,7 +328,7 @@ public class DataViewer extends Application {
                     if (save.size() >= RecentFiles.MAX_COUNT) break;
                 }
                 RecentChoices.setURLs(save);
-                content.loadResources(Collections.singleton(url));
+                content.loadResources(Set.of(url));
             } catch (URISyntaxException e) {
                 ExceptionReporter.canNotReadFile(content.getView(), choice, e);
             }
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/RecentFiles.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/RecentFiles.java
index 2893c45011..5ea3439497 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/RecentFiles.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/RecentFiles.java
@@ -18,7 +18,7 @@ package org.apache.sis.gui;
 
 import java.io.File;
 import java.nio.file.Path;
-import java.util.Collections;
+import java.util.Set;
 import java.util.StringJoiner;
 import javafx.event.ActionEvent;
 import javafx.event.EventHandler;
@@ -173,6 +173,6 @@ final class RecentFiles implements EventHandler<ActionEvent> {
     @Override
     public void handle(final ActionEvent event) {
         final Object file = ((MenuItem) event.getSource()).getUserData();
-        explorer.loadResources(Collections.singleton(file));
+        explorer.loadResources(Set.of(file));
     }
 }
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageControls.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageControls.java
index 266910baa9..650503bd27 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageControls.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageControls.java
@@ -16,8 +16,8 @@
  */
 package org.apache.sis.gui.coverage;
 
+import java.util.List;
 import java.util.Locale;
-import java.util.Collections;
 import javafx.scene.control.TitledPane;
 import javafx.scene.layout.GridPane;
 import javafx.scene.layout.Region;
@@ -149,7 +149,7 @@ final class CoverageControls extends ViewAndControls {
         {   // Block for making variables locale to this scope.
             final ValueColorMapper mapper = new ValueColorMapper(resources, vocabulary);
             isolines = new IsolineRenderer(view);
-            isolines.setIsolineTables(Collections.singletonList(mapper.getSteps()));
+            isolines.setIsolineTables(List.of(mapper.getSteps()));
             final Region view = mapper.getView();
             VBox.setVgrow(view, Priority.ALWAYS);
             isolinesPane = new VBox(view);                          // TODO: add band selector
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ExpandedFeature.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ExpandedFeature.java
index 32e7254b07..26a78bc4ea 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ExpandedFeature.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ExpandedFeature.java
@@ -19,7 +19,7 @@ package org.apache.sis.gui.dataset;
 import java.util.Arrays;
 import java.util.Map;
 import java.util.Collection;
-import java.util.Collections;
+import java.util.List;
 import org.opengis.feature.Feature;
 import org.opengis.feature.FeatureType;
 import org.opengis.feature.Property;
@@ -166,8 +166,8 @@ final class ExpandedFeature implements Feature {
         }
         final Object[] elements = values[i];
         return (index < elements.length)
-               ? Collections.singletonList(elements[index])
-               : Collections.emptyList();
+               ? List.of(elements[index])
+               : List.of();
     }
 
     /**
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/PathAction.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/PathAction.java
index d2e8b45ad6..632d82c96e 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/PathAction.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/PathAction.java
@@ -19,7 +19,6 @@ package org.apache.sis.gui.dataset;
 import java.awt.Desktop;
 import java.util.List;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.nio.file.Path;
 import java.io.File;
 import java.net.URL;
@@ -151,7 +150,7 @@ final class PathAction implements EventHandler<ActionEvent> {
         } catch (DataStoreException e) {
             ResourceTree.unexpectedException("copy", e);
         } else if (file instanceof File) {
-            files = Collections.singletonList((File) file);
+            files = List.of((File) file);
         }
         /*
          * Put in the clipboard all information that we could get.
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/AuthorityCodes.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/AuthorityCodes.java
index e255b5d3a8..ad1080b6f1 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/AuthorityCodes.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/AuthorityCodes.java
@@ -18,7 +18,6 @@ package org.apache.sis.gui.referencing;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.IdentityHashMap;
 import java.util.List;
@@ -429,7 +428,7 @@ final class AuthorityCodes extends ObservableListBase<Code>
         @Override
         protected PartialResult call() throws Exception {
             long lastTime = System.nanoTime();
-            List<String> codes = Collections.emptyList();
+            List<String> codes = List.of();
             final CRSAuthorityFactory factory = getFactory();
             try {
                 if (loadCodes) {
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/GUIUtilities.java b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/GUIUtilities.java
index e8fb7bf958..4d4ece3e7f 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/GUIUtilities.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/GUIUtilities.java
@@ -334,7 +334,7 @@ walk:   for (final T search : path) {
             if (i >= ny) return y;
             if (x.get(i) != y.get(i)) {
                 if (i == 0) {
-                    prefix = Collections.emptyList();
+                    prefix = List.of();
                 } else {
                     prefix = x.subList(0, i);
                     assert   y.subList(0, i).equals(prefix);
@@ -354,7 +354,7 @@ walk:   for (final T search : path) {
             if (sy == 0) return oy;
             if (x.get(sx - 1) != y.get(sy - 1)) {
                 if (i == 0) {
-                    suffix = Collections.emptyList();
+                    suffix = List.of();
                 } else {
                     suffix = x.subList(sx, nx);
                     assert   y.subList(sy, ny).equals(suffix);
diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverage2D.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverage2D.java
index c0c4b1d9ca..6595feced6 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverage2D.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverage2D.java
@@ -19,7 +19,6 @@ package org.apache.sis.coverage.grid;
 import java.util.List;
 import java.util.Arrays;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.concurrent.atomic.AtomicReference;
 import java.text.NumberFormat;
 import java.text.FieldPosition;
@@ -412,7 +411,7 @@ public class GridCoverage2D extends GridCoverage {
                 } else {
                     name = Vocabulary.formatInternational(Vocabulary.Keys.Band_1, i+1);
                 }
-                sd[i] = new SampleDimension(factory.createLocalName(null, name), null, Collections.emptyList());
+                sd[i] = new SampleDimension(factory.createLocalName(null, name), null, List.of());
             }
             range = Arrays.asList(sd);
         }
diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
index 16a8e1b5bd..ad7c4d1fe3 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
@@ -17,7 +17,6 @@
 package org.apache.sis.coverage.grid;
 
 import java.util.Map;
-import java.util.HashMap;
 import java.util.TreeMap;
 import java.util.SortedMap;
 import java.util.Arrays;
@@ -111,15 +110,11 @@ public class GridExtent implements GridEnvelope, LenientComparable, Serializable
      *
      * @see #typeFromAxes(CoordinateReferenceSystem, int)
      */
-    private static final Map<AxisDirection,DimensionNameType> AXIS_DIRECTIONS;
-    static {
-        final Map<AxisDirection,DimensionNameType> dir = new HashMap<>(6);
-        dir.put(AxisDirection.COLUMN_POSITIVE, DimensionNameType.COLUMN);
-        dir.put(AxisDirection.ROW_POSITIVE,    DimensionNameType.ROW);
-        dir.put(AxisDirection.UP,              DimensionNameType.VERTICAL);
-        dir.put(AxisDirection.FUTURE,          DimensionNameType.TIME);
-        AXIS_DIRECTIONS = dir;
-    }
+    private static final Map<AxisDirection,DimensionNameType> AXIS_DIRECTIONS = Map.of(
+            AxisDirection.COLUMN_POSITIVE, DimensionNameType.COLUMN,
+            AxisDirection.ROW_POSITIVE,    DimensionNameType.ROW,
+            AxisDirection.UP,              DimensionNameType.VERTICAL,
+            AxisDirection.FUTURE,          DimensionNameType.TIME);
 
     /**
      * Default axis types for the two-dimensional cases.
diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/PixelTranslation.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/PixelTranslation.java
index f82a3abd32..d24b3d7c4c 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/PixelTranslation.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/PixelTranslation.java
@@ -17,7 +17,6 @@
 package org.apache.sis.coverage.grid;
 
 import java.util.Map;
-import java.util.HashMap;
 import java.io.Serializable;
 
 import org.opengis.referencing.operation.Matrix;
@@ -108,20 +107,18 @@ public final class PixelTranslation extends Static implements Serializable {
     /**
      * The offset for various pixel orientations. Keys must be upper-case names.
      */
-    private static final Map<PixelOrientation, PixelTranslation> ORIENTATIONS = new HashMap<>(12);
-    static {
-        add(CENTER,       0.0,  0.0);
-        add(UPPER_LEFT,  -0.5, -0.5);
-        add(UPPER_RIGHT,  0.5, -0.5);
-        add(LOWER_LEFT,  -0.5,  0.5);
-        add(LOWER_RIGHT,  0.5,  0.5);
-    }
+    private static final Map<PixelOrientation, PixelTranslation> ORIENTATIONS = Map.ofEntries(
+            entry(CENTER,       0.0,  0.0),
+            entry(UPPER_LEFT,  -0.5, -0.5),
+            entry(UPPER_RIGHT,  0.5, -0.5),
+            entry(LOWER_LEFT,  -0.5,  0.5),
+            entry(LOWER_RIGHT,  0.5,  0.5));
 
     /** For {@link #ORIENTATIONS} construction only. */
-    private static void add(final PixelOrientation orientation, final double dx, final double dy) {
-        if (ORIENTATIONS.put(orientation, new PixelTranslation(orientation, dx, dy)) != null) {
-            throw new AssertionError();
-        }
+    private static Map.Entry<PixelOrientation, PixelTranslation> entry(
+                    PixelOrientation orientation, double dx, double dy)
+    {
+        return Map.entry(orientation, new PixelTranslation(orientation, dx, dy));
     }
 
     /**
diff --git a/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java b/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java
index d126ecdd4d..a839937e39 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java
@@ -298,7 +298,10 @@ public abstract class AbstractFeature implements Feature, Serializable {
         if (Field.isSingleton(attribute.getMaximumOccurs())) {
             return defaultValue;
         } else {
-            // Following is for compliance with getPropertyValue(String) method contract - see its javadoc.
+            /*
+             * Following is for compliance with getPropertyValue(String) method contract - see its javadoc.
+             * We use `Collections` instead of `List.of` for accepting `List.contains(null)`.
+             */
             return (defaultValue != null) ? Collections.singletonList(defaultValue) : Collections.emptyList();
         }
     }
diff --git a/core/sis-feature/src/main/java/org/apache/sis/feature/LinkOperation.java b/core/sis-feature/src/main/java/org/apache/sis/feature/LinkOperation.java
index e009f395ff..c34fb2afe9 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/feature/LinkOperation.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/feature/LinkOperation.java
@@ -18,7 +18,6 @@ package org.apache.sis.feature;
 
 import java.util.Set;
 import java.util.Map;
-import java.util.Collections;
 import java.io.IOException;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.parameter.ParameterDescriptorGroup;
@@ -105,7 +104,7 @@ final class LinkOperation extends AbstractOperation {
      */
     @Override
     public Set<String> getDependencies() {
-        return Collections.singleton(referentName);
+        return Set.of(referentName);
     }
 
     /**
diff --git a/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java b/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
index c5fa60f4f9..98b969b62e 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
@@ -18,7 +18,6 @@ package org.apache.sis.feature.builder;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -334,7 +333,7 @@ public class FeatureTypeBuilder extends TypeBuilder {
                 role = null;
             }
             if (role != null) {
-                final Set<AttributeRole> rc = Collections.singleton(role);
+                final Set<AttributeRole> rc = Set.of(role);
                 if (property instanceof AbstractOperation) {
                     for (final String dependency : ((AbstractOperation) property).getDependencies()) {
                         propertyRoles.merge(dependency, rc, AttributeRole::merge);
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/AssociationValue.java b/core/sis-feature/src/main/java/org/apache/sis/filter/AssociationValue.java
index 2718f19400..bcff1a1897 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/AssociationValue.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/AssociationValue.java
@@ -17,9 +17,9 @@
 package org.apache.sis.filter;
 
 import java.util.Arrays;
+import java.util.Set;
 import java.util.List;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Optional;
 import java.util.StringJoiner;
 import org.apache.sis.feature.Features;
@@ -100,7 +100,7 @@ final class AssociationValue<V> extends LeafExpression<Feature, V>
      */
     @Override
     protected final Collection<?> getChildren() {
-        return Collections.singleton(getXPath());
+        return Set.of(getXPath());
     }
 
     /**
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/Capabilities.java b/core/sis-feature/src/main/java/org/apache/sis/filter/Capabilities.java
index e645968257..fd1edadda9 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/Capabilities.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/Capabilities.java
@@ -18,7 +18,6 @@ package org.apache.sis.filter;
 
 import java.util.Set;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Optional;
 import org.opengis.util.LocalName;
 import org.apache.sis.util.collection.CodeListSet;
@@ -86,7 +85,7 @@ final class Capabilities implements FilterCapabilities, Conformance, IdCapabilit
      */
     @Override
     public Collection<LocalName> getResourceIdentifiers() {
-        return Collections.singleton(AttributeConvention.IDENTIFIER_PROPERTY.tip());
+        return Set.of(AttributeConvention.IDENTIFIER_PROPERTY.tip());
     }
 
     /**
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/IdentifierFilter.java b/core/sis-feature/src/main/java/org/apache/sis/filter/IdentifierFilter.java
index 2a1b8b5be0..83ee72bbfe 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/IdentifierFilter.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/IdentifierFilter.java
@@ -18,7 +18,6 @@ package org.apache.sis.filter;
 
 import java.util.List;
 import java.util.Collection;
-import java.util.Collections;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.internal.feature.AttributeConvention;
 
@@ -73,7 +72,7 @@ final class IdentifierFilter<R extends Feature> extends FilterNode<R> implements
      */
     @Override
     public List<Expression<? super R, ?>> getExpressions() {
-        return Collections.singletonList(new LeafExpression.Literal<>(identifier));
+        return List.of(new LeafExpression.Literal<>(identifier));
     }
 
     /**
@@ -82,7 +81,7 @@ final class IdentifierFilter<R extends Feature> extends FilterNode<R> implements
      */
     @Override
     protected Collection<?> getChildren() {
-        return Collections.singleton(identifier);
+        return List.of(identifier);
     }
 
     /**
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/LeafExpression.java b/core/sis-feature/src/main/java/org/apache/sis/filter/LeafExpression.java
index 76dd982fc1..3475a3de5b 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/LeafExpression.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/LeafExpression.java
@@ -68,7 +68,7 @@ abstract class LeafExpression<R,V> extends Node implements FeatureExpression<R,V
      */
     @Override
     public final List<Expression<? super R, ?>> getParameters() {
-        return Collections.emptyList();
+        return List.of();
     }
 
 
@@ -96,6 +96,7 @@ abstract class LeafExpression<R,V> extends Node implements FeatureExpression<R,V
 
         /** For {@link #toString()}, {@link #hashCode()} and {@link #equals(Object)} implementations. */
         @Override protected Collection<?> getChildren() {
+            // Not `List.of(…)` because value may be null.
             return Collections.singleton(value);
         }
 
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/LogicalFilter.java b/core/sis-feature/src/main/java/org/apache/sis/filter/LogicalFilter.java
index d17beffc58..14b075effc 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/LogicalFilter.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/LogicalFilter.java
@@ -18,7 +18,6 @@ package org.apache.sis.filter;
 
 import java.util.List;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.LinkedHashSet;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.internal.util.CollectionsExt;
@@ -247,7 +246,7 @@ abstract class LogicalFilter<R> extends FilterNode<R> implements LogicalOperator
 
         /** Returns the singleton filter used by this operation. */
         @Override public List<Filter<? super R>> getOperands() {
-            return Collections.singletonList(operand);
+            return List.of(operand);
         }
 
         /** Evaluates this filter on the given object. */
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/Optimization.java b/core/sis-feature/src/main/java/org/apache/sis/filter/Optimization.java
index c94c745a30..ffc8e17298 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/Optimization.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/Optimization.java
@@ -19,7 +19,6 @@ package org.apache.sis.filter;
 import java.util.Map;
 import java.util.List;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.IdentityHashMap;
 import java.util.ConcurrentModificationException;
 import java.util.function.Predicate;
@@ -426,7 +425,7 @@ public class Optimization {
      */
     private static <R> List<Filter<? super R>> toAndOperands(final Filter<R> filter) {
         if (filter == null) {
-            return Collections.emptyList();
+            return List.of();
         }
         final CodeList<?> type = filter.getOperatorType();
         if (type == LogicalOperatorName.AND) {
@@ -454,7 +453,7 @@ public class Optimization {
                 return result;
             }
         }
-        return Collections.singletonList(filter);
+        return List.of(filter);
     }
 
     /**
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/UnaryFunction.java b/core/sis-feature/src/main/java/org/apache/sis/filter/UnaryFunction.java
index 62b0d4c76f..d306eeec38 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/UnaryFunction.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/UnaryFunction.java
@@ -18,7 +18,6 @@ package org.apache.sis.filter;
 
 import java.util.List;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Optional;
 import org.apache.sis.xml.NilReason;
 import org.apache.sis.util.ArgumentChecks;
@@ -82,7 +81,7 @@ class UnaryFunction<R,V> extends Node {
      * @return a list of size 1 containing the singleton expression.
      */
     public final List<Expression<? super R, ?>> getExpressions() {
-        return Collections.singletonList(expression);
+        return List.of(expression);
     }
 
     /**
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/AttributeConvention.java b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/AttributeConvention.java
index 47a6267fa3..5062863567 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/AttributeConvention.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/AttributeConvention.java
@@ -77,7 +77,7 @@ public final class AttributeConvention extends Static {
     /**
      * Scope of all names defined by SIS convention.
      */
-    private static final LocalName SCOPE;
+    private static final LocalName SCOPE = Names.createLocalName("Apache", null, "sis");
 
     /**
      * Conventional name for a property used as a unique identifier.
@@ -93,7 +93,7 @@ public final class AttributeConvention extends Static {
      * <p>The {@linkplain org.apache.sis.feature.DefaultAttributeType#getValueClass() value class} is usually
      * {@link String}, {@link Integer}, {@link java.util.UUID} or other types commonly used as identifiers.</p>
      */
-    public static final ScopedName IDENTIFIER_PROPERTY;
+    public static final ScopedName IDENTIFIER_PROPERTY = Names.createScopedName(SCOPE, null, "identifier");
 
     /**
      * Conventional name for a property containing the geometric object to use by default.
@@ -110,11 +110,11 @@ public final class AttributeConvention extends Static {
      *
      * @see #isGeometryAttribute(IdentifiedType)
      */
-    public static final ScopedName GEOMETRY_PROPERTY;
+    public static final ScopedName GEOMETRY_PROPERTY = Names.createScopedName(SCOPE, null, "geometry");
 
     /**
-     * Conventional name for fetching the envelope encompassing all geometries in a feature. Most {@code FeatureType}s
-     * have at most one geometry, which is also the {@link #GEOMETRY_PROPERTY default geometry}.
+     * Conventional name for fetching the envelope encompassing all geometries in a feature.
+     * Most {@code FeatureType}s have at most one geometry, which is also the {@link #GEOMETRY_PROPERTY default geometry}.
      * But if several geometries exist, then the value for this synthetic property is the union of all geometries.
      *
      * <p>Properties of this name are usually
@@ -123,7 +123,7 @@ public final class AttributeConvention extends Static {
      * <p>The {@linkplain org.apache.sis.feature.DefaultAttributeType#getValueClass() value class} should be
      * {@link org.opengis.geometry.Envelope}.</p>
      */
-    public static final ScopedName ENVELOPE_PROPERTY;
+    public static final ScopedName ENVELOPE_PROPERTY = Names.createScopedName(SCOPE, null, "envelope");
 
     /**
      * Conventional name for fetching the Coordinate Reference System (CRS) of a geometry or a coverage.
@@ -142,7 +142,7 @@ public final class AttributeConvention extends Static {
      *
      * @see #getCRSCharacteristic(Property)
      */
-    public static final ScopedName CRS_CHARACTERISTIC;
+    public static final ScopedName CRS_CHARACTERISTIC = Names.createScopedName(SCOPE, null, "crs");
 
     /**
      * Conventional name for fetching the unit of measurement of a property.
@@ -158,7 +158,7 @@ public final class AttributeConvention extends Static {
      * <p>The {@linkplain org.apache.sis.feature.DefaultAttributeType#getValueClass() value class} should be
      * {@link javax.measure.Unit}.</p>
      */
-    public static final ScopedName UNIT_CHARACTERISTIC;
+    public static final ScopedName UNIT_CHARACTERISTIC = Names.createScopedName(SCOPE, null, "unit");
 
     /**
      * Conventional name for fetching the maximal length of string values.
@@ -172,7 +172,7 @@ public final class AttributeConvention extends Static {
      *
      * @see #getMaximalLengthCharacteristic(Property)
      */
-    public static final ScopedName MAXIMAL_LENGTH_CHARACTERISTIC;
+    public static final ScopedName MAXIMAL_LENGTH_CHARACTERISTIC = Names.createScopedName(SCOPE, null, "maximalLength");
 
     /**
      * Conventional name for fetching the enumeration of valid values.
@@ -181,17 +181,7 @@ public final class AttributeConvention extends Static {
      * {@linkplain org.apache.sis.feature.DefaultAttributeType#characteristics() characteristic} associated
      * to the attribute on which the restriction applies.
      */
-    public static final GenericName VALID_VALUES_CHARACTERISTIC;
-    static {
-        SCOPE                         = Names.createLocalName("Apache", null, "sis");
-        IDENTIFIER_PROPERTY           = Names.createScopedName(SCOPE, null, "identifier");
-        GEOMETRY_PROPERTY             = Names.createScopedName(SCOPE, null, "geometry");
-        ENVELOPE_PROPERTY             = Names.createScopedName(SCOPE, null, "envelope");
-        CRS_CHARACTERISTIC            = Names.createScopedName(SCOPE, null, "crs");
-        UNIT_CHARACTERISTIC           = Names.createScopedName(SCOPE, null, "unit");
-        MAXIMAL_LENGTH_CHARACTERISTIC = Names.createScopedName(SCOPE, null, "maximalLength");
-        VALID_VALUES_CHARACTERISTIC   = Names.createScopedName(SCOPE, null, "validValues");
-    }
+    public static final GenericName VALID_VALUES_CHARACTERISTIC = Names.createScopedName(SCOPE, null, "validValues");
 
     /**
      * String representation of the {@link #IDENTIFIER_PROPERTY} name.
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/PathIteratorAdapter.java b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/PathIteratorAdapter.java
index 6c882b3ae7..4774d606e6 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/PathIteratorAdapter.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/PathIteratorAdapter.java
@@ -16,9 +16,9 @@
  */
 package org.apache.sis.internal.feature.jts;
 
+import java.util.List;
 import java.util.Iterator;
 import java.util.Collection;
-import java.util.Collections;
 import java.awt.geom.PathIterator;
 import java.awt.geom.AffineTransform;
 import org.apache.sis.util.Classes;
@@ -178,9 +178,9 @@ final class PathIteratorAdapter implements PathIterator {
     private static Iterator<CoordinateSequence> iterator(final Geometry geometry) {
         final Collection<CoordinateSequence> sequences;
         if (geometry instanceof LineString) {
-            sequences = Collections.singleton(((LineString) geometry).getCoordinateSequence());
+            sequences = List.of(((LineString) geometry).getCoordinateSequence());
         } else if (geometry instanceof Point) {
-            sequences = Collections.singleton(((Point) geometry).getCoordinateSequence());
+            sequences = List.of(((Point) geometry).getCoordinateSequence());
         } else if (geometry instanceof Polygon) {
             return new RingIterator((Polygon) geometry);
         } else if (geometry instanceof GeometryCollection) {
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/GeometryConverter.java b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/GeometryConverter.java
index 54a82cfd76..8e56d67ece 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/GeometryConverter.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/GeometryConverter.java
@@ -18,7 +18,6 @@ package org.apache.sis.internal.filter;
 
 import java.util.List;
 import java.util.Collection;
-import java.util.Collections;
 import org.opengis.util.ScopedName;
 import org.opengis.geometry.Envelope;
 import org.opengis.geometry.DirectPosition;
@@ -114,7 +113,7 @@ final class GeometryConverter<R,G> extends Node implements Optimization.OnExpres
      */
     @Override
     public List<Expression<? super R, ?>> getParameters() {
-        return Collections.singletonList(expression);
+        return List.of(expression);
     }
 
     /**
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/GeometryConstructor.java b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/GeometryConstructor.java
index 23c0f5e460..909d5a779c 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/GeometryConstructor.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/GeometryConstructor.java
@@ -18,7 +18,6 @@ package org.apache.sis.internal.filter.sqlmm;
 
 import java.nio.ByteBuffer;
 import java.util.List;
-import java.util.Collections;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.apache.sis.internal.feature.Geometries;
 import org.apache.sis.internal.feature.GeometryWrapper;
@@ -83,10 +82,7 @@ class GeometryConstructor<R,G> extends FunctionWithSRID<R> {
      */
     @Override
     public final List<Expression<? super R, ?>> getParameters() {
-        if (srid == null) {
-            return Collections.singletonList(geometry);
-        }
-        return List.of(geometry, srid);
+        return (srid != null) ? List.of(geometry, srid) : List.of(geometry);
     }
 
     /**
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/OneGeometry.java b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/OneGeometry.java
index ce89681955..fbac788e5e 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/OneGeometry.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/OneGeometry.java
@@ -17,7 +17,6 @@
 package org.apache.sis.internal.filter.sqlmm;
 
 import java.util.List;
-import java.util.Collections;
 import org.apache.sis.internal.feature.Geometries;
 import org.apache.sis.internal.feature.GeometryWrapper;
 
@@ -49,6 +48,7 @@ class OneGeometry<R,G> extends SpatialFunction<R> {
     /**
      * The expression giving the geometry.
      */
+    @SuppressWarnings("serial")         // Not statically typed as Serializable.
     final Expression<? super R, GeometryWrapper<G>> geometry;
 
     /**
@@ -81,7 +81,7 @@ class OneGeometry<R,G> extends SpatialFunction<R> {
      */
     @Override
     public List<Expression<? super R, ?>> getParameters() {
-        return Collections.singletonList(unwrap(geometry));
+        return List.of(unwrap(geometry));
     }
 
     /**
diff --git a/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/BufferedGridCoverageTest.java b/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/BufferedGridCoverageTest.java
index 40cc8ea8fc..f9025dd300 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/BufferedGridCoverageTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/BufferedGridCoverageTest.java
@@ -18,7 +18,6 @@ package org.apache.sis.coverage.grid;
 
 import java.util.List;
 import java.util.Arrays;
-import java.util.Collections;
 import java.awt.image.BufferedImage;
 import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferInt;
@@ -94,7 +93,7 @@ public final strictfp class BufferedGridCoverageTest extends GridCoverage2DTest
             Arrays.fill(buffer, i, i += sliceSize, t + 10);
         }
         final DataBufferInt data = new DataBufferInt(buffer, size);
-        final GridCoverage coverage = new BufferedGridCoverage(domain, Collections.singletonList(band), data);
+        final GridCoverage coverage = new BufferedGridCoverage(domain, List.of(band), data);
         /*
          * Verify a value in each temporal slice.
          */
diff --git a/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/ConvertedGridCoverageTest.java b/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/ConvertedGridCoverageTest.java
index 8d1597fdc4..eec32d8683 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/ConvertedGridCoverageTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/ConvertedGridCoverageTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.sis.coverage.grid;
 
-import java.util.Collections;
+import java.util.List;
 import java.awt.image.DataBuffer;
 import org.opengis.referencing.datum.PixelInCell;
 import org.opengis.referencing.operation.MathTransform1D;
@@ -61,12 +61,10 @@ public final strictfp class ConvertedGridCoverageTest extends TestCase {
         /*
          * The "grid to CRS" transform does not matter for this test.
          */
-        final GridGeometry grid = new GridGeometry(new GridExtent(2, 1), PixelInCell.CELL_CENTER,
-                new AffineTransform2D(1, 0, 0, 1, 1, 0), HardCodedCRS.WGS84);
-
-        final BufferedGridCoverage coverage = new BufferedGridCoverage(
-                grid, Collections.singletonList(sd), DataBuffer.TYPE_SHORT);
+        final var grid = new GridGeometry(new GridExtent(2, 1), PixelInCell.CELL_CENTER,
+                            new AffineTransform2D(1, 0, 0, 1, 1, 0), HardCodedCRS.WGS84);
 
+        final var coverage = new BufferedGridCoverage(grid, List.of(sd), DataBuffer.TYPE_SHORT);
         coverage.data.setElem(0, -1);
         coverage.data.setElem(1,  3);
         return coverage;
diff --git a/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/GridCoverage2DTest.java b/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/GridCoverage2DTest.java
index ecb2d91856..f766dd9a65 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/GridCoverage2DTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/GridCoverage2DTest.java
@@ -17,7 +17,6 @@
 package org.apache.sis.coverage.grid;
 
 import java.util.List;
-import java.util.Collections;
 import java.awt.Rectangle;
 import java.awt.image.BufferedImage;
 import java.awt.image.DataBuffer;
@@ -82,14 +81,14 @@ public strictfp class GridCoverage2DTest extends TestCase {
      * The domain of source grid indices is the [0 … 1] range in all dimensions.
      */
     private GridCoverage createTestCoverage(final MathTransform gridToCRS) {
-        final GridGeometry grid = new GridGeometry(new GridExtent(GRID_SIZE, GRID_SIZE),
-                PixelInCell.CELL_CENTER, gridToCRS, HardCodedCRS.WGS84);
+        final var grid = new GridGeometry(new GridExtent(GRID_SIZE, GRID_SIZE),
+                            PixelInCell.CELL_CENTER, gridToCRS, HardCodedCRS.WGS84);
 
         final MathTransform1D toUnits = (MathTransform1D) MathTransforms.linear(0.5, 100);
         final SampleDimension sd = new SampleDimension.Builder().setName("Some kind of height")
                 .addQuantitative("data", NumberRange.create(-10, true, 10, true), toUnits, Units.METRE)
                 .build();
-        return createTestCoverage(grid, Collections.singletonList(sd));
+        return createTestCoverage(grid, List.of(sd));
     }
 
     /**
diff --git a/core/sis-feature/src/test/java/org/apache/sis/feature/CustomAttribute.java b/core/sis-feature/src/test/java/org/apache/sis/feature/CustomAttribute.java
index e03b7c0db3..d2fd163eb4 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/feature/CustomAttribute.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/feature/CustomAttribute.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.feature;
 
+import java.util.Set;
 import org.opengis.metadata.quality.DataQuality;
 import org.apache.sis.metadata.iso.quality.DefaultDataQuality;
 import org.apache.sis.metadata.iso.quality.DefaultDomainConsistency;
@@ -23,8 +24,6 @@ import org.apache.sis.metadata.iso.quality.DefaultQuantitativeResult;
 import org.apache.sis.util.SimpleInternationalString;
 import org.apache.sis.referencing.NamedIdentifier;
 
-import static java.util.Collections.singleton;
-
 // Branch-dependent imports
 import org.opengis.feature.AttributeType;
 
@@ -84,8 +83,8 @@ final strictfp class CustomAttribute<V> extends AbstractAttribute<V> {
         final DefaultQuantitativeResult result  = new DefaultQuantitativeResult();
         result.setErrorStatistic(new SimpleInternationalString(ADDITIONAL_QUALITY_INFO));
         report.setMeasureIdentification(NamedIdentifier.castOrCopy(getName()));
-        report .setResults(singleton(result));
-        quality.setReports(singleton(report));
+        report .setResults(Set.of(result));
+        quality.setReports(Set.of(report));
         return quality;
     }
 }
diff --git a/core/sis-feature/src/test/java/org/apache/sis/feature/PropertySingletonTest.java b/core/sis-feature/src/test/java/org/apache/sis/feature/PropertySingletonTest.java
index 324a2a1a85..2b66a07715 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/feature/PropertySingletonTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/feature/PropertySingletonTest.java
@@ -23,7 +23,6 @@ import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
 import static org.junit.Assert.*;
-import static java.util.Collections.singleton;
 import static org.apache.sis.test.TestUtilities.getSingleton;
 
 
@@ -128,7 +127,7 @@ public final strictfp class PropertySingletonTest extends TestCase {
     @Test
     @DependsOnMethod("testSingleton")
     public void testRemoveAll() {
-        final Set<Integer> attributes = singleton(1000);
+        final Set<Integer> attributes = Set.of(1000);
         assertTrue (singleton.addAll(attributes));
         assertFalse(singleton.isEmpty());
         assertTrue (singleton.removeAll(attributes));
diff --git a/core/sis-feature/src/test/java/org/apache/sis/feature/builder/AttributeTypeBuilderTest.java b/core/sis-feature/src/test/java/org/apache/sis/feature/builder/AttributeTypeBuilderTest.java
index 1e87cada7b..533ada5a76 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/feature/builder/AttributeTypeBuilderTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/feature/builder/AttributeTypeBuilderTest.java
@@ -18,7 +18,6 @@ package org.apache.sis.feature.builder;
 
 import java.util.Set;
 import java.util.List;
-import java.util.Collections;
 import com.esri.core.geometry.Geometry;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.apache.sis.feature.Features;
@@ -118,7 +117,7 @@ public final strictfp class AttributeTypeBuilderTest extends TestCase {
         assertSame(builder, builder.setDefaultValue(25f));
         assertSame(builder, builder.setValueClass(Float.class));
         assertEquals("valueClass", Float.class, builder.getValueClass());
-        assertSetEquals(Collections.singleton(builder), builder.owner().properties());
+        assertSetEquals(Set.of(builder), builder.owner().properties());
         final CharacteristicTypeBuilder<Float> stddev = builder.addCharacteristic(Float.class);
         assertSame(stddev, stddev.setName("stddev"));
         assertSame(stddev, stddev.setDefaultValue(2f));
@@ -134,7 +133,7 @@ public final strictfp class AttributeTypeBuilderTest extends TestCase {
         assertEquals("designation",   "test designation", newb.getDesignation());
         assertEquals("valueClass",    Double.class,       newb.getValueClass());
         assertEquals("defaultValue",  Double.valueOf(25), newb.getDefaultValue());
-        assertSetEquals(Collections.singleton(newb), newb.owner().properties());
+        assertSetEquals(Set.of(newb), newb.owner().properties());
         /*
          * In order to avoid accidental misuse, the old builder should not be usable anymore.
          */
@@ -232,7 +231,7 @@ public final strictfp class AttributeTypeBuilderTest extends TestCase {
         assertTrue("isEmpty", roles.isEmpty());
 
         assertTrue("add(DEFAULT_GEOMETRY)", builder.addRole(AttributeRole.DEFAULT_GEOMETRY));
-        assertSetEquals(Collections.singleton(AttributeRole.DEFAULT_GEOMETRY), roles);
+        assertSetEquals(Set.of(AttributeRole.DEFAULT_GEOMETRY), roles);
         assertFalse("add(DEFAULT_GEOMETRY)", builder.addRole(AttributeRole.DEFAULT_GEOMETRY));
 
         assertTrue("add(IDENTIFIER_COMPONENT)", roles.add(AttributeRole.IDENTIFIER_COMPONENT));
@@ -240,7 +239,7 @@ public final strictfp class AttributeTypeBuilderTest extends TestCase {
         assertFalse("add(IDENTIFIER_COMPONENT)", roles.add(AttributeRole.IDENTIFIER_COMPONENT));
 
         assertTrue("remove(DEFAULT_GEOMETRY)", roles.remove(AttributeRole.DEFAULT_GEOMETRY));
-        assertSetEquals(Collections.singleton(AttributeRole.IDENTIFIER_COMPONENT), roles);
+        assertSetEquals(Set.of(AttributeRole.IDENTIFIER_COMPONENT), roles);
         assertFalse("remove(DEFAULT_GEOMETRY)", roles.remove(AttributeRole.DEFAULT_GEOMETRY));
 
         assertTrue("remove(IDENTIFIER_COMPONENT)", roles.remove(AttributeRole.IDENTIFIER_COMPONENT));
diff --git a/core/sis-feature/src/test/java/org/apache/sis/feature/builder/CharacteristicTypeBuilderTest.java b/core/sis-feature/src/test/java/org/apache/sis/feature/builder/CharacteristicTypeBuilderTest.java
index 792cd970ba..fc8476196f 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/feature/builder/CharacteristicTypeBuilderTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/feature/builder/CharacteristicTypeBuilderTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.sis.feature.builder;
 
-import java.util.Collections;
+import java.util.Set;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
@@ -52,7 +52,7 @@ public final strictfp class CharacteristicTypeBuilderTest extends TestCase {
         assertSame(builder, builder.setDefaultValue(2));
         assertSame(builder, builder.setValueClass(Integer.class));
         assertEquals("valueClass", Integer.class, builder.getValueClass());
-        assertSetEquals(Collections.singleton(builder), owner.characteristics());
+        assertSetEquals(Set.of(builder), owner.characteristics());
         /*
          * Pretend that we changed our mind and now want a Float type instead of Integer.
          * In current implementation this requires the creation of a new builder instance,
@@ -65,7 +65,7 @@ public final strictfp class CharacteristicTypeBuilderTest extends TestCase {
         assertEquals("designation",   "test designation", newb.getDesignation());
         assertEquals("valueClass",    Float.class,        newb.getValueClass());
         assertEquals("defaultValue",  Float.valueOf(2),   newb.getDefaultValue());
-        assertSetEquals(Collections.singleton(newb), owner.characteristics());
+        assertSetEquals(Set.of(newb), owner.characteristics());
         /*
          * In order to avoid accidental misuse, the old builder should not be usable anymore.
          */
diff --git a/core/sis-feature/src/test/java/org/apache/sis/filter/LogicalFilterTest.java b/core/sis-feature/src/test/java/org/apache/sis/filter/LogicalFilterTest.java
index 6639491972..7faabe4268 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/filter/LogicalFilterTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/filter/LogicalFilterTest.java
@@ -16,9 +16,9 @@
  */
 package org.apache.sis.filter;
 
+import java.util.Set;
 import java.util.List;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.function.Function;
 import java.util.function.BiFunction;
 import org.apache.sis.feature.builder.FeatureTypeBuilder;
@@ -130,7 +130,7 @@ public final strictfp class LogicalFilterTest extends TestCase {
         } catch (NullPointerException ex) {
         }
         try {
-            anyArity.apply(Collections.singleton(f1));
+            anyArity.apply(Set.of(f1));
             fail("Creation with less then two operands shall raise an exception.");
         } catch (IllegalArgumentException ex) {
             assertNotNull(ex.getMessage());
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapAdapter.java b/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapAdapter.java
index 50db87a59a..e8a3e81a5e 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapAdapter.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapAdapter.java
@@ -24,7 +24,6 @@ import java.util.HashSet;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.AbstractMap;
 import java.util.NoSuchElementException;
 import java.util.Objects;
@@ -99,7 +98,7 @@ public class IdentifierMapAdapter extends AbstractMap<Citation,String> implement
     /**
      * An immutable empty instance.
      */
-    public static final IdentifierMap EMPTY = new IdentifierMapAdapter(Collections.emptySet());
+    public static final IdentifierMap EMPTY = new IdentifierMapAdapter(Set.of());
 
     /**
      * The identifiers to wrap in a map view.
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/NonMarshalledAuthority.java b/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/NonMarshalledAuthority.java
index c7707e22e9..617d63de5a 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/NonMarshalledAuthority.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/NonMarshalledAuthority.java
@@ -29,7 +29,6 @@ import org.opengis.metadata.citation.Citation;
 import org.apache.sis.internal.simple.CitationConstant;
 import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.internal.util.UnmodifiableArrayList;
-import org.apache.sis.util.collection.Containers;
 import org.apache.sis.xml.IdentifierSpace;
 
 
@@ -265,11 +264,13 @@ public final class NonMarshalledAuthority<T> extends CitationConstant.Authority<
         }
         /*
          * Wraps in an unmodifiable list in case the caller is creating an unmodifiable metadata.
+         * Use `Collections` instead of `List.of(…)` for consistency with `UnmodifiableArrayList`
+         * which accepts `List.contains(null)`.
          */
         switch (merged.size()) {
             case 0:  return Collections.emptyList();
             case 1:  return Collections.singletonList(merged.get(0));
-            default: return Containers.unmodifiableList(merged.toArray(Identifier[]::new));
+            default: return UnmodifiableArrayList.wrap(merged.toArray(Identifier[]::new));
         }
     }
 
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ExcludedSet.java b/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ExcludedSet.java
index 28bee8c8a1..0c021b25f7 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ExcludedSet.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ExcludedSet.java
@@ -33,8 +33,6 @@ import org.apache.sis.util.resources.Errors;
  *
  * @param <E>  the type of elements that the collection would have if it was non-empty.
  *
- * @see Collections#emptySet()
- *
  * @since 0.3
  * @module
  */
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameMeaning.java b/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameMeaning.java
index 76493dcd2a..82612578f6 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameMeaning.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameMeaning.java
@@ -17,7 +17,6 @@
 package org.apache.sis.internal.metadata;
 
 import java.util.Map;
-import java.util.HashMap;
 import java.util.Locale;
 import javax.measure.Unit;
 import org.opengis.parameter.*;
@@ -116,23 +115,21 @@ public final class NameMeaning extends Static {
      *
      * @since 0.7
      */
-    private static final Map<String,String> AUTHORITIES = new HashMap<>(12);
-    static {
-        add(Constants.EPSG);    // IOGP
-        add(Constants.OGC);     // Open Geospatial Consortium
-        add("OGC-WFS");         // OGC Web Feature Service
-        add("SI");              // Système International d'Unités
-        add("UCUM");            // Unified Code for Units of Measure
-        add("UNSD");            // United Nations Statistics Division
-        add("USNO");            // United States Naval Observatory
-    }
+    private static final Map<String,String> AUTHORITIES = Map.ofEntries(
+            entry(Constants.EPSG),      // IOGP
+            entry(Constants.OGC),       // Open Geospatial Consortium
+            entry("OGC-WFS"),           // OGC Web Feature Service
+            entry("SI"),                // Système International d'Unités
+            entry("UCUM"),              // Unified Code for Units of Measure
+            entry("UNSD"),              // United Nations Statistics Division
+            entry("USNO"));             // United States Naval Observatory
 
     /**
-     * Adds the given authority to the {@link #AUTHORITIES} map.
-     * This method shall be invoked at class initialization time only.
+     * Returns an {@link #AUTHORITIES} entry for the common case
+     * where the code space is the same as the key.
      */
-    private static void add(final String authority) {
-        AUTHORITIES.put(authority, authority);
+    private static Map.Entry<String,String> entry(final String authority) {
+        return Map.entry(authority, authority);
     }
 
     /**
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/TransformationAccuracy.java b/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/TransformationAccuracy.java
index 334fcfd9d1..13f426fd52 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/TransformationAccuracy.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/TransformationAccuracy.java
@@ -16,7 +16,7 @@
  */
 package org.apache.sis.internal.metadata;
 
-import java.util.Collections;
+import java.util.List;
 import org.opengis.util.RecordType;
 import org.opengis.util.InternationalString;
 import org.opengis.metadata.quality.PositionalAccuracy;
@@ -71,13 +71,13 @@ public final class TransformationAccuracy extends Static {
             record.setAll(accuracy);
 
             final DefaultQuantitativeResult result = new DefaultQuantitativeResult();
-            result.setValues(Collections.singletonList(record));
+            result.setValues(List.of(record));
             result.setValueUnit(Units.METRE);              // In metres by definition in the EPSG database.
             result.setValueType(type);
 
             final DefaultAbsoluteExternalPositionalAccuracy element =
                     new DefaultAbsoluteExternalPositionalAccuracy(result);
-            element.setNamesOfMeasure(Collections.singleton(TRANSFORMATION_ACCURACY));
+            element.setNamesOfMeasure(List.of(TRANSFORMATION_ACCURACY));
             element.setEvaluationMethodType(EvaluationMethodType.DIRECT_EXTERNAL);
             element.transitionTo(DefaultAbsoluteExternalPositionalAccuracy.State.FINAL);
 
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyInformation.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyInformation.java
index 7b0f3b900c..ab15076f17 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyInformation.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyInformation.java
@@ -17,8 +17,8 @@
 package org.apache.sis.metadata;
 
 import java.util.Locale;
+import java.util.Set;
 import java.util.Collection;
-import java.util.Collections;
 import java.lang.reflect.Method;
 import org.opengis.annotation.UML;
 import org.opengis.annotation.Obligation;
@@ -292,7 +292,7 @@ final class PropertyInformation<E> extends SimpleIdentifier           // Impleme
      */
     @Override
     public Collection<String> getParentEntity() {
-        return Collections.singleton(getCodeSpace());
+        return Set.of(getCodeSpace());
     }
 
     /**
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNode.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNode.java
index 5a2e976991..7eb27838f9 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNode.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNode.java
@@ -16,11 +16,11 @@
  */
 package org.apache.sis.metadata;
 
+import java.util.Set;
 import java.util.Map;
 import java.util.List;
 import java.util.Iterator;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Objects;
 import java.util.NoSuchElementException;
 import java.util.ConcurrentModificationException;
@@ -76,7 +76,7 @@ class TreeNode implements Node {
      * does not implement the {@link List} interface. So we are better to never give to the user
      * a collection implementing {@code List} in order to signal incorrect casts sooner.</p>
      */
-    private static final Collection<Node> LEAF = Collections.emptySet();
+    private static final Collection<Node> LEAF = Set.of();
 
     /**
      * The table for which this node is an element. Contains information like
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataWriter.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataWriter.java
index df5ed676ac..b244a90535 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataWriter.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataWriter.java
@@ -23,7 +23,6 @@ import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.IdentityHashMap;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.StringTokenizer;
 import java.util.logging.Level;
 import java.sql.Statement;
@@ -698,11 +697,11 @@ public class MetadataWriter extends MetadataSource {
         String identifier = null;
         final Collection<? extends Identifier> identifiers;
         if (metadata instanceof Identifier) {
-            identifiers = Collections.singleton((Identifier) metadata);
+            identifiers = Set.of((Identifier) metadata);
         } else if (metadata instanceof IdentifiedObject) {
             identifiers = ((IdentifiedObject) metadata).getIdentifiers();
         } else {
-            identifiers = Collections.emptySet();
+            identifiers = Set.of();
         }
         for (final Identifier id : identifiers) {
             identifier = Strings.trimOrNull(id.getCode());
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java
index d5adf15572..4f91ff0fff 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java
@@ -17,7 +17,6 @@
 package org.apache.sis.util.iso;
 
 import java.util.List;
-import java.util.Collections;
 import java.util.Locale;
 import java.util.Objects;
 import java.io.ObjectStreamException;
@@ -223,7 +222,7 @@ public class DefaultLocalName extends AbstractName implements LocalName {
      */
     @Override
     public final List<DefaultLocalName> getParsedNames() {
-        return Collections.singletonList(this);
+        return List.of(this);
     }
 
     /**
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultRecord.java b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultRecord.java
index 20d0940fbb..e70021ff00 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultRecord.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultRecord.java
@@ -22,7 +22,6 @@ import java.util.AbstractMap;
 import java.util.AbstractSet;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
-import java.util.Collections;
 import java.util.Objects;
 import java.io.Serializable;
 import java.lang.reflect.Array;
@@ -183,7 +182,7 @@ public class DefaultRecord implements Record, Serializable {
     @Override
     public Map<MemberName, Object> getFields() {
         if (values == null) {                         // Should never be null, except temporarily at XML unmarshalling time.
-            return Collections.emptyMap();
+            return Map.of();
         }
         return new AbstractMap<MemberName, Object>() {
             /** Returns the number of fields in the record. */
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/xml/Namespaces.java b/core/sis-metadata/src/main/java/org/apache/sis/xml/Namespaces.java
index 332579bcf4..032fdbf6d9 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/xml/Namespaces.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/xml/Namespaces.java
@@ -17,7 +17,6 @@
 package org.apache.sis.xml;
 
 import java.util.Map;
-import java.util.HashMap;
 import java.util.Locale;
 import javax.xml.XMLConstants;
 import org.apache.sis.util.Static;
@@ -536,42 +535,38 @@ public final class Namespaces extends Static {
      * A map of (<var>URLs</var>, <var>prefix</var>). Stores URLs for which
      * the prefix to use cannot be easily inferred from the URL itself.
      */
-    private static final Map<String,String> SPECIFIC_URLS;
-    static {
-        final Map<String,String> p = new HashMap<>(40);
-        p.put(XMLConstants.W3C_XML_SCHEMA_NS_URI,                          "xs");
-        p.put(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI,                "xsi");
-        p.put("http://www.w3.org/2004/02/skos/core#",                    "skos");
-        p.put("http://www.w3.org/1999/02/22-rdf-syntax-ns#",              "rdf");
-        p.put("http://www.w3.org/1998/Math/MathML",                       "mml");
-        p.put("http://www.opengis.net/sensorML/1.0",                     "sml1");
-        p.put("http://www.opengis.net/sensorML/1.0.1",                    "sml");
-        p.put("http://www.opengis.net/swe/1.0",                          "swe1");
-        p.put("http://www.opengis.net/cat/csw/3.0",                       "csw");
-        p.put("http://www.opengis.net/cat/csw/2.0.2",                    "csw2");
-        p.put("http://www.opengis.net/ows/2.0",                           "ows");
-        p.put("http://www.opengis.net/cat/wrs/1.0",                       "wrs");
-        p.put("http://www.opengis.net/cat/wrs",                         "wrs09");
-        p.put("http://www.opengis.net/ows-6/utds/0.3",                   "utds");
-        p.put("http://www.opengis.net/citygml/1.0",                      "core");
-        p.put("http://www.opengis.net/citygml/building/1.0",            "build");
-        p.put("http://www.opengis.net/citygml/cityfurniture/1.0",   "furniture");
-        p.put("http://www.opengis.net/citygml/transportation/1.0",         "tr");
-        p.put("http://www.isotc211.org/2005/gco",                        "gcol");   // "l" for "legacy" (prior version 1).
-        p.put("http://www.isotc211.org/2005/srv",                        "srv1");
-        p.put("http://www.purl.org/dc/elements/1.1/",                     "dc2");
-        p.put("http://www.purl.org/dc/terms/",                           "dct2");
-        p.put("http://purl.org/dc/terms/",                                "dct");
-        p.put("http://www.inspire.org",                                   "ins");
-        p.put("http://inspira.europa.eu/networkservice/view/1.0",  "inspire_vs");
-        p.put("urn:oasis:names:tc:ciq:xsdschema:xAL:2.0",                 "xal");
-        p.put("urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0",              "rim");
-        p.put("urn:oasis:names:tc:ebxml-regrep:rim:xsd:2.5",            "rim25");
-        p.put("urn:oasis:names:tc:xacml:2.0:context:schema:os", "xacml-context");
-        p.put("urn:oasis:names:tc:xacml:2.0:policy:schema:os",   "xacml-policy");
-        p.put("urn:us:gov:ic:ism:v2",                                   "icism");
-        SPECIFIC_URLS = p;
-    }
+    private static final Map<String,String> SPECIFIC_URLS = Map.ofEntries(
+            Map.entry(XMLConstants.W3C_XML_SCHEMA_NS_URI,                          "xs"),
+            Map.entry(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI,                "xsi"),
+            Map.entry("http://www.w3.org/2004/02/skos/core#",                    "skos"),
+            Map.entry("http://www.w3.org/1999/02/22-rdf-syntax-ns#",              "rdf"),
+            Map.entry("http://www.w3.org/1998/Math/MathML",                       "mml"),
+            Map.entry("http://www.opengis.net/sensorML/1.0",                     "sml1"),
+            Map.entry("http://www.opengis.net/sensorML/1.0.1",                    "sml"),
+            Map.entry("http://www.opengis.net/swe/1.0",                          "swe1"),
+            Map.entry("http://www.opengis.net/cat/csw/3.0",                       "csw"),
+            Map.entry("http://www.opengis.net/cat/csw/2.0.2",                    "csw2"),
+            Map.entry("http://www.opengis.net/ows/2.0",                           "ows"),
+            Map.entry("http://www.opengis.net/cat/wrs/1.0",                       "wrs"),
+            Map.entry("http://www.opengis.net/cat/wrs",                         "wrs09"),
+            Map.entry("http://www.opengis.net/ows-6/utds/0.3",                   "utds"),
+            Map.entry("http://www.opengis.net/citygml/1.0",                      "core"),
+            Map.entry("http://www.opengis.net/citygml/building/1.0",            "build"),
+            Map.entry("http://www.opengis.net/citygml/cityfurniture/1.0",   "furniture"),
+            Map.entry("http://www.opengis.net/citygml/transportation/1.0",         "tr"),
+            Map.entry("http://www.isotc211.org/2005/gco",                        "gcol"),   // "l" for "legacy" (prior version 1).
+            Map.entry("http://www.isotc211.org/2005/srv",                        "srv1"),
+            Map.entry("http://www.purl.org/dc/elements/1.1/",                     "dc2"),
+            Map.entry("http://www.purl.org/dc/terms/",                           "dct2"),
+            Map.entry("http://purl.org/dc/terms/",                                "dct"),
+            Map.entry("http://www.inspire.org",                                   "ins"),
+            Map.entry("http://inspira.europa.eu/networkservice/view/1.0",  "inspire_vs"),
+            Map.entry("urn:oasis:names:tc:ciq:xsdschema:xAL:2.0",                 "xal"),
+            Map.entry("urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0",              "rim"),
+            Map.entry("urn:oasis:names:tc:ebxml-regrep:rim:xsd:2.5",            "rim25"),
+            Map.entry("urn:oasis:names:tc:xacml:2.0:context:schema:os", "xacml-context"),
+            Map.entry("urn:oasis:names:tc:xacml:2.0:policy:schema:os",   "xacml-policy"),
+            Map.entry("urn:us:gov:ic:ism:v2",                                   "icism"));
 
     /**
      * Returns the preferred prefix for the given namespace URI.
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingReader.java b/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingReader.java
index 1434204913..b3e7a0383d 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingReader.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingReader.java
@@ -273,7 +273,7 @@ final class TransformingReader extends Transformer implements XMLEventReader {
                 if (namespaces != null) {
                     if (localNS != null) {
                         if (namespaces.isEmpty()) {
-                            namespaces = Collections.singletonList(localNS);
+                            namespaces = List.of(localNS);
                         } else {
                             namespaces.add(localNS);
                         }
@@ -318,6 +318,7 @@ final class TransformingReader extends Transformer implements XMLEventReader {
                 return NAMESPACES;
             }
         }
+        // Do not use `Map.of()` because we need to accept `Map.get(null)`.
         return Collections.emptyMap();
     }
 
@@ -386,7 +387,7 @@ final class TransformingReader extends Transformer implements XMLEventReader {
             final String oldURI, final String newURI, boolean changed)
     {
         if (!namespaces.hasNext()) {
-            return changed ? Collections.emptyList() : null;
+            return changed ? List.of() : null;
         }
         final List<Namespace> modified = new ArrayList<>();
         do {
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingWriter.java b/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingWriter.java
index e87e51913c..24b89b94a0 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingWriter.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingWriter.java
@@ -25,7 +25,6 @@ import java.util.List;
 import java.util.Queue;
 import java.util.ArrayDeque;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.Iterator;
 import javax.xml.stream.XMLEventReader;
 import javax.xml.stream.XMLEventWriter;
@@ -84,7 +83,7 @@ final class TransformingWriter extends Transformer implements XMLEventWriter {
      *
      * This map is initialized only once and should not be modified after that point.
      */
-    private static final Map<String, Map<String,String>> NAMESPACES = load(true, FILENAME, Collections.emptySet(), 60);
+    private static final Map<String, Map<String,String>> NAMESPACES = load(true, FILENAME, Set.of(), 60);
 
     /**
      * Elements that appear in different order in ISO 19139:2007 (or other legacy standards) compared
@@ -110,8 +109,8 @@ final class TransformingWriter extends Transformer implements XMLEventWriter {
     private static final Map<QName, Set<QName>> ELEMENTS_TO_REORDER;
     static {
         final Map<QName, Set<QName>> m = new HashMap<>(4);
-        m.put(new QName(Namespaces.SRV, "couplingType",  "srv"), Collections.singleton(new QName(Namespaces.SRV, "coupledResource", "srv")));
-        m.put(new QName(Namespaces.SRV, "connectPoint",  "srv"), Collections.singleton(new QName(Namespaces.SRV, "parameter",       "srv")));
+        m.put(new QName(Namespaces.SRV, "couplingType",  "srv"), Set.of(new QName(Namespaces.SRV, "coupledResource", "srv")));
+        m.put(new QName(Namespaces.SRV, "connectPoint",  "srv"), Set.of(new QName(Namespaces.SRV, "parameter",       "srv")));
         /*
          * ISO 19139:2997 declared `topicCategory` and `extent` in MD_DataIdentification subclass, while ISO 19115-3
          * moves them to the MD_Identification parent class. In order to write topicCategory at location expected by
@@ -313,7 +312,7 @@ final class TransformingWriter extends Transformer implements XMLEventWriter {
      */
     private List<Namespace> export(final Iterator<Namespace> namespaces, boolean changed) {
         if (!namespaces.hasNext()) {
-            return changed ? Collections.emptyList() : null;
+            return changed ? List.of() : null;
         }
         do {
             final Namespace namespace = namespaces.next();
diff --git a/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java b/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java
index 222844064e..0f135087da 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java
@@ -40,7 +40,6 @@ import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
-import static java.util.Collections.singleton;
 import static org.apache.sis.test.Assert.*;
 import static org.apache.sis.test.TestUtilities.getSingleton;
 
@@ -226,9 +225,9 @@ public final strictfp class MetadataStandardTest extends TestCase {
         final DefaultPlatform platform = new DefaultPlatform();
         platform.setDescription(new SimpleInternationalString("A platform."));
         instrument.setMountedOn(platform);
-        platform.setInstruments(singleton(instrument));
+        platform.setInstruments(Set.of(instrument));
         final DefaultAcquisitionInformation acquisition = new DefaultAcquisitionInformation();
-        acquisition.setPlatforms(singleton(platform));
+        acquisition.setPlatforms(Set.of(platform));
         return acquisition;
     }
 
diff --git a/core/sis-metadata/src/test/java/org/apache/sis/metadata/ModifiableMetadataTest.java b/core/sis-metadata/src/test/java/org/apache/sis/metadata/ModifiableMetadataTest.java
index 75bd7e2a4e..f3d8e25e24 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/ModifiableMetadataTest.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/ModifiableMetadataTest.java
@@ -16,8 +16,8 @@
  */
 package org.apache.sis.metadata;
 
+import java.util.Set;
 import java.util.Arrays;
-import java.util.Collections;
 import org.opengis.metadata.distribution.MediumFormat;
 import org.apache.sis.metadata.iso.DefaultIdentifier;
 import org.apache.sis.metadata.iso.distribution.DefaultMedium;
@@ -94,7 +94,7 @@ public final strictfp class ModifiableMetadataTest extends TestCase {
         md.setVolumes(4);                                                                   // New value.
         md.setMediumNote(new SimpleInternationalString("A new note."));                     // Overwriting.
         md.getMediumFormats().add(MediumFormat.TAR);
-        md.setMediumFormats(Collections.singleton(MediumFormat.CPIO));                      // Discard TAR.
+        md.setMediumFormats(Set.of(MediumFormat.CPIO));                                     // Discard TAR.
         md.getMediumFormats().add(MediumFormat.ISO_9660);
         assertPropertiesEqual(4, "A new note.", MediumFormat.CPIO, MediumFormat.ISO_9660);
     }
@@ -131,7 +131,7 @@ public final strictfp class ModifiableMetadataTest extends TestCase {
         } catch (UnsupportedOperationException e) {
             // This is the expected exception.
         }
-        md.setMediumFormats(Collections.singleton(MediumFormat.CPIO));
+        md.setMediumFormats(Set.of(MediumFormat.CPIO));
         try {
             md.getMediumFormats().add(MediumFormat.ISO_9660);
             fail("Adding new value shall not be allowed.");
@@ -178,7 +178,7 @@ public final strictfp class ModifiableMetadataTest extends TestCase {
             // This is the expected exception.
         }
         try {
-            md.setMediumFormats(Collections.singleton(MediumFormat.CPIO));
+            md.setMediumFormats(Set.of(MediumFormat.CPIO));
             fail("Setting new value shall not be allowed.");
         } catch (UnmodifiableMetadataException e) {
             verifyUnmodifiableException(e);
diff --git a/core/sis-metadata/src/test/java/org/apache/sis/metadata/PrunerTest.java b/core/sis-metadata/src/test/java/org/apache/sis/metadata/PrunerTest.java
index 4b0dc5607f..b62969c927 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/PrunerTest.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/PrunerTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.metadata;
 
+import java.util.Set;
 import org.apache.sis.metadata.iso.DefaultMetadata;
 import org.apache.sis.metadata.iso.citation.DefaultCitation;
 import org.apache.sis.metadata.iso.extent.DefaultExtent;
@@ -30,7 +31,6 @@ import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
 import static org.junit.Assert.*;
-import static java.util.Collections.singleton;
 import static org.apache.sis.metadata.ValueExistencePolicy.isNullOrEmpty;
 
 
@@ -82,10 +82,10 @@ public final strictfp class PrunerTest extends TestCase {
         scale          = new DefaultRepresentativeFraction();
         extent         = new DefaultExtent();
         bbox           = new DefaultGeographicBoundingBox();
-        extent.setGeographicElements(singleton(bbox));
-        identification.setExtents(singleton(extent));
-        identification.setSpatialResolutions(singleton(new DefaultResolution(scale)));
-        metadata.setIdentificationInfo(singleton(identification));
+        extent.setGeographicElements(Set.of(bbox));
+        identification.setExtents(Set.of(extent));
+        identification.setSpatialResolutions(Set.of(new DefaultResolution(scale)));
+        metadata.setIdentificationInfo(Set.of(identification));
     }
 
     /**
@@ -152,7 +152,7 @@ public final strictfp class PrunerTest extends TestCase {
      * The cycle is between {@code platform.instrument} and {@code instrument.isMountedOn}.
      */
     private void createCyclicMetadata() {
-        metadata.setAcquisitionInformation(singleton(MetadataStandardTest.createCyclicMetadata()));
+        metadata.setAcquisitionInformation(Set.of(MetadataStandardTest.createCyclicMetadata()));
     }
 
     /**
diff --git a/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeNodeTest.java b/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeNodeTest.java
index e0406036f8..5778228bd3 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeNodeTest.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeNodeTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.metadata;
 
+import java.util.Set;
 import java.util.Arrays;
 import java.util.Locale;
 import org.opengis.metadata.citation.Address;
@@ -41,7 +42,6 @@ import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
 import static org.apache.sis.test.MetadataAssert.*;
-import static java.util.Collections.singleton;
 
 
 /**
@@ -90,8 +90,8 @@ public final strictfp class TreeNodeTest extends TestCase {
         // Add a second responsible party with deeper hierarchy.
         final DefaultContact contact = new DefaultContact();
         final DefaultAddress address = new DefaultAddress();
-        address.setElectronicMailAddresses(singleton("Some email"));
-        contact.setAddresses(singleton(address));
+        address.setElectronicMailAddresses(Set.of("Some email"));
+        contact.setAddresses(Set.of(address));
         party = new DefaultIndividual("Some person of contact", null, contact);
         responsibility = new DefaultResponsibility(Role.POINT_OF_CONTACT, null, party);
         assertTrue(citation.getCitedResponsibleParties().add(responsibility));
diff --git a/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java b/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java
index f999c21e04..3044c96886 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.metadata;
 
+import java.util.Set;
 import java.util.List;
 import org.opengis.metadata.citation.Role;
 import org.opengis.metadata.citation.PresentationForm;
@@ -35,7 +36,6 @@ import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
-import static java.util.Collections.singleton;
 import static org.apache.sis.test.Assert.*;
 
 
@@ -111,9 +111,9 @@ public final strictfp class TreeTableFormatTest extends TestCase {
         final DefaultCitation   titled = new DefaultCitation("Some specification");
         final DefaultCitation    coded = new DefaultCitation();
         final DefaultCitation untitled = new DefaultCitation();
-        titled  .setPresentationForms(singleton(PresentationForm.DOCUMENT_HARDCOPY));
-        coded   .setPresentationForms(singleton(PresentationForm.IMAGE_HARDCOPY));
-        untitled.setCitedResponsibleParties(singleton(new DefaultResponsibility(Role.AUTHOR, null, null)));
+        titled  .setPresentationForms(Set.of(PresentationForm.DOCUMENT_HARDCOPY));
+        coded   .setPresentationForms(Set.of(PresentationForm.IMAGE_HARDCOPY));
+        untitled.setCitedResponsibleParties(Set.of(new DefaultResponsibility(Role.AUTHOR, null, null)));
         final DefaultProcessing processing = new DefaultProcessing();
         processing.setDocumentations(List.of(titled, coded, untitled));
         final String text = format.format(processing.asTreeTable());
diff --git a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/MarshallingTest.java b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/MarshallingTest.java
index 5a961e7dcc..9f062c23c4 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/MarshallingTest.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/MarshallingTest.java
@@ -22,7 +22,6 @@ import java.util.List;
 import java.util.Set;
 import java.util.Map;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.logging.Filter;
 import java.util.logging.LogRecord;
@@ -150,7 +149,7 @@ public final class MarshallingTest extends TestUsingFile implements Filter {
         md.setLanguages(languages);
 
         // Character Sets (character encoding)
-        final Collection<Charset> charSets = Collections.singleton(StandardCharsets.ISO_8859_1);
+        final Collection<Charset> charSets = Set.of(StandardCharsets.ISO_8859_1);
         md.setCharacterSets(charSets);
         {
             // Parent metadata
@@ -202,7 +201,7 @@ public final class MarshallingTest extends TestUsingFile implements Filter {
                 {
                     // Address information
                     final DefaultAddress address = new DefaultAddress();
-                    address.setDeliveryPoints(Collections.singleton(new SimpleInternationalString("123 Main Street")));
+                    address.setDeliveryPoints(Set.of(new SimpleInternationalString("123 Main Street")));
                     address.getElectronicMailAddresses().add("test@example.com");
                     address.setCity(new SimpleInternationalString("Metropolis city"));
                     address.setAdministrativeArea(new SimpleInternationalString("Utopia province"));
@@ -222,7 +221,7 @@ public final class MarshallingTest extends TestUsingFile implements Filter {
                 onlineResource.setFunction(OnLineFunction.SEARCH);
                 onlineResource.getIdentifierMap().putSpecialized(IdentifierSpace.ID, "timaeus");    // For enabling references
                 contact.getOnlineResources().add(onlineResource);
-                contact.setHoursOfService(Collections.singleton(new SimpleInternationalString("Weekdays 9:00 AM - 5:00 PM")));
+                contact.setHoursOfService(Set.of(new SimpleInternationalString("Weekdays 9:00 AM - 5:00 PM")));
                 contact.setContactInstructions(new SimpleInternationalString("Through thought"));
                 contact.setContactType(new SimpleInternationalString("Virtual"));
                 contact.getIdentifierMap().putSpecialized(IdentifierSpace.ID, "thought");           // For enabling references
@@ -235,7 +234,7 @@ public final class MarshallingTest extends TestUsingFile implements Filter {
                                    new DefaultResponsibility(Role.POINT_OF_CONTACT, null, individual2)));
         }
         // Date info (date stamp in legacy ISO 19115:2003 model)
-        final Collection<CitationDate> dateInfo = Collections.singleton(new DefaultCitationDate(new Date(1260961229580L), DateType.CREATION));
+        final Collection<CitationDate> dateInfo = Set.of(new DefaultCitationDate(new Date(1260961229580L), DateType.CREATION));
         md.setDateInfo(dateInfo);
         {
             // Metadata standard
@@ -315,7 +314,7 @@ public final class MarshallingTest extends TestUsingFile implements Filter {
             elementInfo.setDomainValue(new SimpleInternationalString("Alpha, beta or gamma."));
             elementInfo.setShortName("ExtEltName");
             elementInfo.setDomainCode(1234);
-            elementInfo.setParentEntity(Collections.singleton("VirtualObject"));
+            elementInfo.setParentEntity(Set.of("VirtualObject"));
             elementInfo.setRule(new SimpleInternationalString("Element exists in cited resource."));
             elementInfo.setRationale(new SimpleInternationalString("For testing extended elements."));
             elementInfo.getSources().add(NilReason.valueOf("other:test").createNilObject(Responsibility.class));
@@ -361,7 +360,7 @@ public final class MarshallingTest extends TestUsingFile implements Filter {
             final DefaultTemporalExtent temporal = new DefaultTemporalExtent();
             extent.getTemporalElements().add(temporal);
             extent.getIdentifierMap().putSpecialized(IdentifierSpace.ID, "azores");     // For enabling references
-            extents = Collections.singleton(extent);
+            extents = Set.of(extent);
             dataId.setExtents(extents);
         }
         final Collection<Constraints> resourceConstraints;
@@ -387,7 +386,7 @@ public final class MarshallingTest extends TestUsingFile implements Filter {
             graphic.getImageConstraints().add(new DefaultConstraints());
             graphic.getLinkages().add(new DefaultOnlineResource());
             constraint.getGraphics().add(graphic);
-            constraint.setUseLimitations(Collections.singleton(new SimpleInternationalString("Not for navigation.")));
+            constraint.setUseLimitations(Set.of(new SimpleInternationalString("Not for navigation.")));
 
             // Releasability
             final DefaultReleasability releasability = new DefaultReleasability();
@@ -395,7 +394,7 @@ public final class MarshallingTest extends TestUsingFile implements Filter {
             constraint.setReleasability(releasability);
             constraint.setConstraintApplicationScope(new DefaultScope(ScopeCode.DOCUMENT));
             constraint.getIdentifierMap().putSpecialized(IdentifierSpace.ID, "public");         // For enabling references
-            resourceConstraints = Collections.singleton(constraint);
+            resourceConstraints = Set.of(constraint);
             dataId.setResourceConstraints(resourceConstraints);
         }
         dataId.getSpatialRepresentationTypes().add(SpatialRepresentationType.GRID);
@@ -452,7 +451,7 @@ public final class MarshallingTest extends TestUsingFile implements Filter {
             }
             maintenanceInfo.getIdentifierMap().putSpecialized(IdentifierSpace.ID, "not-planned");
             maintenanceInfo.getMaintenanceScopes().add(maintenanceScope);
-            resourceMaintenances = Collections.singleton(maintenanceInfo);
+            resourceMaintenances = Set.of(maintenanceInfo);
             dataId.setResourceMaintenances(resourceMaintenances);
         }
         {
@@ -491,7 +490,7 @@ public final class MarshallingTest extends TestUsingFile implements Filter {
             keywords.setKeywords(List.of(new SimpleInternationalString("Water"),
                                          new SimpleInternationalString("Aether")));
             keywords.getIdentifierMap().putSpecialized(IdentifierSpace.ID, "greek-elements");
-            descriptiveKeywords = Collections.singleton(keywords);
+            descriptiveKeywords = Set.of(keywords);
             dataId.setDescriptiveKeywords(descriptiveKeywords);
         }
         {
@@ -504,7 +503,7 @@ public final class MarshallingTest extends TestUsingFile implements Filter {
             final DefaultUsage usage = new DefaultUsage();
             usage.setSpecificUsage(new SimpleInternationalString("For testing purpose only."));
             usage.setUsageDate(new Date(1523361600000L));
-            usage.setResponses(Collections.singleton(new SimpleInternationalString("Random elements")));
+            usage.setResponses(Set.of(new SimpleInternationalString("Random elements")));
             usage.setUserDeterminedLimitations(new SimpleInternationalString("Not to be used outside MarshallingTest.java test file."));
             dataId.getResourceSpecificUsages().add(usage);
         }
@@ -515,7 +514,7 @@ public final class MarshallingTest extends TestUsingFile implements Filter {
             associatedResource.setAssociationType(AssociationType.DEPENDENCY);
             associatedResource.setInitiativeType(InitiativeType.EXPERIMENT);
             associatedResource.getIdentifierMap().putSpecialized(IdentifierSpace.ID, "dependency");
-            associatedResources = Collections.singleton(associatedResource);
+            associatedResources = Set.of(associatedResource);
             dataId.setAssociatedResources(associatedResources);
         }
         dataId.setLanguages(languages);     // Locales (ISO 19115:2014) a.k.a Languages and CharacterSets (ISO 19115:2003)
@@ -532,7 +531,7 @@ public final class MarshallingTest extends TestUsingFile implements Filter {
             serviceId.setDescriptiveKeywords(descriptiveKeywords);
             serviceId.setResourceConstraints(resourceConstraints);
             serviceId.setAssociatedResources(associatedResources);
-            serviceId.setServiceTypeVersions(Collections.singleton("Version 1000+"));
+            serviceId.setServiceTypeVersions(Set.of("Version 1000+"));
             // TODO: Coupled resources
             final DefaultCoupledResource coupledResource = new DefaultCoupledResource();
             serviceId.getCoupledResources().add(coupledResource);
diff --git a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java
index a38d2ebc3f..13da8b21bd 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java
@@ -17,9 +17,9 @@
 package org.apache.sis.metadata.iso.citation;
 
 import java.net.URI;
+import java.util.Set;
 import java.util.List;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.Locale;
 import javax.xml.bind.JAXBException;
@@ -85,7 +85,7 @@ public final strictfp class DefaultCitationTest extends TestUsingFile {
         citation.setPresentationForms(List.of(
                 PresentationForm.DOCUMENT_HARDCOPY,
                 PresentationForm.DOCUMENT_DIGITAL));
-        citation.setAlternateTitles(Collections.singleton(
+        citation.setAlternateTitles(Set.of(
                 new SimpleInternationalString("Andākarento")));   // Actually a different script of the Japanese title.
         citation.setCitedResponsibleParties(List.of(
                 new DefaultResponsibility(Role.AUTHOR, null, new DefaultIndividual("Testsuya Toyoda", null, null)),
diff --git a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultCoupledResourceTest.java b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultCoupledResourceTest.java
index 638402f1cb..1d98dd9363 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultCoupledResourceTest.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultCoupledResourceTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.metadata.iso.identification;
 
+import java.util.Set;
 import org.opengis.util.ScopedName;
 import org.opengis.util.NameFactory;
 import org.opengis.parameter.ParameterDescriptor;
@@ -29,7 +30,6 @@ import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
-import static java.util.Collections.singleton;
 import static org.junit.Assert.*;
 
 
@@ -49,8 +49,8 @@ public final strictfp class DefaultCoupledResourceTest extends TestCase {
     static DefaultCoupledResource create(final NameFactory factory) {
         final DefaultOperationMetadata operation = new DefaultOperationMetadata("Get Map",
                 DistributedComputingPlatform.WEB_SERVICES, null);
-        operation.setParameters(singleton((ParameterDescriptor<?>) ServiceParameterTest.create()));
-        operation.setConnectPoints(singleton(NilReason.MISSING.createNilObject(OnlineResource.class)));
+        operation.setParameters(Set.of((ParameterDescriptor<?>) ServiceParameterTest.create()));
+        operation.setConnectPoints(Set.of(NilReason.MISSING.createNilObject(OnlineResource.class)));
 
         final DefaultCoupledResource resource = new DefaultCoupledResource();
         resource.setScopedName((ScopedName) factory.createGenericName(null, "mySpace", "ABC-123"));
@@ -70,7 +70,7 @@ public final strictfp class DefaultCoupledResourceTest extends TestCase {
          */
         resource.setOperation(new OperationName(operation.getOperationName()));
         assertNotSame("Before resolve", operation, resource.getOperation());
-        OperationName.resolve(singleton(operation), singleton(resource));
+        OperationName.resolve(Set.of(operation), Set.of(resource));
         assertSame("After resolve", operation, resource.getOperation());
         /*
          * If the name doesn't match, no replacement shall be done.
@@ -78,7 +78,7 @@ public final strictfp class DefaultCoupledResourceTest extends TestCase {
         final OperationName other = new OperationName("Other");
         resource.setOperation(other);
         assertSame("Before resolve", other, resource.getOperation());
-        OperationName.resolve(singleton(operation), singleton(resource));
+        OperationName.resolve(Set.of(operation), Set.of(resource));
         assertSame("After resolve", other, resource.getOperation());
     }
 }
diff --git a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultDataIdentificationTest.java b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultDataIdentificationTest.java
index 0e60c25f8b..aad7cbb549 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultDataIdentificationTest.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultDataIdentificationTest.java
@@ -18,6 +18,7 @@ package org.apache.sis.metadata.iso.identification;
 
 import java.util.Collection;
 import java.util.Map;
+import java.util.Set;
 import java.util.Locale;
 import java.nio.charset.StandardCharsets;
 import org.opengis.metadata.citation.Citation;
@@ -34,7 +35,6 @@ import org.apache.sis.test.TestCase;
 import org.apache.sis.test.TestUtilities;
 import org.junit.Test;
 
-import static java.util.Collections.singleton;
 import static org.apache.sis.test.MetadataAssert.*;
 
 
@@ -68,8 +68,8 @@ public final strictfp class DefaultDataIdentificationTest extends TestCase {
          *       └─Code……………………………………………………………………… NCEP/SST/Global_5x2p5deg/SST_Global_5x2p5deg_20050922_0000.nc
          */
         final DefaultCitation citation = new DefaultCitation("Sea Surface Temperature Analysis Model");
-        citation.setDates(singleton(new DefaultCitationDate(TestUtilities.date("2005-09-22 00:00:00"), DateType.CREATION)));
-        citation.setIdentifiers(singleton(new DefaultIdentifier("SST_Global.nc")));
+        citation.setDates(Set.of(new DefaultCitationDate(TestUtilities.date("2005-09-22 00:00:00"), DateType.CREATION)));
+        citation.setIdentifiers(Set.of(new DefaultIdentifier("SST_Global.nc")));
         /*
          * Descriptive keywords
          *   ├─Keyword………………………………………………………………………… EARTH SCIENCE > Oceans > Ocean Temperature > Sea Surface Temperature
@@ -107,12 +107,12 @@ public final strictfp class DefaultDataIdentificationTest extends TestCase {
          */
         final DefaultDataIdentification info = new DefaultDataIdentification(citation,
                 "Global 5.0 x 2.5 degree model data", null, null);
-        info.setSpatialRepresentationTypes(singleton(SpatialRepresentationType.GRID));
-        info.setDescriptiveKeywords(singleton(keywords));
-        info.setResourceConstraints(singleton(new DefaultConstraints("Freely available")));
+        info.setSpatialRepresentationTypes(Set.of(SpatialRepresentationType.GRID));
+        info.setDescriptiveKeywords(Set.of(keywords));
+        info.setResourceConstraints(Set.of(new DefaultConstraints("Freely available")));
         info.getLocalesAndCharsets().put(Locale.US,     StandardCharsets.US_ASCII);
         info.getLocalesAndCharsets().put(Locale.FRENCH, StandardCharsets.ISO_8859_1);
-        info.setExtents(singleton(Extents.WORLD));
+        info.setExtents(Set.of(Extents.WORLD));
         return info;
     }
 
@@ -166,7 +166,7 @@ public final strictfp class DefaultDataIdentificationTest extends TestCase {
         final Map<String,Object> map = info.asMap();
         assertEquals("abstract", "Global 5.0 x 2.5 degree model data", map.get("abstract").toString());
         assertTitleEquals("title", "Sea Surface Temperature Analysis Model", (Citation) map.get("citation"));
-        assertEquals("spatialRepresentationType", singleton(SpatialRepresentationType.GRID), map.get("spatialRepresentationType"));
+        assertEquals("spatialRepresentationType", Set.of(SpatialRepresentationType.GRID), map.get("spatialRepresentationType"));
 
         final Locale[] locales = {Locale.US, Locale.FRENCH};
         assertArrayEquals("language",     locales, ((Collection<?>) map.get("language")).toArray());
diff --git a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultServiceIdentificationTest.java b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultServiceIdentificationTest.java
index 63e0e8a3fc..3c26eac39b 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultServiceIdentificationTest.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultServiceIdentificationTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.metadata.iso.identification;
 
+import java.util.Set;
 import javax.xml.bind.JAXBException;
 import org.opengis.util.NameFactory;
 import org.opengis.parameter.ParameterDirection;
@@ -33,7 +34,6 @@ import org.apache.sis.xml.NilReason;
 import org.apache.sis.test.DependsOn;
 import org.junit.Test;
 
-import static java.util.Collections.singleton;
 import static org.apache.sis.test.MetadataAssert.*;
 import static org.apache.sis.test.TestUtilities.getSingleton;
 
@@ -63,15 +63,15 @@ public final strictfp class DefaultServiceIdentificationTest extends TestUsingFi
     private static DefaultServiceIdentification create() {
         final NameFactory factory = DefaultFactories.forBuildin(NameFactory.class);
         final DefaultCoupledResource resource = DefaultCoupledResourceTest.create(factory);
-        resource.setResourceReferences(singleton(new DefaultCitation("WMS specification")));
+        resource.setResourceReferences(Set.of(new DefaultCitation("WMS specification")));
         final DefaultServiceIdentification id = new DefaultServiceIdentification(
                 factory.createGenericName(null, "Web Map Server"),      // serviceType
                 NilReason.MISSING.createNilObject(Citation.class),      // citation
                 "A dummy service for testing purpose.");                // abstract
-        id.setServiceTypeVersions(singleton("1.0"));
-        id.setCoupledResources(singleton(resource));
+        id.setServiceTypeVersions(Set.of("1.0"));
+        id.setCoupledResources(Set.of(resource));
         id.setCouplingType(CouplingType.LOOSE);
-        id.setContainsOperations(singleton(resource.getOperation()));
+        id.setContainsOperations(Set.of(resource.getOperation()));
         return id;
     }
 
diff --git a/core/sis-metadata/src/test/java/org/apache/sis/metadata/sql/MetadataSourceTest.java b/core/sis-metadata/src/test/java/org/apache/sis/metadata/sql/MetadataSourceTest.java
index 55c19f49cb..066beac9ca 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/sql/MetadataSourceTest.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/sql/MetadataSourceTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.metadata.sql;
 
+import java.util.Set;
 import java.util.Collection;
 import java.util.Collections;
 import org.opengis.util.InternationalString;
@@ -126,7 +127,7 @@ public final strictfp class MetadataSourceTest extends TestCase {
     @TestStep
     public static void testSearch(final MetadataSource source) throws MetadataStoreException {
         final DefaultCitation specification = new DefaultCitation("PNG (Portable Network Graphics) Specification");
-        specification.setAlternateTitles(Collections.singleton(new SimpleInternationalString("PNG")));
+        specification.setAlternateTitles(Set.of(new SimpleInternationalString("PNG")));
         final DefaultFormat format = new DefaultFormat();
         format.setFormatSpecificationCitation(specification);
 
diff --git a/core/sis-metadata/src/test/java/org/apache/sis/test/xml/DocumentComparator.java b/core/sis-metadata/src/test/java/org/apache/sis/test/xml/DocumentComparator.java
index d8388b9870..df52743a0e 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/test/xml/DocumentComparator.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/test/xml/DocumentComparator.java
@@ -19,7 +19,6 @@ package org.apache.sis.test.xml;
 import java.util.Map;
 import java.util.Set;
 import java.util.List;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.ArrayList;
 import java.nio.file.Files;
@@ -88,20 +87,17 @@ public strictfp class DocumentComparator {
      *
      * @see #substitutePrefix(String)
      */
-    private static final Map<String, String> PREFIX_URL = new HashMap<>(16);
-    static {
-        final Map<String,String> map = PREFIX_URL;
-        map.put("xmlns", "http://www.w3.org/2000/xmlns");           // No trailing slash.
-        map.put("xlink", Namespaces.XLINK);
-        map.put("xsi",   Namespaces.XSI);
-        map.put("gco",   Namespaces.GCO);
-        map.put("mdb",   Namespaces.MDB);
-        map.put("srv",   Namespaces.SRV);
-        map.put("gml",   Namespaces.GML);
-        map.put("gmd",   LegacyNamespaces.GMD);
-        map.put("gmx",   LegacyNamespaces.GMX);
-        map.put("gmi",   LegacyNamespaces.GMI);
-    }
+    private static final Map<String, String> PREFIX_URL = Map.of(
+            "xmlns", "http://www.w3.org/2000/xmlns",                // No trailing slash.
+            "xlink", Namespaces.XLINK,
+            "xsi",   Namespaces.XSI,
+            "gco",   Namespaces.GCO,
+            "mdb",   Namespaces.MDB,
+            "srv",   Namespaces.SRV,
+            "gml",   Namespaces.GML,
+            "gmd",   LegacyNamespaces.GMD,
+            "gmx",   LegacyNamespaces.GMX,
+            "gmi",   LegacyNamespaces.GMI);
 
     /**
      * The DOM factory, created when first needed.
diff --git a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/SEPortrayer.java b/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/SEPortrayer.java
index 960c1327d7..e6a731647c 100644
--- a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/SEPortrayer.java
+++ b/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/SEPortrayer.java
@@ -20,7 +20,6 @@ import java.awt.geom.AffineTransform;
 import java.awt.geom.NoninvertibleTransformException;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -562,7 +561,7 @@ public final class SEPortrayer {
                 }
             }
             if (!found) {
-                return Collections.emptyList();
+                return List.of();
             }
         }
         // Check semantic, only if we have a feature type.
@@ -603,7 +602,7 @@ public final class SEPortrayer {
                         // Cannot define a `text` type with current API.
                     }
                 }
-                if (!valid) return Collections.emptyList();
+                if (!valid) return List.of();
             }
         }
 
diff --git a/core/sis-portrayal/src/test/java/org/apache/sis/internal/map/coverage/MultiResolutionCoverageLoaderTest.java b/core/sis-portrayal/src/test/java/org/apache/sis/internal/map/coverage/MultiResolutionCoverageLoaderTest.java
index d36e115cd8..a3dab7ed2a 100644
--- a/core/sis-portrayal/src/test/java/org/apache/sis/internal/map/coverage/MultiResolutionCoverageLoaderTest.java
+++ b/core/sis-portrayal/src/test/java/org/apache/sis/internal/map/coverage/MultiResolutionCoverageLoaderTest.java
@@ -17,7 +17,6 @@
 package org.apache.sis.internal.map.coverage;
 
 import java.util.List;
-import java.util.Collections;
 import java.awt.image.RenderedImage;
 import org.opengis.geometry.DirectPosition;
 import org.opengis.referencing.datum.PixelInCell;
@@ -127,8 +126,8 @@ public final strictfp class MultiResolutionCoverageLoaderTest extends TestCase {
 
         /** Returns a dummy value (will not be used by this test). */
         @Override public GridCoverage read(final GridGeometry domain, final int... ranges) {
-            final SampleDimension band = new SampleDimension(Names.createLocalName(null, null, "dummy"), null, Collections.emptyList());
-            return new GridCoverage(domain, Collections.singletonList(band)) {
+            final SampleDimension band = new SampleDimension(Names.createLocalName(null, null, "dummy"), null, List.of());
+            return new GridCoverage(domain, List.of(band)) {
                 @Override public RenderedImage render(GridExtent sliceExtent) {
                     throw new UnsupportedOperationException();                      // Not needed by this test.
                 }
diff --git a/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/FinalLocationType.java b/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/FinalLocationType.java
index c37c69745c..9c1d259e12 100644
--- a/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/FinalLocationType.java
+++ b/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/FinalLocationType.java
@@ -177,6 +177,10 @@ final class FinalLocationType extends AbstractLocationType implements Serializab
             array[i] = copy;
         }
         switch (array.length) {
+            /*
+             * Use `Collections` instead of `List.of(…)` for consistency with
+             * `UnmodifiableArrayList` which accepts `List.contains(null)`.
+             */
             case 0:  return Collections.emptyList();
             case 1:  return Collections.singletonList(array[0]);
             default: return UnmodifiableArrayList.wrap(array);
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/AxisDirections.java b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/AxisDirections.java
index ad85a6176a..e85dbdc805 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/AxisDirections.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/AxisDirections.java
@@ -159,20 +159,16 @@ public final class AxisDirections extends Static {
 
     /**
      * Proposed abbreviations for some axis directions.
-     * This map shall be immutable after construction.
      */
-    private static final Map<AxisDirection,String> ABBREVIATIONS = new HashMap<>(12);
-    static {
-        final Map<AxisDirection,String> m = ABBREVIATIONS;
-        m.put(FUTURE,            "t");
-        m.put(COLUMN_POSITIVE,   "i");
-        m.put(ROW_POSITIVE,      "j");
-        m.put(DISPLAY_RIGHT,     "x");
-        m.put(DISPLAY_UP,        "y");
-        m.put(OTHER,             "z");      // Arbitrary abbreviation, may change in any future SIS version.
-        m.put(AWAY_FROM,         "r");
-        m.put(COUNTER_CLOCKWISE, "θ");
-    }
+    private static final Map<AxisDirection,String> ABBREVIATIONS = Map.of(
+            FUTURE,            "t",
+            COLUMN_POSITIVE,   "i",
+            ROW_POSITIVE,      "j",
+            DISPLAY_RIGHT,     "x",
+            DISPLAY_UP,        "y",
+            OTHER,             "z",     // Arbitrary abbreviation, may change in any future SIS version.
+            AWAY_FROM,         "r",
+            COUNTER_CLOCKWISE, "θ");
 
     /**
      * Do not allow instantiation of this class.
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/CoordinateOperations.java b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/CoordinateOperations.java
index 7fcd3a1eae..dd30f594fc 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/CoordinateOperations.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/CoordinateOperations.java
@@ -19,7 +19,6 @@ package org.apache.sis.internal.referencing;
 import java.util.Set;
 import java.util.Map;
 import java.util.HashMap;
-import java.util.Collections;
 import java.util.function.Supplier;
 import javax.measure.UnitConverter;
 import javax.measure.IncommensurableException;
@@ -179,7 +178,7 @@ public final class CoordinateOperations extends SystemListener {
             {
                 return CoordinateOperations.factory();
             }
-            properties = Collections.emptyMap();
+            properties = Map.of();
         }
         final HashMap<String,Object> p = new HashMap<>(properties);
         p.putIfAbsent(ReferencingFactoryContainer.CRS_FACTORY, crsFactory);
@@ -252,7 +251,7 @@ public final class CoordinateOperations extends SystemListener {
                 return wrapAroundChanges(source, target.getCoordinateSystem());
             }
         }
-        return Collections.emptySet();
+        return Set.of();
     }
 
     /**
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Element.java b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Element.java
index 0fa2077c63..90ed2cc72a 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Element.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Element.java
@@ -21,7 +21,6 @@ import java.util.Map;
 import java.util.List;
 import java.util.LinkedList;
 import java.util.Iterator;
-import java.util.Collections;
 import java.util.Locale;
 import java.text.ParsePosition;
 import java.text.ParseException;
@@ -183,7 +182,7 @@ final class Element {
     Element(final String keyword, final LinkedList<Object> children, final int offset, final Locale errorLocale) {
         this.keyword       = keyword;
         this.isEnumeration = (children == null);
-        this.children      = isEnumeration ? Collections.emptyList() : children;
+        this.children      = isEnumeration ? List.of() : children;
         this.isFragment    = (offset < 0);
         this.offset        = isFragment ? ~offset : offset;
         this.errorLocale   = errorLocale;
@@ -237,7 +236,7 @@ final class Element {
                                 openingBracket = text.codePointAt(lower))) < 0)
         {
             position.setIndex(lower);
-            children = Collections.emptyList();
+            children = List.of();
             isEnumeration = true;
             return;
         }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java
index 0314f41781..02d8863e5a 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java
@@ -23,7 +23,6 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Locale;
 import java.util.Date;
 import java.text.DateFormat;
@@ -857,7 +856,7 @@ public class Formatter implements Localized {
                 if (filterID) {
                     for (final Identifier id : identifiers) {
                         if (Citations.identifierMatches(authority, id.getAuthority())) {
-                            identifiers = Collections.singleton(id);
+                            identifiers = Set.of(id);
                             break;
                         }
                     }
@@ -1761,7 +1760,7 @@ public class Formatter implements Localized {
      */
     private Warnings warnings() {
         if (warnings == null) {
-            warnings = new Warnings(errorLocale, false, Collections.emptyMap());
+            warnings = new Warnings(errorLocale, false, Map.of());
         }
         return warnings;
     }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
index 1dc23fec11..2efac7146e 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
@@ -905,7 +905,7 @@ class GeodeticObjectParser extends MathTransformParser implements Comparator<Coo
             name = AxisDirections.appendTo(buffer.append("CS"), axes);
         }
         if (csProperties == null) {
-            csProperties = Map.of(CoordinateSystem.NAME_KEY, name);
+            csProperties = singletonMap(CoordinateSystem.NAME_KEY, name);
         } else {
             csProperties.put(CoordinateSystem.NAME_KEY, name);
         }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java
index b345b0d6d2..6a1c697638 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java
@@ -17,7 +17,6 @@
 package org.apache.sis.io.wkt;
 
 import java.util.Map;
-import java.util.Collections;
 import java.util.Arrays;
 import java.util.Locale;
 import java.text.DateFormat;
@@ -140,7 +139,7 @@ class MathTransformParser extends AbstractParser {
      * @param  mtFactory  the factory to use for creating {@link MathTransform} objects.
      */
     public MathTransformParser(final MathTransformFactory mtFactory) {
-        this(Symbols.getDefault(), Collections.emptyMap(), null, null, null,
+        this(Symbols.getDefault(), Map.of(), null, null, null,
                 new ReferencingFactoryContainer(null, null, null, null, null, mtFactory), null);
     }
 
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/SingletonElement.java b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/SingletonElement.java
index 266fec5e6d..d3f91b0ea5 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/SingletonElement.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/SingletonElement.java
@@ -66,7 +66,7 @@ final class SingletonElement extends AbstractSet<Element> {
      */
     @Override
     public Iterator<Element> iterator() {
-        return (isEmpty() ? Collections.<Element>emptySet() : Collections.singleton(value)).iterator();
+        return isEmpty() ? Collections.emptyIterator() : Collections.singleton(value).iterator();
     }
 
     /**
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Transliterator.java b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Transliterator.java
index e452999e0b..0f6cf2eb2f 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Transliterator.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Transliterator.java
@@ -17,7 +17,6 @@
 package org.apache.sis.io.wkt;
 
 import java.util.Map;
-import java.util.HashMap;
 import java.io.Serializable;
 import java.io.ObjectStreamException;
 import org.opengis.referencing.cs.PolarCS;
@@ -111,21 +110,15 @@ public abstract class Transliterator implements Serializable {
     /**
      * Default names to associate to axis directions in a Cartesian coordinate system.
      * Those names do not apply to other kind of coordinate systems.
-     *
-     * <p>For thread safety reasons, this map shall not be modified after construction.</p>
      */
-    private static final Map<AxisDirection,String> CARTESIAN;
-    static {
-        final Map<AxisDirection,String> m = new HashMap<>(12);
-        m.put(AxisDirection.EAST,         AxisNames.EASTING);
-        m.put(AxisDirection.WEST,         AxisNames.WESTING);
-        m.put(AxisDirection.NORTH,        AxisNames.NORTHING);
-        m.put(AxisDirection.SOUTH,        AxisNames.SOUTHING);
-        m.put(AxisDirection.GEOCENTRIC_X, AxisNames.GEOCENTRIC_X);
-        m.put(AxisDirection.GEOCENTRIC_Y, AxisNames.GEOCENTRIC_Y);
-        m.put(AxisDirection.GEOCENTRIC_Z, AxisNames.GEOCENTRIC_Z);
-        CARTESIAN = m;
-    }
+    private static final Map<AxisDirection,String> CARTESIAN = Map.of(
+            AxisDirection.EAST,         AxisNames.EASTING,
+            AxisDirection.WEST,         AxisNames.WESTING,
+            AxisDirection.NORTH,        AxisNames.NORTHING,
+            AxisDirection.SOUTH,        AxisNames.SOUTHING,
+            AxisDirection.GEOCENTRIC_X, AxisNames.GEOCENTRIC_X,
+            AxisDirection.GEOCENTRIC_Y, AxisNames.GEOCENTRIC_Y,
+            AxisDirection.GEOCENTRIC_Z, AxisNames.GEOCENTRIC_Z);
 
     /**
      * A transliterator compliant with ISO 19162 on a <cite>"best effort"</cite> basis.
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTFormat.java b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
index 5e35ae2dc8..4a3c80389c 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
@@ -25,7 +25,6 @@ import java.util.HashMap;
 import java.util.TreeMap;
 import java.util.List;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
 import java.util.function.Function;
@@ -311,7 +310,7 @@ public class WKTFormat extends CompoundFormat<Object> {
         if (fragments == null) {
             if (!modifiable) {
                 // Most common cases: invoked before to parse a WKT and no fragments specified.
-                return Collections.emptyMap();
+                return Map.of();
             }
             fragments = new TreeMap<>();
             isCloned  = false;
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java b/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java
index e1ee9b984e..6c42e7b59c 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java
@@ -243,7 +243,7 @@ public class DefaultParameterDescriptorGroup extends AbstractParameterDescriptor
         if (descriptor instanceof DefaultParameterDescriptorGroup &&
                 ((DefaultParameterDescriptorGroup) descriptor).descriptors == c)
         {
-            descriptors = c; // Share the immutable instance (no need to clone).
+            descriptors = c;            // Share the immutable instance (no need to clone).
         } else {
             descriptors = asList(c.toArray(GeneralParameterDescriptor[]::new));
         }
@@ -254,6 +254,10 @@ public class DefaultParameterDescriptorGroup extends AbstractParameterDescriptor
      */
     private static List<GeneralParameterDescriptor> asList(final GeneralParameterDescriptor[] parameters) {
         switch (parameters.length) {
+            /*
+             * Use `Collections` instead of `List.of(…)` for consistency with
+             * `UnmodifiableArrayList` which accepts `List.contains(null)`.
+             */
             case 0:  return Collections.emptyList();
             case 1:  return Collections.singletonList(parameters[0]);
             case 2:  // fall through
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
index 193212f7fc..e288bcf6af 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
@@ -19,7 +19,6 @@ package org.apache.sis.referencing;
 import java.util.Map;
 import java.util.List;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.logging.Filter;
 import java.util.logging.LogRecord;
 import org.opengis.util.FactoryException;
@@ -704,7 +703,7 @@ public final class CRS extends Static {
             if (AuthorityFactories.failure(e)) {
                 throw e;
             } else try {
-                return Collections.singletonList(factory.createOperation(sourceCRS, targetCRS, context));
+                return List.of(factory.createOperation(sourceCRS, targetCRS, context));
             } catch (FactoryException ex) {
                 ex.addSuppressed(e);
                 throw ex;
@@ -1319,7 +1318,7 @@ public final class CRS extends Static {
     public static List<SingleCRS> getSingleComponents(final CoordinateReferenceSystem crs) {
         final List<SingleCRS> singles;
         if (crs == null) {
-            singles = Collections.emptyList();
+            singles = List.of();
         } else if (crs instanceof CompoundCRS) {
             if (crs instanceof DefaultCompoundCRS) {
                 singles = ((DefaultCompoundCRS) crs).getSingleComponents();
@@ -1330,7 +1329,7 @@ public final class CRS extends Static {
             }
         } else {
             // Intentional CassCastException here if the crs is not a SingleCRS.
-            singles = Collections.singletonList((SingleCRS) crs);
+            singles = List.of((SingleCRS) crs);
         }
         return singles;
     }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java
index 504a290011..096a9acd93 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java
@@ -16,7 +16,6 @@
  */
 package org.apache.sis.referencing;
 
-import java.util.Collections;
 import java.util.Set;
 import java.util.LinkedHashSet;
 import javax.measure.Unit;
@@ -123,7 +122,7 @@ final class EPSGFactoryFallback extends GeodeticAuthorityFactory
      */
     @Override
     public Set<String> getCodeSpaces() {
-        return Collections.singleton(Constants.EPSG);
+        return Set.of(Constants.EPSG);
     }
 
     /**
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java
index 2bfeba2f4a..f6a5846ff1 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java
@@ -20,7 +20,6 @@ import java.util.Map;
 import java.util.List;
 import java.util.Arrays;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import javax.xml.bind.annotation.XmlType;
@@ -623,8 +622,8 @@ public class DefaultCompoundCRS extends AbstractCRS implements CompoundCRS {
      * to JAXB, which will assign values to the fields using reflection.
      */
     private DefaultCompoundCRS() {
-        components = Collections.emptyList();
-        singles    = Collections.emptyList();
+        components = List.of();
+        singles    = List.of();
         /*
          * At least one component CRS is mandatory for SIS working. We do not verify their presence here
          * because the verification would have to be done in an 'afterMarshal(…)' method and throwing an
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java
index 851dc82bd0..f3a3555422 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java
@@ -17,7 +17,6 @@
 package org.apache.sis.referencing.cs;
 
 import java.util.Map;
-import java.util.HashMap;
 import java.util.Locale;
 import java.util.Objects;
 import javax.measure.Unit;
@@ -143,21 +142,17 @@ public class DefaultCoordinateSystemAxis extends AbstractIdentifiedObject implem
      *
      * @see #isHeuristicMatchForName(String)
      */
-    private static final Map<String,Object> ALIASES = new HashMap<>(12);
-    static {
-        final Boolean latitude  = Boolean.TRUE;
-        final Boolean longitude = Boolean.FALSE;
-        ALIASES.put("lat",                latitude);
-        ALIASES.put("latitude",           latitude);
-        ALIASES.put("geodetic latitude",  latitude);
-        ALIASES.put("lon",                longitude);
-        ALIASES.put("long",               longitude);
-        ALIASES.put("longitude",          longitude);
-        ALIASES.put("geodetic longitude", longitude);
-        /*
-         * Do not add aliases for "x" and "y" in this map. See ALIASES_XY for more information.
-         */
-    }
+    private static final Map<String,Object> ALIASES = Map.of(
+            "lat",                Boolean.TRUE,
+            "latitude",           Boolean.TRUE,
+            "geodetic latitude",  Boolean.TRUE,
+            "lon",                Boolean.FALSE,
+            "long",               Boolean.FALSE,
+            "longitude",          Boolean.FALSE,
+            "geodetic longitude", Boolean.FALSE);
+    /*
+     * Do not add aliases for "x" and "y" in this map. See ALIASES_XY for more information.
+     */
 
     /**
      * Aliases for the "x" and "y" abbreviations (special cases). "x" and "y" are sometimes used (especially in WKT)
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryProxy.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryProxy.java
index 350109340b..6a41667ee6 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryProxy.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryProxy.java
@@ -17,7 +17,6 @@
 package org.apache.sis.referencing.factory;
 
 import java.util.Map;
-import java.util.HashMap;
 import java.util.Locale;
 import javax.measure.Unit;
 import org.opengis.referencing.cs.*;
@@ -568,23 +567,19 @@ abstract class AuthorityFactoryProxy<T> {
      *
      * <p>Keys must be in lower case.</p>
      */
-    private static final Map<String, AuthorityFactoryProxy<?>> BY_URN_TYPE;
-    static {
-        final Map<String, AuthorityFactoryProxy<?>> map = new HashMap<>(16);
-        map.put("crs",                  CRS);
-        map.put("crs-compound",         CRS);
-        map.put("datum",                DATUM);
-        map.put("ellipsoid",            ELLIPSOID);
-        map.put("meridian",             PRIME_MERIDIAN);
-        map.put("cs",                   COORDINATE_SYSTEM);
-        map.put("axis",                 AXIS);
-        map.put("coordinateoperation",  OPERATION);
-        map.put("method",               METHOD);
-        map.put("parameter",            PARAMETER);
-        map.put("referencesystem",      CRS);
-        map.put("uom",                  UNIT);
-        BY_URN_TYPE = map;
-    }
+    private static final Map<String, AuthorityFactoryProxy<?>> BY_URN_TYPE = Map.ofEntries(
+            Map.entry("crs",                  CRS),
+            Map.entry("crs-compound",         CRS),
+            Map.entry("datum",                DATUM),
+            Map.entry("ellipsoid",            ELLIPSOID),
+            Map.entry("meridian",             PRIME_MERIDIAN),
+            Map.entry("cs",                   COORDINATE_SYSTEM),
+            Map.entry("axis",                 AXIS),
+            Map.entry("coordinateoperation",  OPERATION),
+            Map.entry("method",               METHOD),
+            Map.entry("parameter",            PARAMETER),
+            Map.entry("referencesystem",      CRS),
+            Map.entry("uom",                  UNIT));
 
     /**
      * Returns the instance for the given type. The {@code type} argument can be a GeoAPI interface
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
index 7d78cbb3ad..80569e125f 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
@@ -17,7 +17,6 @@
 package org.apache.sis.referencing.factory;
 
 import java.util.Set;
-import java.util.Collections;
 import javax.measure.Unit;
 import org.opengis.referencing.*;
 import org.opengis.referencing.cs.*;
@@ -139,7 +138,7 @@ public abstract class GeodeticAuthorityFactory extends AbstractFactory implement
      */
     public Set<String> getCodeSpaces() {
         final String authority = Citations.toCodeSpace(getAuthority());
-        return (authority != null) ? Collections.singleton(authority) : Collections.emptySet();
+        return (authority != null) ? Set.of(authority) : Set.of();
     }
 
     /**
@@ -1226,7 +1225,7 @@ public abstract class GeodeticAuthorityFactory extends AbstractFactory implement
     public Set<CoordinateOperation> createFromCoordinateReferenceSystemCodes(String sourceCRS, String targetCRS)
             throws NoSuchAuthorityCodeException, FactoryException
     {
-        return Collections.emptySet();
+        return Set.of();
     }
 
     /**
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java
index 4bdedb862d..424d16bae7 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java
@@ -17,7 +17,6 @@
 package org.apache.sis.referencing.factory;
 
 import java.util.Set;
-import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
@@ -339,7 +338,7 @@ public class IdentifiedObjectFinder {
                         candidate = createFromNames(object);
                     }
                     if (candidate != null) {
-                        result = Collections.singleton(candidate);
+                        result = Set.of(candidate);
                     }
                 }
                 /*
@@ -348,7 +347,7 @@ public class IdentifiedObjectFinder {
                  */
                 if (result == null) {
                     if (domain == Domain.DECLARATION) {
-                        result = Collections.emptySet();
+                        result = Set.of();
                     } else {
                         result = createFromCodes(object);
                     }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
index 73ebd52965..21ff855420 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
@@ -520,7 +520,7 @@ public class MultiAuthoritiesFactory extends GeodeticAuthorityFactory implements
             return ((GeodeticAuthorityFactory) factory).getCodeSpaces();
         } else {
             final String authority = Citations.toCodeSpace(factory.getAuthority());
-            return (authority != null) ? Collections.singleton(authority) : Collections.emptySet();
+            return (authority != null) ? Set.of(authority) : Set.of();
         }
     }
 
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGCodeFinder.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGCodeFinder.java
index d72294b1e1..b2eebd81bd 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGCodeFinder.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGCodeFinder.java
@@ -18,7 +18,6 @@ package org.apache.sis.referencing.factory.sql;
 
 import java.util.Set;
 import java.util.List;
-import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.sql.Statement;
 import java.sql.ResultSet;
@@ -172,7 +171,7 @@ final class EPSGCodeFinder extends IdentifiedObjectFinder {
      */
     private static class Condition {
         /** A sentinel value for filtering by name. */
-        static final Condition NAME = new Condition("NAME", Collections.emptySet());
+        static final Condition NAME = new Condition("NAME", Set.of());
 
         /** The column on which the condition apply. */
         final String column;
@@ -239,7 +238,7 @@ final class EPSGCodeFinder extends IdentifiedObjectFinder {
     private static final class FloatCondition extends Condition {
         /** Creates a new condition for the given value. */
         FloatCondition(final String column, final double value) {
-            super(column, Collections.singleton(value));
+            super(column, Set.of(value));
         }
 
         /**
@@ -305,7 +304,7 @@ crs:    if (isInstance(CoordinateReferenceSystem.class, object)) {
                             if ((filters[i] = dependencies((i==0) ? "CMPD_HORIZCRS_CODE" : "CMPD_VERTCRS_CODE",
                                     CoordinateReferenceSystem.class, components.get(i), false)) == null)
                             {
-                                return Collections.emptySet();
+                                return Set.of();
                             }
                         }
                         break crs;
@@ -336,10 +335,10 @@ crs:    if (isInstance(CoordinateReferenceSystem.class, object)) {
             } else if (object instanceof SingleCRS) {
                 filter = dependencies("DATUM_CODE", Datum.class, ((SingleCRS) object).getDatum(), true);
             } else {
-                return Collections.emptySet();
+                return Set.of();
             }
             if (filter == null) {
-                return Collections.emptySet();
+                return Set.of();
             }
             filters = new Condition[] {filter};
         } else if (isInstance(Datum.class, object)) {
@@ -359,13 +358,13 @@ crs:    if (isInstance(CoordinateReferenceSystem.class, object)) {
                     Condition.NAME
                 };
                 if (filters[0] == null) {
-                    return Collections.emptySet();
+                    return Set.of();
                 }
             } else {
                 if (isInstance(VerticalDatum.class, object)) {
                     final VerticalDatumType type = ((VerticalDatum) object).getVerticalDatumType();
                     if (type != null && !type.equals(EPSGDataAccess.VERTICAL_DATUM_TYPE)) {
-                        return Collections.emptySet();
+                        return Set.of();
                     }
                 }
                 filters = new Condition[] {
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
index f75879798e..0730a71e19 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
@@ -24,7 +24,6 @@ import java.util.HashMap;
 import java.util.LinkedHashSet;
 import java.util.LinkedHashMap;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.Calendar;
 import java.util.Date;
@@ -563,7 +562,7 @@ addURIs:    for (int i=0; ; i++) {
                 return existing;
             }
         }
-        Map<String,String> result = Collections.emptyMap();
+        Map<String,String> result = Map.of();
         for (final TableInfo table : TableInfo.EPSG) {
             /*
              * We test `isAssignableFrom` in the two ways for catching the following use cases:
@@ -627,7 +626,7 @@ addURIs:    for (int i=0; ; i++) {
      */
     @Override
     public Set<String> getCodeSpaces() {
-        return Collections.emptySet();
+        return Set.of();
     }
 
     /**
@@ -2554,7 +2553,7 @@ codes:  for (int i=0; i<codes.length; i++) {
                 final Set<Unit<?>> units;
                 if (epsg != null && Arrays.binarySearch(EPSG_CODE_PARAMETERS, epsg) >= 0) {
                     type  = Integer.class;
-                    units = Collections.emptySet();
+                    units = Set.of();
                 } else {
                     /*
                      * If the parameter appears to have at least one non-null value in the "Parameter File Name" column,
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
index 3140648a46..f69e253222 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
@@ -16,7 +16,6 @@
  */
 package org.apache.sis.referencing.factory.sql;
 
-import java.util.Collections;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
@@ -254,7 +253,7 @@ public class EPSGFactory extends ConcurrentAuthorityFactory<EPSGDataAccess> impl
     public EPSGFactory(Map<String,?> properties) throws FactoryException {
         super(EPSGDataAccess.class);
         if (properties == null) {
-            properties = Collections.emptyMap();
+            properties = Map.of();
         }
         DataSource ds  = (DataSource)                 properties.get("dataSource");
         Locale locale  = (Locale)                     properties.get("locale");
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java
index 3dc678ea79..516152c8db 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java
@@ -18,7 +18,6 @@ package org.apache.sis.referencing.factory.sql;
 
 import java.util.Set;
 import java.util.Locale;
-import java.util.Collections;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
 import java.sql.Connection;
@@ -362,7 +361,7 @@ public abstract class InstallationScriptProvider extends InstallationResources {
          */
         @Override
         public Set<String> getAuthorities() {
-            return (directory != null) ? super.getAuthorities() : Collections.emptySet();
+            return (directory != null) ? super.getAuthorities() : Set.of();
         }
 
         /**
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
index 0d74e6ece8..48e30c93de 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
@@ -20,7 +20,6 @@ import java.util.Map;
 import java.util.Set;
 import java.util.Objects;
 import java.util.Collection;
-import java.util.Collections;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import javax.xml.bind.Unmarshaller;
@@ -256,7 +255,7 @@ public class AbstractCoordinateOperation extends AbstractIdentifiedObject implem
             if (value instanceof PositionalAccuracy[]) {
                 coordinateOperationAccuracy = CollectionsExt.nonEmptySet((PositionalAccuracy[]) value);
             } else {
-                coordinateOperationAccuracy = Collections.singleton((PositionalAccuracy) value);
+                coordinateOperationAccuracy = Set.of((PositionalAccuracy) value);
             }
         }
     }
@@ -407,7 +406,7 @@ check:      for (int isTarget=0; ; isTarget++) {        // 0 == source check; 1
         if (sourceCRS != null && targetCRS != null) {
             wrapAroundChanges = CoordinateOperations.wrapAroundChanges(sourceCRS, targetCRS.getCoordinateSystem());
         } else {
-            wrapAroundChanges = Collections.emptySet();
+            wrapAroundChanges = Set.of();
         }
     }
 
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java
index a63547a52a..842f1bbdab 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java
@@ -19,7 +19,6 @@ package org.apache.sis.referencing.operation;
 import java.util.Map;
 import java.util.List;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Objects;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlElement;
@@ -412,7 +411,7 @@ final class DefaultConcatenatedOperation extends AbstractCoordinateOperation imp
      * reserved to JAXB, which will assign values to the fields using reflection.
      */
     private DefaultConcatenatedOperation() {
-        operations = Collections.emptyList();
+        operations = List.of();
     }
 
     /**
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
index b10e461634..54b7530121 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
@@ -18,7 +18,6 @@ package org.apache.sis.referencing.operation.transform;
 
 import java.util.Map;
 import java.util.List;
-import java.util.Collections;
 import java.util.Optional;
 import java.awt.geom.AffineTransform;
 import org.opengis.util.FactoryException;
@@ -590,10 +589,10 @@ public final class MathTransforms extends Static {
             if (transform instanceof ConcatenatedTransform) {
                 return ((ConcatenatedTransform) transform).getSteps();
             } else {
-                return Collections.singletonList(transform);
+                return List.of(transform);
             }
         } else {
-            return Collections.emptyList();
+            return List.of();
         }
     }
 
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform.java
index 8e4f5ed9a3..cd6dac5eba 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform.java
@@ -20,7 +20,6 @@ import java.util.Map;
 import java.util.List;
 import java.util.Arrays;
 import java.util.Objects;
-import java.util.Collections;
 import java.io.Serializable;
 import org.opengis.geometry.Envelope;
 import org.opengis.geometry.DirectPosition;
@@ -163,7 +162,7 @@ class SpecializableTransform extends AbstractMathTransform implements Serializab
              * SpecializableTransforms we will store directly the specializations that it contains. It will
              * reduce the amountof steps when transforming coordinates.
              */
-            List<SubArea> inherited = Collections.emptyList();
+            List<SubArea> inherited = List.of();
             if (tr instanceof SpecializableTransform) {
                 inherited = ((SpecializableTransform) tr).roots();
                 tr        = ((SpecializableTransform) tr).global;
@@ -197,9 +196,9 @@ class SpecializableTransform extends AbstractMathTransform implements Serializab
     @SuppressWarnings("unchecked")
     private List<SubArea> roots() {
         if (domains == null) {
-            return Collections.emptyList();
+            return List.of();
         } else if (domains instanceof SubArea) {
-            return Collections.singletonList((SubArea) domains);
+            return List.of((SubArea) domains);
         } else {
             /*
              * We are cheating here since we have a `List<RTreeNode>`. But this `SpecializableTransform`
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java b/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
index 48b75d4046..7c7348c0ca 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.sis.io.wkt;
 
-import java.util.Collections;
+import java.util.Map;
 import java.util.Date;
 import java.util.Iterator;
 import java.util.Locale;
@@ -84,7 +84,7 @@ public final strictfp class GeodeticObjectParserTest extends TestCase {
      * Instantiates the parser to test.
      */
     private void newParser(final Convention convention) {
-        parser = new GeodeticObjectParser(Symbols.getDefault(), Collections.emptyMap(),
+        parser = new GeodeticObjectParser(Symbols.getDefault(), Map.of(),
                 null, null, null, convention, Transliterator.DEFAULT, null, new ReferencingFactoryContainer());
         assertEquals(GeodeticObjectFactory.class.getCanonicalName(), parser.getPublicFacade());
     }
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java b/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java
index 45dbe11c7e..ba119e1404 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java
@@ -21,7 +21,6 @@ import java.util.Map;
 import java.util.HashMap;
 import java.util.LinkedHashSet;
 import java.util.Locale;
-import java.util.Collections;
 import org.opengis.test.Validators;
 import org.opengis.metadata.Identifier;
 import org.apache.sis.referencing.datum.AbstractDatum;
@@ -133,7 +132,7 @@ public final strictfp class AbstractIdentifiedObjectTest extends TestCase {
      */
     @Test
     public void testWithoutIdentifier() {
-        final Set<Identifier>          identifiers = Collections.emptySet();
+        final Set<Identifier>          identifiers = Set.of();
         final AbstractIdentifiedObject object      = new AbstractIdentifiedObject(properties(identifiers));
         final Identifier               gmlId       = validate(object, identifiers, "GRS1980");
         assertNull("gmlId", gmlId);
@@ -234,7 +233,7 @@ public final strictfp class AbstractIdentifiedObjectTest extends TestCase {
     @Test
     @DependsOnMethod("testWithoutIdentifier")
     public void testSerialization() {
-        final Set<Identifier>     identifiers = Collections.emptySet();
+        final Set<Identifier>     identifiers = Set.of();
         final AbstractIdentifiedObject object = new AbstractIdentifiedObject(properties(identifiers));
         final AbstractIdentifiedObject actual = assertSerializedEquals(object);
         assertNotSame(object, actual);
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformFactoryBase.java b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformFactoryBase.java
index 37373fa898..a296ca2c34 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformFactoryBase.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformFactoryBase.java
@@ -17,7 +17,6 @@
 package org.apache.sis.referencing.operation.transform;
 
 import java.util.Set;
-import java.util.Collections;
 import org.opengis.util.FactoryException;
 import org.opengis.util.NoSuchIdentifierException;
 import org.opengis.metadata.citation.Citation;
@@ -64,7 +63,7 @@ strictfp class MathTransformFactoryBase implements MathTransformFactory {
     /** Default implementation returns an empty set. */
     @Override
     public Set<OperationMethod> getAvailableMethods(Class<? extends SingleOperation> type) {
-        return Collections.emptySet();
+        return Set.of();
     }
 
     /** Default implementation unconditionally returns {@code null}. */
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateOperationMethods.java b/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateOperationMethods.java
index 22313e785d..fb1a6b87c2 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateOperationMethods.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateOperationMethods.java
@@ -154,7 +154,7 @@ public strictfp class CoordinateOperationMethods extends HTMLGenerator {
      */
     public CoordinateOperationMethods() throws IOException {
         super("CoordinateOperationMethods.html", "Apache SIS Coordinate Operation Methods", "authority-codes.css");
-        domainOfValidity = Collections.emptyMap();      // TODO: not yet available.
+        domainOfValidity = Map.of();                // TODO: not yet available.
         rangeFormat = new RangeFormat(LOCALE);
         final int header = openTag("header");
         println("h1", "Apache SIS™ Coordinate Operation Methods");
diff --git a/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java b/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java
index 3d10f29c15..5129f2865e 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java
@@ -584,9 +584,11 @@ public final class DefinitionURI {
             if (path == null) {
                 return null;
             }
-            // TODO: For now do nothing since PATHS is a singleton. However if a future SIS version
-            //       defines more PATHS entries, then we should replace here the `paths` reference by
-            //       a new Collections.singletonMap containing only the entry of interest.
+            /*
+             * TODO: For now do nothing because PATHS is a singleton. However if a future SIS version
+             *       defines more PATHS entries, then we should replace here the `paths` reference by
+             *       a new `Map.of(…)` containing only the entry of interest.
+             */
         }
         for (final Map.Entry<String,String> entry : paths.entrySet()) {
             final String path = entry.getValue();
diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractConverter.java b/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractConverter.java
index db684090e6..bffbb99d93 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractConverter.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractConverter.java
@@ -17,7 +17,6 @@
 package org.apache.sis.measure;
 
 import java.util.List;
-import java.util.Collections;
 import java.io.Serializable;
 import javax.measure.UnitConverter;
 import org.apache.sis.util.ArgumentChecks;
@@ -155,6 +154,6 @@ abstract class AbstractConverter implements UnitConverter, Serializable {
      */
     @Override
     public List<UnitConverter> getConversionSteps() {
-        return Collections.singletonList(this);
+        return List.of(this);
     }
 }
diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitDimension.java b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitDimension.java
index 916501ccbe..6f15d876d7 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitDimension.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitDimension.java
@@ -16,7 +16,7 @@
  */
 package org.apache.sis.measure;
 
-import java.util.Collections;
+import java.util.Set;
 import java.util.Map;
 import java.util.LinkedHashMap;
 import java.io.Serializable;
@@ -68,7 +68,7 @@ final class UnitDimension implements Dimension, Serializable {
     /**
      * Pseudo-dimension for dimensionless units.
      */
-    static final UnitDimension NONE = new UnitDimension(Collections.emptyMap());
+    static final UnitDimension NONE = new UnitDimension(Map.of());
     // No need to store in UnitRegistry since UnitDimension performs special checks for dimensionless instances.
 
     /**
@@ -78,6 +78,7 @@ final class UnitDimension implements Dimension, Serializable {
      *
      * @see #getBaseDimensions()
      */
+    @SuppressWarnings("serial")         // Not statically typed as Serializable.
     final Map<UnitDimension,Fraction> components;
 
     /**
@@ -197,7 +198,7 @@ final class UnitDimension implements Dimension, Serializable {
      */
     final boolean numeratorIs(final char s) {
         if (symbol == s) {                                  // Optimization for a simple case.
-            assert components.keySet().equals(Collections.singleton(this));
+            assert components.keySet().equals(Set.of(this));
             return true;
         }
         boolean found = false;
diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java
index 29715f77c8..d393c4bdec 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java
@@ -268,6 +268,7 @@ public class UnitFormat extends Format implements javax.measure.format.UnitForma
      *
      * @see #label(Unit, String)
      */
+    @SuppressWarnings("serial")         // Not statically typed as Serializable.
     private final Map<Unit<?>,String> unitToLabel;
 
     /**
@@ -278,6 +279,7 @@ public class UnitFormat extends Format implements javax.measure.format.UnitForma
      *
      * @see #label(Unit, String)
      */
+    @SuppressWarnings("serial")         // Not statically typed as Serializable.
     private final Map<String,Unit<?>> labelToUnit;
 
     /**
@@ -311,8 +313,8 @@ public class UnitFormat extends Format implements javax.measure.format.UnitForma
     private UnitFormat() {
         locale      = Locale.ROOT;
         style       = Style.SYMBOL;
-        unitToLabel = Collections.emptyMap();
-        labelToUnit = Collections.emptyMap();
+        unitToLabel = Map.of();
+        labelToUnit = Map.of();
     }
 
     /**
@@ -1634,7 +1636,7 @@ search:     while ((i = CharSequences.skipTrailingWhitespaces(symbols, start, i)
 
     /**
      * Clones the given map, which can be either a {@link HashMap}
-     * or the instance returned by {@link Collections#emptyMap()}.
+     * or the instance returned by {@link Map#of()}.
      */
     private static Object clone(final Map<?,?> value) {
         if (value instanceof HashMap<?,?>) {
diff --git a/core/sis-utility/src/main/java/org/apache/sis/setup/OptionalInstallations.java b/core/sis-utility/src/main/java/org/apache/sis/setup/OptionalInstallations.java
index 03b8b0f4cc..13cd4f8697 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/setup/OptionalInstallations.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/setup/OptionalInstallations.java
@@ -17,7 +17,6 @@
 package org.apache.sis.setup;
 
 import java.util.Set;
-import java.util.Collections;
 import java.util.Locale;
 import java.util.ServiceLoader;
 import java.net.URL;
@@ -142,7 +141,7 @@ public abstract class OptionalInstallations extends InstallationResources implem
      */
     @Override
     public Set<String> getAuthorities() {
-        return (destinationDirectory != null) ? Collections.singleton(EPSG) : Collections.emptySet();
+        return (destinationDirectory != null) ? Set.of(EPSG) : Set.of();
     }
 
     /**
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Loader.java b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Loader.java
index 3de24688f2..9c4cde15bb 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Loader.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Loader.java
@@ -19,7 +19,6 @@ package org.apache.sis.util.resources;
 import java.net.URL;
 import java.util.List;
 import java.util.Locale;
-import java.util.Collections;
 import java.util.ResourceBundle;
 import java.lang.reflect.InvocationTargetException;
 import java.io.IOException;
@@ -43,7 +42,7 @@ final class Loader extends ResourceBundle.Control {
     /**
      * The formats supported by this loader.
      */
-    private static final List<String> FORMATS = Collections.singletonList("apache-sis." + EXTENSION);
+    private static final List<String> FORMATS = List.of("apache-sis." + EXTENSION);
 
     /**
      * The singleton instance of the {@link Loader} class.
diff --git a/profiles/sis-french-profile/src/test/java/org/apache/sis/internal/profile/fra/DirectReferenceSystemTest.java b/profiles/sis-french-profile/src/test/java/org/apache/sis/internal/profile/fra/DirectReferenceSystemTest.java
index ff6f4f2603..23caa43ca7 100644
--- a/profiles/sis-french-profile/src/test/java/org/apache/sis/internal/profile/fra/DirectReferenceSystemTest.java
+++ b/profiles/sis-french-profile/src/test/java/org/apache/sis/internal/profile/fra/DirectReferenceSystemTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.internal.profile.fra;
 
+import java.util.Set;
 import java.util.Collection;
 import javax.xml.bind.JAXBException;
 import org.opengis.metadata.citation.Responsibility;
@@ -29,7 +30,6 @@ import org.apache.sis.test.TestUtilities;
 import org.apache.sis.test.xml.TestCase;
 import org.junit.Test;
 
-import static java.util.Collections.singleton;
 import static org.apache.sis.test.Assert.*;
 
 
@@ -60,11 +60,11 @@ public final strictfp class DirectReferenceSystemTest extends TestCase {
         final DefaultCitation citation = new DefaultCitation("EPSG Geodetic Parameter Dataset");
         Collection<Responsibility> r = HardCodedCitations.EPSG.getCitedResponsibleParties();
         if (legacy) {
-            r = singleton(new DefaultResponsibleParty(TestUtilities.getSingleton(r)));
+            r = Set.of(new DefaultResponsibleParty(TestUtilities.getSingleton(r)));
         }
         citation.setCitedResponsibleParties(r);
         final DirectReferenceSystem refSys = new DirectReferenceSystem(new DefaultIdentifier(citation, "4326"));
-        metadata.setReferenceSystemInfo(singleton(refSys));
+        metadata.setReferenceSystemInfo(Set.of(refSys));
         return metadata;
     }
 
diff --git a/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_C.java b/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_C.java
index d2a82037c3..2d31d1553c 100644
--- a/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_C.java
+++ b/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_C.java
@@ -20,7 +20,6 @@ import java.util.Objects;
 import java.util.Set;
 import java.util.Map;
 import java.util.HashMap;
-import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.regex.Pattern;
 import java.util.function.Function;
@@ -147,23 +146,19 @@ public final class GCOM_C extends Convention {
      * the corner minimal and maximal coordinates is not guaranteed to encompass the whole data,
      * and may even contain no data at all.
      */
-    private static final Map<String,String> ATTRIBUTES;
-    static {
-        final Map<String,String> m = new HashMap<>(16);
-        m.put(AttributeNames.TITLE,               "Product_name");             // identification­Info / citation / title
-        m.put(AttributeNames.PRODUCT_VERSION,     "Product_version");          // identification­Info / citation / edition
-        m.put(AttributeNames.IDENTIFIER.TEXT,     "Product_file_name");        // identification­Info / citation / identifier / code
-        m.put(AttributeNames.DATE_CREATED,        "Processing_UT");            // identification­Info / citation / date
-        m.put(AttributeNames.CREATOR.INSTITUTION, "Processing_organization");  // identification­Info / citation / citedResponsibleParty
-        m.put(AttributeNames.SUMMARY,             "Dataset_description");      // identification­Info / abstract
-        m.put(AttributeNames.PLATFORM.TEXT,       "Satellite");                // acquisition­Information / platform / identifier
-        m.put(AttributeNames.INSTRUMENT.TEXT,     "Sensor");                   // acquisition­Information / platform / instrument / identifier
-        m.put(AttributeNames.PROCESSING_LEVEL,    "Product_level");            // content­Info / processing­Level­Code
-        m.put(AttributeNames.SOURCE,              "Input_files");              // data­Quality­Info / lineage / source / description
-        m.put(AttributeNames.TIME.MINIMUM,        "Scene_start_time");         // identification­Info / extent / temporal­Element / extent
-        m.put(AttributeNames.TIME.MAXIMUM,        "Scene_end_time");           // identification­Info / extent / temporal­Element / extent
-        ATTRIBUTES = m;
-    }
+    private static final Map<String,String> ATTRIBUTES = Map.ofEntries(
+        Map.entry(AttributeNames.TITLE,               "Product_name"),              // identification­Info / citation / title
+        Map.entry(AttributeNames.PRODUCT_VERSION,     "Product_version"),           // identification­Info / citation / edition
+        Map.entry(AttributeNames.IDENTIFIER.TEXT,     "Product_file_name"),         // identification­Info / citation / identifier / code
+        Map.entry(AttributeNames.DATE_CREATED,        "Processing_UT"),             // identification­Info / citation / date
+        Map.entry(AttributeNames.CREATOR.INSTITUTION, "Processing_organization"),   // identification­Info / citation / citedResponsibleParty
+        Map.entry(AttributeNames.SUMMARY,             "Dataset_description"),       // identification­Info / abstract
+        Map.entry(AttributeNames.PLATFORM.TEXT,       "Satellite"),                 // acquisition­Information / platform / identifier
+        Map.entry(AttributeNames.INSTRUMENT.TEXT,     "Sensor"),                    // acquisition­Information / platform / instrument / identifier
+        Map.entry(AttributeNames.PROCESSING_LEVEL,    "Product_level"),             // content­Info / processing­Level­Code
+        Map.entry(AttributeNames.SOURCE,              "Input_files"),               // data­Quality­Info / lineage / source / description
+        Map.entry(AttributeNames.TIME.MINIMUM,        "Scene_start_time"),          // identification­Info / extent / temporal­Element / extent
+        Map.entry(AttributeNames.TIME.MAXIMUM,        "Scene_end_time"));           // identification­Info / extent / temporal­Element / extent
 
     /**
      * Name of the group defining map projection parameters, localization grid, <i>etc</i>.
@@ -343,7 +338,7 @@ public final class GCOM_C extends Convention {
      */
     @Override
     public Set<Linearizer> linearizers(final Decoder decoder) {
-        return Collections.singleton(new Linearizer(CommonCRS.WGS84, Linearizer.Type.UNIVERSAL));
+        return Set.of(new Linearizer(CommonCRS.WGS84, Linearizer.Type.UNIVERSAL));
     }
 
     /**
diff --git a/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_W.java b/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_W.java
index f44919f817..90e0cd85b6 100644
--- a/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_W.java
+++ b/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_W.java
@@ -18,8 +18,6 @@ package org.apache.sis.internal.earth.netcdf;
 
 import java.util.Set;
 import java.util.Map;
-import java.util.HashMap;
-import java.util.Collections;
 import java.util.regex.Pattern;
 import javax.measure.Unit;
 import javax.measure.format.ParserException;
@@ -92,22 +90,18 @@ public final class GCOM_W extends Convention {
     /**
      * Mapping from ACDD or CF-Convention attribute names to names of attributes used by GCOM-W.
      */
-    private static final Map<String,String> ATTRIBUTES;
-    static {
-        final Map<String,String> m = new HashMap<>();
-        m.put(AttributeNames.TITLE,               "ProductName");              // identification­Info / citation / title
-        m.put(AttributeNames.PRODUCT_VERSION,     "ProductVersion");           // identification­Info / citation / edition
-        m.put(AttributeNames.IDENTIFIER.TEXT,     "GranuleID");                // identification­Info / citation / identifier / code
-        m.put(AttributeNames.DATE_CREATED,        "ProductionDateTime");       // identification­Info / citation / date
-        m.put(AttributeNames.TIME.MINIMUM,        "ObservationStartDateTime"); // identification­Info / extent / temporal­Element / extent
-        m.put(AttributeNames.TIME.MAXIMUM,        "ObservationEndDateTime");   // identification­Info / extent / temporal­Element / extent
-        m.put(AttributeNames.CREATOR.INSTITUTION, "ProcessingCenter");         // identification­Info / citation / citedResponsibleParty
-        m.put(AttributeNames.SUMMARY,             "GeophysicalName");          // identification­Info / abstract
-        m.put(AttributeNames.PLATFORM.TEXT,       "PlatformShortName");        // acquisition­Information / platform / identifier
-        m.put(AttributeNames.INSTRUMENT.TEXT,     "SensorShortName");          // acquisition­Information / platform / instrument / identifier
-        m.put(AttributeNames.SOURCE,              "InputFileName");            // data­Quality­Info / lineage / source / description
-        ATTRIBUTES = m;
-    }
+    private static final Map<String,String> ATTRIBUTES = Map.ofEntries(
+        Map.entry(AttributeNames.TITLE,               "ProductName"),               // identification­Info / citation / title
+        Map.entry(AttributeNames.PRODUCT_VERSION,     "ProductVersion"),            // identification­Info / citation / edition
+        Map.entry(AttributeNames.IDENTIFIER.TEXT,     "GranuleID"),                 // identification­Info / citation / identifier / code
+        Map.entry(AttributeNames.DATE_CREATED,        "ProductionDateTime"),        // identification­Info / citation / date
+        Map.entry(AttributeNames.TIME.MINIMUM,        "ObservationStartDateTime"),  // identification­Info / extent / temporal­Element / extent
+        Map.entry(AttributeNames.TIME.MAXIMUM,        "ObservationEndDateTime"),    // identification­Info / extent / temporal­Element / extent
+        Map.entry(AttributeNames.CREATOR.INSTITUTION, "ProcessingCenter"),          // identification­Info / citation / citedResponsibleParty
+        Map.entry(AttributeNames.SUMMARY,             "GeophysicalName"),           // identification­Info / abstract
+        Map.entry(AttributeNames.PLATFORM.TEXT,       "PlatformShortName"),         // acquisition­Information / platform / identifier
+        Map.entry(AttributeNames.INSTRUMENT.TEXT,     "SensorShortName"),           // acquisition­Information / platform / instrument / identifier
+        Map.entry(AttributeNames.SOURCE,              "InputFileName"));            // data­Quality­Info / lineage / source / description
 
     /**
      * Names of variables to use as axes (first word only).
@@ -203,7 +197,7 @@ public final class GCOM_W extends Convention {
      */
     @Override
     public Set<Linearizer> linearizers(final Decoder decoder) {
-        return Collections.singleton(new Linearizer(CommonCRS.WGS84, Linearizer.Type.UNIVERSAL));
+        return Set.of(new Linearizer(CommonCRS.WGS84, Linearizer.Type.UNIVERSAL));
     }
 
     /**
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Convention.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Convention.java
index 0a2bb561c6..4ebf91fd61 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Convention.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Convention.java
@@ -20,7 +20,6 @@ import java.util.Map;
 import java.util.Set;
 import java.util.HashMap;
 import java.util.Iterator;
-import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Locale;
 import java.util.function.Function;
@@ -374,7 +373,7 @@ public class Convention {
      * @see #defaultHorizontalCRS(boolean)
      */
     public Set<Linearizer> linearizers(final Decoder decoder) {
-        return Collections.emptySet();
+        return Set.of();
     }
 
     /**
@@ -395,7 +394,7 @@ public class Convention {
      */
     public Set<String> nameOfMappingNode(final Variable data) {
         final String mapping = data.getAttributeAsString(CF.GRID_MAPPING);
-        return (mapping != null) ? Collections.singleton(mapping) : Collections.emptySet();
+        return (mapping != null) ? Set.of(mapping) : Set.of();
     }
 
     /**
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java
index ab2c94e325..47098327d6 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java
@@ -273,7 +273,7 @@ public final class ChannelDecoder extends Decoder {
          */
         DimensionInfo[] dimensions = null;
         VariableInfo[]  variables  = null;
-        List<Map.Entry<String,Object>> attributes = Collections.emptyList();
+        List<Map.Entry<String,Object>> attributes = List.of();
         for (int i=0; i<3; i++) {
             final long tn = input.readLong();                   // Combination of tag and nelems
             if (tn != 0) {
@@ -299,7 +299,7 @@ public final class ChannelDecoder extends Decoder {
             this.variableMap = toCaseInsensitiveNameMap(variables);
         } else {
             this.variables   = new VariableInfo[0];
-            this.variableMap = Collections.emptyMap();
+            this.variableMap = Map.of();
         }
         initialize();
     }
@@ -617,7 +617,7 @@ public final class ChannelDecoder extends Decoder {
              * Following block is almost a copy-and-paste of similar block in the contructor,
              * but with less cases in the "switch" statements.
              */
-            List<Map.Entry<String,Object>> attributes = Collections.emptyList();
+            List<Map.Entry<String,Object>> attributes = List.of();
             final long tn = input.readLong();
             if (tn != 0) {
                 final int tag = (int) (tn >>> Integer.SIZE);
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DecoderWrapper.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DecoderWrapper.java
index e8d65d0ee5..6bbd44cd76 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DecoderWrapper.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DecoderWrapper.java
@@ -18,10 +18,10 @@ package org.apache.sis.internal.netcdf.ucar;
 
 import java.io.File;
 import java.util.Date;
+import java.util.Set;
 import java.util.List;
 import java.util.Formatter;
 import java.util.Collection;
-import java.util.Collections;
 import java.io.IOException;
 import ucar.nc2.Group;
 import ucar.nc2.Attribute;
@@ -149,7 +149,7 @@ public final class DecoderWrapper extends Decoder implements CancelTask {
          * enhancement shall NOT be enabled because it causes the use of integer types twice bigger than needed
          * (e.g. `int` instead of `short`).
          */
-        file = NetcdfDatasets.openDataset(url, Collections.singleton(NetcdfDataset.Enhance.CoordSystems), -1, this, null);
+        file = NetcdfDatasets.openDataset(url, Set.of(NetcdfDataset.Enhance.CoordSystems), -1, this, null);
         groups = new Group[1];
         initialize();
     }
@@ -493,7 +493,7 @@ public final class DecoderWrapper extends Decoder implements CancelTask {
     @SuppressWarnings({"ReturnOfCollectionOrArrayField"})
     public Grid[] getGridCandidates() throws IOException {
         if (geometries == null) {
-            List<CoordinateSystem> systems = Collections.emptyList();
+            List<CoordinateSystem> systems = List.of();
             if (file instanceof NetcdfDataset) {
                 /*
                  * We take all coordinate systems as associated to a grid. As an alternative,
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
index 42490e534a..55385907ce 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
@@ -27,7 +27,6 @@ import java.util.LinkedHashMap;
 import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.io.IOException;
 import javax.measure.Unit;
 import javax.measure.UnitConverter;
@@ -80,7 +79,6 @@ import ucar.nc2.constants.ACDD;
 import ucar.nc2.constants.CDM;
 import ucar.nc2.constants.CF;
 
-import static java.util.Collections.singleton;
 import static org.apache.sis.storage.netcdf.AttributeNames.*;
 import static org.apache.sis.internal.util.CollectionsExt.first;
 
@@ -226,7 +224,7 @@ final class MetadataReader extends MetadataBuilder {
      */
     static List<String> split(final String value) {
         if (value == null) {
-            return Collections.emptyList();
+            return List.of();
         }
         final List<String> items = new ArrayList<>();
         int start = 0;      // Index of the first character of the next item to add in the list.
@@ -401,7 +399,7 @@ split:  while ((start = CharSequences.skipLeadingWhitespaces(value, start, lengt
     private static Address createAddress(final String email) {
         if (email != null) {
             final DefaultAddress address = new DefaultAddress();
-            address.setElectronicMailAddresses(singleton(email));
+            address.setElectronicMailAddresses(Set.of(email));
             return address;
         }
         return null;
@@ -413,8 +411,8 @@ split:  while ((start = CharSequences.skipLeadingWhitespaces(value, start, lengt
     private static Contact createContact(final Address address, final OnlineResource url) {
         if (address != null || url != null) {
             final DefaultContact contact = new DefaultContact();
-            if (address != null) contact.setAddresses(singleton(address));
-            if (url     != null) contact.setOnlineResources(singleton(url));
+            if (address != null) contact.setAddresses(Set.of(address));
+            if (url     != null) contact.setOnlineResources(Set.of(url));
             return contact;
         }
         return null;
@@ -522,7 +520,7 @@ split:  while ((start = CharSequences.skipLeadingWhitespaces(value, start, lengt
                 if (individualName   != null) party = new DefaultIndividual(individualName, null, null);
                 if (organisationName != null) party = new DefaultOrganisation(organisationName, null, (Individual) party, null);
                 if (party            == null) party = isOrganisation(keys) ? new DefaultOrganisation() : new DefaultIndividual();
-                if (contact          != null) party.setContactInfo(singleton(contact));
+                if (contact          != null) party.setContactInfo(Set.of(contact));
                 responsibility = new DefaultResponsibility(role, null, party);
             }
         }
diff --git a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/PrimaryKey.java b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/PrimaryKey.java
index c722f377ae..c6c9d48989 100644
--- a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/PrimaryKey.java
+++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/PrimaryKey.java
@@ -18,7 +18,6 @@ package org.apache.sis.internal.sql.feature;
 
 import java.util.List;
 import java.util.Collection;
-import java.util.Collections;
 import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.internal.util.UnmodifiableArrayList;
 
@@ -85,7 +84,7 @@ abstract class PrimaryKey {
         /** Returns the single column composing this primary key. */
         @Override
         public List<String> getColumns() {
-            return Collections.singletonList(column);
+            return List.of(column);
         }
     }
 
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelFactory.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelFactory.java
index f7add02777..117f4035a4 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelFactory.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelFactory.java
@@ -19,7 +19,6 @@ package org.apache.sis.internal.storage.io;
 import java.util.Set;
 import java.util.EnumSet;
 import java.util.HashSet;
-import java.util.Collections;
 import java.util.Arrays;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
@@ -173,7 +172,7 @@ public abstract class ChannelFactory {
          */
         final Set<OpenOption> optionSet;
         if (options == null || options.length == 0) {
-            optionSet = Collections.singleton(StandardOpenOption.READ);
+            optionSet = Set.of(StandardOpenOption.READ);
         } else {
             optionSet = new HashSet<>(Arrays.asList(options));
             optionSet.add(StandardOpenOption.READ);
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureNaming.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureNaming.java
index 5c3a0f8f0d..168121aedf 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureNaming.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureNaming.java
@@ -215,7 +215,7 @@ public class FeatureNaming<E> {
                 /*
                  * If there is more than one GenericName for the same alias, we have an ambiguity.
                  * Remove any value associated to that alias, unless the value was associated to
-                 * exactly the user-specified name (not an alias). The 'get' method in this class
+                 * exactly the user-specified name (not an alias). The `get` method in this class
                  * will know when the value is missing because of ambiguous name.
                  */
                 if (!fullNames.contains(alias)) {
@@ -223,7 +223,7 @@ public class FeatureNaming<E> {
                 }
             } else if (values.putIfAbsent(alias, value) != null) {
                 /*
-                 * If a value already existed for that alias but the alias was not declared in the 'aliases' map,
+                 * If a value already existed for that alias but the alias was not declared in the `aliases` map,
                  * this means that the list was implicitly Collections.singletonList(key). Since we now have an
                  * additional value, we need to add explicitly the previously implicit value.
                  */
@@ -269,7 +269,7 @@ public class FeatureNaming<E> {
             remaining = CollectionsExt.removeFromMultiValuesMap(aliases, alias, key);
             /*
              * The list of remaining GenericNames may be empty but should never be null unless the tail
-             * is inconsistent with the one found by the 'add(…) method.  Otherwise if there is exactly
+             * is inconsistent with the one found by the `add(…)` method. Otherwise if there is exactly
              * one remaining GenericName, then the alias is not ambiguous anymore for that name.
              */
             error |= (remaining == null);
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/GridCoverageResource.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/GridCoverageResource.java
index 58d7dffccb..049ac5df22 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/GridCoverageResource.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/GridCoverageResource.java
@@ -17,7 +17,6 @@
 package org.apache.sis.storage;
 
 import java.util.List;
-import java.util.Collections;
 import org.apache.sis.coverage.SampleDimension;
 import org.apache.sis.coverage.grid.GridGeometry;
 import org.apache.sis.coverage.grid.GridCoverage;
@@ -136,10 +135,10 @@ public interface GridCoverageResource extends DataSet {
         if (gg != null && gg.isDefined(GridGeometry.RESOLUTION)) {      // Should never be null but we are paranoiac.
             final double[] resolution = gg.getResolution(false);
             if (!ArraysExt.allEquals(resolution, Double.NaN)) {
-                return Collections.singletonList(resolution);
+                return List.of(resolution);
             }
         }
-        return Collections.emptyList();
+        return List.of();
     }
 
     /**
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java
index c5619f6e55..b5c6ea837d 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java
@@ -18,7 +18,6 @@ package org.apache.sis.storage;
 
 import java.util.Map;
 import java.util.Iterator;
-import java.util.Collections;
 import java.util.IdentityHashMap;
 import java.io.Reader;
 import java.io.DataInput;
@@ -222,6 +221,7 @@ public class StorageConnector implements Serializable {
      *
      * @see #getStorage()
      */
+    @SuppressWarnings("serial")         // Not statically typed as Serializable.
     final Object storage;
 
     /**
@@ -242,6 +242,7 @@ public class StorageConnector implements Serializable {
      * @see #getOption(OptionKey)
      * @see #setOption(OptionKey, Object)
      */
+    @SuppressWarnings("serial")         // Not statically typed as Serializable.
     private Map<OptionKey<?>, Object> options;
 
     /**
@@ -1517,7 +1518,7 @@ public class StorageConnector implements Serializable {
      */
     public void closeAllExcept(final Object view) throws DataStoreException {
         if (views == null) {
-            views = Collections.emptyMap();         // For blocking future usage of this StorageConnector instance.
+            views = Map.of();               // For blocking future usage of this StorageConnector instance.
             if (storage != view && storage instanceof AutoCloseable) try {
                 ((AutoCloseable) storage).close();
             } catch (DataStoreException e) {
@@ -1586,7 +1587,7 @@ public class StorageConnector implements Serializable {
                 }
             }
         }
-        views = Collections.emptyMap();         // For blocking future usage of this StorageConnector instance.
+        views = Map.of();                   // For blocking future usage of this StorageConnector instance.
         /*
          * Now close all remaining items. Typically (but not necessarily) there is only one remaining item.
          * If an exception occurs, we will propagate it only after we are done closing all items.
diff --git a/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/MetadataBuilderTest.java b/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/MetadataBuilderTest.java
index 24dfdf538f..879678970c 100644
--- a/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/MetadataBuilderTest.java
+++ b/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/MetadataBuilderTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.sis.internal.storage;
 
-import java.util.Collections;
+import java.util.Map;
 import org.opengis.util.GenericName;
 import org.opengis.metadata.citation.Citation;
 import org.opengis.metadata.content.ContentInformation;
@@ -138,9 +138,8 @@ public final strictfp class MetadataBuilderTest extends TestCase {
      * @param valueToInsert  the value to send to the metadata builder.
      */
     private static void verifyFeatureInstanceCount(final String errorMessage, final Integer expected, final long valueToInsert) {
-        final DefaultFeatureType dataType = new DefaultFeatureType(
-                Collections.singletonMap(DefaultFeatureType.NAME_KEY, "Test type"), false, null);
-        final MetadataBuilder builder = new MetadataBuilder();
+        final var dataType = new DefaultFeatureType(Map.of(DefaultFeatureType.NAME_KEY, "Test type"), false, null);
+        final var builder  = new MetadataBuilder();
         final GenericName name = builder.addFeatureType(dataType, valueToInsert);
         assertNotNull(name);
 
diff --git a/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java b/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java
index 2387c93a91..421e59a612 100644
--- a/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java
+++ b/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java
@@ -35,7 +35,6 @@ import com.esri.core.geometry.Point2D;
 import com.esri.core.geometry.Polyline;
 
 import static org.junit.Assert.*;
-import static java.util.Collections.singletonList;
 import static org.apache.sis.test.TestUtilities.date;
 import static org.apache.sis.test.TestUtilities.getSingleton;
 
@@ -154,9 +153,9 @@ public final strictfp class StoreTest extends TestCase {
             verifyFeatureType(store.featureType, Polyline.class, Integer.MAX_VALUE);
             assertEquals("foliation", Foliation.TIME, store.foliation);
             final Iterator<Feature> it = store.features(false).iterator();
-            assertPropertyEquals(it.next(), "a", "12:33:51", "12:36:51", new double[] {11, 2, 12, 3, 10, 3}, singletonList("walking"), List.of(1, 2));
-            assertPropertyEquals(it.next(), "b", "12:33:51", "12:36:51", new double[] {10, 2, 11, 3},        singletonList("walking"), List.of(2));
-            assertPropertyEquals(it.next(), "c", "12:33:51", "12:36:51", new double[] {12, 1, 10, 2, 11, 3}, singletonList("vehicle"), List.of(1));
+            assertPropertyEquals(it.next(), "a", "12:33:51", "12:36:51", new double[] {11, 2, 12, 3, 10, 3}, List.of("walking"), List.of(1, 2));
+            assertPropertyEquals(it.next(), "b", "12:33:51", "12:36:51", new double[] {10, 2, 11, 3},        List.of("walking"), List.of(2));
+            assertPropertyEquals(it.next(), "c", "12:33:51", "12:36:51", new double[] {12, 1, 10, 2, 11, 3}, List.of("vehicle"), List.of(1));
             assertFalse(it.hasNext());
         }
     }
diff --git a/storage/sis-storage/src/test/java/org/apache/sis/storage/GridResourceMock.java b/storage/sis-storage/src/test/java/org/apache/sis/storage/GridResourceMock.java
index d4fd7e8217..a27ef845b7 100644
--- a/storage/sis-storage/src/test/java/org/apache/sis/storage/GridResourceMock.java
+++ b/storage/sis-storage/src/test/java/org/apache/sis/storage/GridResourceMock.java
@@ -17,7 +17,6 @@
 package org.apache.sis.storage;
 
 import java.util.List;
-import java.util.Collections;
 import java.awt.image.BufferedImage;
 import org.apache.sis.coverage.SampleDimension;
 import org.apache.sis.coverage.grid.GridCoverage;
@@ -58,7 +57,7 @@ final strictfp class GridResourceMock extends AbstractGridCoverageResource {
         super(null, false);
         assertNotNull(gridGeometry);
         this.gridGeometry     = gridGeometry;
-        this.sampleDimensions = Collections.singletonList(new SampleDimension.Builder().setName(0).build());
+        this.sampleDimensions = List.of(new SampleDimension.Builder().setName(0).build());
     }
 
     /**


[sis] 02/02: Resolve some "TODO" which were waiting for JDK 10 or JDK 11.

Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 2c7abea573334f1494fa67aa49815e3a9927eabd
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Mon Dec 12 17:19:35 2022 +0100

    Resolve some "TODO" which were waiting for JDK 10 or JDK 11.
---
 .../apache/sis/internal/feature/j2d/Factory.java   |  4 +--
 .../sis/internal/jaxb/IdentifierMapAdapter.java    |  5 ++--
 .../org/apache/sis/xml/TransformingReader.java     |  1 -
 .../org/apache/sis/internal/util/Numerics.java     | 11 +++++--
 .../org/apache/sis/internal/util/NumericsTest.java | 35 +++++++++++++++++++++-
 .../apache/sis/internal/storage/inflater/ZIP.java  | 31 ++-----------------
 .../internal/storage/inflater/package-info.java    |  2 +-
 .../sis/internal/storage/xml/AbstractProvider.java |  2 +-
 .../storage/aggregate/AggregatedFeatureSet.java    |  2 +-
 .../sis/storage/aggregate/GroupBySample.java       |  2 +-
 10 files changed, 54 insertions(+), 41 deletions(-)

diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/j2d/Factory.java b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/j2d/Factory.java
index b8a2191ae4..0376a8b10b 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/j2d/Factory.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/j2d/Factory.java
@@ -253,7 +253,7 @@ public final class Factory extends Geometries<Shape> {
         for (final Shape geometry : shapes) {
             path.append(geometry, false);
         }
-        // path.trimToSize();       // TODO: uncomment with JDK10.
+        path.trimToSize();
         return new Wrapper(path);
     }
 
@@ -309,7 +309,7 @@ public final class Factory extends Geometries<Shape> {
                     }
                 }
             }
-            // path.trimToSize();       // TODO: uncomment with JDK10.
+            path.trimToSize();
             geometry = path;
         }
         return new Wrapper(geometry);
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapAdapter.java b/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapAdapter.java
index e8a3e81a5e..1cf8530f66 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapAdapter.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapAdapter.java
@@ -21,7 +21,6 @@ import java.util.Set;
 import java.util.List;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.Collection;
 import java.util.AbstractMap;
@@ -131,10 +130,10 @@ public class IdentifierMapAdapter extends AbstractMap<Citation,String> implement
     public final Collection<Identifier> getIdentifiers(final Class<?> type) {
         if (!type.isInstance(identifiers)) {
             if (type.isAssignableFrom(Set.class)) {
-                return new HashSet<>(identifiers);      // TODO: use Set.copyOf in JDK10.
+                return Set.copyOf(identifiers);
             }
             if (type.isAssignableFrom(List.class)) {
-                return new ArrayList<>(identifiers);    // TODO: use List.copyOf in JDK10.
+                return List.copyOf(identifiers);
             }
         }
         return identifiers;
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingReader.java b/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingReader.java
index b3e7a0383d..21dacce17d 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingReader.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingReader.java
@@ -99,7 +99,6 @@ final class TransformingReader extends Transformer implements XMLEventReader {
      * This map is initialized only once and should not be modified after that point.
      */
     private static final Map<String, Map<String,String>> NAMESPACES = load(false, FILENAME, LEGACY_NAMESPACES, 260);
-    // TODO: use Set.copyOf(…) with JDK10.
 
     /**
      * Returns the namespace for the given ISO type, or {@code null} if unknown.
diff --git a/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java b/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java
index ca272ef6ce..a16dabd699 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java
@@ -21,6 +21,7 @@ import java.util.HashMap;
 import java.text.Format;
 import java.text.DecimalFormat;
 import java.util.function.BiFunction;
+import java.math.BigInteger;
 import org.apache.sis.util.Debug;
 import org.apache.sis.util.Static;
 import org.apache.sis.util.Workaround;
@@ -39,7 +40,7 @@ import static java.lang.Math.ulp;
  * Miscellaneous utilities methods working on floating point numbers.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.3
  * @module
  */
@@ -270,7 +271,13 @@ public final class Numerics extends Static {
      * @return {@code value} × {@code multiplier} / {@code divisor} rounded toward zero.
      */
     public static long multiplyDivide(final long value, final long multiplier, final long divisor) {
-        return Math.multiplyExact(value, multiplier) / divisor;
+        try {
+            return Math.multiplyExact(value, multiplier) / divisor;
+        } catch (ArithmeticException e) {
+            // We do not have a better algorithm at this time.
+            return BigInteger.valueOf(value).multiply(BigInteger.valueOf(multiplier))
+                             .divide(BigInteger.valueOf(divisor)).longValueExact();
+        }
     }
 
     /**
diff --git a/core/sis-utility/src/test/java/org/apache/sis/internal/util/NumericsTest.java b/core/sis-utility/src/test/java/org/apache/sis/internal/util/NumericsTest.java
index db3dedbec3..21f9ce7933 100644
--- a/core/sis-utility/src/test/java/org/apache/sis/internal/util/NumericsTest.java
+++ b/core/sis-utility/src/test/java/org/apache/sis/internal/util/NumericsTest.java
@@ -17,6 +17,7 @@
 package org.apache.sis.internal.util;
 
 import java.util.Random;
+import java.math.BigInteger;
 import org.apache.sis.math.MathFunctions;
 import org.apache.sis.test.TestUtilities;
 import org.apache.sis.test.TestCase;
@@ -34,7 +35,7 @@ import static org.junit.Assert.*;
  * Tests the {@link Numerics} class.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.3
  * @module
  */
@@ -84,6 +85,38 @@ public final strictfp class NumericsTest extends TestCase {
         assertEquals(-2L, ceilDiv( -8L, 3L));
     }
 
+    /**
+     * Tests {@link Numerics#multiplyDivide(long, long, long)}.
+     * This method uses {@link BigInteger} as a reference.
+     */
+    @Test
+    public void testMultiplyDivide() {
+        final Random random = TestUtilities.createRandomNumberGenerator();
+        for (int i=0; i<10; i++) {
+            final long value      = random.nextLong();
+            final long multiplier = random.nextLong();
+            final long divisor    = random.nextLong();              // Accepted also 0.
+            final long expected;
+            try {
+                // ArithmeticException may occur because of overflow or division by 0.
+                expected = BigInteger.valueOf(value).multiply(BigInteger.valueOf(multiplier))
+                                     .divide(BigInteger.valueOf(divisor)).longValueExact();
+            } catch (ArithmeticException e) {
+                // If BigInteger fails, then `multiplyDivide(…)` shall also fail.
+                try {
+                    Numerics.multiplyDivide(value, multiplier, divisor);
+                    fail("Expected " + e);
+                } catch (ArithmeticException ex) {
+                    // Expected exception.
+                    continue;
+                }
+                throw e;
+            }
+            final long actual = Numerics.multiplyDivide(value, multiplier, divisor);
+            assertEquals(expected, actual);
+        }
+    }
+
     /**
      * Tests {@link Numerics#saturatingAdd(long, int)}.
      */
diff --git a/storage/sis-geotiff/src/main/java/org/apache/sis/internal/storage/inflater/ZIP.java b/storage/sis-geotiff/src/main/java/org/apache/sis/internal/storage/inflater/ZIP.java
index a66e4080f7..4275c8ebd2 100644
--- a/storage/sis-geotiff/src/main/java/org/apache/sis/internal/storage/inflater/ZIP.java
+++ b/storage/sis-geotiff/src/main/java/org/apache/sis/internal/storage/inflater/ZIP.java
@@ -30,7 +30,7 @@ import org.apache.sis.internal.storage.io.ChannelDataInput;
  *
  * @author  Rémi Marechal (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   1.1
  * @module
  */
@@ -83,13 +83,13 @@ final class ZIP extends CompressionChannel {
         int required = 0;
         try {
             int n;
-            while ((n = inflate(target)) == 0) {
+            while ((n = inflater.inflate(target)) == 0) {
                 if (inflater.needsInput()) {
                     if (++required >= input.buffer.capacity()) {
                         throw new BufferOverflowException();
                     }
                     input.ensureBufferContains(required);
-                    setInput(input.buffer);
+                    inflater.setInput(input.buffer);
                 } else if (inflater.finished()) {
                     return -1;
                 } else {
@@ -102,31 +102,6 @@ final class ZIP extends CompressionChannel {
         return target.position() - start;
     }
 
-    /**
-     * Placeholder for {@code Inflater.inflate(ByteBuffer)}.
-     *
-     * @todo Remove after migration to JDK11.
-     */
-    private int inflate(final ByteBuffer target) throws DataFormatException {
-//      return inflater.inflate(target);        // JDK11
-        final int p = target.position();
-        final int n = inflater.inflate(target.array(), p, target.remaining());
-        target.position(p + n);
-        return n;
-    }
-
-    /**
-     * Placeholder for {@code Inflater.setInput(ByteBuffer)}.
-     *
-     * @todo Remove after migration to JDK11.
-     */
-    private void setInput(final ByteBuffer target) throws DataFormatException {
-//      inflater.setInput(target);        // JDK11
-        final byte[] b = new byte[target.remaining()];
-        target.get(b);
-        inflater.setInput(b);
-    }
-
     /**
      * Releases resources used by the inflater.
      */
diff --git a/storage/sis-geotiff/src/main/java/org/apache/sis/internal/storage/inflater/package-info.java b/storage/sis-geotiff/src/main/java/org/apache/sis/internal/storage/inflater/package-info.java
index 2f90f2c480..78c31299c4 100644
--- a/storage/sis-geotiff/src/main/java/org/apache/sis/internal/storage/inflater/package-info.java
+++ b/storage/sis-geotiff/src/main/java/org/apache/sis/internal/storage/inflater/package-info.java
@@ -42,7 +42,7 @@
  * </dl>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   1.1
  * @module
  */
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/AbstractProvider.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/AbstractProvider.java
index 6588e2ea90..ad42518dd5 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/AbstractProvider.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/AbstractProvider.java
@@ -115,7 +115,7 @@ public abstract class AbstractProvider extends DocumentedStoreProvider {
             }
             // Quick check for "<?xml " header.
             for (int i=0; i<HEADER.length; i++) {
-                if (buffer.get() != HEADER[i]) {              // TODO: use ByteBuffer.mismatch(…) with JDK11.
+                if (buffer.get() != HEADER[i]) {
                     return ProbeResult.UNSUPPORTED_STORAGE;
                 }
             }
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/AggregatedFeatureSet.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/AggregatedFeatureSet.java
index b05db5c0f3..56c6be896a 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/AggregatedFeatureSet.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/AggregatedFeatureSet.java
@@ -100,7 +100,7 @@ abstract class AggregatedFeatureSet extends AbstractFeatureSet {
                 }
             } else {
                 final Optional<Envelope> e = fs.getEnvelope();
-                if (!e.isPresent()) return false;                   // TODO: use isEmpty() with JDK11.
+                if (e.isEmpty()) return false;
                 addTo.add(e.get());
             }
         }
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/GroupBySample.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/GroupBySample.java
index 1f5f859905..dc7d4bda5a 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/GroupBySample.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/GroupBySample.java
@@ -47,7 +47,7 @@ final class GroupBySample extends Group<GroupByCRS<GroupByTransform>> {
      * @param  ranges  the sample dimensions of this group.
      */
     private GroupBySample(final List<SampleDimension> ranges) {
-        this.ranges = ranges;       // TODO: use List.copyOf(…) with JDK10.
+        this.ranges = List.copyOf(ranges);
     }
 
     /**