我有一个实例属性
private ArrayList<String> list;
由构造函数设置。我想阻止此列表包含空值,因此我为列表编写了自己的add()
和remove()
方法,并从构造函数的列表中删除了所有null元素。
现在没有人应该直接访问此列表,以防止他们只是添加null。
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);
}
}
但是对于这个类,我仍然可以访问列表,如下面的测试代码所示。
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());
控制台:[line0, line1, line2, null]
正如您所看到的,null被添加到列表中,因为我仍然引用了类外部类中的列表。 (我不确定这个解释是否100%正确,但原则上我理解这一点)
我解决这个问题的方法:
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);
}
}
使用相同的代码进行测试:[line0, line1, line2]
,现在它可以正常运行。
欢迎所有评论和提示。
答案 0 :(得分:4)
您已实施delegation software design pattern。
要完成课程的意图,请使用“安全发布”,它会返回内部数据结构的副本(尽管浅副本):
public List<String> getList() {
return new ArrayList<>(list);
}
然后,客户可以使用列表执行他们喜欢的操作,而不会影响您的列表 或者,您可以返回一个不可变列表:
public List<String> getList() {
return Collections.unmodifiableList(list);
}
如果尝试修改它,将引发异常。
if (e == null) {
return false;
}
return list.add(e);
可以重写为一行:
return e != null && list.add(e);