我正在寻找解释Guava ForwardingList类的示例代码。基本上,我实现了一个自定义ArrayList类,该类将用于解决my earlier SO question中提到的这一要求。我以前从未使用过Google Collection 。但是,仅通过查看JavaDoc of ForwardingList,我认为可以通过对ForwardingList进行子类化来实现我的自定义类。

最佳答案

ForwardingList (即 extends ForwardingCollection ,又称为 extends ForwardingObject )实现了decorator pattern

要使用它,您只需要做两件事:

  • @Override delegate()返回将方法转发到
  • 的支持委托(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才能实现更完整的实现。

    10-08 00:44