1 /* Copyright 2002-2025 CS GROUP 2 * Licensed to CS GROUP (CS) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * CS licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.orekit.estimation.measurements; 18 19 import org.orekit.time.TimeStamped; 20 21 22 /** Base interface for comparing measurements regardless of their type. 23 * @author Luc Maisonobe 24 * @author Evan M. Ward 25 * @since 9.2 26 */ 27 public interface ComparableMeasurement extends TimeStamped, Comparable<ComparableMeasurement> { 28 29 /** Get the observed value. 30 * <p> 31 * The observed value is the value that was measured by the instrument. 32 * </p> 33 * @return observed value 34 */ 35 double[] getObservedValue(); 36 37 /** Set the observed value. 38 * <p> 39 * The observed value is the value that was measured by the instrument. 40 * </p> 41 * @param newObserved observed value 42 * @since 13.0 43 */ 44 void setObservedValue(double[] newObserved); 45 46 /** 47 * {@inheritDoc} 48 * 49 * <p>Measurements comparison is primarily chronological, but measurements with 50 * the same date are sorted based on the observed value. Even if they have 51 * the same value too, they will <em>likely</em> not be considered equal if 52 * they correspond to different instances. 53 * 54 * <p>Care should be taken before storing measurements in a 55 * {@link java.util.SortedSet SortedSet} as it may lose redundant 56 * measurements if they, by chance, have the same identity hash code. 57 * 58 * @see System#identityHashCode(Object) 59 */ 60 @Override 61 default int compareTo(final ComparableMeasurement other) { 62 63 if (this == other) { 64 // quick return for comparing a measurement to itself 65 return 0; 66 } 67 68 // Compare date first 69 int result = getDate().compareTo(other.getDate()); 70 if (result != 0) { 71 return result; 72 } 73 74 // Simultaneous measurements, we compare the size of the measurements 75 final double[] thisV = getObservedValue(); 76 final double[] otherV = other.getObservedValue(); 77 // "Bigger" measurements after "smaller" measurement 78 if (thisV.length > otherV.length) { 79 return +1; 80 } else if (thisV.length < otherV.length) { 81 return -1; 82 } 83 84 // Measurements have same size 85 // Compare the first different value 86 // "Bigger" measurements after "smaller" measurement 87 for (int i = 0; i < thisV.length; ++i) { 88 result = Double.compare(thisV[i], otherV[i]); 89 if (result != 0) { 90 return result; 91 } 92 } 93 94 // Measurements have the same value, 95 // but we do not want them to appear as equal 96 // we set up an arbitrary order based on hash code 97 result = Integer.compare(this.hashCode(), other.hashCode()); 98 if (result != 0) { 99 return result; 100 } 101 // next try identity hash code 102 result = Integer.compare( 103 System.identityHashCode(this), 104 System.identityHashCode(other)); 105 // Tried all the fields to compare, and though we want an arbitrary 106 // total order, we still must obey the contract of compareTo, see #1364. 107 // So this may return zero if this==other, or for equal objects that by 108 // chance have the same identity hash code. 109 return result; 110 111 } 112 113 }