【问题标题】:Guava ForwardingList usage exampleGuava ForwardingList 使用示例
【发布时间】:2011-03-30 22:42:24
【问题描述】:

我正在寻找解释 Guava ForwardingList 类的示例代码。基本上我正在实现一个自定义 ArrayList 类,它将用于解决my earlier SO question 中提到的这个要求。我以前从未使用过谷歌收藏。但是只看JavaDoc of ForwardingList,我想我可以通过继承ForwardingList来实现我的自定义类。

【问题讨论】:

    标签: java collections guava


    【解决方案1】:

    ForwardingList(其中extends ForwardingCollection,又是extends ForwardingObject)实现decorator pattern

    要使用,你只需要做两件事:

    • @Override delegate() 返回方法转发到的支持委托实例
    • @Override 任何你想要/需要装饰的List 方法

    装饰器模式允许您使用组合而不是继承(Effective Java 2nd Edition,Favor composition over inheritance),来自 Guava 的 ForwardingList 提供了一个方便的模板,您可以从中编写自己的 @ 987654334@实现,为你提供所有的管道机制。

    请注意,如果您打算装饰 ArrayList,您可能希望您的 ForwardingList 子类也实现 RandomAccess


    示例:ListWithDefault

    这是一个(不完整!)ForwardingList 示例,它将委托中的 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() 方法仍然返回委托的toString(),它不知道默认值。其他一些方法也必须是 @Override 才能实现更完整的实现。

    【讨论】:

    【解决方案2】:

    您应该实现 ForwardingList 的 delegate() 方法以返回您在元素中使用的委托列表。

    public class YourList<E> extends ForwardingList<E> {
        private final List<E> delegate;
    
        public YourList(List<E> list1, List<E> list2) {
            delegate = new ArrayList<E>(list1);
            delegate.addAll(list2);
        }
    
        @Override
        public List<E> delegate() {
            return delegate;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多