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 — <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) <= 0 ? 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) >= 0 ? 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<SomeObject> comparator = ...
152 * final Stream<SomeObject> stream = ...
153 * final MinMax<SomeObject> 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<SomeObject> stream = ...
178 * final MinMax<SomeObject> 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 }
|