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