Exemple d’utilisation de Guava ForwardingList

Je cherche un exemple de code qui explique la classe Guava ForwardingList. Fondamentalement, j’implémente une classe ArrayList personnalisée qui sera utilisée pour résoudre cette exigence mentionnée dans ma précédente question SO . Je n’ai jamais utilisé Google Collection auparavant. Mais en regardant simplement le JavaDoc de ForwardingList , je pense que je peux implémenter ma classe personnalisée en sous classant ForwardingList.

ForwardingList (qui extends ForwardingCollection , qui à son tour extends ForwardingObject ) implémente le motif de décorateur .

Pour l’utiliser, vous devez simplement faire deux choses:

  • @Override delegate() pour renvoyer l’instance de délégué de sauvegarde à laquelle les méthodes sont transférées
  • @Override quelle que soit la méthode de List que vous voulez / devez décorer

Le modèle de décorateur vous permet d’utiliser la composition au lieu de l’inheritance ( Effective Java 2nd Edition, Favoriser la composition plutôt que l’inheritance ), et ForwardingList de Guava fournit un modèle pratique pour écrire votre propre implémentation de List , fournissant tout le mécanisme de plomberie.

Notez que si vous envisagez de décorer une ArrayList , vous voudrez probablement que votre sous-classe ForwardingList implémente également RandomAccess .


Exemple: ListWithDefault

Voici un exemple (incomplet!) De ForwardingList qui remplace null valeurs null dans le délégué par une valeur par défaut donnée.

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

Nous pouvons ensuite le tester comme suit:

  public static void main(Ssortingng[] args) { List names = new ListWithDefault( Arrays.asList("Alice", null, "Bob", "Carol", null), "UNKNOWN" ); for (Ssortingng name : names) { System.out.println(name); } // Alice // UNKNOWN // Bob // Carol // UNKNOWN System.out.println(names); // [Alice, null, Bob, Carol, null] } 

Notez qu’il s’agit d’une implémentation incomplète . La toSsortingng() renvoie toujours le toSsortingng() du délégué, qui n’a pas connaissance de la valeur par défaut. Quelques autres méthodes doivent également être @Override pour une implémentation plus complète.

Vous devez implémenter la méthode delegate () de ForwardingList pour renvoyer la liste de delegates que vous utilisez dans vos éléments.

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