Разделить весь список всех категорий на подкатегории? (только с Java)

#java #oop #jpa #collections #dto

#java #ооп #jpa #Коллекции #dto

Вопрос:

У нас есть класс сущности и список всех категорий:

 class Category {
  Long id, parentId;
}
...
List<Category> categoryList = <...>;
  

Как преобразовать в список DTO, подобный этому:

 class CategoryDTO {
  Long id; 
  List<CategoryDTO> subcategories;
}
  

Как это можно сделать без отношения объекта «Один к одному»?

Комментарии:

1. На основе Category класса. Могут быть объекты без родительского элемента? Если да, то как вы это отмечаете? Если нет, это означает, что между всеми ними существует цикл?

2. Очевидно, что может быть многоуровневый уровень, верно?

3. Может быть неограниченное количество уровней. Основные уровни имеют ParentID = null

Ответ №1:

 public class CategoryConverterImpl implements CategoryConverter {
    private CategoryDTO convertEntity(Category s) {
        Long id = s.getId();
        return new CategoryDTO()
                .setId(id)
                .setSubcategories(
                        convertCollection(
                                categoryCollection.stream()
                                        .filter(c -> Objects.equals(c.getParentCategoryId(), id))
                                        .collect(Collectors.toList())
                        )
                );
    }

    private List<CategoryDTO> convertCollection(Collection<Category> categoryCollection) {
        return categoryCollection.stream()
                .map(this::convertEntity)
                .collect(Collectors.toList());
    }

    private Collection<Category> categoryCollection;

    @Override
    public List<CategoryDTO> convert(Collection<Category> categoryCollection) {
        this.categoryCollection = categoryCollection;
        return categoryCollection.stream()
                .filter(c -> c.getParentCategoryId() == null)
                .map(this::convertEntity)
                .collect(Collectors.toList());
    }
}
  

Ответ №2:

Создайте Map<Long, CategoryDTO> и заполните его из categoryList , сопоставив id с CategoryDTO созданным из Category объектом.

Затем повторите categoryList цикл, найдите оба id и parentId на карте и добавьте в subcategories список соответствующим образом.

Например, что-то вроде этого:

 Map<Long, CategoryDTO> categoryDTOs = new LinkedHashMap<>();
for (Category category : categoryList) {
    categoryDTOs.put(category.getId(), new CategoryDTO(category.getId()));
}
for (Category category : categoryList) {
    if (category.getParentId() != null) {
        categoryDTOs.get(category.getParentId())
                    .addSubcategory(categoryDTOs.get(category.getId()));
    }
}