또다시 나에게 찾아온 고비
재귀함수 실습이라고는 하지만, 사실상 나에겐 JSON이 가장 큰 고비였다.
또다시 처음보는 언어와 구조..
현업에서는 좋은 라이브러리를 사용한다고 하니, 개념만 이해하는 식으로 넘어가야겠다.
# StringifyJSON
- null을 입력받을 경우, 알맞은 형태의 JSON으로 변환합니다.
- Boolean 타입을 입력받을 경우, 알맞은 형태의 JSON으로 변환합니다.
- String 타입을 입력받을 경우, 알맞은 형태의 JSON으로 변환합니다.
- 배열을 입력받을 경우, 알맞은 형태의 JSON으로 변환합니다.
- HashMap을 입력받을 경우, 알맞은 형태의 JSON으로 변환합니다.
- 배열, Map 타입의 요소를 가진 배열이나 Map을 입력받을 경우, 알맞은 형태의 JSON으로 변환합니다.
# StringifyJSON_ 실습
1. JSON 이란?
: SON(JavaScript Object Notation)
→ 자바스크립트의 오브젝트
→ 네트워크를 통해 어떤 객체의 내용을 다른 프로그램에게 전송 또는 연결하려면 객체를 JSON의 형태로 변환하거나 : : : JSON을 객체의 형태로 변환할 필요가 있음
→ JSON은 서로 다른 프로그램 사이에서 데이터를 교환하기 위한 포맷
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(message);
System.out.println(json);
(이 걸 writeValueAsString하는 이 과정을 직렬화(serialize)한다고 함)
ObjectMapper mapper = new ObjectMapper();
String json = "{\"createdAt\":\"2021-01-12,10:10:10\",\"receiver\":\"박해커\",\"sender\":\"김코딩\",\"message\":\"밥먹을래?\"}";
Map<String, String> deserializedData = mapper.readValue(json, Map.class);
System.out.println(deserializedData);
직렬화된 JSON에 메서드 readValue을 적용하면 다시 객체의 형태로 변환 가능
( readValue를 적용하는 이 과정을 역직렬화(deserialize))
2. JSON의 기본 규칙
- JSON : key-value store
: key는 항상 스트링
: value는 다양한 것이 올 수 있음(오브젝트도 가능)
→ String, int, array, object(key-value)
→ 만약 오브젝트가 오면, 본래 자신이 읽어왔던 방식대로 재귀적으로 처리
¤ 문자열은 그대로 문자열 붙여서 출력
¤ Integer, Boolean toString이용해서 출력
¤ 배열입력시
¤ HashMap 입력시
¤ 이터레이터 반복하며
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.w3c.dom.ls.LSOutput;
import java.util.*;
public class stringifyJSON {
public String ObjectMapper(Object data) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(data);
}
public String stringify(Object data) {
// 입력된 값이 문자열일 경우
// String이 input으로 주어졌을 경우 stringify("foo");
if (data instanceof String) {
// ()안의 포맷으로 문자열 출력
return String.format("\"%s\"", data);
}
// 입력된 값이 Integer일 경우
// 데이터가 정수형 일 경우 "숫자" 반환
if (data instanceof Integer) {
return data.toString();
}
// 입력된 값이 Boolean일 경우
// 데이터가 true인 경우 "true" 반환
if (data instanceof Boolean) {
return data.toString();
}
//입력된 값이 Object[]일 경우
if (data instanceof Object[]) {
// Object[]로 다운 캐스팅
Object[] newData = (Object[]) data;
// newData가 빈 배열일 경우
if (newData.length == 0) {
return "[]";
}
String jsonData = "";
// newData배열에서 Object 타입을 가지고 있는 요소 반복검사
for (Object obj : newData) {
// 배열의 요소를 하나씩 stringify(문자열로 변환)하여 ","로 연결하여 jsonData에 넣음
jsonData += stringify(obj) + ",";
}
// 마지막에 추가된 "," 문자를 제거 | 0번 인덱스 ~ 마지막인덱스 전까지만
jsonData = jsonData.substring(0, jsonData.length() -1);
return String.format("[%s]", jsonData);
}
// 입력된 값이 HashMap일 경우
// HashMap일 경우 JSON Object 형태로 변경합니다.
if (data instanceof HashMap) {
// HashMap으로 다운 캐스팅
// HashMap은 key와 value의 타입을 모두 지정해 주어야 함
// <Object, Object>는 모든 데이터 타입을 담을 수 있는 유연한 HashMap이 가능
HashMap<Object, Object> newHashMap = (HashMap<Object, Object>) data;
// HashMap이 비어있을 경우 {}를 출력하는 것이 일반적
// 사용할 때는 HashMap<>로 사용
if (newHashMap.isEmpty()) {
return "{}";
}
// newHashMap의 key-value를 set으로 변환
// entrySet은 Map에 저장된 키-값 쌍을 Map.Entry객체의 형태로 가져오는 메서드
// newHashMap.entrySet()은 newHashMap에 저장된 모든 키밸류쌍을 순회하며, 각각의 키와 밸류를 가져오기 위함
// Set<Map.Entry<Object, Object>>은 위에서 호출한 쌍을 Map.Entry객체의 형태로 가져와 Set형식으로 반환
Set<Map.Entry<Object, Object>> entrySet = newHashMap.entrySet();
// 이렇게 반환된 Set 객체는 Iterator<Map.Entry<Object, Object>>를 사용해 순회함
// entrySet.iterator() 객체를 호출하면 entrySet요소 순회를 위한 iterator객체가 생성되며, entryIterator 변수에 할당
Iterator<Map.Entry<Object, Object>> entryIterator = entrySet.iterator();
// jsonData 빈 문자열로 초기화
String jsonData = "";
// entryIterator.hasNext()로 entryIterator에 다음 요소가 있는지 확인
while (entryIterator.hasNext()) {
// entryIterator.next() 메서드로 다음 요소에 접근, 요소가 있다면 entry 변수에 할당
Map.Entry<Object, Object> entry = entryIterator.next();
// entry 변수에서 key는 key 변수에, value는 value 변수에 각각 할당
Object key = entry.getKey();
Object value = entry.getValue();
jsonData += String.format("%s:%s,", stringify(key), stringify(value));
}
jsonData = jsonData.substring(0, jsonData.length() -1);
return String.format("{%s}", jsonData);
}
//지정되지 않은 타입의 경우에는 "null"을 리턴합니다.
if (data == null) {
return "null";
}
return "null";
}
}
처음에는
Stream.iterate() 메소드는 초기값(initial seed)과 이전 값(previous value)을 이용하여 무한한(또는 제한된) 요소를 생성하는 스트림(Stream)을 생성하는 메소드입니다.
public static<T> Stream<T> iterate(T seed, UnaryOperator<T> f)
여기서 seed는 초기값을 나타내고, f는 이전 값(previous value)을 입력으로 받아서 새로운 값을 생성하는 함수(UnaryOperator)입니다.
즉, Stream.iterate() 메소드는 초기값 seed로부터 시작하여, f 함수를 이용하여 이전 값 previous를 가지고 새로운 값을 계속 생성하는 방식으로 무한(또는 제한된) 요소를 생성합니다.
예를 들어, Stream.iterate(1, n -> n + 1) 코드는 1부터 시작하여 1씩 증가하는 무한한 정수 스트림을 생성합니다.
Stream.iterate() 메소드는 무한한 스트림을 생성할 수 있으므로, 이를 제한하기 위해서는 Stream.takeWhile() 등과 같은 중간 연산을 이용하여 특정 조건을 만족하는 요소만을 선택하거나, Stream.limit() 등과 같은 연산을 이용하여 특정 개수 이하의 요소만을 선택해야 합니다.
# 자료구조의 이해
# stack
# Queue
↓ 이전 글 ↓
↓ 코트스테이츠 부트캠프 관련 글 한번에 보기 ↓
[코드스테이츠] 05_15_TIL : 알고리즘/자료구조 _ Tree / Graph (2) | 2023.05.16 |
---|---|
[코드스테이츠] 05_12_TIL : 알고리즘/자료구조 _ Stack/Queue (0) | 2023.05.13 |
[코드스테이츠] 05_10_TIL : 알고리즘 / 자료구조 _ 재귀함수 이론 (0) | 2023.05.10 |
[코드스테이츠] Section 1 회고 _ 04.11 ~ 05.09 (0) | 2023.05.09 |
[코드스테이츠] 05_08_TIL : 스레드와 JVM (0) | 2023.05.09 |