Problem 5 (immutable)

Let's now create a list of ImmutableMelon via Collections.unmodifiableList() and the List.of() methods:

private static final ImmutableMelon MELON_1 
= new ImmutableMelon("Crenshaw", 2000);
private static final ImmutableMelon MELON_2
= new ImmutableMelon("Gac", 1200);

private static final List<ImmutableMelon> LIST
= Collections.unmodifiableList(Arrays.asList(MELON_1, MELON_2));
private static final List<ImmutableMelon> LIST
= List.of(MELON_1, MELON_2);

So, is the list unmodifiable or immutable? The answer is immutable. Mutator methods will throw UnsupportedOperationException, and we cannot mutate the instances of ImmutableMelon.

As a rule of thumb, a collection is unmodifiable if it is defined via unmodifiableFoo() or of() methods and contains mutable data, and it is immutable if it is unmodifiable and contains immutable data (including primitives).

Pay attention to the fact that impenetrable immutability should take into consideration Java Reflection API and similar APIs that have supplementary powers in manipulating code.

For third-party library support, please consider Apache Common Collection, UnmodifiableList (and companions), and Guava's ImmutableList (and companions).

In the case of Map, we can create an unmodifiable/immutable Map via unmodifiableMap() or the Map.of() methods.

But we can also create an immutable empty Map via Collections.emptyMap():

Map<Integer, MutableMelon> emptyMap = Collections.emptyMap();
Similar to emptyMap(), we have Collections.emptyList(), and Collections.emptySet(). These methods are very handy as returns in methods that return a Map, List, or Set, and we want to avoid returning null.

Alternatively, we can create an unmodifiable/immutable Map with a single element via Collections.singletonMap(K key, V value):

// unmodifiable
Map<Integer, MutableMelon> mapOfSingleMelon
= Collections.singletonMap(1, new MutableMelon("Gac", 1200));

// immutable
Map<Integer, ImmutableMelon> mapOfSingleMelon
= Collections.singletonMap(1, new ImmutableMelon("Gac", 1200));
Similar to singletonMap(), we have singletonList() and singleton(). The latter is for Set.

Moreover, starting with JDK 9, we can create an unmodifiable Map via a method named ofEntries(). This method takes Map.Entry as an argument, as in the following example:

// unmodifiable Map.Entry containing the given key and value
import static java.util.Map.entry;
...
Map<Integer, MutableMelon> mapOfMelon = Map.ofEntries(
entry(1, new MutableMelon("Apollo", 3000)),
entry(2, new MutableMelon("Jade Dew", 3500)),
entry(3, new MutableMelon("Cantaloupe", 1500))
);

Alternatively, an immutable Map is another option:

Map<Integer, ImmutableMelon> mapOfMelon = Map.ofEntries(
entry(1, new ImmutableMelon("Apollo", 3000)),
entry(2, new ImmutableMelon("Jade Dew", 3500)),
entry(3, new ImmutableMelon("Cantaloupe", 1500))
);

In addition, an unmodifiable/immutable Map can be obtained from a modifiable/mutable Map via JDK 10, the Map.copyOf​(Map<? extends K,​? extends V> map) method:

Map<Integer, ImmutableMelon> mapOfMelon = new HashMap<>();
mapOfMelon.put(1, new ImmutableMelon("Apollo", 3000));
mapOfMelon.put(2, new ImmutableMelon("Jade Dew", 3500));
mapOfMelon.put(3, new ImmutableMelon("Cantaloupe", 1500));

Map<Integer, ImmutableMelon> immutableMapOfMelon
= Map.copyOf(mapOfMelon);

By way of a bonus for this section, let's talk about an immutable array.

Question: Can I create an immutable array in Java?

Answer: No, you cannot. Or... there is one way to make an immutable array in Java:

static final String[] immutable = new String[0];

So, all useful arrays in Java are mutable. But we can create a helper class to create immutable arrays based on Arrays.copyOf(), which copies the elements and creates a new array (behind the scenes, this method relies on System.arraycopy()).

So, our helper class is as follows:

import java.util.Arrays;

public final class ImmutableArray<T> {

private final T[] array;

private ImmutableArray(T[] a) {
array = Arrays.copyOf(a, a.length);
}

public static <T> ImmutableArray<T> from(T[] a) {
return new ImmutableArray<>(a);
}

public T get(int index) {
return array[index];
}

// equals(), hashCode() and toString() omitted for brevity
}

A usage example is as follows:

ImmutableArray<String> sample =
ImmutableArray.from(new String[] {
"a", "b", "c"
});
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.35.255