2009-05-14 7 views
3

Je suis nouveau en Java, alors soyez patient.Quelle est la manière la plus élégante de mapper une liste à une autre en Java?

Il est courant de mapper (convertir) des listes en listes. Certaines langues ont une méthode map, certaines (C#) Select. Comment cela est-il fait avec Java? Une boucle for est-elle la seule option?

J'espère être en mesure de faire quelque chose comme ceci:

List<Customer> customers = new ArrayList<Customer>(); 
... 
List<CustomerDto> dtos = customers.convert(new Converter(){ 
    public convert(c) { 
    return new CustomerDto(); 
    } 
}) 

je manqué quelque chose? S'il vous plaît, donnez-moi un point de départ.

Répondre

4

Je mis en œuvre quelque chose à la volée. Voyez si cela vous aide. Sinon, utilisez Google Collections comme suggéré.

public interface Func<E, T> { 
    T apply(E e); 
} 

public class CollectionUtils { 

    public static <T, E> List<T> transform(List<E> list, Func<E, T> f) { 
     if (null == list) 
      throw new IllegalArgumentException("null list"); 
     if (null == f) 
      throw new IllegalArgumentException("null f"); 

     List<T> transformed = new ArrayList<T>(); 
     for (E e : list) { 
      transformed.add(f.apply(e)); 
     } 
     return transformed; 
    } 
} 

List<CustomerDto> transformed = CollectionUtils.transform(l, new Func<Customer, CustomerDto>() { 
    @Override 
    public CustomerDto apply(Customer e) { 
     // return whatever !!! 
    } 
}); 
+0

Comme la réponse de Steve McLeod, vous pouvez être plus flexible avec vos paramètres de type. –

5

Il n'y a pas de façon intégrée de le faire en Java - vous devez écrire ou utiliser une classe auxiliaire. Google Collections comprend

public static <F,T> List<T> transform(List<F> fromList, 
            Function<? super F,? extends T> function) 

Cela fonctionne bien, mais il est un peu maladroit d'utiliser, comme vous devez utiliser une classe anonyme d'une méthode et une méthode statique. Ce n'est pas la faute de Google Collections, c'est juste la nature de faire ce genre de tâche en Java.

Notez que cela transforme paresseusement les éléments de la liste source selon les besoins.

+0

Pitié .. Mais merci, cela a vraiment besoin d'un coup d'oeil. –

2

Tant que customerDto étend Client, cela fonctionnera

List<Customer> customers = new ArrayList<Customer>(); 

    List<CustomerDto> dtos = new ArrayList<CustomerDto>(customers); 

Sinon:

List<Customer> customers = new ArrayList<Customer>(); 

List<CustomerDto> dtos = new ArrayList<CustomerDto>(); 

for (Customer cust:customers) { 
    dtos.add(new CustomerDto(cust)); 
} 
+0

Pourquoi pensez-vous que CustomerDto étend le client? Ce n'est pas le cas. Merci pour votre replay. –

0

Il n'y a pas encore un moyen d'appliquer une fonction de mappage comme celui-ci à un Java List (ou autres collections). Les fermetures, qui fourniront cette fonctionnalité, ont été sérieusement envisagées pour la prochaine version du JDK 7, mais elles ont été reportées à une version ultérieure en raison d'un manque de consensus.

Avec les constructions en cours, vous pouvez mettre en œuvre quelque chose comme ceci:

public abstract class Convertor<P, Q> 
{ 

    protected abstract Q convert(P p); 

    public static <P, Q> List<Q> convert(List<P> input, Convertor<P, Q> convertor) 
    { 
    ArrayList<Q> output = new ArrayList<Q>(input.size()); 
    for (P p : input) 
     output.add(convertor.convert(p)); 
    return output; 
    } 

} 
+0

Merci de clarifier les choses. –

+0

Les fermetures minimalistes sont en JDK 1.1. –

+0

Je ne suis pas un fan de toute proposition de fermeture; les classes intérieures combinées avec l'itération sont assez bonnes pour moi. Mon point ici est qu'il n'y a aucune méthode pour appliquer un à une collection comme l'affiche demandée. – erickson

0

Personnellement, je trouve ce qui suit plus court et plus simple, mais si vous trouvez l'approche fonctionnelle plus simple que vous pourriez le faire de cette façon. Si d'autres développeurs Java peuvent avoir besoin de lire/maintenir le code, je suggère d'utiliser l'approche avec laquelle ils pourraient se sentir plus à l'aise.

List<CustomerDto> dtos = new ArrayList<CustoemrDto>(); 
for(Customer customer: customers) 
    dtos.add(new CustomerDto()); 

Vous trouverez peut-être cette bibliothèque intéressante Functional Java

Questions connexes