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 63484e9c3eb8cd0ece17aaa0433a961921de14c1 Author: Martin Desruisseaux <[email protected]> AuthorDate: Mon Jan 21 20:06:17 2019 +0100 Replace the "remove" method by a categories() list supporting the List.remove(int) operation. The intend is to let user choose themselves their criterion for selecting the category to remove. --- .../org/apache/sis/coverage/SampleDimension.java | 84 +++++++++++++--------- .../apache/sis/coverage/SampleDimensionTest.java | 9 +-- 2 files changed, 56 insertions(+), 37 deletions(-) diff --git a/core/sis-raster/src/main/java/org/apache/sis/coverage/SampleDimension.java b/core/sis-raster/src/main/java/org/apache/sis/coverage/SampleDimension.java index 074dc32..68c0505 100644 --- a/core/sis-raster/src/main/java/org/apache/sis/coverage/SampleDimension.java +++ b/core/sis-raster/src/main/java/org/apache/sis/coverage/SampleDimension.java @@ -17,10 +17,10 @@ package org.apache.sis.coverage; import java.util.List; -import java.util.ArrayList; +import java.util.AbstractList; +import java.util.Arrays; import java.util.Set; import java.util.TreeSet; -import java.util.Iterator; import java.util.Collection; import java.util.Collections; import java.util.Locale; @@ -32,6 +32,7 @@ import org.opengis.util.GenericName; import org.opengis.util.InternationalString; import org.opengis.referencing.operation.MathTransform1D; import org.apache.sis.referencing.operation.transform.TransferFunction; +import org.apache.sis.internal.util.UnmodifiableArrayList; import org.apache.sis.internal.raster.Resources; import org.apache.sis.measure.MeasurementRange; import org.apache.sis.measure.NumberRange; @@ -515,11 +516,18 @@ public class SampleDimension implements Serializable { * <li>{@link #setBackground(CharSequence, Number)}</li> * <li>{@link #addQualitative(CharSequence, NumberRange)}</li> * <li>{@link #addQuantitative(CharSequence, NumberRange, MathTransform1D, Unit)}</li> - * <li>{@link #remove(String)}</li> + * <li>{@code categories().remove(int)}</li> * <li>{@link #clear()}</li> * </ul> + * + * @see #categories() */ - protected final List<Category> categories; + private Category[] categories; + + /** + * Number of valid elements in {@link #categories}. + */ + private int count; /** * The ordinal NaN values used for this sample dimension. @@ -532,7 +540,7 @@ public class SampleDimension implements Serializable { * Callers shall invoke at least one {@code addFoo(…)} method before {@link #build()}. */ public Builder() { - categories = new ArrayList<>(); + categories = new Category[10]; toNaN = new ToNaN(); } @@ -640,7 +648,7 @@ public class SampleDimension implements Serializable { final NumberRange<?> samples = range(sample.getClass(), sample, sample); // Use of 'getMinValue()' below shall be consistent with this.remove(…). toNaN.background = samples.getMinValue(); - categories.add(new Category(name, samples, null, null, toNaN)); + add(new Category(name, samples, null, null, toNaN)); return this; } @@ -771,7 +779,7 @@ public class SampleDimension implements Serializable { if (name == null) { name = Vocabulary.formatInternational(Vocabulary.Keys.Nodata); } - categories.add(new Category(name, samples, null, null, toNaN)); + add(new Category(name, samples, null, null, toNaN)); return this; } @@ -915,42 +923,51 @@ public class SampleDimension implements Serializable { */ public Builder addQuantitative(CharSequence name, NumberRange<?> samples, MathTransform1D toUnits, Unit<?> units) { ArgumentChecks.ensureNonNull("toUnits", toUnits); - categories.add(new Category(name, samples, toUnits, units, toNaN)); + add(new Category(name, samples, toUnits, units, toNaN)); return this; } /** - * Removes and returns the first category having the given name. - * Category names are compared using their {@link InternationalString#toString()} representation. - * If no category has the given name, then this method returns {@code null}. - * If more than one category has the given name, then only the first occurrence is removed. - * - * @param name name of the category to remove. - * @return the removed category, or {@code null} if none. - * - * @see Category#getName() + * Adds the given category to the list. This method is not public because the category + * should have been created with {@link #toNaN} passed in argument to its constructor. */ - public Category remove(final String name) { - ArgumentChecks.ensureNonNull("name", name); - for (final Iterator<Category> it = categories.iterator(); it.hasNext();) { - final Category c = it.next(); - if (name.equals(c.name.toString())) { - it.remove(); - // Use of 'c.minimum' shall be consistent with 'this.setBackground(…)'. - toNaN.remove(c.minimum, c.converse.minimum); - return c; - } + private void add(final Category category) { + if (count == categories.length) { + categories = Arrays.copyOf(categories, count * 2); } - return null; + categories[count++] = category; } /** - * Returns an unmodifiable view of the list of categories added so far. + * Returns the list of categories added so far. The returned list does not support the + * {@link List#add(Object) add} operation, but supports the {@link List#remove(int) remove} operation. * - * @return an unmodifiable view of the current category list. + * @return the current category list, read-only except for the {@code remove} operation. */ public List<Category> categories() { - return Collections.unmodifiableList(categories); + return new AbstractList<Category>() { + /** Returns the number of categories in this list. */ + @Override public int size() { + return count; + } + + /** Returns the category at the given index. */ + @Override public Category get(int i) { + ArgumentChecks.ensureValidIndex(count, i); + return categories[i]; + } + + /** Removes the category at the given index. */ + @Override public Category remove(int i) { + ArgumentChecks.ensureValidIndex(count, i); + final Category c = categories[i]; + System.arraycopy(categories, i+1, categories, i, --count - i); + categories[count] = null; + // Use of 'c.minimum' shall be consistent with 'this.setBackground(…)'. + toNaN.remove(c.minimum, c.converse.minimum); + return c; + } + }; } /** @@ -969,7 +986,7 @@ defName: if (name == null) { } name = createLocalName(Vocabulary.formatInternational(Vocabulary.Keys.Untitled)); } - return new SampleDimension(name, toNaN.background, categories); + return new SampleDimension(name, toNaN.background, UnmodifiableArrayList.wrap(categories, 0, count)); } /** @@ -979,7 +996,8 @@ defName: if (name == null) { */ public void clear() { dimensionName = null; - categories.clear(); + count = 0; + Arrays.fill(categories, null); toNaN.clear(); } } diff --git a/core/sis-raster/src/test/java/org/apache/sis/coverage/SampleDimensionTest.java b/core/sis-raster/src/test/java/org/apache/sis/coverage/SampleDimensionTest.java index 95df262..aca491d 100644 --- a/core/sis-raster/src/test/java/org/apache/sis/coverage/SampleDimensionTest.java +++ b/core/sis-raster/src/test/java/org/apache/sis/coverage/SampleDimensionTest.java @@ -17,6 +17,7 @@ package org.apache.sis.coverage; import java.util.Set; +import java.util.List; import org.opengis.referencing.operation.MathTransform1D; import org.apache.sis.referencing.operation.transform.LinearTransform; import org.apache.sis.referencing.operation.transform.TransferFunction; @@ -123,9 +124,9 @@ public final strictfp class SampleDimensionTest extends TestCase { .setBackground (null, 0) .addQualitative("Clouds", 1) .addQualitative("Lands", 255); - assertEquals(3, builder.categories.size()); - assertNotNull(builder.remove("Clouds")); - assertEquals(2, builder.categories.size()); - assertNull(builder.remove("Clouds")); + final List<Category> categories = builder.categories(); + assertEquals(3, categories.size()); + assertEquals("Clouds", categories.remove(1).getName().toString()); + assertEquals(2, categories.size()); } }
