11package me .croabeast .file ;
22
3+ import lombok .Getter ;
34import org .jetbrains .annotations .NotNull ;
45
56import java .util .*;
7+ import java .util .function .Supplier ;
68
79/**
810 * A concrete implementation of {@link Mappable} backed by a {@link HashMap}.
911 * <p>
1012 * {@code HashMappable} associates integer keys with collections of elements of type {@code T}.
1113 * It extends {@code HashMap<Integer, C>} and implements the {@code Mappable} interface, providing
12- * utility methods for ordering and copying the mapping. This implementation is intended as a base
13- * class; certain methods (such as {@link #getStoredValues()}) must be overridden in subclasses or
14- * specific instances to provide concrete functionality.
14+ * utility methods for ordering and copying the mapping. In addition, it stores a {@link Supplier} to
15+ * generate new instances of the collection type {@code C} when needed.
1516 * </p>
1617 *
1718 * @param <T> the type of elements stored in the collections.
1819 * @param <C> the type of collection that holds the elements.
1920 * @see Mappable
2021 */
22+ @ Getter
2123public class HashMappable <T , C extends Collection <T >> extends HashMap <Integer , C > implements Mappable <T , C , HashMappable <T , C >> {
2224
2325 /**
24- * Constructs an empty {@code HashMappable }.
26+ * A supplier for creating new instances of the collection type {@code C }.
2527 */
26- public HashMappable () {}
28+ private final Supplier <C > supplier ;
29+
30+ /**
31+ * Constructs an empty {@code HashMappable} with the specified collection supplier.
32+ *
33+ * @param supplier a {@link Supplier} used to create new collections of type {@code C}; must not be {@code null}
34+ */
35+ public HashMappable (Supplier <C > supplier ) {
36+ super ();
37+ this .supplier = Objects .requireNonNull (supplier );
38+ }
2739
2840 /**
2941 * Constructs a new {@code HashMappable} with the mappings copied from the provided map.
3042 *
31- * @param map the map whose entries are to be placed in this mappable.
43+ * @param supplier a {@link Supplier} used to create new collections of type {@code C}; must not be {@code null}
44+ * @param map the map whose entries are to be placed in this mappable
3245 */
33- public HashMappable (Map <Integer , ? extends C > map ) {
46+ public HashMappable (Supplier < C > supplier , Map <Integer , ? extends C > map ) {
3447 super (map );
48+ this .supplier = Objects .requireNonNull (supplier );
3549 }
3650
3751 /**
@@ -42,49 +56,58 @@ public HashMappable(Map<Integer, ? extends C> map) {
4256 * containing the ordered entries.
4357 * </p>
4458 *
45- * @param comparator the comparator used for ordering the keys.
46- * @return a new {@code HashMappable} instance with entries ordered according to the comparator.
59+ * @param comparator the comparator used for ordering the keys; must not be {@code null}
60+ * @return a new {@code HashMappable} instance with entries ordered according to the comparator
4761 */
4862 @ NotNull
4963 public HashMappable <T , C > order (Comparator <Integer > comparator ) {
5064 TreeMap <Integer , C > map = new TreeMap <>(comparator );
51- map .putAll (this );
52- return new HashMappable <>(map );
65+ forEach ((k , v ) -> {
66+ C collection = supplier .get ();
67+ collection .addAll (v );
68+ map .put (k , collection );
69+ });
70+ return new HashMappable <>(supplier , map );
5371 }
5472
5573 /**
5674 * Creates a shallow copy of this {@code HashMappable}.
5775 * <p>
58- * The returned copy contains the same keys and values as this instance.
76+ * The returned copy contains the same keys and values as this instance. Note that the collections
77+ * associated with each key are also copied using the supplier, but their elements are not deep-cloned.
5978 * </p>
6079 *
61- * @return a new {@code HashMappable} instance with the same data.
80+ * @return a new {@code HashMappable} instance with the same data as this instance .
6281 */
6382 @ NotNull
6483 public HashMappable <T , C > copy () {
65- return new HashMappable <>(this );
84+ HashMappable <T , C > mappable = new HashMappable <>(supplier );
85+ forEach ((k , v ) -> {
86+ C collection = supplier .get ();
87+ collection .addAll (v );
88+ mappable .put (k , collection );
89+ });
90+ return mappable ;
6691 }
6792
6893 /**
69- * Retrieves all stored values combined into a single collection.
94+ * Retrieves all stored values across all keys combined into a single collection.
7095 * <p>
71- * <b>Note:</b> This method is not implemented in {@code HashMappable} and throws an
72- * {@link UnsupportedOperationException}. It must be overridden in a subclass or a concrete
73- * instance to provide the desired behavior.
96+ * This method collects all elements from each collection in the mapping and returns a new collection
97+ * containing all these elements.
7498 * </p>
7599 *
76- * @return a collection containing all values from the mapping.
77- * @throws UnsupportedOperationException if this method is not overridden.
100+ * @return a collection containing all values from the mapping
78101 */
79102 @ NotNull
80103 public C getStoredValues () {
81- throw new UnsupportedOperationException ( " getStoredValues" );
104+ return getStoredValues ( supplier );
82105 }
83106
84107 /**
85- * Returns this instance.
108+ * Returns this instance as a {@code HashMappable} .
86109 *
87- * @return this {@code HashMappable} instance.
110+ * @return this {@code HashMappable} instance
88111 */
89112 @ NotNull
90113 public HashMappable <T , C > instance () {
0 commit comments