|
1 | 1 | package ai.timefold.solver.core.api.score.stream; |
2 | 2 |
|
| 3 | +import java.util.Collection; |
3 | 4 | import java.util.function.BiFunction; |
4 | 5 | import java.util.function.BiPredicate; |
5 | 6 | import java.util.function.Function; |
@@ -256,6 +257,92 @@ public final class Joiners { |
256 | 257 | .and(Joiners.greaterThan(leftEndMapping, rightStartMapping)); |
257 | 258 | } |
258 | 259 |
|
| 260 | + /** |
| 261 | + * Joins every A and B where a value of property on B is contained in the collection of properties on A. |
| 262 | + * <p> |
| 263 | + * For example: |
| 264 | + * <ul> |
| 265 | + * <li>{@code ["A", "B"]} containing {@code "A"} is {@code true}</li> |
| 266 | + * <li>{@code ["A"]} containing {@code "A"} is {@code true}</li> |
| 267 | + * <li>{@code ["X", "Y"]} containing {@code "A"} is {@code false}</li> |
| 268 | + * <li>{@code []} containing {@code "A"} is {@code false}</li> |
| 269 | + * <li>{@code ["A", "B"]} containing {@code null} is {@code false}</li> |
| 270 | + * <li>{@code []} containing {@code null} is {@code false}</li> |
| 271 | + * </ul> |
| 272 | + * |
| 273 | + * @param leftMapping mapping function to apply to A |
| 274 | + * @param rightMapping mapping function to apply to B |
| 275 | + * @param <A> the type of object on the left |
| 276 | + * @param <B> the type of object on the right |
| 277 | + * @param <Property_> the type of the property to compare |
| 278 | + */ |
| 279 | + public static <A, B, Property_> @NonNull BiJoiner<A, B> containing(@NonNull Function<A, Collection<Property_>> leftMapping, |
| 280 | + @NonNull Function<B, Property_> rightMapping) { |
| 281 | + return new DefaultBiJoiner<>(leftMapping, JoinerType.CONTAINING, rightMapping); |
| 282 | + } |
| 283 | + |
| 284 | + /** |
| 285 | + * Joins every A and B where a value of property on A is contained in the collection of properties on B. |
| 286 | + * <p> |
| 287 | + * For example: |
| 288 | + * <ul> |
| 289 | + * <li>{@code "A"} contained in {@code ["A", "B"]} is {@code true}</li> |
| 290 | + * <li>{@code "A"} contained in {@code ["A"]} is {@code true}</li> |
| 291 | + * <li>{@code "A"} contained in {@code ["X", "Y"]} is {@code false}</li> |
| 292 | + * <li>{@code "A"} contained in {@code []} is {@code false}</li> |
| 293 | + * <li>{@code null} contained in {@code ["A", "B"]} is {@code false}</li> |
| 294 | + * <li>{@code null} contained in {@code []} is {@code false}</li> |
| 295 | + * </ul> |
| 296 | + * |
| 297 | + * @param leftMapping mapping function to apply to A |
| 298 | + * @param rightMapping mapping function to apply to B |
| 299 | + * @param <A> the type of object on the left |
| 300 | + * @param <B> the type of object on the right |
| 301 | + * @param <Property_> the type of the property to compare |
| 302 | + */ |
| 303 | + public static <A, B, Property_> @NonNull BiJoiner<A, B> containedIn(@NonNull Function<A, Property_> leftMapping, |
| 304 | + @NonNull Function<B, Collection<Property_>> rightMapping) { |
| 305 | + return new DefaultBiJoiner<>(leftMapping, JoinerType.CONTAINED_IN, rightMapping); |
| 306 | + } |
| 307 | + |
| 308 | + /** |
| 309 | + * As defined by {@link #containingAnyOf(Function, Function)} with both arguments using the same mapping. |
| 310 | + * |
| 311 | + * @param mapping mapping function to apply to both A and B |
| 312 | + * @param <A> the type of both objects |
| 313 | + * @param <Property_> the type of the property to compare |
| 314 | + */ |
| 315 | + public static <A, Property_> @NonNull BiJoiner<A, A> containingAnyOf( |
| 316 | + @NonNull Function<A, Collection<Property_>> mapping) { |
| 317 | + return containingAnyOf(mapping, mapping); |
| 318 | + } |
| 319 | + |
| 320 | + /** |
| 321 | + * Joins every A and B where a collection of properties on A overlaps with a collection of properties on B. |
| 322 | + * <p> |
| 323 | + * For example: |
| 324 | + * <ul> |
| 325 | + * <li>{@code ["A", "B"]} intersecting {@code ["A", "B"]} is {@code true}</li> |
| 326 | + * <li>{@code ["A", "B"]} intersecting {@code ["A"]} is {@code true}</li> |
| 327 | + * <li>{@code ["A"]} intersecting {@code ["A", "B"]} is {@code true}</li> |
| 328 | + * <li>{@code ["A", "B"]} intersecting {@code ["X", "Y"]} is {@code false}</li> |
| 329 | + * <li>{@code ["A", "B"]} intersecting {@code []} is {@code false}</li> |
| 330 | + * <li>{@code []} intersecting {@code ["A", "B"]} is {@code false}</li> |
| 331 | + * <li>{@code []} intersecting {@code []} is {@code false}</li> |
| 332 | + * </ul> |
| 333 | + * |
| 334 | + * @param leftMapping mapping function to apply to A |
| 335 | + * @param rightMapping mapping function to apply to B |
| 336 | + * @param <A> the type of object on the left |
| 337 | + * @param <B> the type of object on the right |
| 338 | + * @param <Property_> the type of the property to compare |
| 339 | + */ |
| 340 | + public static <A, B, Property_> @NonNull BiJoiner<A, B> containingAnyOf( |
| 341 | + @NonNull Function<A, Collection<Property_>> leftMapping, |
| 342 | + @NonNull Function<B, Collection<Property_>> rightMapping) { |
| 343 | + return new DefaultBiJoiner<>(leftMapping, JoinerType.CONTAINING_ANY_OF, rightMapping); |
| 344 | + } |
| 345 | + |
259 | 346 | // ************************************************************************ |
260 | 347 | // TriJoiner |
261 | 348 | // ************************************************************************ |
@@ -366,6 +453,53 @@ public final class Joiners { |
366 | 453 | .and(Joiners.greaterThan(leftEndMapping, rightStartMapping)); |
367 | 454 | } |
368 | 455 |
|
| 456 | + /** |
| 457 | + * As defined by {@link #containing(Function, Function)}. |
| 458 | + * |
| 459 | + * @param <A> the type of the first object on the left |
| 460 | + * @param <B> the type of the second object on the left |
| 461 | + * @param <C> the type of the object on the right |
| 462 | + * @param <Property_> the type of the collection elements |
| 463 | + * @param leftMapping mapping function to apply to (A,B) |
| 464 | + * @param rightMapping mapping function to apply to C |
| 465 | + */ |
| 466 | + public static <A, B, C, Property_> @NonNull TriJoiner<A, B, C> containing( |
| 467 | + @NonNull BiFunction<A, B, Collection<Property_>> leftMapping, |
| 468 | + @NonNull Function<C, Property_> rightMapping) { |
| 469 | + return new DefaultTriJoiner<>(leftMapping, JoinerType.CONTAINING, rightMapping); |
| 470 | + } |
| 471 | + |
| 472 | + /** |
| 473 | + * As defined by {@link #containedIn(Function, Function)}. |
| 474 | + * |
| 475 | + * @param <A> the type of the first object on the left |
| 476 | + * @param <B> the type of the second object on the left |
| 477 | + * @param <C> the type of the object on the right |
| 478 | + * @param <Property_> the type of the collection elements |
| 479 | + * @param leftMapping mapping function to apply to (A,B) |
| 480 | + * @param rightMapping mapping function to apply to C |
| 481 | + */ |
| 482 | + public static <A, B, C, Property_> @NonNull TriJoiner<A, B, C> containedIn(@NonNull BiFunction<A, B, Property_> leftMapping, |
| 483 | + @NonNull Function<C, Collection<Property_>> rightMapping) { |
| 484 | + return new DefaultTriJoiner<>(leftMapping, JoinerType.CONTAINED_IN, rightMapping); |
| 485 | + } |
| 486 | + |
| 487 | + /** |
| 488 | + * As defined by {@link #containingAnyOf(Function, Function)}. |
| 489 | + * |
| 490 | + * @param <A> the type of the first object on the left |
| 491 | + * @param <B> the type of the second object on the left |
| 492 | + * @param <C> the type of the object on the right |
| 493 | + * @param <Property_> the type of the collection elements |
| 494 | + * @param leftMapping mapping function to apply to (A,B) |
| 495 | + * @param rightMapping mapping function to apply to C |
| 496 | + */ |
| 497 | + public static <A, B, C, Property_> @NonNull TriJoiner<A, B, C> containingAnyOf( |
| 498 | + @NonNull BiFunction<A, B, Collection<Property_>> leftMapping, |
| 499 | + @NonNull Function<C, Collection<Property_>> rightMapping) { |
| 500 | + return new DefaultTriJoiner<>(leftMapping, JoinerType.CONTAINING_ANY_OF, rightMapping); |
| 501 | + } |
| 502 | + |
369 | 503 | // ************************************************************************ |
370 | 504 | // QuadJoiner |
371 | 505 | // ************************************************************************ |
@@ -483,6 +617,57 @@ public final class Joiners { |
483 | 617 | .and(Joiners.greaterThan(leftEndMapping, rightStartMapping)); |
484 | 618 | } |
485 | 619 |
|
| 620 | + /** |
| 621 | + * As defined by {@link #containing(Function, Function)}. |
| 622 | + * |
| 623 | + * @param <A> the type of the first object on the left |
| 624 | + * @param <B> the type of the second object on the left |
| 625 | + * @param <C> the type of the third object on the left |
| 626 | + * @param <D> the type of the object on the right |
| 627 | + * @param <Property_> the type of the collection elements |
| 628 | + * @param leftMapping mapping function to apply to (A,B,C) |
| 629 | + * @param rightMapping mapping function to apply to D |
| 630 | + */ |
| 631 | + public static <A, B, C, D, Property_> @NonNull QuadJoiner<A, B, C, D> containing( |
| 632 | + @NonNull TriFunction<A, B, C, Collection<Property_>> leftMapping, |
| 633 | + @NonNull Function<D, Property_> rightMapping) { |
| 634 | + return new DefaultQuadJoiner<>(leftMapping, JoinerType.CONTAINING, rightMapping); |
| 635 | + } |
| 636 | + |
| 637 | + /** |
| 638 | + * As defined by {@link #containedIn(Function, Function)}. |
| 639 | + * |
| 640 | + * @param <A> the type of the first object on the left |
| 641 | + * @param <B> the type of the second object on the left |
| 642 | + * @param <C> the type of the third object on the left |
| 643 | + * @param <D> the type of the object on the right |
| 644 | + * @param <Property_> the type of the collection elements |
| 645 | + * @param leftMapping mapping function to apply to (A,B,C) |
| 646 | + * @param rightMapping mapping function to apply to D |
| 647 | + */ |
| 648 | + public static <A, B, C, D, Property_> @NonNull QuadJoiner<A, B, C, D> containedIn( |
| 649 | + @NonNull TriFunction<A, B, C, Property_> leftMapping, |
| 650 | + @NonNull Function<D, Collection<Property_>> rightMapping) { |
| 651 | + return new DefaultQuadJoiner<>(leftMapping, JoinerType.CONTAINED_IN, rightMapping); |
| 652 | + } |
| 653 | + |
| 654 | + /** |
| 655 | + * As defined by {@link #containingAnyOf(Function, Function)}. |
| 656 | + * |
| 657 | + * @param <A> the type of the first object on the left |
| 658 | + * @param <B> the type of the second object on the left |
| 659 | + * @param <C> the type of the third object on the left |
| 660 | + * @param <D> the type of the object on the right |
| 661 | + * @param <Property_> the type of the collection elements |
| 662 | + * @param leftMapping mapping function to apply to (A,B,C) |
| 663 | + * @param rightMapping mapping function to apply to D |
| 664 | + */ |
| 665 | + public static <A, B, C, D, Property_> @NonNull QuadJoiner<A, B, C, D> containingAnyOf( |
| 666 | + @NonNull TriFunction<A, B, C, Collection<Property_>> leftMapping, |
| 667 | + @NonNull Function<D, Collection<Property_>> rightMapping) { |
| 668 | + return new DefaultQuadJoiner<>(leftMapping, JoinerType.CONTAINING_ANY_OF, rightMapping); |
| 669 | + } |
| 670 | + |
486 | 671 | // ************************************************************************ |
487 | 672 | // PentaJoiner |
488 | 673 | // ************************************************************************ |
@@ -608,7 +793,60 @@ public final class Joiners { |
608 | 793 | .and(Joiners.greaterThan(leftEndMapping, rightStartMapping)); |
609 | 794 | } |
610 | 795 |
|
611 | | - private Joiners() { |
| 796 | + /** |
| 797 | + * As defined by {@link #containing(Function, Function)}. |
| 798 | + * |
| 799 | + * @param <A> the type of the first object on the left |
| 800 | + * @param <B> the type of the second object on the left |
| 801 | + * @param <C> the type of the third object on the left |
| 802 | + * @param <D> the type of the fourth object on the left |
| 803 | + * @param <E> the type of the object on the right |
| 804 | + * @param <Property_> the type of the collection elements |
| 805 | + * @param leftMapping mapping function to apply to (A,B,C,D) |
| 806 | + * @param rightMapping mapping function to apply to E |
| 807 | + */ |
| 808 | + public static <A, B, C, D, E, Property_> @NonNull PentaJoiner<A, B, C, D, E> containing( |
| 809 | + @NonNull QuadFunction<A, B, C, D, Collection<Property_>> leftMapping, |
| 810 | + @NonNull Function<E, Property_> rightMapping) { |
| 811 | + return new DefaultPentaJoiner<>(leftMapping, JoinerType.CONTAINING, rightMapping); |
| 812 | + } |
| 813 | + |
| 814 | + /** |
| 815 | + * As defined by {@link #containedIn(Function, Function)}. |
| 816 | + * |
| 817 | + * @param <A> the type of the first object on the left |
| 818 | + * @param <B> the type of the second object on the left |
| 819 | + * @param <C> the type of the third object on the left |
| 820 | + * @param <D> the type of the fourth object on the left |
| 821 | + * @param <E> the type of the object on the right |
| 822 | + * @param <Property_> the type of the collection elements |
| 823 | + * @param leftMapping mapping function to apply to (A,B,C,D) |
| 824 | + * @param rightMapping mapping function to apply to E |
| 825 | + */ |
| 826 | + public static <A, B, C, D, E, Property_> @NonNull PentaJoiner<A, B, C, D, E> containedIn( |
| 827 | + @NonNull QuadFunction<A, B, C, D, Property_> leftMapping, |
| 828 | + @NonNull Function<E, Collection<Property_>> rightMapping) { |
| 829 | + return new DefaultPentaJoiner<>(leftMapping, JoinerType.CONTAINED_IN, rightMapping); |
612 | 830 | } |
613 | 831 |
|
| 832 | + /** |
| 833 | + * As defined by {@link #containingAnyOf(Function, Function)}. |
| 834 | + * |
| 835 | + * @param <A> the type of the first object on the left |
| 836 | + * @param <B> the type of the second object on the left |
| 837 | + * @param <C> the type of the third object on the left |
| 838 | + * @param <D> the type of the fourth object on the left |
| 839 | + * @param <E> the type of the object on the right |
| 840 | + * @param <Property_> the type of the collection elements |
| 841 | + * @param leftMapping mapping function to apply to (A,B,C,D) |
| 842 | + * @param rightMapping mapping function to apply to E |
| 843 | + */ |
| 844 | + public static <A, B, C, D, E, Property_> @NonNull PentaJoiner<A, B, C, D, E> containingAnyOf( |
| 845 | + @NonNull QuadFunction<A, B, C, D, Collection<Property_>> leftMapping, |
| 846 | + @NonNull Function<E, Collection<Property_>> rightMapping) { |
| 847 | + return new DefaultPentaJoiner<>(leftMapping, JoinerType.CONTAINING_ANY_OF, rightMapping); |
| 848 | + } |
| 849 | + |
| 850 | + private Joiners() { |
| 851 | + } |
614 | 852 | } |
0 commit comments