MinMax.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-3.0.0).
003  * Copyright (c) 2007-2014 Franz Wilhelmstötter
004  *
005  * Licensed under the Apache License, Version 2.0 (the "License");
006  * you may not use this file except in compliance with the License.
007  * You may obtain a copy of the License at
008  *
009  *      http://www.apache.org/licenses/LICENSE-2.0
010  *
011  * Unless required by applicable law or agreed to in writing, software
012  * distributed under the License is distributed on an "AS IS" BASIS,
013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014  * See the License for the specific language governing permissions and
015  * limitations under the License.
016  *
017  * Author:
018  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
019  */
020 package org.jenetics.stat;
021 
022 import static java.util.Objects.requireNonNull;
023 
024 import java.util.Comparator;
025 import java.util.function.Consumer;
026 import java.util.stream.Collector;
027 
028 /**
029  * This <i>consumer</i> class is used for calculating the min and max value
030  * according to the given {@code Comparator}.
031  *
032  @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
033  @since 3.0
034  @version 3.0 &mdash; <em>$Date: 2014-12-28 $</em>
035  */
036 public final class MinMax<C> implements Consumer<C> {
037 
038     private final Comparator<? super C> _comparator;
039 
040     private C _min;
041     private C _max;
042     private long _count = 0L;
043 
044     private MinMax(final Comparator<? super C> comparator) {
045         _comparator = requireNonNull(comparator);
046     }
047 
048     /**
049      * Accept the element for min-max calculation.
050      *
051      @param object the element to use for min-max calculation
052      */
053     @Override
054     public void accept(final C object) {
055         _min = min(_comparator, _min, object);
056         _max = max(_comparator, _max, object);
057         ++_count;
058     }
059 
060     /**
061      * Combine two {@code MinMax} objects.
062      *
063      @param other the other {@code MinMax} object to combine
064      @return {@code this}
065      */
066     public MinMax<C> combine(final MinMax<C> other) {
067         _min = min(_comparator, _min, other._min);
068         _max = max(_comparator, _max, other._max);
069         _count += other._count;
070 
071         return this;
072     }
073 
074     /**
075      * Return the current minimal object or {@code null} if no element has been
076      * accepted yet.
077      *
078      @return the current minimal object
079      */
080     public C getMin() {
081         return _min;
082     }
083 
084     /**
085      * Return the current maximal object or {@code null} if no element has been
086      * accepted yet.
087      *
088      @return the current maximal object
089      */
090     public C getMax() {
091         return _max;
092     }
093 
094     /**
095      * Returns the count of values recorded.
096      *
097      @return the count of recorded values
098      */
099     public long getCount() {
100         return _count;
101     }
102 
103     /* *************************************************************************
104      *  Some static helper methods.
105      * ************************************************************************/
106 
107     /**
108      * Return the minimum of two values, according the given comparator.
109      * {@code null} values are allowed.
110      *
111      @param comp the comparator used for determining the min value
112      @param a the first value to compare
113      @param b the second value to compare
114      @param <T> the type of the compared objects
115      @return the minimum value, or {@code null} if both values are {@code null}.
116      *         If only one value is {@code null}, the non {@code null} values is
117      *         returned.
118      */
119     public static <T> T
120     min(final Comparator<? super T> comp, final T a, final T b) {
121         return a != null ? b != null ? comp.compare(a, b<= ? a : b : a : b;
122     }
123 
124     /**
125      * Return the maximum of two values, according the given comparator.
126      * {@code null} values are allowed.
127      *
128      @param comp the comparator used for determining the max value
129      @param a the first value to compare
130      @param b the second value to compare
131      @param <T> the type of the compared objects
132      @return the maximum value, or {@code null} if both values are {@code null}.
133      *         If only one value is {@code null}, the non {@code null} values is
134      *         returned.
135      */
136     public static <T> T
137     max(final Comparator<? super T> comp, final T a, final T b) {
138         return a != null ? b != null ? comp.compare(a, b>= ? a : b : a : b;
139     }
140 
141 
142     /* *************************************************************************
143      *  Some static factory methods.
144      * ************************************************************************/
145 
146     /**
147      * Return a {@code Collector} which calculates the minimum and maximum value.
148      * The given {@code comparator} is used for comparing two objects.
149      *
150      * [code]
151      * final Comparator&lt;SomeObject&gt; comparator = ...
152      * final Stream&lt;SomeObject&gt; stream = ...
153      * final MinMax&lt;SomeObject&gt; moments = stream
154      *     .collect(doubleMoments.toMinMax(comparator));
155      * [/code]
156      *
157      @param comparator the {@code Comparator} to use
158      @param <T> the type of the input elements
159      @return a {@code Collector} implementing the min-max reduction
160      @throws java.lang.NullPointerException if the given {@code mapper} is
161      *         {@code null}
162      */
163     public static <T>
164     Collector<T, ?, MinMax<T>> toMinMax(final Comparator<? super T> comparator) {
165         return Collector.of(
166             () -> MinMax.of(comparator),
167             MinMax::accept,
168             MinMax::combine
169         );
170     }
171 
172     /**
173      * Return a {@code Collector} which calculates the minimum and maximum value.
174      * The <i>reducing</i> objects must be comparable.
175      *
176      * [code]
177      * final Stream&lt;SomeObject&gt; stream = ...
178      * final MinMax&lt;SomeObject&gt; moments = stream
179      *     .collect(doubleMoments.toMinMax(comparator));
180      * [/code]
181      *
182      @param <C> the type of the input elements
183      @return a {@code Collector} implementing the min-max reduction
184      @throws java.lang.NullPointerException if the given {@code mapper} is
185      *         {@code null}
186      */
187     public static <C extends Comparable<? super C>>
188     Collector<C, ?, MinMax<C>> toMinMax() {
189         return toMinMax((a, b-> a.compareTo(b));
190     }
191 
192     /**
193      * Create a new {@code MinMax} <i>consumer</i> with the given
194      {@link java.util.Comparator}.
195      *
196      @param comparator the comparator used for comparing two elements
197      @param <T> the element type
198      @return a new {@code MinMax} <i>consumer</i>
199      @throws java.lang.NullPointerException if the {@code comparator} is
200      *         {@code null}.
201      */
202     public static <T> MinMax<T> of(final Comparator<? super T> comparator) {
203         return new MinMax<>(comparator);
204     }
205 
206     /**
207      * Create a new {@code MinMax} <i>consumer</i>.
208      *
209      @param <C> the element type
210      @return a new {@code MinMax} <i>consumer</i>
211      */
212     public static <C extends Comparable<? super C>> MinMax<C> of() {
213         return of((a, b-> a.compareTo(b));
214     }
215 
216 }