如何在Java中将数据从一个对象列表复制到另一个对象?

时间:2018-10-14 06:54:35

标签: java spring-boot stream

我有以下两个对象TeamGroup。我在每个这些类中都有标准的getters setters和toString方法,并且不允许对其进行修改。

public class Team { 
  private List<Team> teams;
  private List<TeamMember> members;
  private String teamId;    
}

public class Group {    
  private List<GroupMember> groupMember;
  private List<Group> groups;
  private String groupId;
}

团队可以具有列表类型的List<Team>作为属性,其中List<Group>可以具有List<Group>作为属性。

团队示例列表如下所示: enter image description here

我想创建一个反映TeamList相同结构的网上论坛列表。

这是我到目前为止所得到的。

@Service
public class GroupService {

@Autowired
TeamService teamService;

public List<Group> createGroupList(){

    List<Group> groups = Collections.emptyList();

    List<Team> teams = teamService.createTeamList();

    if (teams != null && !teams.isEmpty()) {

        groups = teams.stream().map(t -> {

            Group group = new Group();
            group.setGroupId(t.getTeamId());

            //this is to be modified
            group.setGroups(getSubgroups(teams, group.getGroupId()));

            return group;

        }).collect(Collectors.toList());

    }

    return groups;
}



private List<Group> getSubgroups(List<Team> teams, String parentGroupName) {

    Optional<Team> parentTeam = teams.stream()
            .filter(t -> t.getTeamId().equalsIgnoreCase(parentGroupName)).findFirst();

    if(parentTeam.isPresent()){

        List<Team> subTeams = new ArrayList<>();
        List<Group> lstOfGroups = new ArrayList<>();

        System.out.println("parentname " + parentTeam.get().getTeamId());


        if(parentTeam.get().getTeams() != null){
            parentTeam.get().getTeams().stream().forEach(r -> {
                subTeams.add(r);
            });
        }

        subTeams.stream().forEach(st -> {
            Group gr = new Group();
            gr.setGroupId(st.getTeamId());
            lstOfGroups.add(gr);    
        });

        return lstOfGroups;

    }
    return null;            

 }

}

我的想法是修改getSubgroups方法以正确设置每个给定路径的子组。(例如:getSubgroubs可以返回设置了所有子组的team2,直到team7为止),我知道我必须使用递归,但是我在努力寻找解。我该如何实现?

编辑

我已经更新了我的代码,现在我可以访问儿童的第一级,而不能访问其他级别的

2 个答案:

答案 0 :(得分:2)

您可以只创建一个方法将一个方法复制到另一个方法中,然后递归调用它:

public Group toGroup(Team team) {
    Group result = new Group(team.teamId());
    // this is missing in your sample code
    result.setGroupMembers(transform(team.getTeamMembers());
    List<Group> subGroups = team.getTeams().stream()
        .map(this::toGroup) // recursive call to this method
        .collect(toList());
    result.setSubgroups(subGroups);
    return result;
}

所以你可以做

List<Group> groups = teamService.getTeams()
                         // you should return an empty list if no elements are present
                         .stream()  
                         .map(this::toGroup) // initial call
                         .collect(toList());

您可能还想研究mapstruct,它可以自动生成简单的映射器。

答案 1 :(得分:0)

让您了解在mapstruct中的外观:

@Mapper(componentModel="spring")
interface TeamGroupMapper {
    @Mappings({
        @Mapping(source="teamId", target="groupId"),
        @Mapping(source="teams", target="groups"),
        @Mapping(source="teamMembers", target="groupMembers")
    })
    Group toGroup(Team team);

    List<Group> toGroups(List<Team> teams);
    GroupMember toGroupMember(TeamMember teamMember);
}

将生成实际代码。如果这些类具有相同名称的属性(例如,如果idTeam都被称为Group?,则不需要@Mapping注释。< / p>

然后,您可以@Autowire作为组件并使用它。

@Component
class YourGroupService implements GroupService {
    @Autowired TeamGroupMapper mapper;
    @Autowired TeamService teamService;

    public List<Group> getGroups() {
        return mapper.toGroups(teamService.getTeams());
    }
}

我确定这段代码实际上不会起作用,但是它应该使您了解mapstruct的作用。我真的很喜欢它,以避免样板映射代码。