list; which is set by the constructor...">

Java ArrayList without "direct access"

I have an instance attribute

private ArrayList<String> list;

      

which is set by the constructor. I want this list does not contain zero, so I wrote my own methods add()

, and remove()

for the list, and I remove all null elements from a list in the constructor.

Now no one should be able to directly access this list to prevent the simple addition of a null value.

public class TestList {
    private ArrayList<String> list;

    public TestList(ArrayList<String> list) {
        while (list.remove(null));
        this.list = list;
    }

    public List<String> getList() { //Just for the test code
        return list;
    }

    public boolean add(String e) {
        if (e == null) {
            return false;
        }

        return list.add(e);
    }

    public boolean remove(String e) {
        return list.remove(e);
    }
}

      

But with this class, I still have access to the list, as you can see in the following test code.

ArrayList<String> list = new ArrayList<String>();
list.add("line0");
list.add("line1");
list.add("line2");
TestList tl = new TestList(list);
list.add(null);
System.out.println(tl.getList().toString());

      

Console: [line0, line1, line2, null]

As you can see, null is added to the list because I have a reference to a list in a class outside of the class. (I'm not sure if this explanation is 100% correct, but basically I understand it)

My solution for this problem:

public class TestList {
    private ArrayList<String> list;

    public TestList(ArrayList<String> list) {
        ArrayList<String> newList = new ArrayList<String>(list);
        while (newList.remove(null));
        this.list = newList;
    }

    public List<String> getList() { //Just for the test code
        return list;
    }

    public boolean add(String e) {
        if (e == null) {
            return false;
        }

        return list.add(e);
    }

    public boolean remove(String e) {
        return list.remove(e);
    }
}

      

Test with the same code: [line0, line1, line2]

so it works correctly now.

My question (s):

  • Is this code bad practice?
  • Are there any better solutions?

All comments and advice are welcome.

+3


source to share


1 answer


You have implemented the Delegation Software Development Pattern .

To complete your intent, use "safe publication", which returns a copy of the internal data structure (albeit a shallow copy):

public List<String> getList() {
    return new ArrayList<>(list);
}

      

The client can then do what they like with the list without affecting your list.
Alternatively, you can return an immutable list:

public List<String> getList() {
    return Collections.unmodifiableList(list);
}

      

Which will throw an exception if an attempt is made to change it.




btw, in terms of coding style, you might want to consider this "optimization":

if (e == null) {
    return false;
}

return list.add(e);

      

can be rewritten as a single line:

return e != null && list.add(e);

      

+4


source







All Articles