@@ -43,6 +43,19 @@ static Opaque forBytes(byte[] bytes) {
4343 return new OpaqueImpl (bytes .clone ());
4444 }
4545
46+ /**
47+ * Returns an mutable {@link Opaque} instance based on the given byte array.
48+ * <p>
49+ * Note that the returned {@link Opaque} is typically not suitable for <em>storing</em> in a
50+ * {@link java.util.HashMap}, but merely for lookups. Call {@link #toImmutableOpaque()} when necessary.
51+ *
52+ * @param bytes The bytes.
53+ * @return The {@link Opaque} instance.
54+ */
55+ static Opaque forMutableByteArray (byte [] bytes ) {
56+ return new OpaqueMutableImpl (bytes );
57+ }
58+
4659 /**
4760 * Returns an immutable {@link Opaque} instance based on a copy of the {@code length} bytes from the given
4861 * {@link ByteBuffer}.
@@ -161,12 +174,12 @@ default void putBytes(ByteBuffer buf) {
161174 @ Override
162175 boolean equals (Object o );
163176
164- final class OpaqueImpl implements Opaque {
165- private final byte [] _opaque ;
177+ class OpaqueImpl implements Opaque {
178+ final byte [] _opaque ;
166179 private String base64 = null ;
167180 private int hashCode ;
168181
169- private OpaqueImpl (byte [] opaque ) {
182+ OpaqueImpl (byte [] opaque ) {
170183 _opaque = opaque ;
171184 }
172185
@@ -175,10 +188,14 @@ public byte[] toBytes() {
175188 return _opaque .clone ();
176189 }
177190
191+ protected String toBase64Impl () {
192+ return Base64 .getEncoder ().withoutPadding ().encodeToString (_opaque );
193+ }
194+
178195 @ Override
179196 public String toBase64 () {
180197 if (base64 == null ) {
181- base64 = Base64 . getEncoder (). withoutPadding (). encodeToString ( _opaque );
198+ base64 = toBase64Impl ( );
182199 }
183200 return base64 ;
184201 }
@@ -246,6 +263,28 @@ public Opaque toImmutableOpaque() {
246263 }
247264 }
248265
266+ final class OpaqueMutableImpl extends OpaqueImpl {
267+ protected OpaqueMutableImpl (byte [] opaque ) {
268+ super (opaque );
269+ }
270+
271+ @ Override
272+ public Opaque toImmutableOpaque () {
273+ return Opaque .forBytes (_opaque );
274+ }
275+
276+ @ Override
277+ public String toBase64 () {
278+ return toBase64Impl ();
279+ }
280+
281+ @ Override
282+ public int hashCode () {
283+ return Arrays .hashCode (_opaque );
284+ }
285+
286+ }
287+
249288 final class OpaqueBufferImpl implements Opaque {
250289 private final ByteBuffer buf ;
251290 private final int index ;
0 commit comments