본문 바로가기

트러블 슈팅

다른 클래스타입의 리스트 복사하기 JAVA

  • 문제점

JPA사용 과정에서 데이터 값을 client에게 보낼때, 몇가지 정보를 제외한 체로 보내려고 시도하다가 생긴 문제이다.

//메모 보여주기
    @GetMapping("/api/memos")
    public List<IgnorePwResponseDto> getMemos() {
        return memoService.getMemos();
    }

이렇게 controller에서 dto클래스타입 list를 리턴하고 싶었다.

service에서 문제가 있었는데

public List<IgnorePwResponseDto> getMemos() {
	//memoRepository.findAllByOrderByModifiedAtDesc()이것은 List<Memo>타입만 반환을 하였다.
        List<IgnorePwResponseDto> ignorePwResponseDtos = memoRepository.findAllByOrderByModifiedAtDesc();
        return ignorePwResponseDtos;
    }

때문에 List<IgnorePwResponseDto> 리스트를 만들고, List<Memo>리스트를 복사를 해야하는 상황이었다.

for문으로 복사가 가능하다는것을 알고있었지만 서버단에서 for문을 사용하면 부하가 많이 걸린다는 소리를 들어서 배제시키고 시도했다.

 

시도1) 매개변수 사용

    public List<IgnorePwResponseDto> getMemos() {
        List<Memo> memos = memoRepository.findAllByOrderByModifiedAtDesc();
        //클래스의 타입이 달라서 실패
        List<IgnorePwResponseDto> ignorePwResponseDtos = new ArrayList<>(memos);
        return ignorePwResponseDtos;
    }

 

시도2) 메소드 사용

    public List<IgnorePwResponseDto> getMemos() {
        List<Memo> memos = memoRepository.findAllByOrderByModifiedAtDesc();
        //길이만 같게 해주고
        List<IgnorePwResponseDto> ignorePwResponseDtos = new ArrayList<>(memos.size());
        //Collections.copy()메소드를 사용하여 복사
        //클래스의 타입이 달라서 실패
        Collections.copy(ignorePwResponseDtos, memos);
        return ignorePwResponseDtos;
}

 

  • 해결

도저히 모르겠어서 팀원분께 자문을 구했다.

다른타입의 List는 어떤 방법을 쓰더라도 그냥 복사는 불가능하다 메소드를 사용한다는것은 타고들어가면 for문이 어차피 마오게 된다 for문을 사용하는것이 좋을것같다 라고 말씀하셔서 만들어 봤다.

public List<IgnorePwResponseDto> getMemos() {
	//먼저 List<Momo>를 만들어 주고
        List<Memo> memos = memoRepository.findAllByOrderByModifiedAtDesc();
    	//List<IgnorePwResponseDto> 또한 만들고 초기화 한다.
    	List<IgnorePwResponseDto> ignorePwResponseDtos = new ArrayList<>();
    	//향상된 for문을 사용한다.
        for(Memo memo: memos){
    	//IgnorePwResponseDto 객체를 사용하고 매개변수 값으로 memo를 준다.
            IgnorePwResponseDto ignorePwResponseDto = new IgnorePwResponseDto(memo);
        //List에 ignorePwResponseDto 를 순차적으로 넣는다.
            ignorePwResponseDtos.add(ignorePwResponseDto);
        }
    	//return
        return ignorePwResponseDtos;
    }

IgnnorePwResponseDto 클래스는 이렇게 생겼다.

package com.sparta.personal_assignment.dto;

import com.sparta.personal_assignment.entity.Memo;
import lombok.Getter;

import java.time.LocalDateTime;

@Getter
public class IgnorePwResponseDto {
	//Pw가 빠져있다.
    private final String nickname;
    private final String title;
    private final String comment;
    private final LocalDateTime createdAt;
    private final LocalDateTime modifiedAt;
    private final Long id;
	//생성자의 매개변수로 Memo타입을 받는다.
    public IgnorePwResponseDto(Memo memo) {
        this.nickname = memo.getNickname();
        this.title = memo.getTitle();
        this.comment = memo.getComment();
        this.createdAt = memo.getCreatedAt();
        this.modifiedAt = memo.getModifiedAt();
        this.id = memo.getId();
    }
}
  • 몰랐던점

for문을 사용하는것이 부하때문에 안좋다라고 들은것에 너무 얽매여있었던 것 같다.

메소드를 사용한다는것도 그안에 for문을 편하게 사용한다는 의미와 같다는것을 알았다.

 

  • 추가

우리 인텔리한 인텔리제이의 도움을 받아 아까 향상된 for문을 stream().map()으로 바꿔봤다.

    public List<IgnorePwResponseDto> getMemos() {
        List<Memo> memos = memoRepository.findAllByOrderByModifiedAtDesc();
        return memos.stream().map(IgnorePwResponseDto::new).collect(Collectors.toList());
    }

저 코드는 먼저 stream()타입으로 list를 바꾸고, map()메소드를 사용하고, collect메소드를 이용하여 List타입으로 다시 바꿔주는 그런 코드다... 음... 이쪽은 더 공부를 해보는걸로.