0001 /*
0002 * Copyright 2008-2017 the original author or authors.
0003 *
0004 * Licensed under the Apache License, Version 2.0 (the "License");
0005 * you may not use this file except in compliance with the License.
0006 * You may obtain a copy of the License at
0007 *
0008 * http://www.apache.org/licenses/LICENSE-2.0
0009 *
0010 * Unless required by applicable law or agreed to in writing, software
0011 * distributed under the License is distributed on an "AS IS" BASIS,
0012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013 * See the License for the specific language governing permissions and
0014 * limitations under the License.
0015 */
0016 package griffon.javafx.beans.binding;
0017
0018 import javafx.beans.binding.NumberBinding;
0019 import javafx.beans.binding.StringBinding;
0020 import javafx.beans.value.ObservableValue;
0021 import javafx.collections.ObservableList;
0022 import javafx.collections.ObservableMap;
0023 import javafx.collections.ObservableSet;
0024
0025 import javax.annotation.Nonnull;
0026 import javax.annotation.Nullable;
0027 import java.util.Map;
0028 import java.util.function.DoubleSupplier;
0029 import java.util.function.Function;
0030 import java.util.function.Supplier;
0031 import java.util.function.ToDoubleFunction;
0032
0033 import static java.util.Objects.requireNonNull;
0034 import static java.util.stream.Collectors.joining;
0035 import static javafx.beans.binding.Bindings.createDoubleBinding;
0036 import static javafx.beans.binding.Bindings.createStringBinding;
0037
0038 /**
0039 * @author Andres Almiray
0040 * @since 2.10.0
0041 */
0042 public final class CollectionBindings {
0043 private static final String ERROR_ITEMS_NULL = "Argument 'items' must not be null";
0044 private static final String ERROR_MAPPER_NULL = "Argument 'mapper' must not be null";
0045 private static final String ERROR_SUPPLIER_NULL = "Argument 'supplier' must not be null";
0046 private static final String ERROR_DELIMITER_NULL = "Argument 'delimiter' must not be null";
0047 private static final String ERROR_DEFAULT_VALUE_NULL = "Argument 'defaultValue' must not be null";
0048
0049 private CollectionBindings() {
0050 // prevent instantiation
0051 }
0052
0053 /**
0054 * Creates a string binding that constructs a sequence of characters separated by a delimiter.
0055 *
0056 * @param items the observable list of items.
0057 * @param delimiter the sequence of characters to be used between each element.
0058 *
0059 * @return a string binding.
0060 */
0061 @Nonnull
0062 public static StringBinding joinList(@Nonnull final ObservableList<?> items, @Nullable final String delimiter) {
0063 return joinList(items, delimiter, String::valueOf);
0064 }
0065
0066 /**
0067 * Creates a string binding that constructs a sequence of characters separated by a delimiter.
0068 *
0069 * @param items the observable list of items.
0070 * @param delimiter the sequence of characters to be used between each element.
0071 * @param mapper a non-interfering, stateless function to apply to the each element.
0072 *
0073 * @return a string binding.
0074 */
0075 @Nonnull
0076 public static <T> StringBinding joinList(@Nonnull final ObservableList<T> items, @Nullable final String delimiter, @Nonnull final Function<? super T, String> mapper) {
0077 requireNonNull(items, ERROR_ITEMS_NULL);
0078 requireNonNull(mapper, ERROR_MAPPER_NULL);
0079 final String value = delimiter == null ? "" : delimiter;
0080 return createStringBinding(() -> items.stream().map(mapper).collect(joining(value)), items);
0081 }
0082
0083 /**
0084 * Creates a string binding that constructs a sequence of characters separated by a delimiter.
0085 *
0086 * @param items the observable list of items.
0087 * @param delimiter the sequence of characters to be used between each element.
0088 *
0089 * @return a string binding.
0090 */
0091 @Nonnull
0092 public static StringBinding joinList(@Nonnull final ObservableList<?> items, @Nonnull final ObservableValue<String> delimiter) {
0093 requireNonNull(items, ERROR_ITEMS_NULL);
0094 requireNonNull(delimiter, ERROR_DELIMITER_NULL);
0095 return createStringBinding(() -> {
0096 String value = delimiter.getValue();
0097 value = value == null ? "" : value;
0098 return items.stream().map(String::valueOf).collect(joining(value));
0099 }, items, delimiter);
0100 }
0101
0102 /**
0103 * Creates a string binding that constructs a sequence of characters separated by a delimiter.
0104 *
0105 * @param items the observable list of items.
0106 * @param delimiter the sequence of characters to be used between each element.
0107 * @param mapper a non-interfering, stateless function to apply to the each element.
0108 *
0109 * @return a string binding.
0110 */
0111 @Nonnull
0112 public static <T> StringBinding joinList(@Nonnull final ObservableList<T> items, @Nonnull final ObservableValue<String> delimiter, @Nonnull final ObservableValue<Function<? super T, String>> mapper) {
0113 requireNonNull(items, ERROR_ITEMS_NULL);
0114 requireNonNull(delimiter, ERROR_DELIMITER_NULL);
0115 requireNonNull(mapper, ERROR_MAPPER_NULL);
0116 return createStringBinding(() -> {
0117 String value = delimiter.getValue();
0118 value = value == null ? "" : value;
0119 final Function<? super T, String> mapperValue = mapper.getValue() != null ? mapper.getValue() : String::valueOf;
0120 return items.stream().map(mapperValue).collect(joining(value));
0121 }, items, delimiter, mapper);
0122 }
0123
0124 /**
0125 * Creates a string binding that constructs a sequence of characters separated by a delimiter.
0126 *
0127 * @param items the observable set of items.
0128 * @param delimiter the sequence of characters to be used between each element.
0129 *
0130 * @return a string binding.
0131 */
0132 @Nonnull
0133 public static StringBinding joinSet(@Nonnull final ObservableSet<?> items, @Nullable final String delimiter) {
0134 return joinSet(items, delimiter, String::valueOf);
0135 }
0136
0137 /**
0138 * Creates a string binding that constructs a sequence of characters separated by a delimiter.
0139 *
0140 * @param items the observable set of items.
0141 * @param delimiter the sequence of characters to be used between each element.
0142 * @param mapper a non-interfering, stateless function to apply to the each element.
0143 *
0144 * @return a string binding.
0145 */
0146 @Nonnull
0147 public static <T> StringBinding joinSet(@Nonnull final ObservableSet<T> items, @Nullable final String delimiter, @Nonnull final Function<? super T, String> mapper) {
0148 requireNonNull(items, ERROR_ITEMS_NULL);
0149 requireNonNull(mapper, ERROR_MAPPER_NULL);
0150 final String value = delimiter == null ? "" : delimiter;
0151 return createStringBinding(() -> items.stream().map(mapper).collect(joining(value)), items);
0152 }
0153
0154 /**
0155 * Creates a string binding that constructs a sequence of characters separated by a delimiter.
0156 *
0157 * @param items the observable set of items.
0158 * @param delimiter the sequence of characters to be used between each element.
0159 *
0160 * @return a string binding.
0161 */
0162 @Nonnull
0163 public static StringBinding joinSet(@Nonnull final ObservableSet<?> items, @Nonnull final ObservableValue<String> delimiter) {
0164 requireNonNull(items, ERROR_ITEMS_NULL);
0165 requireNonNull(delimiter, ERROR_DELIMITER_NULL);
0166 return createStringBinding(() -> {
0167 String value = delimiter.getValue();
0168 value = value == null ? "" : value;
0169 return items.stream().map(String::valueOf).collect(joining(value));
0170 }, items, delimiter);
0171 }
0172
0173 /**
0174 * Creates a string binding that constructs a sequence of characters separated by a delimiter.
0175 *
0176 * @param items the observable set of items.
0177 * @param delimiter the sequence of characters to be used between each element.
0178 * @param mapper a non-interfering, stateless function to apply to the each element.
0179 *
0180 * @return a string binding.
0181 */
0182 @Nonnull
0183 public static <T> StringBinding joinSet(@Nonnull final ObservableSet<T> items, @Nonnull final ObservableValue<String> delimiter, @Nonnull final ObservableValue<Function<? super T, String>> mapper) {
0184 requireNonNull(items, ERROR_ITEMS_NULL);
0185 requireNonNull(delimiter, ERROR_DELIMITER_NULL);
0186 requireNonNull(mapper, ERROR_MAPPER_NULL);
0187 return createStringBinding(() -> {
0188 String value = delimiter.getValue();
0189 value = value == null ? "" : value;
0190 final Function<? super T, String> mapperValue = mapper.getValue() != null ? mapper.getValue() : String::valueOf;
0191 return items.stream().map(mapperValue).collect(joining(value));
0192 }, items, delimiter, mapper);
0193 }
0194
0195 /**
0196 * Creates a string binding that constructs a sequence of characters separated by a delimiter.
0197 *
0198 * @param items the observable map of items.
0199 * @param delimiter the sequence of characters to be used between each entry.
0200 *
0201 * @return a string binding.
0202 */
0203 @Nonnull
0204 public static <K, V> StringBinding joinMap(@Nonnull final ObservableMap<K, V> items, @Nullable final String delimiter) {
0205 return joinMap(items, delimiter, entry -> String.valueOf(entry.getKey()) + "=" + String.valueOf(entry.getValue()));
0206 }
0207
0208 /**
0209 * Creates a string binding that constructs a sequence of characters separated by a delimiter.
0210 *
0211 * @param items the observable map of items.
0212 * @param delimiter the sequence of characters to be used between each element.
0213 * @param mapper a non-interfering, stateless function to apply to the each entry.
0214 *
0215 * @return a string binding.
0216 */
0217 @Nonnull
0218 public static <K, V> StringBinding joinMap(@Nonnull final ObservableMap<K, V> items, @Nullable final String delimiter, @Nonnull final Function<Map.Entry<K, V>, String> mapper) {
0219 requireNonNull(items, ERROR_ITEMS_NULL);
0220 requireNonNull(mapper, ERROR_MAPPER_NULL);
0221 final String value = delimiter == null ? "," : delimiter;
0222 return createStringBinding(() -> items.entrySet().stream().map(mapper).collect(joining(value)), items);
0223 }
0224
0225 /**
0226 * Creates a string binding that constructs a sequence of characters separated by a delimiter.
0227 *
0228 * @param items the observable map of items.
0229 * @param delimiter the sequence of characters to be used between each entry.
0230 *
0231 * @return a string binding.
0232 */
0233 @Nonnull
0234 public static <K, V> StringBinding joinMap(@Nonnull final ObservableMap<K, V> items, @Nonnull final ObservableValue<String> delimiter) {
0235 requireNonNull(items, ERROR_ITEMS_NULL);
0236 requireNonNull(delimiter, ERROR_DELIMITER_NULL);
0237 final Function<Map.Entry<K, V>, String> mapper = entry -> String.valueOf(entry.getKey()) + "=" + String.valueOf(entry.getValue());
0238 return createStringBinding(() -> {
0239 String value = delimiter.getValue();
0240 value = value == null ? "" : value;
0241 return items.entrySet().stream().map(mapper).collect(joining(value));
0242 }, items, delimiter);
0243 }
0244
0245 /**
0246 * Creates a string binding that constructs a sequence of characters separated by a delimiter.
0247 *
0248 * @param items the observable map of items.
0249 * @param delimiter the sequence of characters to be used between each element.
0250 * @param mapper a non-interfering, stateless function to apply to the each entry.
0251 *
0252 * @return a string binding.
0253 */
0254 @Nonnull
0255 public static <K, V> StringBinding joinMap(@Nonnull final ObservableMap<K, V> items, @Nonnull final ObservableValue<String> delimiter, @Nonnull final ObservableValue<Function<Map.Entry<K, V>, String>> mapper) {
0256 requireNonNull(items, ERROR_ITEMS_NULL);
0257 requireNonNull(delimiter, ERROR_DELIMITER_NULL);
0258 requireNonNull(mapper, ERROR_MAPPER_NULL);
0259 final Function<Map.Entry<K, V>, String> mv = entry -> String.valueOf(entry.getKey()) + "=" + String.valueOf(entry.getValue());
0260 return createStringBinding(() -> {
0261 String value = delimiter.getValue();
0262 value = value == null ? "" : value;
0263 final Function<Map.Entry<K, V>, String> mapperValue = mapper.getValue() != null ? mapper.getValue() : mv;
0264 return items.entrySet().stream().map(mapperValue).collect(joining(value));
0265 }, items, delimiter, mapper);
0266 }
0267
0268 /**
0269 * Creates a number binding that computes the minimum value amongst elements.
0270 *
0271 * @param items the observable list of items.
0272 * @param defaultValue the value to be returned if there is no value present.
0273 *
0274 * @return a number binding
0275 */
0276 @Nonnull
0277 public static NumberBinding minInList(@Nonnull final ObservableList<? extends Number> items, @Nonnull final Number defaultValue) {
0278 requireNonNull(items, ERROR_ITEMS_NULL);
0279 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
0280 return createDoubleBinding(() -> items.stream().mapToDouble(Number::doubleValue).min().orElse(defaultValue.doubleValue()), items);
0281 }
0282
0283 /**
0284 * Creates a number binding that computes the minimum value amongst elements.
0285 *
0286 * @param items the observable list of items.
0287 * @param supplier a {@code Supplier} whose result is returned if no value is present.
0288 *
0289 * @return a number binding
0290 */
0291 @Nonnull
0292 public static NumberBinding minInList(@Nonnull final ObservableList<? extends Number> items, @Nonnull final Supplier<? extends Number> supplier) {
0293 requireNonNull(items, ERROR_ITEMS_NULL);
0294 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0295 return createDoubleBinding(() -> items.stream().mapToDouble(Number::doubleValue).min().orElseGet(resolveDoubleSupplier(supplier)), items);
0296 }
0297
0298 /**
0299 * Creates a number binding that computes the maximum value amongst elements.
0300 *
0301 * @param items the observable list of items.
0302 * @param defaultValue the value to be returned if there is no value present.
0303 *
0304 * @return a number binding
0305 */
0306 @Nonnull
0307 public static NumberBinding maxInList(@Nonnull final ObservableList<? extends Number> items, @Nonnull final Number defaultValue) {
0308 requireNonNull(items, ERROR_ITEMS_NULL);
0309 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
0310 return createDoubleBinding(() -> items.stream().mapToDouble(Number::doubleValue).max().orElse(defaultValue.doubleValue()), items);
0311 }
0312
0313 /**
0314 * Creates a number binding that computes the maximum value amongst elements.
0315 *
0316 * @param items the observable list of items.
0317 * @param supplier a {@code Supplier} whose result is returned if no value is present.
0318 *
0319 * @return a number binding
0320 */
0321 @Nonnull
0322 public static NumberBinding maxInList(@Nonnull final ObservableList<? extends Number> items, @Nonnull final Supplier<? extends Number> supplier) {
0323 requireNonNull(items, ERROR_ITEMS_NULL);
0324 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0325 return createDoubleBinding(() -> items.stream().mapToDouble(Number::doubleValue).max().orElseGet(resolveDoubleSupplier(supplier)), items);
0326 }
0327
0328 /**
0329 * Creates a number binding that computes the average value amongst elements.
0330 *
0331 * @param items the observable list of items.
0332 * @param defaultValue the value to be returned if there is no value present.
0333 *
0334 * @return a number binding
0335 */
0336 @Nonnull
0337 public static NumberBinding averageInList(@Nonnull final ObservableList<? extends Number> items, @Nonnull final Number defaultValue) {
0338 requireNonNull(items, ERROR_ITEMS_NULL);
0339 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
0340 return createDoubleBinding(() -> items.stream().mapToDouble(Number::doubleValue).average().orElse(defaultValue.doubleValue()), items);
0341 }
0342
0343 /**
0344 * Creates a number binding that computes the average value amongst elements.
0345 *
0346 * @param items the observable list of items.
0347 * @param supplier a {@code Supplier} whose result is returned if no value is present.
0348 *
0349 * @return a number binding
0350 */
0351 @Nonnull
0352 public static NumberBinding averageInList(@Nonnull final ObservableList<? extends Number> items, @Nonnull final Supplier<? extends Number> supplier) {
0353 requireNonNull(items, ERROR_ITEMS_NULL);
0354 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0355 return createDoubleBinding(() -> items.stream().mapToDouble(Number::doubleValue).average().orElseGet(resolveDoubleSupplier(supplier)), items);
0356 }
0357
0358 /**
0359 * Creates a number binding that contains the sum of the items of the given observable list.
0360 *
0361 * @param items the observable list of items.
0362 *
0363 * @return a number binding.
0364 */
0365 @Nonnull
0366 public static NumberBinding sumOfList(@Nonnull final ObservableList<? extends Number> items) {
0367 requireNonNull(items, ERROR_ITEMS_NULL);
0368 return createDoubleBinding(() -> items.stream().mapToDouble(Number::doubleValue).sum(), items);
0369 }
0370
0371 /**
0372 * Creates a number binding that computes the minimum value amongst elements.
0373 *
0374 * @param items the observable list of items.
0375 * @param defaultValue the value to be returned if there is no value present.
0376 * @param mapper a non-interfering, stateless function to apply to the each element.
0377 *
0378 * @return a number binding
0379 */
0380 @Nonnull
0381 public static <T> NumberBinding minInList(@Nonnull final ObservableList<T> items, @Nonnull final Number defaultValue, @Nonnull final ToDoubleFunction<? super T> mapper) {
0382 requireNonNull(items, ERROR_ITEMS_NULL);
0383 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
0384 requireNonNull(mapper, ERROR_MAPPER_NULL);
0385 return createDoubleBinding(() -> items.stream().mapToDouble(mapper).min().orElse(defaultValue.doubleValue()), items);
0386 }
0387
0388 /**
0389 * Creates a number binding that computes the minimum value amongst elements.
0390 *
0391 * @param items the observable list of items.
0392 * @param supplier a {@code Supplier} whose result is returned if no value is present.
0393 * @param mapper a non-interfering, stateless function to apply to the each element.
0394 *
0395 * @return a number binding
0396 */
0397 @Nonnull
0398 public static <T> NumberBinding minInList(@Nonnull final ObservableList<T> items, @Nonnull final Supplier<? extends Number> supplier, @Nonnull final ToDoubleFunction<? super T> mapper) {
0399 requireNonNull(items, ERROR_ITEMS_NULL);
0400 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0401 requireNonNull(mapper, ERROR_MAPPER_NULL);
0402 return createDoubleBinding(() -> items.stream().mapToDouble(mapper).min().orElseGet(resolveDoubleSupplier(supplier)), items);
0403 }
0404
0405 /**
0406 * Creates a number binding that computes the maximum value amongst elements.
0407 *
0408 * @param items the observable list of items.
0409 * @param defaultValue the value to be returned if there is no value present.
0410 * @param mapper a non-interfering, stateless function to apply to the each element.
0411 *
0412 * @return a number binding
0413 */
0414 @Nonnull
0415 public static <T> NumberBinding maxInList(@Nonnull final ObservableList<T> items, @Nonnull final Number defaultValue, @Nonnull final ToDoubleFunction<? super T> mapper) {
0416 requireNonNull(items, ERROR_ITEMS_NULL);
0417 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
0418 requireNonNull(mapper, ERROR_MAPPER_NULL);
0419 return createDoubleBinding(() -> items.stream().mapToDouble(mapper).max().orElse(defaultValue.doubleValue()), items);
0420 }
0421
0422 /**
0423 * Creates a number binding that computes the maximum value amongst elements.
0424 *
0425 * @param items the observable list of items.
0426 * @param supplier a {@code Supplier} whose result is returned if no value is present.
0427 * @param mapper a non-interfering, stateless function to apply to the each element.
0428 *
0429 * @return a number binding
0430 */
0431 @Nonnull
0432 public static <T> NumberBinding maxInList(@Nonnull final ObservableList<T> items, @Nonnull final Supplier<? extends Number> supplier, @Nonnull final ToDoubleFunction<? super T> mapper) {
0433 requireNonNull(items, ERROR_ITEMS_NULL);
0434 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0435 requireNonNull(mapper, ERROR_MAPPER_NULL);
0436 return createDoubleBinding(() -> items.stream().mapToDouble(mapper).max().orElseGet(resolveDoubleSupplier(supplier)), items);
0437 }
0438
0439 /**
0440 * Creates a number binding that computes the average value amongst elements.
0441 *
0442 * @param items the observable list of items.
0443 * @param defaultValue the value to be returned if there is no value present.
0444 * @param mapper a non-interfering, stateless function to apply to the each element.
0445 *
0446 * @return a number binding
0447 */
0448 @Nonnull
0449 public static <T> NumberBinding averageInList(@Nonnull final ObservableList<T> items, @Nonnull final Number defaultValue, @Nonnull final ToDoubleFunction<? super T> mapper) {
0450 requireNonNull(items, ERROR_ITEMS_NULL);
0451 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
0452 requireNonNull(mapper, ERROR_MAPPER_NULL);
0453 return createDoubleBinding(() -> items.stream().mapToDouble(mapper).average().orElse(defaultValue.doubleValue()), items);
0454 }
0455
0456 /**
0457 * Creates a number binding that computes the average value amongst elements.
0458 *
0459 * @param items the observable list of items.
0460 * @param supplier a {@code Supplier} whose result is returned if no value is present.
0461 * @param mapper a non-interfering, stateless function to apply to the each element.
0462 *
0463 * @return a number binding
0464 */
0465 @Nonnull
0466 public static <T> NumberBinding averageInList(@Nonnull final ObservableList<T> items, @Nonnull final Supplier<? extends Number> supplier, @Nonnull final ToDoubleFunction<? super T> mapper) {
0467 requireNonNull(items, ERROR_ITEMS_NULL);
0468 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0469 requireNonNull(mapper, ERROR_MAPPER_NULL);
0470 return createDoubleBinding(() -> items.stream().mapToDouble(mapper).average().orElseGet(resolveDoubleSupplier(supplier)), items);
0471 }
0472
0473 /**
0474 * Creates a number binding that contains the sum of the items of the given observable list.
0475 *
0476 * @param items the observable list of items.
0477 * @param mapper a non-interfering, stateless function to apply to the each element.
0478 *
0479 * @return a number binding.
0480 */
0481 @Nonnull
0482 public static <T> NumberBinding sumOfList(@Nonnull final ObservableList<T> items, @Nonnull final ToDoubleFunction<? super T> mapper) {
0483 requireNonNull(items, ERROR_ITEMS_NULL);
0484 requireNonNull(mapper, ERROR_MAPPER_NULL);
0485 return createDoubleBinding(() -> items.stream().mapToDouble(mapper).sum(), items);
0486 }
0487
0488 /**
0489 * Creates a number binding that computes the minimum value amongst elements.
0490 *
0491 * @param items the observable list of items.
0492 * @param defaultValue the value to be returned if there is no value present.
0493 * @param mapper a non-interfering, stateless function to apply to the each element.
0494 *
0495 * @return a number binding
0496 */
0497 @Nonnull
0498 public static <T> NumberBinding minInList(@Nonnull final ObservableList<T> items, @Nonnull final Number defaultValue, @Nonnull final ObservableValue<ToDoubleFunction<? super T>> mapper) {
0499 requireNonNull(items, ERROR_ITEMS_NULL);
0500 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
0501 requireNonNull(mapper, ERROR_MAPPER_NULL);
0502 return createDoubleBinding(() -> {
0503 ToDoubleFunction<? super T> mapperValue = mapper.getValue();
0504 requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0505 return items.stream().mapToDouble(mapperValue).min().orElse(defaultValue.doubleValue());
0506 }, items, mapper);
0507 }
0508
0509 /**
0510 * Creates a number binding that computes the minimum value amongst elements.
0511 *
0512 * @param items the observable list of items.
0513 * @param supplier a {@code Supplier} whose result is returned if no value is present.
0514 * @param mapper a non-interfering, stateless function to apply to the each element.
0515 *
0516 * @return a number binding
0517 */
0518 @Nonnull
0519 public static <T> NumberBinding minInList(@Nonnull final ObservableList<T> items, @Nonnull final Supplier<? extends Number> supplier, @Nonnull final ObservableValue<ToDoubleFunction<? super T>> mapper) {
0520 requireNonNull(items, ERROR_ITEMS_NULL);
0521 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0522 requireNonNull(mapper, ERROR_MAPPER_NULL);
0523 return createDoubleBinding(() -> {
0524 ToDoubleFunction<? super T> mapperValue = mapper.getValue();
0525 requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0526 return items.stream().mapToDouble(mapperValue).min().orElseGet(resolveDoubleSupplier(supplier));
0527 }, items, mapper);
0528 }
0529
0530 /**
0531 * Creates a number binding that computes the maximum value amongst elements.
0532 *
0533 * @param items the observable list of items.
0534 * @param defaultValue the value to be returned if there is no value present.
0535 * @param mapper a non-interfering, stateless function to apply to the each element.
0536 *
0537 * @return a number binding
0538 */
0539 @Nonnull
0540 public static <T> NumberBinding maxInList(@Nonnull final ObservableList<T> items, @Nonnull final Number defaultValue, @Nonnull final ObservableValue<ToDoubleFunction<? super T>> mapper) {
0541 requireNonNull(items, ERROR_ITEMS_NULL);
0542 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
0543 requireNonNull(mapper, ERROR_MAPPER_NULL);
0544 return createDoubleBinding(() -> {
0545 ToDoubleFunction<? super T> mapperValue = mapper.getValue();
0546 requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0547 return items.stream().mapToDouble(mapperValue).max().orElse(defaultValue.doubleValue());
0548 }, items, mapper);
0549 }
0550
0551 /**
0552 * Creates a number binding that computes the maximum value amongst elements.
0553 *
0554 * @param items the observable list of items.
0555 * @param supplier a {@code Supplier} whose result is returned if no value is present.
0556 * @param mapper a non-interfering, stateless function to apply to the each element.
0557 *
0558 * @return a number binding
0559 */
0560 @Nonnull
0561 public static <T> NumberBinding maxInList(@Nonnull final ObservableList<T> items, @Nonnull final Supplier<? extends Number> supplier, @Nonnull final ObservableValue<ToDoubleFunction<? super T>> mapper) {
0562 requireNonNull(items, ERROR_ITEMS_NULL);
0563 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0564 requireNonNull(mapper, ERROR_MAPPER_NULL);
0565 return createDoubleBinding(() -> {
0566 ToDoubleFunction<? super T> mapperValue = mapper.getValue();
0567 requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0568 return items.stream().mapToDouble(mapperValue).max().orElseGet(resolveDoubleSupplier(supplier));
0569 }, items, mapper);
0570 }
0571
0572 /**
0573 * Creates a number binding that computes the average value amongst elements.
0574 *
0575 * @param items the observable list of items.
0576 * @param defaultValue the value to be returned if there is no value present.
0577 * @param mapper a non-interfering, stateless function to apply to the each element.
0578 *
0579 * @return a number binding
0580 */
0581 @Nonnull
0582 public static <T> NumberBinding averageInList(@Nonnull final ObservableList<T> items, @Nonnull final Number defaultValue, @Nonnull final ObservableValue<ToDoubleFunction<? super T>> mapper) {
0583 requireNonNull(items, ERROR_ITEMS_NULL);
0584 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
0585 requireNonNull(mapper, ERROR_MAPPER_NULL);
0586 return createDoubleBinding(() -> {
0587 ToDoubleFunction<? super T> mapperValue = mapper.getValue();
0588 requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0589 return items.stream().mapToDouble(mapperValue).average().orElse(defaultValue.doubleValue());
0590 }, items, mapper);
0591 }
0592
0593 /**
0594 * Creates a number binding that computes the average value amongst elements.
0595 *
0596 * @param items the observable list of items.
0597 * @param supplier a {@code Supplier} whose result is returned if no value is present.
0598 * @param mapper a non-interfering, stateless function to apply to the each element.
0599 *
0600 * @return a number binding
0601 */
0602 @Nonnull
0603 public static <T> NumberBinding averageInList(@Nonnull final ObservableList<T> items, @Nonnull final Supplier<? extends Number> supplier, @Nonnull final ObservableValue<ToDoubleFunction<? super T>> mapper) {
0604 requireNonNull(items, ERROR_ITEMS_NULL);
0605 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0606 requireNonNull(mapper, ERROR_MAPPER_NULL);
0607 return createDoubleBinding(() -> {
0608 ToDoubleFunction<? super T> mapperValue = mapper.getValue();
0609 requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0610 return items.stream().mapToDouble(mapperValue).average().orElseGet(resolveDoubleSupplier(supplier));
0611 }, items, mapper);
0612 }
0613
0614 /**
0615 * Creates a number binding that contains the sum of the items of the given observable list.
0616 *
0617 * @param items the observable list of items.
0618 * @param mapper a non-interfering, stateless function to apply to the each element.
0619 *
0620 * @return a number binding.
0621 */
0622 @Nonnull
0623 public static <T> NumberBinding sumOfList(@Nonnull final ObservableList<T> items, @Nonnull final ObservableValue<ToDoubleFunction<? super T>> mapper) {
0624 requireNonNull(items, ERROR_ITEMS_NULL);
0625 requireNonNull(mapper, ERROR_MAPPER_NULL);
0626 return createDoubleBinding(() -> {
0627 ToDoubleFunction<? super T> mapperValue = mapper.getValue();
0628 requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0629 return items.stream().mapToDouble(mapperValue).sum();
0630 }, items, mapper);
0631 }
0632
0633 /**
0634 * Creates a number binding that computes the minimum value amongst elements.
0635 *
0636 * @param items the observable set of items.
0637 * @param defaultValue the value to be returned if there is no value present.
0638 *
0639 * @return a number binding
0640 */
0641 @Nonnull
0642 public static NumberBinding minInSet(@Nonnull final ObservableSet<? extends Number> items, @Nonnull final Number defaultValue) {
0643 requireNonNull(items, ERROR_ITEMS_NULL);
0644 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
0645 return createDoubleBinding(() -> items.stream().mapToDouble(Number::doubleValue).min().orElse(defaultValue.doubleValue()), items);
0646 }
0647
0648 /**
0649 * Creates a number binding that computes the minimum value amongst elements.
0650 *
0651 * @param items the observable set of items.
0652 * @param supplier a {@code Supplier} whose result is returned if no value is present.
0653 *
0654 * @return a number binding
0655 */
0656 @Nonnull
0657 public static NumberBinding minInSet(@Nonnull final ObservableSet<? extends Number> items, @Nonnull final Supplier<? extends Number> supplier) {
0658 requireNonNull(items, ERROR_ITEMS_NULL);
0659 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0660 return createDoubleBinding(() -> items.stream().mapToDouble(Number::doubleValue).min().orElseGet(resolveDoubleSupplier(supplier)), items);
0661 }
0662
0663 /**
0664 * Creates a number binding that computes the maximum value amongst elements.
0665 *
0666 * @param items the observable set of items.
0667 * @param defaultValue the value to be returned if there is no value present.
0668 *
0669 * @return a number binding
0670 */
0671 @Nonnull
0672 public static NumberBinding maxInSet(@Nonnull final ObservableSet<? extends Number> items, @Nonnull final Number defaultValue) {
0673 requireNonNull(items, ERROR_ITEMS_NULL);
0674 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
0675 return createDoubleBinding(() -> items.stream().mapToDouble(Number::doubleValue).max().orElse(defaultValue.doubleValue()), items);
0676 }
0677
0678 /**
0679 * Creates a number binding that computes the maximum value amongst elements.
0680 *
0681 * @param items the observable set of items.
0682 * @param supplier a {@code Supplier} whose result is returned if no value is present.
0683 *
0684 * @return a number binding
0685 */
0686 @Nonnull
0687 public static NumberBinding maxInSet(@Nonnull final ObservableSet<? extends Number> items, @Nonnull final Supplier<? extends Number> supplier) {
0688 requireNonNull(items, ERROR_ITEMS_NULL);
0689 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0690 return createDoubleBinding(() -> items.stream().mapToDouble(Number::doubleValue).max().orElseGet(resolveDoubleSupplier(supplier)), items);
0691 }
0692
0693 /**
0694 * Creates a number binding that computes the average value amongst elements.
0695 *
0696 * @param items the observable set of items.
0697 * @param defaultValue the value to be returned if there is no value present.
0698 *
0699 * @return a number binding
0700 */
0701 @Nonnull
0702 public static NumberBinding averageInSet(@Nonnull final ObservableSet<? extends Number> items, @Nonnull final Number defaultValue) {
0703 requireNonNull(items, ERROR_ITEMS_NULL);
0704 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
0705 return createDoubleBinding(() -> items.stream().mapToDouble(Number::doubleValue).average().orElse(defaultValue.doubleValue()), items);
0706 }
0707
0708 /**
0709 * Creates a number binding that computes the average value amongst elements.
0710 *
0711 * @param items the observable set of items.
0712 * @param supplier a {@code Supplier} whose result is returned if no value is present.
0713 *
0714 * @return a number binding
0715 */
0716 @Nonnull
0717 public static NumberBinding averageInSet(@Nonnull final ObservableSet<? extends Number> items, @Nonnull final Supplier<? extends Number> supplier) {
0718 requireNonNull(items, ERROR_ITEMS_NULL);
0719 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0720 return createDoubleBinding(() -> items.stream().mapToDouble(Number::doubleValue).average().orElseGet(resolveDoubleSupplier(supplier)), items);
0721 }
0722
0723 /**
0724 * Creates a number binding that contains the sum of the items of the given observable set.
0725 *
0726 * @param items the observable set of items.
0727 *
0728 * @return a number binding.
0729 */
0730 @Nonnull
0731 public static NumberBinding sumOfSet(@Nonnull final ObservableSet<? extends Number> items) {
0732 requireNonNull(items, ERROR_ITEMS_NULL);
0733 return createDoubleBinding(() -> items.stream().mapToDouble(Number::doubleValue).sum(), items);
0734 }
0735
0736 /**
0737 * Creates a number binding that computes the minimum value amongst elements.
0738 *
0739 * @param items the observable set of items.
0740 * @param defaultValue the value to be returned if there is no value present.
0741 * @param mapper a non-interfering, stateless function to apply to the each element.
0742 *
0743 * @return a number binding
0744 */
0745 @Nonnull
0746 public static <T> NumberBinding minInSet(@Nonnull final ObservableSet<T> items, @Nonnull final Number defaultValue, @Nonnull final ToDoubleFunction<? super T> mapper) {
0747 requireNonNull(items, ERROR_ITEMS_NULL);
0748 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
0749 requireNonNull(mapper, ERROR_MAPPER_NULL);
0750 return createDoubleBinding(() -> items.stream().mapToDouble(mapper).min().orElse(defaultValue.doubleValue()), items);
0751 }
0752
0753 /**
0754 * Creates a number binding that computes the minimum value amongst elements.
0755 *
0756 * @param items the observable set of items.
0757 * @param supplier a {@code Supplier} whose result is returned if no value is present.
0758 * @param mapper a non-interfering, stateless function to apply to the each element.
0759 *
0760 * @return a number binding
0761 */
0762 @Nonnull
0763 public static <T> NumberBinding minInSet(@Nonnull final ObservableSet<T> items, @Nonnull final Supplier<? extends Number> supplier, @Nonnull final ToDoubleFunction<? super T> mapper) {
0764 requireNonNull(items, ERROR_ITEMS_NULL);
0765 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0766 requireNonNull(mapper, ERROR_MAPPER_NULL);
0767 return createDoubleBinding(() -> items.stream().mapToDouble(mapper).min().orElseGet(resolveDoubleSupplier(supplier)), items);
0768 }
0769
0770 /**
0771 * Creates a number binding that computes the maximum value amongst elements.
0772 *
0773 * @param items the observable set of items.
0774 * @param defaultValue the value to be returned if there is no value present.
0775 * @param mapper a non-interfering, stateless function to apply to the each element.
0776 *
0777 * @return a number binding
0778 */
0779 @Nonnull
0780 public static <T> NumberBinding maxInSet(@Nonnull final ObservableSet<T> items, @Nonnull final Number defaultValue, @Nonnull final ToDoubleFunction<? super T> mapper) {
0781 requireNonNull(items, ERROR_ITEMS_NULL);
0782 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
0783 requireNonNull(mapper, ERROR_MAPPER_NULL);
0784 return createDoubleBinding(() -> items.stream().mapToDouble(mapper).max().orElse(defaultValue.doubleValue()), items);
0785 }
0786
0787 /**
0788 * Creates a number binding that computes the maximum value amongst elements.
0789 *
0790 * @param items the observable set of items.
0791 * @param supplier a {@code Supplier} whose result is returned if no value is present.
0792 * @param mapper a non-interfering, stateless function to apply to the each element.
0793 *
0794 * @return a number binding
0795 */
0796 @Nonnull
0797 public static <T> NumberBinding maxInSet(@Nonnull final ObservableSet<T> items, @Nonnull final Supplier<? extends Number> supplier, @Nonnull final ToDoubleFunction<? super T> mapper) {
0798 requireNonNull(items, ERROR_ITEMS_NULL);
0799 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0800 requireNonNull(mapper, ERROR_MAPPER_NULL);
0801 return createDoubleBinding(() -> items.stream().mapToDouble(mapper).max().orElseGet(resolveDoubleSupplier(supplier)), items);
0802 }
0803
0804 /**
0805 * Creates a number binding that computes the average value amongst elements.
0806 *
0807 * @param items the observable set of items.
0808 * @param defaultValue the value to be returned if there is no value present.
0809 * @param mapper a non-interfering, stateless function to apply to the each element.
0810 *
0811 * @return a number binding
0812 */
0813 @Nonnull
0814 public static <T> NumberBinding averageInSet(@Nonnull final ObservableSet<T> items, @Nonnull final Number defaultValue, @Nonnull final ToDoubleFunction<? super T> mapper) {
0815 requireNonNull(items, ERROR_ITEMS_NULL);
0816 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
0817 requireNonNull(mapper, ERROR_MAPPER_NULL);
0818 return createDoubleBinding(() -> items.stream().mapToDouble(mapper).average().orElse(defaultValue.doubleValue()), items);
0819 }
0820
0821 /**
0822 * Creates a number binding that computes the average value amongst elements.
0823 *
0824 * @param items the observable set of items.
0825 * @param supplier a {@code Supplier} whose result is returned if no value is present.
0826 * @param mapper a non-interfering, stateless function to apply to the each element.
0827 *
0828 * @return a number binding
0829 */
0830 @Nonnull
0831 public static <T> NumberBinding averageInSet(@Nonnull final ObservableSet<T> items, @Nonnull final Supplier<? extends Number> supplier, @Nonnull final ToDoubleFunction<? super T> mapper) {
0832 requireNonNull(items, ERROR_ITEMS_NULL);
0833 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0834 requireNonNull(mapper, ERROR_MAPPER_NULL);
0835 return createDoubleBinding(() -> items.stream().mapToDouble(mapper).average().orElseGet(resolveDoubleSupplier(supplier)), items);
0836 }
0837
0838 /**
0839 * Creates a number binding that contains the sum of the items of the given observable set.
0840 *
0841 * @param items the observable set of items.
0842 * @param mapper a non-interfering, stateless function to apply to the each element.
0843 *
0844 * @return a number binding.
0845 */
0846 @Nonnull
0847 public static <T> NumberBinding sumOfSet(@Nonnull final ObservableSet<T> items, @Nonnull final ToDoubleFunction<? super T> mapper) {
0848 requireNonNull(items, ERROR_ITEMS_NULL);
0849 requireNonNull(mapper, ERROR_MAPPER_NULL);
0850 return createDoubleBinding(() -> items.stream().mapToDouble(mapper).sum(), items);
0851 }
0852
0853 /**
0854 * Creates a number binding that computes the minimum value amongst elements.
0855 *
0856 * @param items the observable set of items.
0857 * @param defaultValue the value to be returned if there is no value present.
0858 * @param mapper a non-interfering, stateless function to apply to the each element.
0859 *
0860 * @return a number binding
0861 */
0862 @Nonnull
0863 public static <T> NumberBinding minInSet(@Nonnull final ObservableSet<T> items, @Nonnull final Number defaultValue, @Nonnull final ObservableValue<ToDoubleFunction<? super T>> mapper) {
0864 requireNonNull(items, ERROR_ITEMS_NULL);
0865 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
0866 requireNonNull(mapper, ERROR_MAPPER_NULL);
0867 return createDoubleBinding(() -> {
0868 ToDoubleFunction<? super T> mapperValue = mapper.getValue();
0869 requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0870 return items.stream().mapToDouble(mapperValue).min().orElse(defaultValue.doubleValue());
0871 }, items, mapper);
0872 }
0873
0874 /**
0875 * Creates a number binding that computes the minimum value amongst elements.
0876 *
0877 * @param items the observable set of items.
0878 * @param supplier a {@code Supplier} whose result is returned if no value is present.
0879 * @param mapper a non-interfering, stateless function to apply to the each element.
0880 *
0881 * @return a number binding
0882 */
0883 @Nonnull
0884 public static <T> NumberBinding minInSet(@Nonnull final ObservableSet<T> items, @Nonnull final Supplier<? extends Number> supplier, @Nonnull final ObservableValue<ToDoubleFunction<? super T>> mapper) {
0885 requireNonNull(items, ERROR_ITEMS_NULL);
0886 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0887 requireNonNull(mapper, ERROR_MAPPER_NULL);
0888 return createDoubleBinding(() -> {
0889 ToDoubleFunction<? super T> mapperValue = mapper.getValue();
0890 requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0891 return items.stream().mapToDouble(mapperValue).min().orElseGet(resolveDoubleSupplier(supplier));
0892 }, items, mapper);
0893 }
0894
0895 /**
0896 * Creates a number binding that computes the maximum value amongst elements.
0897 *
0898 * @param items the observable set of items.
0899 * @param defaultValue the value to be returned if there is no value present.
0900 * @param mapper a non-interfering, stateless function to apply to the each element.
0901 *
0902 * @return a number binding
0903 */
0904 @Nonnull
0905 public static <T> NumberBinding maxInSet(@Nonnull final ObservableSet<T> items, @Nonnull final Number defaultValue, @Nonnull final ObservableValue<ToDoubleFunction<? super T>> mapper) {
0906 requireNonNull(items, ERROR_ITEMS_NULL);
0907 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
0908 requireNonNull(mapper, ERROR_MAPPER_NULL);
0909 return createDoubleBinding(() -> {
0910 ToDoubleFunction<? super T> mapperValue = mapper.getValue();
0911 requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0912 return items.stream().mapToDouble(mapperValue).max().orElse(defaultValue.doubleValue());
0913 }, items, mapper);
0914 }
0915
0916 /**
0917 * Creates a number binding that computes the maximum value amongst elements.
0918 *
0919 * @param items the observable set of items.
0920 * @param supplier a {@code Supplier} whose result is returned if no value is present.
0921 * @param mapper a non-interfering, stateless function to apply to the each element.
0922 *
0923 * @return a number binding
0924 */
0925 @Nonnull
0926 public static <T> NumberBinding maxInSet(@Nonnull final ObservableSet<T> items, @Nonnull final Supplier<? extends Number> supplier, @Nonnull final ObservableValue<ToDoubleFunction<? super T>> mapper) {
0927 requireNonNull(items, ERROR_ITEMS_NULL);
0928 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0929 requireNonNull(mapper, ERROR_MAPPER_NULL);
0930 return createDoubleBinding(() -> {
0931 ToDoubleFunction<? super T> mapperValue = mapper.getValue();
0932 requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0933 return items.stream().mapToDouble(mapperValue).max().orElseGet(resolveDoubleSupplier(supplier));
0934 }, items, mapper);
0935 }
0936
0937 /**
0938 * Creates a number binding that computes the average value amongst elements.
0939 *
0940 * @param items the observable set of items.
0941 * @param defaultValue the value to be returned if there is no value present.
0942 * @param mapper a non-interfering, stateless function to apply to the each element.
0943 *
0944 * @return a number binding
0945 */
0946 @Nonnull
0947 public static <T> NumberBinding averageInSet(@Nonnull final ObservableSet<T> items, @Nonnull final Number defaultValue, @Nonnull final ObservableValue<ToDoubleFunction<? super T>> mapper) {
0948 requireNonNull(items, ERROR_ITEMS_NULL);
0949 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
0950 requireNonNull(mapper, ERROR_MAPPER_NULL);
0951 return createDoubleBinding(() -> {
0952 ToDoubleFunction<? super T> mapperValue = mapper.getValue();
0953 requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0954 return items.stream().mapToDouble(mapperValue).average().orElse(defaultValue.doubleValue());
0955 }, items, mapper);
0956 }
0957
0958 /**
0959 * Creates a number binding that computes the average value amongst elements.
0960 *
0961 * @param items the observable set of items.
0962 * @param supplier a {@code Supplier} whose result is returned if no value is present.
0963 * @param mapper a non-interfering, stateless function to apply to the each element.
0964 *
0965 * @return a number binding
0966 */
0967 @Nonnull
0968 public static <T> NumberBinding averageInSet(@Nonnull final ObservableSet<T> items, @Nonnull final Supplier<? extends Number> supplier, @Nonnull final ObservableValue<ToDoubleFunction<? super T>> mapper) {
0969 requireNonNull(items, ERROR_ITEMS_NULL);
0970 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0971 requireNonNull(mapper, ERROR_MAPPER_NULL);
0972 return createDoubleBinding(() -> {
0973 ToDoubleFunction<? super T> mapperValue = mapper.getValue();
0974 requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0975 return items.stream().mapToDouble(mapperValue).average().orElseGet(resolveDoubleSupplier(supplier));
0976 }, items, mapper);
0977 }
0978
0979 /**
0980 * Creates a number binding that contains the sum of the items of the given observable set.
0981 *
0982 * @param items the observable set of items.
0983 * @param mapper a non-interfering, stateless function to apply to the each element.
0984 *
0985 * @return a number binding.
0986 */
0987 @Nonnull
0988 public static <T> NumberBinding sumOfSet(@Nonnull final ObservableSet<T> items, @Nonnull final ObservableValue<ToDoubleFunction<? super T>> mapper) {
0989 requireNonNull(items, ERROR_ITEMS_NULL);
0990 requireNonNull(mapper, ERROR_MAPPER_NULL);
0991 return createDoubleBinding(() -> {
0992 ToDoubleFunction<? super T> mapperValue = mapper.getValue();
0993 requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0994 return items.stream().mapToDouble(mapperValue).sum();
0995 }, items, mapper);
0996 }
0997
0998 /**
0999 * Creates a number binding that computes the minimum value amongst values.
1000 *
1001 * @param items the observable map of items.
1002 * @param defaultValue the value to be returned if there is no value present.
1003 *
1004 * @return a number binding
1005 */
1006 @Nonnull
1007 public static <K> NumberBinding minInMap(@Nonnull final ObservableMap<K, ? extends Number> items, @Nonnull final Number defaultValue) {
1008 requireNonNull(items, ERROR_ITEMS_NULL);
1009 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
1010 return createDoubleBinding(() -> items.values().stream().mapToDouble(Number::doubleValue).min().orElse(defaultValue.doubleValue()), items);
1011 }
1012
1013 /**
1014 * Creates a number binding that computes the minimum value amongst values.
1015 *
1016 * @param items the observable map of items.
1017 * @param supplier a {@code Supplier} whose result is returned if no value is present.
1018 *
1019 * @return a number binding
1020 */
1021 @Nonnull
1022 public static <K> NumberBinding minInMap(@Nonnull final ObservableMap<K, ? extends Number> items, @Nonnull final Supplier<? extends Number> supplier) {
1023 requireNonNull(items, ERROR_ITEMS_NULL);
1024 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1025 return createDoubleBinding(() -> items.values().stream().mapToDouble(Number::doubleValue).min().orElseGet(resolveDoubleSupplier(supplier)), items);
1026 }
1027
1028 /**
1029 * Creates a number binding that computes the maximum value amongst values.
1030 *
1031 * @param items the observable map of items.
1032 * @param defaultValue the value to be returned if there is no value present.
1033 *
1034 * @return a number binding
1035 */
1036 @Nonnull
1037 public static <K> NumberBinding maxInMap(@Nonnull final ObservableMap<K, ? extends Number> items, @Nonnull final Number defaultValue) {
1038 requireNonNull(items, ERROR_ITEMS_NULL);
1039 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
1040 return createDoubleBinding(() -> items.values().stream().mapToDouble(Number::doubleValue).max().orElse(defaultValue.doubleValue()), items);
1041 }
1042
1043 /**
1044 * Creates a number binding that computes the maximum value amongst values.
1045 *
1046 * @param items the observable map of items.
1047 * @param supplier a {@code Supplier} whose result is returned if no value is present.
1048 *
1049 * @return a number binding
1050 */
1051 @Nonnull
1052 public static <K> NumberBinding maxInMap(@Nonnull final ObservableMap<K, ? extends Number> items, @Nonnull final Supplier<? extends Number> supplier) {
1053 requireNonNull(items, ERROR_ITEMS_NULL);
1054 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1055 return createDoubleBinding(() -> items.values().stream().mapToDouble(Number::doubleValue).max().orElseGet(resolveDoubleSupplier(supplier)), items);
1056 }
1057
1058 /**
1059 * Creates a number binding that computes the average value amongst values.
1060 *
1061 * @param items the observable map of items.
1062 * @param defaultValue the value to be returned if there is no value present.
1063 *
1064 * @return a number binding
1065 */
1066 @Nonnull
1067 public static <K> NumberBinding averageInMap(@Nonnull final ObservableMap<K, ? extends Number> items, @Nonnull final Number defaultValue) {
1068 requireNonNull(items, ERROR_ITEMS_NULL);
1069 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
1070 return createDoubleBinding(() -> items.values().stream().mapToDouble(Number::doubleValue).average().orElse(defaultValue.doubleValue()), items);
1071 }
1072
1073 /**
1074 * Creates a number binding that computes the average value amongst values.
1075 *
1076 * @param items the observable map of items.
1077 * @param supplier a {@code Supplier} whose result is returned if no value is present.
1078 *
1079 * @return a number binding
1080 */
1081 @Nonnull
1082 public static <K> NumberBinding averageInMap(@Nonnull final ObservableMap<K, ? extends Number> items, @Nonnull final Supplier<? extends Number> supplier) {
1083 requireNonNull(items, ERROR_ITEMS_NULL);
1084 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1085 return createDoubleBinding(() -> items.values().stream().mapToDouble(Number::doubleValue).average().orElseGet(resolveDoubleSupplier(supplier)), items);
1086 }
1087
1088 /**
1089 * Creates a number binding that contains the sum of the values of the given observable map.
1090 *
1091 * @param items the observable map of items.
1092 *
1093 * @return a number binding.
1094 */
1095 @Nonnull
1096 public static <K> NumberBinding sumOfMap(@Nonnull final ObservableMap<K, ? extends Number> items) {
1097 requireNonNull(items, ERROR_ITEMS_NULL);
1098 return createDoubleBinding(() -> items.values().stream().mapToDouble(Number::doubleValue).sum(), items);
1099 }
1100
1101 /**
1102 * Creates a number binding that computes the minimum value amongst values.
1103 *
1104 * @param items the observable map of items.
1105 * @param defaultValue the value to be returned if there is no value present.
1106 * @param mapper a non-interfering, stateless function to apply to the each value.
1107 *
1108 * @return a number binding
1109 */
1110 @Nonnull
1111 public static <K, V> NumberBinding minInMap(@Nonnull final ObservableMap<K, V> items, @Nonnull final Number defaultValue, @Nonnull final ToDoubleFunction<? super V> mapper) {
1112 requireNonNull(items, ERROR_ITEMS_NULL);
1113 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
1114 requireNonNull(mapper, ERROR_MAPPER_NULL);
1115 return createDoubleBinding(() -> items.values().stream().mapToDouble(mapper).min().orElse(defaultValue.doubleValue()), items);
1116 }
1117
1118 /**
1119 * Creates a number binding that computes the minimum value amongst values.
1120 *
1121 * @param items the observable map of items.
1122 * @param supplier a {@code Supplier} whose result is returned if no value is present.
1123 * @param mapper a non-interfering, stateless function to apply to the each value.
1124 *
1125 * @return a number binding
1126 */
1127 @Nonnull
1128 public static <K, V> NumberBinding minInMap(@Nonnull final ObservableMap<K, V> items, @Nonnull final Supplier<? extends Number> supplier, @Nonnull final ToDoubleFunction<? super V> mapper) {
1129 requireNonNull(items, ERROR_ITEMS_NULL);
1130 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1131 requireNonNull(mapper, ERROR_MAPPER_NULL);
1132 return createDoubleBinding(() -> items.values().stream().mapToDouble(mapper).min().orElseGet(resolveDoubleSupplier(supplier)), items);
1133 }
1134
1135 /**
1136 * Creates a number binding that computes the maximum value amongst values.
1137 *
1138 * @param items the observable map of items.
1139 * @param defaultValue the value to be returned if there is no value present.
1140 * @param mapper a non-interfering, stateless function to apply to the each value.
1141 *
1142 * @return a number binding
1143 */
1144 @Nonnull
1145 public static <K, V> NumberBinding maxInMap(@Nonnull final ObservableMap<K, V> items, @Nonnull final Number defaultValue, @Nonnull final ToDoubleFunction<? super V> mapper) {
1146 requireNonNull(items, ERROR_ITEMS_NULL);
1147 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
1148 requireNonNull(mapper, ERROR_MAPPER_NULL);
1149 return createDoubleBinding(() -> items.values().stream().mapToDouble(mapper).max().orElse(defaultValue.doubleValue()), items);
1150 }
1151
1152 /**
1153 * Creates a number binding that computes the maximum value amongst values.
1154 *
1155 * @param items the observable map of items.
1156 * @param supplier a {@code Supplier} whose result is returned if no value is present.
1157 * @param mapper a non-interfering, stateless function to apply to the each value.
1158 *
1159 * @return a number binding
1160 */
1161 @Nonnull
1162 public static <K, V> NumberBinding maxInMap(@Nonnull final ObservableMap<K, V> items, @Nonnull final Supplier<? extends Number> supplier, @Nonnull final ToDoubleFunction<? super V> mapper) {
1163 requireNonNull(items, ERROR_ITEMS_NULL);
1164 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1165 requireNonNull(mapper, ERROR_MAPPER_NULL);
1166 return createDoubleBinding(() -> items.values().stream().mapToDouble(mapper).max().orElseGet(resolveDoubleSupplier(supplier)), items);
1167 }
1168
1169 /**
1170 * Creates a number binding that computes the average value amongst values.
1171 *
1172 * @param items the observable map of items.
1173 * @param defaultValue the value to be returned if there is no value present.
1174 * @param mapper a non-interfering, stateless function to apply to the each value.
1175 *
1176 * @return a number binding
1177 */
1178 @Nonnull
1179 public static <K, V> NumberBinding averageInMap(@Nonnull final ObservableMap<K, V> items, @Nonnull final Number defaultValue, @Nonnull final ToDoubleFunction<? super V> mapper) {
1180 requireNonNull(items, ERROR_ITEMS_NULL);
1181 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
1182 requireNonNull(mapper, ERROR_MAPPER_NULL);
1183 return createDoubleBinding(() -> items.values().stream().mapToDouble(mapper).average().orElse(defaultValue.doubleValue()), items);
1184 }
1185
1186 /**
1187 * Creates a number binding that computes the average value amongst values.
1188 *
1189 * @param items the observable map of items.
1190 * @param supplier a {@code Supplier} whose result is returned if no value is present.
1191 * @param mapper a non-interfering, stateless function to apply to the each value.
1192 *
1193 * @return a number binding
1194 */
1195 @Nonnull
1196 public static <K, V> NumberBinding averageInMap(@Nonnull final ObservableMap<K, V> items, @Nonnull final Supplier<? extends Number> supplier, @Nonnull final ToDoubleFunction<? super V> mapper) {
1197 requireNonNull(items, ERROR_ITEMS_NULL);
1198 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1199 requireNonNull(mapper, ERROR_MAPPER_NULL);
1200 return createDoubleBinding(() -> items.values().stream().mapToDouble(mapper).average().orElseGet(resolveDoubleSupplier(supplier)), items);
1201 }
1202
1203 /**
1204 * Creates a number binding that contains the sum of the values of the given observable map.
1205 *
1206 * @param items the observable map of items.
1207 * @param mapper a non-interfering, stateless function to apply to the each value.
1208 *
1209 * @return a number binding.
1210 */
1211 @Nonnull
1212 public static <K, V> NumberBinding sumOfMap(@Nonnull final ObservableMap<K, V> items, @Nonnull final ToDoubleFunction<? super V> mapper) {
1213 requireNonNull(items, ERROR_ITEMS_NULL);
1214 requireNonNull(mapper, ERROR_MAPPER_NULL);
1215 return createDoubleBinding(() -> items.values().stream().mapToDouble(mapper).sum(), items);
1216 }
1217
1218 /**
1219 * Creates a number binding that computes the minimum value amongst values.
1220 *
1221 * @param items the observable map of items.
1222 * @param defaultValue the value to be returned if there is no value present.
1223 * @param mapper a non-interfering, stateless function to apply to the each value.
1224 *
1225 * @return a number binding
1226 */
1227 @Nonnull
1228 public static <K, V> NumberBinding minInMap(@Nonnull final ObservableMap<K, V> items, @Nonnull final Number defaultValue, @Nonnull final ObservableValue<ToDoubleFunction<? super V>> mapper) {
1229 requireNonNull(items, ERROR_ITEMS_NULL);
1230 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
1231 requireNonNull(mapper, ERROR_MAPPER_NULL);
1232 return createDoubleBinding(() -> {
1233 ToDoubleFunction<? super V> mapperValue = mapper.getValue();
1234 requireNonNull(mapperValue, ERROR_MAPPER_NULL);
1235 return items.values().stream().mapToDouble(mapperValue).min().orElse(defaultValue.doubleValue());
1236 }, items, mapper);
1237 }
1238
1239 /**
1240 * Creates a number binding that computes the minimum value amongst values.
1241 *
1242 * @param items the observable map of items.
1243 * @param supplier a {@code Supplier} whose result is returned if no value is present.
1244 * @param mapper a non-interfering, stateless function to apply to the each value.
1245 *
1246 * @return a number binding
1247 */
1248 @Nonnull
1249 public static <K, V> NumberBinding minInMap(@Nonnull final ObservableMap<K, V> items, @Nonnull final Supplier<? extends Number> supplier, @Nonnull final ObservableValue<ToDoubleFunction<? super V>> mapper) {
1250 requireNonNull(items, ERROR_ITEMS_NULL);
1251 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1252 requireNonNull(mapper, ERROR_MAPPER_NULL);
1253 return createDoubleBinding(() -> {
1254 ToDoubleFunction<? super V> mapperValue = mapper.getValue();
1255 requireNonNull(mapperValue, ERROR_MAPPER_NULL);
1256 return items.values().stream().mapToDouble(mapperValue).min().orElseGet(resolveDoubleSupplier(supplier));
1257 }, items, mapper);
1258 }
1259
1260 /**
1261 * Creates a number binding that computes the maximum value amongst values.
1262 *
1263 * @param items the observable map of items.
1264 * @param defaultValue the value to be returned if there is no value present.
1265 * @param mapper a non-interfering, stateless function to apply to the each value.
1266 *
1267 * @return a number binding
1268 */
1269 @Nonnull
1270 public static <K, V> NumberBinding maxInMap(@Nonnull final ObservableMap<K, V> items, @Nonnull final Number defaultValue, @Nonnull final ObservableValue<ToDoubleFunction<? super V>> mapper) {
1271 requireNonNull(items, ERROR_ITEMS_NULL);
1272 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
1273 requireNonNull(mapper, ERROR_MAPPER_NULL);
1274 return createDoubleBinding(() -> {
1275 ToDoubleFunction<? super V> mapperValue = mapper.getValue();
1276 requireNonNull(mapperValue, ERROR_MAPPER_NULL);
1277 return items.values().stream().mapToDouble(mapperValue).max().orElse(defaultValue.doubleValue());
1278 }, items, mapper);
1279 }
1280
1281 /**
1282 * Creates a number binding that computes the maximum value amongst values.
1283 *
1284 * @param items the observable map of items.
1285 * @param supplier a {@code Supplier} whose result is returned if no value is present.
1286 * @param mapper a non-interfering, stateless function to apply to the each value.
1287 *
1288 * @return a number binding
1289 */
1290 @Nonnull
1291 public static <K, V> NumberBinding maxInMap(@Nonnull final ObservableMap<K, V> items, @Nonnull final Supplier<? extends Number> supplier, @Nonnull final ObservableValue<ToDoubleFunction<? super V>> mapper) {
1292 requireNonNull(items, ERROR_ITEMS_NULL);
1293 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1294 requireNonNull(mapper, ERROR_MAPPER_NULL);
1295 return createDoubleBinding(() -> {
1296 ToDoubleFunction<? super V> mapperValue = mapper.getValue();
1297 requireNonNull(mapperValue, ERROR_MAPPER_NULL);
1298 return items.values().stream().mapToDouble(mapperValue).max().orElseGet(resolveDoubleSupplier(supplier));
1299 }, items, mapper);
1300 }
1301
1302 /**
1303 * Creates a number binding that computes the average value amongst values.
1304 *
1305 * @param items the observable map of items.
1306 * @param defaultValue the value to be returned if there is no value present.
1307 * @param mapper a non-interfering, stateless function to apply to the each value.
1308 *
1309 * @return a number binding
1310 */
1311 @Nonnull
1312 public static <K, V> NumberBinding averageInMap(@Nonnull final ObservableMap<K, V> items, @Nonnull final Number defaultValue, @Nonnull final ObservableValue<ToDoubleFunction<? super V>> mapper) {
1313 requireNonNull(items, ERROR_ITEMS_NULL);
1314 requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
1315 requireNonNull(mapper, ERROR_MAPPER_NULL);
1316 return createDoubleBinding(() -> {
1317 ToDoubleFunction<? super V> mapperValue = mapper.getValue();
1318 requireNonNull(mapperValue, ERROR_MAPPER_NULL);
1319 return items.values().stream().mapToDouble(mapperValue).average().orElse(defaultValue.doubleValue());
1320 }, items, mapper);
1321 }
1322
1323 /**
1324 * Creates a number binding that computes the average value amongst values.
1325 *
1326 * @param items the observable map of items.
1327 * @param supplier a {@code Supplier} whose result is returned if no value is present.
1328 * @param mapper a non-interfering, stateless function to apply to the each value.
1329 *
1330 * @return a number binding
1331 */
1332 @Nonnull
1333 public static <K, V> NumberBinding averageInMap(@Nonnull final ObservableMap<K, V> items, @Nonnull final Supplier<? extends Number> supplier, @Nonnull final ObservableValue<ToDoubleFunction<? super V>> mapper) {
1334 requireNonNull(items, ERROR_ITEMS_NULL);
1335 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1336 requireNonNull(mapper, ERROR_MAPPER_NULL);
1337 return createDoubleBinding(() -> {
1338 ToDoubleFunction<? super V> mapperValue = mapper.getValue();
1339 requireNonNull(mapperValue, ERROR_MAPPER_NULL);
1340 return items.values().stream().mapToDouble(mapperValue).average().orElseGet(resolveDoubleSupplier(supplier));
1341 }, items, mapper);
1342 }
1343
1344 /**
1345 * Creates a number binding that contains the sum of the values of the given observable map.
1346 *
1347 * @param items the observable map of items.
1348 * @param mapper a non-interfering, stateless function to apply to the each value.
1349 *
1350 * @return a number binding.
1351 */
1352 @Nonnull
1353 public static <K, V> NumberBinding sumOfMap(@Nonnull final ObservableMap<K, V> items, @Nonnull final ObservableValue<ToDoubleFunction<? super V>> mapper) {
1354 requireNonNull(items, ERROR_ITEMS_NULL);
1355 requireNonNull(mapper, ERROR_MAPPER_NULL);
1356 return createDoubleBinding(() -> {
1357 ToDoubleFunction<? super V> mapperValue = mapper.getValue();
1358 requireNonNull(mapperValue, ERROR_MAPPER_NULL);
1359 return items.values().stream().mapToDouble(mapperValue).sum();
1360 }, items, mapper);
1361 }
1362
1363 @Nonnull
1364 private static DoubleSupplier resolveDoubleSupplier(@Nonnull final Supplier<? extends Number> supplier) {
1365 requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1366 return () -> supplier.get().doubleValue();
1367 }
1368 }
|