Unchanging collection by adding strings

0

I'm starting java programming and am having a problem creating an immutable collection. Below is what I created:

package br.com.estudos;

import java.util.Collection;


public class MinhaColecaoImutavel<String> extends MinhaColecao<String> {


    public static MinhaColecaoImutavel instancia;


    public static synchronized MinhaColecaoImutavel getinstancia(Collection<?> colecao) {
        if (instancia == null) {
            instancia = new MinhaColecaoImutavel(colecao);
        }

        return instancia;
    }

    private MinhaColecaoImutavel(Collection<String> colecao) {
        instancia.addAll(colecao);
    }

}

When running main from the command below,

MinhaColecaoImutavel<String> x = MinhaColecaoImutavel.getinstancia(new ArrayList<>());
        x.add("x");

Give me the error NullPointerException in line " instancia.addAll(colecao) ". My x is to add a value in the instance so it is not null.

Does anyone have a light to help?

Thank you.

    
asked by anonymous 12.07.2018 / 16:53

1 answer

1

This static field means that it is impossible to use two instances of MinhaColecaoImutavel . This is a bad idea, after all, there should be no problem in creating two distinct instances of this class in different places for different purposes. For example, in one place I create an immutable collection with names of printers and one another another part of the totally different code I create an immutable list with words read from a dictionary. With this code, the same list will be returned in both cases, causing confusion, pain and suffering. static should not be used this way.

The solution is simple. Forget the static and static method and use the constructor directly:

package br.com.estudos;

import java.util.Collection;

public class MinhaColecaoImutavel<String> extends MinhaColecao<String> {
    public MinhaColecaoImutavel(Collection<String> colecao) {
        this.addAll(colecao);
    }
}

And you use it like this:

MinhaColecaoImutavel<String> x = new MinhaColecaoImutavel(new ArrayList<>());
x.add("x");

However, this is still not right. Note that the MinhaColecaoImutavel class does not add anything to the superclass besides a constructor. Once an instance of the subclass has been constructed, it has nothing different than what is offered by the superclass. This means that this is a misuse of inheritance that does not bring any benefit. The solution is to put the constructor in the superclass (I'm assuming the generic type is T ):

    public MinhaColecao(Collection<T> colecao) {
        this.addAll(colecao);
    }

And you use it like this:

MinhaColecao<String> x = new MinhaColecao(new ArrayList<>());
x.add("x");

If your idea is to make an immutable subclass of a mutable superclass, this is not a good idea. The best would be to have an interface defining your collection and have two distinct implementations, one changeable and one immutable. Using concrete methods with the default modifier in the interface (enabled from Java 8) should help you simplify the implementation code.

    
12.07.2018 / 17:12