我正在寻找解释Guava ForwardingList类的示例代码。基本上,我实现了一个自定义ArrayList类,该类将用于解决my earlier SO question中提到的这一要求。我以前从未使用过Google Collection 。但是,仅通过查看JavaDoc of ForwardingList,我认为可以通过对ForwardingList进行子类化来实现我的自定义类。
最佳答案
ForwardingList
(即 extends ForwardingCollection
,又称为 extends ForwardingObject
)实现了decorator pattern。
要使用它,您只需要做两件事:
@Override delegate()
返回将方法转发到@Override
您想要/需要装饰List
方法装饰器模式允许您使用合成而不是继承(Effective Java 2nd Edition,在继承上偏爱合成),并且Guava的
ForwardingList
提供了一个方便的模板,您可以从中编写自己的List
实现,为您提供所有管道机制。请注意,如果您打算装饰
ArrayList
,则可能希望ForwardingList
子类也实现 RandomAccess
。示例:
ListWithDefault
这是
ForwardingList
的一个(不完整!)示例,该示例将委托(delegate)中的null
值替换为给定的默认值。import java.util.*;
import com.google.common.collect.*;
public class ListWithDefault<E> extends ForwardingList<E> {
final E defaultValue;
final List<E> delegate;
ListWithDefault(List<E> delegate, E defaultValue) {
this.delegate = delegate;
this.defaultValue = defaultValue;
}
@Override protected List delegate() {
return delegate;
}
@Override public E get(int index) {
E v = super.get(index);
return (v == null ? defaultValue : v);
}
@Override public Iterator<E> iterator() {
final Iterator<E> iter = super.iterator();
return new ForwardingIterator<E>() {
@Override protected Iterator<E> delegate() {
return iter;
}
@Override public E next() {
E v = super.next();
return (v == null ? defaultValue : v);
}
};
}
}
然后,我们可以对其进行如下测试:
public static void main(String[] args) {
List<String> names = new ListWithDefault<String>(
Arrays.asList("Alice", null, "Bob", "Carol", null),
"UNKNOWN"
);
for (String name : names) {
System.out.println(name);
}
// Alice
// UNKNOWN
// Bob
// Carol
// UNKNOWN
System.out.println(names);
// [Alice, null, Bob, Carol, null]
}
请注意,这是一个不完整的实现。
toString()
方法仍然返回委托(delegate)的toString()
,它不知道默认值。其他一些方法也必须是@Override
才能实现更完整的实现。