你通常如何使用Java收集getter?例如,我有两个班级。
public class A
{
String s = "1";
A () {}
}
public class B
{
List<A> list;
public B()
{
list = new ArrayList<>();
}
public List<A> getList()
{
return list;
}
}
如果我喜欢这样的话,我可以这样做:
B elem = new B();
elem.getList().add(new A());
所以它打破了吸气剂的想法。
我能做到
public List<A> getList()
{
return new ArrayList<>(list);
}
但是,如果我修改了一些结果元素,原始元素将会改变。
答案 0 :(得分:5)
使用Collection.unmodifiableList(list)
返回不可修改的集合:
public List<A> getList() {
return Collections.unmodifiableList(list);
}
引用Javadoc:
返回指定列表的不可修改视图。此方法允许模块为用户提供对内部列表的“只读”访问。对返回列表的查询操作“通读”到指定列表,并尝试修改返回的列表,无论是直接还是通过其迭代器,都会产生
UnsupportedOperationException
。
因此无法在返回的列表中追加/删除元素,也无法修改其元素。
如果您想要返回列表的深层克隆而不是不可修改的列表,请参阅this question。
答案 1 :(得分:2)
如果您需要深层复印,可以
public List<A> getList() {
return list.stream().map(A::copy).collect(toList());
}
更好的解决方案是首先不返回列表。您可以返回类似的内容。
public int getCount() { return list.size(); }
public String getASAt(int index) { return list.get(index).s; }
现在无法修改基础A
对象,也无需冗余复制它们。
答案 2 :(得分:2)
通常我会在班上提供有意义的维护方法来管理列表。列表仅用于查看目的:
public class Foo
{
private List<Bar> bars = ....;
// or even stricter, returning Iterator<Bar>
/** be clear in javadoc the list is immutable */
public List<Bar> getBars() {
return Collections.unmodifiableList(bars);
}
public void addBar(Bar bar) {
this.bars.add(bar);
// and maybe some other works against bar
}
public void removeBar(Bar bar) {
this.bars.remove(bar);
// and maybe some other works against bar
}
// even something more meaningful
public void removeExpiredBars() {
// iterate thru this.bar and remove all bars with bar.isExpired()
}
}
始终提醒自己: getter的想法 (和setter)很糟糕。你不应该设计你的课程,以便从中获取数据&#34;。你应该为你的班级提供有意义的行为。
答案 3 :(得分:1)
您可以通过这种方式返回副本:
public List<A> getList()
{
List<A> destination = new ArrayList<A> ( list.size());
Collections.copy(destination , list);
return destination ;
}
<强> EDITED 强>
这是最短的版本:
public List<A> getList()
{
return new ArrayList<A> ( list);
}