Java generic : appliquer une fonction sur une liste d’objet

Aller zou, le beau temps revient et les envies de me faire plaisir aussi.

J’avais besoin d’effectuer des opérations répétitives sur un groupe de variables. J’ai donc essayé de faire avec les générics une classe utilitaire pour faire ce traitement « facilement ».

Déclaration

Donc tout d’abord, la classe en question :

Apply.java
  1. package fr.fluminis.blog;
  2.  
  3. import java.util.List;
  4.  
  5. /**
  6.  * Apply
  7.  *
  8.  * Execute une fonction sur une liste d'elements
  9.  * @author fluminis
  10.  */
  11. public class Apply<E> {
  12.  
  13.     /**
  14.      * Execute une fonction sur un nombre variable d'elements
  15.      *
  16.      * @param <E>
  17.      *            type de l'element
  18.      * @param action
  19.      *            action a executer sur toute la liste d'elements
  20.      * @param objetcs
  21.      *            suite d'elements a traiter (de 1 à N éléments)
  22.      */
  23.     public static <E> void apply(IAction<E> action, E… objetcs) {
  24.         for (E e : objetcs) {
  25.             action.doAction(e);
  26.         }
  27.     }
  28.  
  29.     /**
  30.      * Execute une fonction sur une liste d'elements
  31.      *
  32.      * @param <E>
  33.      *            type de l'element
  34.      * @param action
  35.      *            action a executer sur toute la liste d'elements
  36.      * @param objetcs
  37.      *            liste d'elements a traiter
  38.      */
  39.     public static <E> void apply(IAction<E> action, List<E> objetcs) {
  40.         if (objetcs != null && objetcs.size() > 0) {
  41.             for (E e : objetcs) {
  42.                 action.doAction(e);
  43.             }
  44.         }
  45.     }
  46. }

On note ici que l’utilisation des « … » nous permet d’avoir un nombre variable d’arguments de type E.

Ensuite il nous suffit d’une petite interface pour exécuter nos actions :

IAction.java
  1. package fr.fluminis.blog;
  2.  
  3. /**
  4.  * IAction
  5.  *
  6.  * Interface permettant d'exécuter une action sur un element
  7.  * @author fluminis
  8.  */
  9. public interface IAction<E> {
  10.     void doAction(E e);
  11. }

Utilisation

Bien, tout est en place. Un petit exemple qui fait un system.out de tous les arguments :

La manière la plus simple mais assez crade est de créer la classe directement dans le code :

  1. public static void main(String[] args) {
  2.     Integer i1 = 1;
  3.     Integer i2 = 2;
  4.     Apply.apply(new IAction<Integer>() {
  5.         public void doAction(Integer i) {
  6.             System.out.println(i);
  7.         }
  8.     }, i1, i2);
  9. }

Par contre si vous avez besoin de refaire ce traitement ailleurs, je vous conseille de créez une vraie classe pour ne pas dupliquer le code.
Si vous n’avez pas besoin que votre classe action soit générique, vous n’avez qu’à la déclarer comme cela :

  1. package fr.fluminis.blog;
  2.  
  3. public class MonAction implements IAction<MaClasse> {
  4.     public void doAction(MaClasse e) {
  5.         System.out.println("-> " + e);
  6.     };
  7. }

Et l’utiliser, comme cela :

  1. MaClasse obj1;
  2. MaClasse obj2;
  3. Apply.apply(new MonAction(),  obj1, obj2);

Mais continuons avec les generics, on peut pousser le vice a créer une classe qui est encore une fois générique, ainsi le traitement peut être fait sur n’importe quel type d’objet :

  1. package fr.fluminis.blog;
  2.  
  3. public class PrintAction<E> implements IAction<E> {
  4.     public void doAction(E e) {
  5.         System.out.println("-> " + e);
  6.     };
  7. }

Que vous utiliserez comme cela :

  1. Integer i1;
  2. Integer i2;
  3. Apply.apply(new PrintAction<Integer>(), i1, i2);
  4.  
  5. ou
  6.  
  7. MaClasse obj1;
  8. MaClasse obj2;
  9. Apply.apply(new PrintAction<MaClasse>(), obj1, obj2);

Have fun !

Le commentaires sont fermés.