Guava ForwardingList usage example

前端 未结 2 1222
孤街浪徒
孤街浪徒 2020-12-15 11:41

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 men

2条回答
  •  旧时难觅i
    2020-12-15 12:14

    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 extends ForwardingList {
        final E defaultValue;
        final List delegate;
    
        ListWithDefault(List 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 iterator() {
            final Iterator iter = super.iterator();
            return new ForwardingIterator() {
                @Override protected Iterator 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 names = new ListWithDefault(
                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.

提交回复
热议问题