Stream Collection到其他结构

时间:2017-10-19 11:28:32

标签: java java-8 java-stream

我尝试将Dictionary的列表对象转换为包含列表的对象。

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

Dictionary类的示例数据:

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

结果应该是这样的:

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

我的流解决方案有效,但速度慢,因为我不止一次使用列表流。

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

使用Java 8中的流来解决此问题的更好方法是什么?

1 个答案:

答案 0 :(得分:2)

这似乎是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())));

这将为您提供字典代码到DictElemDTO s。

的相应列表的映射

创建DictDTO对象需要更多的工作。