Guava ForwardingList usage example

旧城冷巷雨未停 提交于 2019-12-18 02:48:09

问题


I am looking for sample code which explains Guava ForwardingList class. Basically I am implementing a custom ArrayList class which will be used to solve this requirement mentioned in my earlier SO question. I never used Google collection before. But by just looking at the JavaDoc of ForwardingList, I think I can implement my custom class by sub classing ForwardingList.


回答1:


ForwardingList (which extends ForwardingCollection, which in turn extends ForwardingObject) implements the decorator pattern.

To use, you simply need to do two things:

  • @Override delegate() to return the backing delegate instance that methods are forwarded to
  • @Override whatever List method you want/need to decorate

The decorator pattern allows you to use composition instead of inheritance (Effective Java 2nd Edition, Favor composition over inheritance), and ForwardingList from Guava provides a convenient template from which to write your own List implementation, providing all the plumbing mechanism for you.

Note that if you are planning to decorate an ArrayList, you'd probably want your ForwardingList subclass to also implement RandomAccess.


Example: ListWithDefault

Here's an (incomplete!) example of a ForwardingList that substitutes null values in the delegate with a given default value.

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); 
            }
        };
    }
}

We can then test it as follows:

    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]
}

Note that this is an incomplete implementation. The toString() method still returns the delegate's toString(), which isn't aware of the default value. A few other methods must be @Override as well for a more complete implementation.




回答2:


You should implement delegate() method of ForwardingList to return delegate list you are using in your elements.

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;
    }
}


来源:https://stackoverflow.com/questions/3502066/guava-forwardinglist-usage-example

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!