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.
source to share
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);
source to share