import java.util.List;
import java.util.Map;
import java.util.Set;
-import javax.annotation.Nonnull;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
/**
* Implementation of the {@link Map} interface which stores a set of immutable mappings using a key-to-offset map and
static final class Ordered<K, V> extends ImmutableOffsetMap<K, V> {
private static final long serialVersionUID = 1L;
- Ordered(final Map<K, Integer> offsets, final V[] objects) {
+ Ordered(final @NonNull Map<K, Integer> offsets, final @NonNull V[] objects) {
super(offsets, objects);
}
- @Nonnull
@Override
- public MutableOffsetMap<K, V> toModifiableMap() {
+ public @NonNull MutableOffsetMap<K, V> toModifiableMap() {
return MutableOffsetMap.orderedCopyOf(this);
}
super(offsets, objects);
}
- @Nonnull
@Override
- public MutableOffsetMap<K, V> toModifiableMap() {
+ public @NonNull MutableOffsetMap<K, V> toModifiableMap() {
return MutableOffsetMap.unorderedCopyOf(this);
}
private static final long serialVersionUID = 1L;
- private final transient Map<K, Integer> offsets;
- private final transient V[] objects;
+ private final transient @NonNull Map<K, Integer> offsets;
+ private final transient @NonNull V[] objects;
private transient int hashCode;
/**
* @param objects Array of value object, may not be null. The array is stored as is, the caller
* is responsible for ensuring its contents remain unmodified.
*/
- ImmutableOffsetMap(@Nonnull final Map<K, Integer> offsets, @Nonnull final V[] objects) {
+ ImmutableOffsetMap(final @NonNull Map<K, Integer> offsets, final @NonNull V[] objects) {
this.offsets = requireNonNull(offsets);
this.objects = requireNonNull(objects);
checkArgument(offsets.size() == objects.length);
}
- @Nonnull
@Override
- public abstract MutableOffsetMap<K, V> toModifiableMap();
+ public abstract @NonNull MutableOffsetMap<K, V> toModifiableMap();
abstract void setFields(List<K> keys, V[] values) throws IOException;
* Input map, may not be null.
* @return An isolated, immutable copy of the input map
*/
- @Nonnull public static <K, V> Map<K, V> orderedCopyOf(@Nonnull final Map<K, V> map) {
- // Prevent a copy. Note that ImmutableMap is not listed here because of its potentially larger keySet overhead.
- if (map instanceof ImmutableOffsetMap || map instanceof SharedSingletonMap) {
- return map;
- }
-
- // Familiar and efficient to copy
- if (map instanceof MutableOffsetMap) {
- return ((MutableOffsetMap<K, V>) map).toUnmodifiableMap();
+ public static <K, V> @NonNull Map<K, V> orderedCopyOf(final @NonNull Map<K, V> map) {
+ final Map<K, V> common = commonCopy(map);
+ if (common != null) {
+ return common;
}
final int size = map.size();
- if (size == 0) {
- // Shares a single object
- return ImmutableMap.of();
- }
if (size == 1) {
// Efficient single-entry implementation
final Entry<K, V> e = map.entrySet().iterator().next();
* Input map, may not be null.
* @return An isolated, immutable copy of the input map
*/
- @Nonnull public static <K, V> Map<K, V> unorderedCopyOf(@Nonnull final Map<K, V> map) {
- // Prevent a copy. Note that ImmutableMap is not listed here because of its potentially larger keySet overhead.
- if (map instanceof ImmutableOffsetMap || map instanceof SharedSingletonMap) {
- return map;
- }
-
- // Familiar and efficient to copy
- if (map instanceof MutableOffsetMap) {
- return ((MutableOffsetMap<K, V>) map).toUnmodifiableMap();
+ public static <K, V> @NonNull Map<K, V> unorderedCopyOf(final @NonNull Map<K, V> map) {
+ final Map<K, V> common = commonCopy(map);
+ if (common != null) {
+ return common;
}
final int size = map.size();
- if (size == 0) {
- // Shares a single object
- return ImmutableMap.of();
- }
if (size == 1) {
// Efficient single-entry implementation
final Entry<K, V> e = map.entrySet().iterator().next();
return new Unordered<>(offsets, array);
}
+ private static <K, V> @Nullable Map<K, V> commonCopy(final @NonNull Map<K, V> map) {
+ // Prevent a copy. Note that ImmutableMap is not listed here because of its potentially larger keySet overhead.
+ if (map instanceof ImmutableOffsetMap || map instanceof SharedSingletonMap) {
+ return map;
+ }
+
+ // Familiar and efficient to copy
+ if (map instanceof MutableOffsetMap) {
+ return ((MutableOffsetMap<K, V>) map).toUnmodifiableMap();
+ }
+
+ if (map.isEmpty()) {
+ // Shares a single object
+ return ImmutableMap.of();
+ }
+
+ return null;
+ }
+
@Override
public final int size() {
return offsets.size();
@Override
@SuppressWarnings("checkstyle:parameterName")
- public final void putAll(@Nonnull final Map<? extends K, ? extends V> m) {
+ public final void putAll(final Map<? extends K, ? extends V> m) {
throw new UnsupportedOperationException();
}
return offsets.keySet();
}
- @Nonnull
@Override
- public final Collection<V> values() {
+ public final @NonNull Collection<V> values() {
return new ConstantArrayCollection<>(objects);
}
- @Nonnull
@Override
- public final Set<Entry<K, V>> entrySet() {
+ public final @NonNull Set<Entry<K, V>> entrySet() {
return new EntrySet();
}
return sb.append('}').toString();
}
- final Map<K, Integer> offsets() {
+ final @NonNull Map<K, Integer> offsets() {
return offsets;
}
- final V[] objects() {
+ final @NonNull V[] objects() {
return objects;
}
private final class EntrySet extends AbstractSet<Entry<K, V>> {
- @Nonnull
@Override
- public Iterator<Entry<K, V>> iterator() {
+ public @NonNull Iterator<Entry<K, V>> iterator() {
final Iterator<Entry<K, Integer>> it = offsets.entrySet().iterator();
-
return new UnmodifiableIterator<Entry<K, V>>() {
@Override
public boolean hasNext() {
private static final Field OFFSETS_FIELD = fieldFor("offsets");
private static final Field ARRAY_FIELD = fieldFor("objects");
- private static Field fieldFor(final String name) {
+ private static @NonNull Field fieldFor(final @NonNull String name) {
final Field f;
try {
f = ImmutableOffsetMap.class.getDeclaredField(name);
return f;
}
- private static void setField(final ImmutableOffsetMap<?, ?> map, final Field field, final Object value)
- throws IOException {
+ private static void setField(final @NonNull ImmutableOffsetMap<?, ?> map, final @NonNull Field field,
+ final Object value) throws IOException {
try {
field.set(map, value);
} catch (IllegalArgumentException | IllegalAccessException e) {
}
@SuppressWarnings("unchecked")
- private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
+ private void readObject(final @NonNull ObjectInputStream in) throws IOException, ClassNotFoundException {
final int s = in.readInt();
final List<K> keys = new ArrayList<>(s);