2017-10-19 11 views
0

J'essaie de convertir des objets de liste de Dictionary en objet avec une liste contenant.Collection de flux vers une autre structure

public class Dictionary { 
    private String dictCode; 
    private String dictName; 
    private String dictDescription; 
    private String dictElemCode; 
    private String dictElemName; 
    private String dictElemDescription; 

} 

//parent 
public class DictDTO { 

    private String code; 
    private String value; 
    private String description; 
    private List<DictElemDTO> listDictElemDTO; 
} 

//children 
public class DictElemDTO { 

    private String code; 
    private String value; 
    private String description; 
} 

Exemple de données pour Dictionary Classe:

Dictionary d1 = new Dictionary("a1", "dict1", "desc1", "elem_code_1", "elem_code_name", "elem_code_desc"); 
Dictionary d2 = new Dictionary("a1", "dict1", "desc1", "elem_code_2", "elem_code_name2", "elem_code_desc2"); 
Dictionary d3 = new Dictionary("a2", "dict2", "desc2", "elem_code_3", "elem_code_name3", "elem_code_desc3"); 

Et le résultat devrait par comme ceci:

a1 
------ elem_code_1 
------ elem_code_2 
a2 
------ elem_code_3 

Ma solution pour les travaux de flux, mais il est lent parce que j'utiliser un jet de liste plus qu'une seule fois.

public static void main(String[] args) { 
     Dictionary d1 = new Dictionary("a1", "dict1", "desc1", "elem_code_1", "elem_code_name", "elem_code_desc"); 
     Dictionary d2 = new Dictionary("a1", "dict1", "desc1", "elem_code_2", "elem_code_name2", "elem_code_desc2"); 
     Dictionary d3 = new Dictionary("a2", "dict2", "desc2", "elem_code_3", "elem_code_name3", "elem_code_desc3"); 

     List<Dictionary> list = ImmutableList.of(d1, d2, d3); 


     List<DictDTO> newList = list.stream().filter(distinctByKey(Dictionary::getDictCode)).map(t -> { 
      DictDTO dto = new DictDTO(); 
      dto.setCode(t.getDictCode()); 
      dto.setValue(t.getDictName()); 
      dto.setDescription(t.getDictDescription()); 
      dto.setListDictElemDTO(
            list.stream().filter(e -> e.getDictCode().equals(t.getDictCode())).map(w -> { 
             DictElemDTO elemDto = new DictElemDTO(); 
             elemDto.setCode(w.getDictElemCode()); 
             elemDto.setValue(w.getDictElemName()); 
             elemDto.setDescription(w.getDictElemDescription()); 
             return elemDto; 
            }).collect(Collectors.toList()) 
          ); 
      return dto; 
     }).collect(Collectors.toList()); 

     for (DictDTO dto : newList) { 
      System.err.println(dto.getCode()); 
      for (DictElemDTO dtoE : dto.getListDictElemDTO()) { 
       System.err.println("------ " + dtoE.getCode()); 
      } 
     } 

    } 

static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) { 
     Map<Object, Boolean> seen = new ConcurrentHashMap<>(); 
     return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; 
    } 

Quelle est la meilleure approche pour ce problème en utilisant stream dans Java 8?

+0

Pourquoi exactement voulez-vous utiliser stream pour cela? Je ne vois pas beaucoup de valeur de l'utilisation de flux (vous utilisez juste pour filtrer ...) – Lino

Répondre

2

Cela ressemble à un travail pour Collectors.groupingBy:

Map<String,List<DictElemDTO>> 
    map = Stream.of(d1,d2,d3) 
       .collect(Collectors.groupingBy(Dictionary::getDictCode, 
               Collectors.mapping(d-> new DictElemDTO (d.getDictElemCode(),d.getDictElemName(),d.getDictElemDescription()), 
                    Collectors.toList()))); 

Cela vous donnera une cartographie des codes de dictionnaire à la liste correspondante de DictElemDTO s.

Il faut un peu plus de travail pour créer les objets DictDTO.

+0

Pouvez-vous ajouter une solution complète pour ce problème? –