001/* ===========================================================
002 * JFreeChart : a free chart library for the Java(tm) platform
003 * ===========================================================
004 *
005 * (C) Copyright 2000-2022, by David Gilbert and Contributors.
006 *
007 * Project Info:  http://www.jfree.org/jfreechart/index.html
008 *
009 * This library is free software; you can redistribute it and/or modify it
010 * under the terms of the GNU Lesser General Public License as published by
011 * the Free Software Foundation; either version 2.1 of the License, or
012 * (at your option) any later version.
013 *
014 * This library is distributed in the hope that it will be useful, but
015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
017 * License for more details.
018 *
019 * You should have received a copy of the GNU Lesser General Public
020 * License along with this library; if not, write to the Free Software
021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
022 * USA.
023 *
024 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 
025 * Other names may be trademarks of their respective owners.]
026 *
027 * ----------------------
028 * BoxAndWhiskerItem.java
029 * ----------------------
030 * (C) Copyright 2003-2022, by David Gilbert and Contributors.
031 *
032 * Original Author:  David Gilbert;
033 * Contributor(s):   -;
034 *
035 */
036
037package org.jfree.data.statistics;
038
039import java.io.Serializable;
040import java.util.Collections;
041import java.util.List;
042import java.util.Objects;
043
044/**
045 * Represents one data item within a box-and-whisker dataset.  Instances of
046 * this class are immutable.
047 */
048public class BoxAndWhiskerItem implements Serializable {
049
050    /** For serialization. */
051    private static final long serialVersionUID = 7329649623148167423L;
052
053    /** The mean. */
054    private Number mean;
055
056    /** The median. */
057    private Number median;
058
059    /** The first quarter. */
060    private Number q1;
061
062    /** The third quarter. */
063    private Number q3;
064
065    /** The minimum regular value. */
066    private Number minRegularValue;
067
068    /** The maximum regular value. */
069    private Number maxRegularValue;
070
071    /** The minimum outlier. */
072    private Number minOutlier;
073
074    /** The maximum outlier. */
075    private Number maxOutlier;
076
077    /** The outliers. */
078    private List<? extends Number> outliers;
079
080    /**
081     * Creates a new box-and-whisker item.
082     *
083     * @param mean  the mean ({@code null} permitted).
084     * @param median  the median ({@code null} permitted).
085     * @param q1  the first quartile ({@code null} permitted).
086     * @param q3  the third quartile ({@code null} permitted).
087     * @param minRegularValue  the minimum regular value ({@code null}
088     *                         permitted).
089     * @param maxRegularValue  the maximum regular value ({@code null}
090     *                         permitted).
091     * @param minOutlier  the minimum outlier ({@code null} permitted).
092     * @param maxOutlier  the maximum outlier ({@code null} permitted).
093     * @param outliers  the outliers ({@code null} permitted).
094     */
095    public BoxAndWhiskerItem(Number mean, Number median, Number q1, Number q3,
096            Number minRegularValue, Number maxRegularValue, Number minOutlier,
097            Number maxOutlier, List<? extends Number> outliers) {
098
099        this.mean = mean;
100        this.median = median;
101        this.q1 = q1;
102        this.q3 = q3;
103        this.minRegularValue = minRegularValue;
104        this.maxRegularValue = maxRegularValue;
105        this.minOutlier = minOutlier;
106        this.maxOutlier = maxOutlier;
107        this.outliers = outliers;
108
109    }
110
111    /**
112     * Creates a new box-and-whisker item.
113     *
114     * @param mean  the mean.
115     * @param median  the median
116     * @param q1  the first quartile.
117     * @param q3  the third quartile.
118     * @param minRegularValue  the minimum regular value.
119     * @param maxRegularValue  the maximum regular value.
120     * @param minOutlier  the minimum outlier value.
121     * @param maxOutlier  the maximum outlier value.
122     * @param outliers  a list of the outliers.
123     *
124     * @since 1.0.7
125     */
126    public BoxAndWhiskerItem(double mean, double median, double q1, double q3,
127            double minRegularValue, double maxRegularValue, double minOutlier,
128            double maxOutlier, List<? extends Number> outliers) {
129
130        // pass values to other constructor
131        this(Double.valueOf(mean), Double.valueOf(median), Double.valueOf(q1),
132                Double.valueOf(q3), Double.valueOf(minRegularValue),
133                Double.valueOf(maxRegularValue), Double.valueOf(minOutlier),
134                Double.valueOf(maxOutlier), outliers);
135
136    }
137
138    /**
139     * Returns the mean.
140     *
141     * @return The mean (possibly {@code null}).
142     */
143    public Number getMean() {
144        return this.mean;
145    }
146
147    /**
148     * Returns the median.
149     *
150     * @return The median (possibly {@code null}).
151     */
152    public Number getMedian() {
153        return this.median;
154    }
155
156    /**
157     * Returns the first quartile.
158     *
159     * @return The first quartile (possibly {@code null}).
160     */
161    public Number getQ1() {
162        return this.q1;
163    }
164
165    /**
166     * Returns the third quartile.
167     *
168     * @return The third quartile (possibly {@code null}).
169     */
170    public Number getQ3() {
171        return this.q3;
172    }
173
174    /**
175     * Returns the minimum regular value.
176     *
177     * @return The minimum regular value (possibly {@code null}).
178     */
179    public Number getMinRegularValue() {
180        return this.minRegularValue;
181    }
182
183    /**
184     * Returns the maximum regular value.
185     *
186     * @return The maximum regular value (possibly {@code null}).
187     */
188    public Number getMaxRegularValue() {
189        return this.maxRegularValue;
190    }
191
192    /**
193     * Returns the minimum outlier.
194     *
195     * @return The minimum outlier (possibly {@code null}).
196     */
197    public Number getMinOutlier() {
198        return this.minOutlier;
199    }
200
201    /**
202     * Returns the maximum outlier.
203     *
204     * @return The maximum outlier (possibly {@code null}).
205     */
206    public Number getMaxOutlier() {
207        return this.maxOutlier;
208    }
209
210    /**
211     * Returns a list of outliers.
212     *
213     * @return A list of outliers (possibly {@code null}).
214     */
215    public List<? extends Number> getOutliers() {
216        if (this.outliers == null) {
217            return null;
218        }
219        return Collections.unmodifiableList(this.outliers);
220    }
221
222    /**
223     * Returns a string representation of this instance, primarily for
224     * debugging purposes.
225     *
226     * @return A string representation of this instance.
227     */
228    @Override
229    public String toString() {
230        return super.toString() + "[mean=" + this.mean + ",median="
231                + this.median + ",q1=" + this.q1 + ",q3=" + this.q3 + "]";
232    }
233
234    /**
235     * Tests this object for equality with an arbitrary object.
236     *
237     * @param obj  the object to test against ({@code null} permitted).
238     *
239     * @return A boolean.
240     */
241    @Override
242    public boolean equals(Object obj) {
243
244        if (obj == this) {
245            return true;
246        }
247        if (!(obj instanceof BoxAndWhiskerItem)) {
248            return false;
249        }
250        BoxAndWhiskerItem that = (BoxAndWhiskerItem) obj;
251        if (!Objects.equals(this.mean, that.mean)) {
252            return false;
253        }
254        if (!Objects.equals(this.median, that.median)) {
255            return false;
256        }
257        if (!Objects.equals(this.q1, that.q1)) {
258            return false;
259        }
260        if (!Objects.equals(this.q3, that.q3)) {
261            return false;
262        }
263        if (!Objects.equals(this.minRegularValue, that.minRegularValue)) {
264            return false;
265        }
266        if (!Objects.equals(this.maxRegularValue, that.maxRegularValue)) {
267            return false;
268        }
269        if (!Objects.equals(this.minOutlier, that.minOutlier)) {
270            return false;
271        }
272        if (!Objects.equals(this.maxOutlier, that.maxOutlier)) {
273            return false;
274        }
275        if (!Objects.equals(this.outliers, that.outliers)) {
276            return false;
277        }
278        return true;
279    }
280
281    @Override
282    public int hashCode(){
283        int hash = 3;
284        hash = 67 * hash + Objects.hashCode(this.mean);
285        hash = 67 * hash + Objects.hashCode(this.median);
286        hash = 67 * hash + Objects.hashCode(this.q1);
287        hash = 67 * hash + Objects.hashCode(this.q3);
288        hash = 67 * hash + Objects.hashCode(this.minRegularValue);
289        hash = 67 * hash + Objects.hashCode(this.maxRegularValue);
290        hash = 67 * hash + Objects.hashCode(this.minOutlier);
291        hash = 67 * hash + Objects.hashCode(this.maxOutlier);
292        hash = 67 * hash + Objects.hashCode(this.outliers);
293        return hash;
294    }
295
296}