1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.collections4.multiset;
18
19 import java.util.Comparator;
20
21 import org.apache.commons.collections4.SortedMultiSet;
22 import org.apache.commons.collections4.Transformer;
23
24 /**
25 * Decorates another {@link SortedMultiSet} to transform objects that are added.
26 * <p>
27 * The add and setCount methods are affected by this class.
28 * Thus objects must be removed or searched for using their transformed form.
29 * For example, if the transformation converts Strings to Integers, you must
30 * use the Integer form to remove objects.
31 * </p>
32 *
33 * @param <E> The type held in the multiset.
34 * @since 4.6.0
35 */
36 public class TransformedSortedMultiSet<E> extends TransformedMultiSet<E> implements SortedMultiSet<E> {
37
38 /** Serialization version */
39 private static final long serialVersionUID = 20260710L;
40
41 /**
42 * Factory method to create a transforming sorted multiset that will transform
43 * existing contents of the specified sorted multiset.
44 * <p>
45 * If there are any elements already in the multiset being decorated, they
46 * will be transformed by this method.
47 * Contrast this with {@link #transformingSortedMultiSet(SortedMultiSet, Transformer)}.
48 * </p>
49 *
50 * @param <E> The type of the elements in the multiset.
51 * @param multiset The multiset to decorate, must not be null.
52 * @param transformer The transformer to use for conversion, must not be null.
53 * @return A new transformed SortedMultiSet.
54 * @throws NullPointerException if multiset or transformer is null.
55 */
56 public static <E> TransformedSortedMultiSet<E> transformedSortedMultiSet(final SortedMultiSet<E> multiset,
57 final Transformer<? super E, ? extends E> transformer) {
58 final TransformedSortedMultiSet<E> decorated = new TransformedSortedMultiSet<>(multiset, transformer);
59 if (!multiset.isEmpty()) {
60 @SuppressWarnings("unchecked") // multiset is of type E
61 final E[] values = (E[]) multiset.toArray(); // NOPMD - false positive for generics
62 multiset.clear();
63 for (final E value : values) {
64 decorated.decorated().add(transformer.apply(value));
65 }
66 }
67 return decorated;
68 }
69
70 /**
71 * Factory method to create a transforming sorted multiset.
72 * <p>
73 * If there are any elements already in the multiset being decorated, they
74 * are NOT transformed. Contrast this with
75 * {@link #transformedSortedMultiSet(SortedMultiSet, Transformer)}.
76 * </p>
77 *
78 * @param <E> The type of the elements in the multiset.
79 * @param multiset The multiset to decorate, must not be null.
80 * @param transformer The transformer to use for conversion, must not be null.
81 * @return A new transformed SortedMultiSet.
82 * @throws NullPointerException if multiset or transformer is null.
83 */
84 public static <E> TransformedSortedMultiSet<E> transformingSortedMultiSet(final SortedMultiSet<E> multiset,
85 final Transformer<? super E, ? extends E> transformer) {
86 return new TransformedSortedMultiSet<>(multiset, transformer);
87 }
88
89 /**
90 * Constructor that wraps (not copies).
91 * <p>
92 * If there are any elements already in the multiset being decorated, they
93 * are NOT transformed.
94 * </p>
95 *
96 * @param multiset The multiset to decorate, must not be null.
97 * @param transformer The transformer to use for conversion, must not be null.
98 * @throws NullPointerException if multiset or transformer is null.
99 */
100 protected TransformedSortedMultiSet(final SortedMultiSet<E> multiset,
101 final Transformer<? super E, ? extends E> transformer) {
102 super(multiset, transformer);
103 }
104
105 @Override
106 public Comparator<? super E> comparator() {
107 return getSortedMultiSet().comparator();
108 }
109
110 @Override
111 public E first() {
112 return getSortedMultiSet().first();
113 }
114
115 /**
116 * Gets the decorated sorted multiset.
117 *
118 * @return The decorated sorted multiset.
119 */
120 protected SortedMultiSet<E> getSortedMultiSet() {
121 return (SortedMultiSet<E>) decorated();
122 }
123
124 @Override
125 public E last() {
126 return getSortedMultiSet().last();
127 }
128
129 }