|
18 | 18 | */
|
19 | 19 | package org.apache.iceberg.util;
|
20 | 20 |
|
21 |
| -import java.io.Serializable; |
22 |
| -import java.util.Collection; |
23 |
| -import java.util.Iterator; |
24 |
| -import java.util.Set; |
25 |
| -import java.util.stream.Collectors; |
26 |
| -import org.apache.iceberg.relocated.com.google.common.collect.ImmutableList; |
| 21 | +import org.apache.iceberg.relocated.com.google.common.base.Preconditions; |
27 | 22 | import org.apache.iceberg.relocated.com.google.common.collect.Iterables;
|
28 |
| -import org.apache.iceberg.relocated.com.google.common.collect.Iterators; |
29 |
| -import org.apache.iceberg.relocated.com.google.common.collect.Sets; |
30 |
| -import org.apache.iceberg.relocated.com.google.common.collect.Streams; |
31 | 23 |
|
32 |
| -public class CharSequenceSet implements Set<CharSequence>, Serializable { |
| 24 | +public class CharSequenceSet extends WrapperSet<CharSequence> { |
33 | 25 | private static final ThreadLocal<CharSequenceWrapper> WRAPPERS =
|
34 | 26 | ThreadLocal.withInitial(() -> CharSequenceWrapper.wrap(null));
|
35 | 27 |
|
36 |
| - public static CharSequenceSet of(Iterable<CharSequence> charSequences) { |
37 |
| - return new CharSequenceSet(charSequences); |
38 |
| - } |
39 |
| - |
40 |
| - public static CharSequenceSet empty() { |
41 |
| - return new CharSequenceSet(ImmutableList.of()); |
42 |
| - } |
43 |
| - |
44 |
| - private final Set<CharSequenceWrapper> wrapperSet; |
45 |
| - |
46 |
| - private CharSequenceSet(Iterable<CharSequence> charSequences) { |
47 |
| - this.wrapperSet = |
48 |
| - Sets.newHashSet(Iterables.transform(charSequences, CharSequenceWrapper::wrap)); |
| 28 | + private CharSequenceSet() { |
| 29 | + // needed for serialization |
49 | 30 | }
|
50 | 31 |
|
51 |
| - @Override |
52 |
| - public int size() { |
53 |
| - return wrapperSet.size(); |
| 32 | + private CharSequenceSet(Iterable<? extends CharSequence> charSequences) { |
| 33 | + super( |
| 34 | + Iterables.transform( |
| 35 | + charSequences, |
| 36 | + obj -> { |
| 37 | + Preconditions.checkNotNull(obj, "Invalid object: null"); |
| 38 | + return CharSequenceWrapper.wrap(obj); |
| 39 | + })); |
54 | 40 | }
|
55 | 41 |
|
56 |
| - @Override |
57 |
| - public boolean isEmpty() { |
58 |
| - return wrapperSet.isEmpty(); |
| 42 | + public static CharSequenceSet of(Iterable<? extends CharSequence> charSequences) { |
| 43 | + return new CharSequenceSet(charSequences); |
59 | 44 | }
|
60 | 45 |
|
61 |
| - @Override |
62 |
| - public boolean contains(Object obj) { |
63 |
| - if (obj instanceof CharSequence) { |
64 |
| - CharSequenceWrapper wrapper = WRAPPERS.get(); |
65 |
| - boolean result = wrapperSet.contains(wrapper.set((CharSequence) obj)); |
66 |
| - wrapper.set(null); // don't hold a reference to the value |
67 |
| - return result; |
68 |
| - } |
69 |
| - return false; |
| 46 | + public static CharSequenceSet empty() { |
| 47 | + return new CharSequenceSet(); |
70 | 48 | }
|
71 | 49 |
|
72 | 50 | @Override
|
73 |
| - public Iterator<CharSequence> iterator() { |
74 |
| - return Iterators.transform(wrapperSet.iterator(), CharSequenceWrapper::get); |
| 51 | + protected Wrapper<CharSequence> wrapper() { |
| 52 | + return WRAPPERS.get(); |
75 | 53 | }
|
76 | 54 |
|
77 | 55 | @Override
|
78 |
| - public Object[] toArray() { |
79 |
| - return Iterators.toArray(iterator(), CharSequence.class); |
| 56 | + protected Wrapper<CharSequence> wrap(CharSequence file) { |
| 57 | + return CharSequenceWrapper.wrap(file); |
80 | 58 | }
|
81 | 59 |
|
82 | 60 | @Override
|
83 |
| - @SuppressWarnings("unchecked") |
84 |
| - public <T> T[] toArray(T[] destArray) { |
85 |
| - int size = wrapperSet.size(); |
86 |
| - if (destArray.length < size) { |
87 |
| - return (T[]) toArray(); |
88 |
| - } |
89 |
| - |
90 |
| - Iterator<CharSequence> iter = iterator(); |
91 |
| - int ind = 0; |
92 |
| - while (iter.hasNext()) { |
93 |
| - destArray[ind] = (T) iter.next(); |
94 |
| - ind += 1; |
95 |
| - } |
96 |
| - |
97 |
| - if (destArray.length > size) { |
98 |
| - destArray[size] = null; |
99 |
| - } |
100 |
| - |
101 |
| - return destArray; |
| 61 | + protected Class<CharSequence> elementClass() { |
| 62 | + return CharSequence.class; |
102 | 63 | }
|
103 | 64 |
|
104 | 65 | @Override
|
105 | 66 | public boolean add(CharSequence charSequence) {
|
106 |
| - return wrapperSet.add(CharSequenceWrapper.wrap(charSequence)); |
107 |
| - } |
108 |
| - |
109 |
| - @Override |
110 |
| - public boolean remove(Object obj) { |
111 |
| - if (obj instanceof CharSequence) { |
112 |
| - CharSequenceWrapper wrapper = WRAPPERS.get(); |
113 |
| - boolean result = wrapperSet.remove(wrapper.set((CharSequence) obj)); |
114 |
| - wrapper.set(null); // don't hold a reference to the value |
115 |
| - return result; |
116 |
| - } |
117 |
| - return false; |
118 |
| - } |
119 |
| - |
120 |
| - @Override |
121 |
| - @SuppressWarnings("CollectionUndefinedEquality") |
122 |
| - public boolean containsAll(Collection<?> objects) { |
123 |
| - if (objects != null) { |
124 |
| - return Iterables.all(objects, this::contains); |
125 |
| - } |
126 |
| - return false; |
127 |
| - } |
128 |
| - |
129 |
| - @Override |
130 |
| - public boolean addAll(Collection<? extends CharSequence> charSequences) { |
131 |
| - if (charSequences != null) { |
132 |
| - return Iterables.addAll( |
133 |
| - wrapperSet, Iterables.transform(charSequences, CharSequenceWrapper::wrap)); |
134 |
| - } |
135 |
| - return false; |
136 |
| - } |
137 |
| - |
138 |
| - @Override |
139 |
| - public boolean retainAll(Collection<?> objects) { |
140 |
| - if (objects != null) { |
141 |
| - Set<CharSequenceWrapper> toRetain = |
142 |
| - objects.stream() |
143 |
| - .filter(CharSequence.class::isInstance) |
144 |
| - .map(CharSequence.class::cast) |
145 |
| - .map(CharSequenceWrapper::wrap) |
146 |
| - .collect(Collectors.toSet()); |
147 |
| - |
148 |
| - return Iterables.retainAll(wrapperSet, toRetain); |
149 |
| - } |
150 |
| - |
151 |
| - return false; |
152 |
| - } |
153 |
| - |
154 |
| - @Override |
155 |
| - @SuppressWarnings("CollectionUndefinedEquality") |
156 |
| - public boolean removeAll(Collection<?> objects) { |
157 |
| - if (objects != null) { |
158 |
| - return objects.stream().filter(this::remove).count() != 0; |
159 |
| - } |
160 |
| - |
161 |
| - return false; |
162 |
| - } |
163 |
| - |
164 |
| - @Override |
165 |
| - public void clear() { |
166 |
| - wrapperSet.clear(); |
167 |
| - } |
168 |
| - |
169 |
| - @SuppressWarnings("CollectionUndefinedEquality") |
170 |
| - @Override |
171 |
| - public boolean equals(Object other) { |
172 |
| - if (this == other) { |
173 |
| - return true; |
174 |
| - } else if (!(other instanceof Set)) { |
175 |
| - return false; |
176 |
| - } |
177 |
| - |
178 |
| - Set<?> that = (Set<?>) other; |
179 |
| - |
180 |
| - if (size() != that.size()) { |
181 |
| - return false; |
182 |
| - } |
183 |
| - |
184 |
| - try { |
185 |
| - return containsAll(that); |
186 |
| - } catch (ClassCastException | NullPointerException unused) { |
187 |
| - return false; |
188 |
| - } |
189 |
| - } |
190 |
| - |
191 |
| - @Override |
192 |
| - public int hashCode() { |
193 |
| - return wrapperSet.stream().mapToInt(CharSequenceWrapper::hashCode).sum(); |
194 |
| - } |
195 |
| - |
196 |
| - @Override |
197 |
| - public String toString() { |
198 |
| - return Streams.stream(iterator()).collect(Collectors.joining("CharSequenceSet({", ", ", "})")); |
| 67 | + // method is needed to not break API compatibility |
| 68 | + return super.add(charSequence); |
199 | 69 | }
|
200 | 70 | }
|
0 commit comments