[Java] 이중 for문 방지를 위한 List TO Map 변환하기

뉴브이·2023년 5월 26일
1
post-custom-banner

다음과 같은 데이터를 요청받거나 DB에서 조회한다고 가정하자.

사원목록과 직급정보를 JSON형태로 표현하였다.

{
  "empList": [
    {
      "empNo": "3278",
      "name": "김철수",
      "rankId": "3"
    },
    {
      "empNo": "2457",
      "name": "안영희",
      "rankId": "2"
    },
    {
      "empNo": "6323",
      "name": "고민수",
      "rankId": "1"
    },
    {
      "empNo": "7342",
      "name": "황동석",
      "rankId": "2"
    },
    {
      "empNo": "4215",
      "name": "김가영",
      "rankId": "1"
    }
  ],
  "rankList": [
    {
      "rankId": "1",
      "name": "과장"
    },
    {
      "rankId": "2",
      "name": "대리"
    },
    {
      "rankId": "3",
      "name": "사원"
    }
  ]
}

어플리케이션단에서 해당 정보를 가지고 직급아이디(rankId)가 아닌 직급명(rankName)으로 사원목록을 표현하고 싶다면 어떻게 코드를 짜야할까?

ObjectMapper objectMapper = new ObjectMapper();
List<Map<String, String>> empList = (List<Map<String, String>>) objectMapper.readValue(jsonStr, Map.class).get("empList");
List<Map<String, String>> rankList = (List<Map<String, String>>) objectMapper.readValue(jsonStr, Map.class).get("rankList");

먼저 jackson라이브러리의 ObjectMapper통해 json데이터를 단순히 리스트<맵> 형태로 담아보았다.

이중 for문 사용

for (Map<String, String> empMap : empList) {
	for (Map<String, String> rankMap : rankList) {
		if (empMap.get("rankId").equals(rankMap.get("rankId"))) {
			empMap.put("rankName", rankMap.get("name"));
		}
	}
    empMap.remove("rankId");
}

코드를 보면 알겠지만 for문을 이중으로 돌려 각 사원정보를 참조할때마다 직급정보를 한번더 순회하여 데이터를 붙이는 방식이다.
보통 이런 형태로 2중 for문을 사용하는 코드는 시간복잡도를 늘리는 등 지양하는 편이다.
그럼 어떤 코드를 작성하면 좋을까?

List를 Map으로 변환 후 for문 한번 돌리기

Map<String, Map<String, String>> rankMap = rankList.stream().collect(Collectors.toMap(i -> i.get("rankId"), i -> i));
for (Map<String, String> empMap : empList) {
	empMap.put("rankName", rankMap.get(empMap.get("rankId")).get("name"));
	empMap.remove("rankId");
}

stream의 collector를 사용하여 타겟데이터의 list를 Map으로 변환후 for문 한번으로 각 key를 참조하여 필요한 데이터를 Map에서 가지고와 데이터 붙이는 방식이다.
이런 방식이면 for문 한번으로도 원하는 형태의 데이터를 반환할 수 있다.

직급ID에서 직급명 형태로 표현한 사원목록 json 데이터

[
  {
    "empNo": "3278",
    "name": "김철수",
    "rankName": "사원"
  },
  {
    "empNo": "2457",
    "name": "안영희",
    "rankName": "대리"
  },
  {
    "empNo": "6323",
    "name": "고민수",
    "rankName": "과장"
  },
  {
    "empNo": "7342",
    "name": "황동석",
    "rankName": "대리"
  },
  {
    "empNo": "4215",
    "name": "김가영",
    "rankName": "과장"
  }
]
profile
new vision and new value
post-custom-banner

0개의 댓글