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 2015/06/18 16:40:07 UTC
svn commit: r1686238 - in /sis/branches/JDK8/core/sis-feature/src:
main/java/org/apache/sis/feature/ test/java/org/apache/sis/feature/
Author: desruisseaux
Date: Thu Jun 18 14:40:07 2015
New Revision: 1686238
URL: http://svn.apache.org/r1686238
Log:
Feature: hashCode() shall be consistent with equals(Object).
Modified:
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DenseFeature.java
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/MultiValuedAttribute.java
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/SparseFeature.java
sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureTestCase.java
Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java?rev=1686238&r1=1686237&r2=1686238&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java [UTF-8] Thu Jun 18 14:40:07 2015
@@ -573,7 +573,7 @@ public abstract class AbstractFeature im
/**
* Returns the exception for a property type which is neither an attribute or an association.
* This method is invoked after a {@link PropertyType} has been found for the user-supplied name,
- * but that property can not be stored in a {@link Property} instance.
+ * but that property can not be stored in or extracted from a {@link Property} instance.
*/
static IllegalArgumentException unsupportedPropertyType(final GenericName name) {
return new IllegalArgumentException(Errors.format(Errors.Keys.CanNotInstantiate_1, name));
Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DenseFeature.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DenseFeature.java?rev=1686238&r1=1686237&r2=1686238&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DenseFeature.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DenseFeature.java [UTF-8] Thu Jun 18 14:40:07 2015
@@ -291,12 +291,36 @@ final class DenseFeature extends Abstrac
/**
* Returns a hash code value for this feature.
+ * This implementation computes the hash code using only the property values, not the {@code Property} instances,
+ * in order to keep the hash code value stable before and after the {@code properties} array is promoted from the
+ * {@code Object[]} type to the {@code Property[]} type.
*
* @return A hash code value.
*/
@Override
public int hashCode() {
- return type.hashCode() + 37 * Arrays.hashCode(properties);
+ int code = 1;
+ if (properties != null) {
+ if (properties instanceof Property[]) {
+ for (final Property p : (Property[]) properties) {
+ code = 31 * code;
+ final Object value;
+ if (p instanceof Attribute<?>) {
+ value = getAttributeValue((Attribute<?>) p);
+ } else if (p instanceof FeatureAssociation) {
+ value = getAssociationValue((FeatureAssociation) p);
+ } else {
+ continue;
+ }
+ if (value != null) {
+ code += value.hashCode();
+ }
+ }
+ } else {
+ code = Arrays.hashCode(properties);
+ }
+ }
+ return type.hashCode() + code;
}
/**
Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/MultiValuedAttribute.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/MultiValuedAttribute.java?rev=1686238&r1=1686237&r2=1686238&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/MultiValuedAttribute.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/MultiValuedAttribute.java [UTF-8] Thu Jun 18 14:40:07 2015
@@ -90,10 +90,13 @@ final class MultiValuedAttribute<V> exte
final Class<V> valueClass = type.getValueClass();
if (values == null) {
this.values = new CheckedArrayList<>(valueClass);
- } else if (((CheckedArrayList<?>) values).getElementType() == valueClass) {
- this.values = (CheckedArrayList<V>) values;
} else {
- throw new ClassCastException();
+ final Class<?> actual = ((CheckedArrayList<?>) values).getElementType();
+ if (actual == valueClass) {
+ this.values = (CheckedArrayList<V>) values;
+ } else {
+ throw new ClassCastException(Errors.format(Errors.Keys.IllegalArgumentClass_3, "values", valueClass, actual));
+ }
}
}
Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/SparseFeature.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/SparseFeature.java?rev=1686238&r1=1686237&r2=1686238&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/SparseFeature.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/SparseFeature.java [UTF-8] Thu Jun 18 14:40:07 2015
@@ -27,6 +27,7 @@ import org.apache.sis.util.CorruptedObje
import org.apache.sis.util.resources.Errors;
// Branch-dependent imports
+import java.util.Objects;
import org.opengis.feature.Property;
import org.opengis.feature.Attribute;
import org.opengis.feature.FeatureAssociation;
@@ -361,12 +362,32 @@ final class SparseFeature extends Abstra
/**
* Returns a hash code value for this feature.
+ * This implementation computes the hash code using only the property values, not the {@code Property} instances,
+ * in order to keep the hash code value stable before and after the {@code properties} map is (conceptually)
+ * promoted from the {@code Map<Integer,Object>} type to the {@code Map<Integer,Property>} type.
*
* @return A hash code value.
*/
@Override
public int hashCode() {
- return type.hashCode() + 37 * properties.hashCode();
+ int code = type.hashCode() * 37;
+ if (valuesKind == PROPERTIES) {
+ for (final Map.Entry<Integer,Object> entry : properties.entrySet()) {
+ final Object p = entry.getValue();
+ final Object value;
+ if (p instanceof Attribute<?>) {
+ value = getAttributeValue((Attribute<?>) p);
+ } else if (p instanceof FeatureAssociation) {
+ value = getAssociationValue((FeatureAssociation) p);
+ } else {
+ value = null;
+ }
+ code += Objects.hashCode(entry.getKey()) ^ Objects.hashCode(value);
+ }
+ } else {
+ code += properties.hashCode();
+ }
+ return code;
}
/**
Modified: sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureTestCase.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureTestCase.java?rev=1686238&r1=1686237&r2=1686238&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureTestCase.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureTestCase.java [UTF-8] Thu Jun 18 14:40:07 2015
@@ -371,11 +371,13 @@ public abstract strictfp class FeatureTe
* the Features to be compared. The implementation shall be able to wrap or unwrap the values.
*/
assertEquals("Tokyo", clone.getProperty("city").getValue());
- assertEquals(feature, clone);
+ assertEquals("hashCode", feature.hashCode(), clone.hashCode());
+ assertEquals("equals", feature, clone);
/*
* For the other Feature instance to contain full Property object and test again.
*/
assertEquals("Tokyo", feature.getProperty("city").getValue());
- assertEquals(feature, clone);
+ assertEquals("hashCode", feature.hashCode(), clone.hashCode());
+ assertEquals("equals", feature, clone);
}
}