포스트

Day40 실습프로젝트(Gson, Generic)

JSON 포맷 입출력

1. Gson 라이브러리

  • 정의 구글에서 만든 Json포맷 입출력 라이브러리
  • 기본구조 image

2. myApp에 적용하기

  • gradle 설정하기
    • App에 위치한 gradle.build의 dependencies에 gson 라이브러리를 추가한다. ```gradle { implementation 'com.google.code.gson:gson:2.11.0' } ```
  • Save/ Load 코드 수정하기
    • Save 코드수정하기
      1. Gson을 새로 인스턴스한다.
      2. toJson(List)을 호출한다.
      3. FileWriter로 생성한 객체에 대입한다.
    • load 코드수정하기
      1. BufferedReader : 한줄 씩 읽어들이는 InputStream 이며, 빈 문자열 일 경우 null을 return한다.
      2. 한줄 씩 읽어 line에 대입하고, line이 null이 아닐때까지 반복한다.
      3. line을 StringBuffer에 대입한다.
      4. Gson.fromJson(문자열, 데이터구조)로 구조화 한 후 boadList에 전부 대입한다.
      5. 데이터 구조: TypeTokeon(ArrayList(Board))로 ArrayList의 데이터 구조를 말한다.
      ```java private void loadBoards() { try (BufferedReader in = new BufferedReader(new FileReader("board.json"))) { StringBuilder strBuilder = new StringBuilder(); String line; while ((line = in.readLine()) != null) { strBuilder.append(line); } boardList.addAll(new Gson().fromJson(strBuilder.toString(), new TypeToken>() { })); int maxBoardNo = 0; for (Board board : boardList) { if (board.getNo() > maxBoardNo) { maxBoardNo = board.getNo(); } } Board.initSeqNo(maxBoardNo); } catch (IOException e) { System.out.println("게시글 정보 로딩 중 오류 발생!"); // e.printStackTrace(); } } private void saveBoards() { try (FileWriter out = new FileWriter("board.json")) { Gson gson = new Gson(); out.write(gson.toJson(boardList)); } catch (IOException e) { System.out.println("게시글 정보 저장 중 오류 발생!"); // e.printStackTrace(); } } ```
  • 데이터 맞춤 설정하기
    • json파일에 데이터 타입이 "createdDate":"Jul 22, 2024, 5:13:25 PM"으로 출력이 된다.
    • 이를 "yyyy-MM-dd"타입으로 출력하기 위해서 설정이 필요하다.
    • GsonBuilder을 통해서 설정을 해줄 수 있으며 코드는 다음과 같다 ```java new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create() ```
    • Save/Load 코드를 수정하면 다음과 같다. ```java private void loadBoards() { try (BufferedReader in = new BufferedReader(new FileReader("board.json"))) { StringBuilder strBuilder = new StringBuilder(); String line; while ((line = in.readLine()) != null) { strBuilder.append(line); } boardList.addAll(new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create().fromJson(strBuilder.toString(), new TypeToken>() { })); int maxBoardNo = 0; for (Board board : boardList) { if (board.getNo() > maxBoardNo) { maxBoardNo = board.getNo(); } } Board.initSeqNo(maxBoardNo); } catch (IOException e) { System.out.println("게시글 정보 로딩 중 오류 발생!"); // e.printStackTrace(); } } private void saveBoards() { try (FileWriter out = new FileWriter("board.json")) { out.write(new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create().toJson(boardList)); } catch (IOException e) { System.out.println("게시글 정보 저장 중 오류 발생!"); // e.printStackTrace(); } } ```
# Generic 적용하기

1. Generic의 개념

  • 결정되지 않은 타입을 파라미터로 처리하고 실제 사용할 때 파라미터를 구체적인 타입으로 대체 시키는 기능을 말한다.
  • 실행 할 때 사용할 타입을 정하면 캐스팅없이 해당 타입을 다룰 수 있다. ```java public class Test{ static class Box{ private T value; public T get(){return this.value;} public void set(T value){this.value = value;} } public static void main(String[] args){ Box box = new Box<>(); box.set("안녕하세요"); System.out.println(box.get()); //안녕하세요 Box boxInt = new Box<>(); box.set(1); System.out.println(box.get()); //1 } } ```

2. Generic의 사용

  1. 배열에 제네릭 적용하기 ```java public class Test { static T[] reverse2(T[] arr) { for (int i = 0; i < arr.length / 2; i++) { T temp = arr[i]; int targetIndex = arr.length - 1 - i; arr[i] = arr[targetIndex]; arr[targetIndex] = temp; } return arr; } public static void main(String[] args) { String[] arr2 = reverse2(new String[] {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"}); for (String value : arr2) { System.out.print(value + ","); } System.out.println(); } } // String[] arr = new String[]{~~~} ```
  2. 제네릭을 이용하여 배열을 직접 생성할 수는 없다. 그렇기 때문에 다른 방법으로 배열을 생성해야한다.
    코드 접기/펴기 ```java // 제네릭(Generic) : 배열 만들기 import java.lang.reflect.Array; import java.util.Arrays; public class Test { // 예1) 제네릭의 타입 파라미터로 레퍼런스 배열을 생성할 수 없다. static T[] create1() { T[] arr; // arr = new T[10]; // 컴파일 오류! new 명령어를 사용할 때 제네릭의 타입 파라미터를 사용할 수 없다. return null; } // 예2) 견본 배열을 받아서 복제하는 방법을 사용한다. static T[] create2(T[] arr) { return Arrays.copyOf(arr, 10); } // 예3) 배열의 타입 정보를 받아 생성하기 static T[] create3(Class type) { return (T[]) Array.newInstance(type, 10); } // 예4) 견본 배열에서 타입 정보를 추출하여 배열을 생성하기 static T[] create4(T[] arr) { Class arrayTypeInfo = arr.getClass(); // 예) String[] System.out.println(arrayTypeInfo); Class arrayItemTypeInfo = arrayTypeInfo.getComponentType(); // 예) String System.out.println(arrayItemTypeInfo); return (T[]) Array.newInstance(arrayItemTypeInfo, 10); } public static void main(String[] args) { // 제네릭을 사용하는 메서드를 이용하여 배열 만들기 // 파라미터로 빈 배열을 넘기면, String[] arr1 = create2(new String[0]); System.out.println(arr1.length); // 내부에서 생성할 배열 크기 보다 더 큰 배열을 파라미터로 넘긴다면? // copyOf() 그래도 새 크기에 맞춰 새 배열을 생성한다. String[] temp = new String[100]; String[] arr2 = create2(temp); System.out.println(arr2.length); System.out.println(temp == arr2); // 생성할 배열의 타입 정보를 넘긴다. String[] arr3 = create3(String.class); System.out.println(arr3.length); // 배열을 넘기면 배열의 항목 타입을 알아내어 새 배열을 만든다. String[] arr4 = create4(new String[0]); System.out.println(arr4.length); } } ``` </details> </ol> </div>

    3. Generic의 특징