Java ArrayList没有"直接访问"

时间:2014-11-26 22:48:11

标签: java list arraylist null

我有一个实例属性

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],现在它可以正常运行。

我的问题:

  • 这段代码不好吗?
  • 有没有更好的解决方案?

欢迎所有评论和提示。

1 个答案:

答案 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);