【问题标题】:Java ArrayList without "direct access"没有“直接访问”的 Java ArrayList
【发布时间】:2015-01-25 10:24:18
【问题描述】:

我有一个实例属性

private ArrayList<String> list;

由构造函数设置。我想防止该列表包含空值,因此我为该列表编写了自己的add()remove() 方法,并在构造函数中从列表中删除了所有空元素。

现在没有人应该直接访问这个列表,以防止他们简单地添加 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],所以现在它可以正常工作了。

我的问题:

  • 此代码是不好的做法吗?
  • 有没有更好的解决方案?

欢迎所有 cmets 和提示。

【问题讨论】:

  • 您正在制作列表的浅表副本,我认为这是一件好事。如果您想将 List 的副本返回给另一个对象,您甚至可以这样做。
  • 注意:我已经编辑了您的问题并删除了您对“英语不好”的道歉。你的英语很好,所以没有这个必要。
  • 是的,这正是我打算做的(返回副本的部分......)谢谢你的回答。
  • 您仍然可以使用new TestList(someArrayList).getList().add(null),因为getList 返回内部列表。我会改写ArrayList。 (其中一个原因是能够在需要 List 的地方使用它,这是您当前的实现无法做到的)
  • 哦,对不起,我添加 getList() 只是为了测试代码,它不应该在那里。编辑:它适用于:return new ArrayList(list)

标签: java list arraylist null


【解决方案1】:

你已经实现了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);

【讨论】:

    猜你喜欢
    • 2014-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-27
    • 2014-04-15
    • 1970-01-01
    • 2013-04-19
    • 1970-01-01
    相关资源
    最近更新 更多