📖
Kyu9's Repo
  • Library of mameil
  • 이슈 경험
    • 20230220_트랜잭션
    • 20230306_캐싱이슈
    • 20230722_테스트코드에서 @Transactional
    • 20230807_deadlock
  • 인턴 스터디
    • Gradle
    • Stream, Optional, 람다식
    • JVM의 메모리 구조, Garbage Collector
    • RESTful API
    • Microservice Architecture
    • HTTP
    • 웹서버란 무엇인가
    • Git Branch
    • TDD
    • Redis을 이용한 캐시
    • Thymeleaf
    • 정리가 필요한 자료들
    • SpringBoot Management
    • 테스크 코드 분할
  • 동아리 스터디
    • 기본 SQL 공부
      • SQL의 기본 개념
      • SELECT 문장을 이용하여 원하는 데이터 출력하기
        • 집합 연산자 사용하기
        • where절에 비교 연산자를 사용해보기
        • SELECT_EX
        • 산술 연산자 사용해보기
      • 단일 행 함수 사용
        • lower/upper 함수 사용하기
        • length함수 사용하기
        • concat함수 사용
        • substr/mid/substring 함수 사용
        • instr함수 사용하기
        • lpad/rpad 함수 사용하기
        • trim/ltrim/rtrim 함수 사용하기
        • replace 함수 사용하기
        • round 함수 사용하기
        • truncate 함수 사용하기
        • mod함수 사용하기
        • ceil함수 사용하기
        • floor함수 사용하기
        • power 함수 사용하기
        • Date fn(날짜 함수)
        • 형 변환 함수
        • 일반함수란
    • a-ha 실습
    • 혼자서 만들어본 게시판
    • AWS 강의
  • 학교 나머지 공부 자료
    • 웹프레임워크(Spring)
      • Spring이란?
      • Webframework1-1
      • Webframework1-2
      • SpringBoot의 특징
      • SpringBoot 생성 방법
      • Spring Data JPA
      • SpringBoot Security
      • SpringBoot HATEOAS
  • 공부 자료들
  • WS 온라인 자바 스터디
    • Week1(JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가.)
    • Week2(자바 데이터 타입, 변수 그리고 배열)
    • Week3(연산자)
    • Week4(제어문)
    • Week5(클래스)
    • Week6(상속)
    • Week7(패키지)
    • Week8(인터페이스)
    • Week9(예외처리)
    • Week10(멀티쓰레드 프로그래밍)
    • Week11(Enum)
    • Week12(Annotation)
    • Week13(I/O)
    • Week14(Generic)
    • Week15(람다식)
  • 백준문제
    • 입출력과 사칙연산
      • We love kriii(10718)
      • 고양이(10171)
      • 개(10172)
      • A+B(1000)
      • A-B(1001)
      • AxB(10998)
      • A/B(1008)
      • 사칙연산(10869)
      • 나머지(10430)
      • 곱셈(2588)
    • for문
      • 구구단(2739)
      • A+B - 3(10950)
      • 합(8393)
      • 빠른 A+B(15552)
      • N 찍기(2741)
      • 기찍 N(2742)
      • A+B - 7(11021)
      • A+B - 8(11022)
      • 별 찍기 - 1(2438)
      • 별 찍기 - 2(2439)
      • X보다 작은 수(10871)
    • if문
      • 두 수 비교하기(1330)
      • 시험 성적(9498)
      • 윤년(2753)
      • 사분면 고르기(14681)
      • 알람 시계(2884)
      • 오븐 시계(2525)
      • 주사위 세개(2480)
      • 영수증(25304)
    • While문
      • A+B - 5(10952)
      • A+B - 4(10951)
      • 더하기 사이클(1110)
    • 1차원 배열
      • 최소, 최대(10818)
      • 최댓값(2562)
      • 숫자의 개수(2577)
      • 나머지(3052)
      • 평균(1546)
      • OX퀴즈(8958)
      • 평균은 넘겠지(4344)
    • 함수
      • 정수N개의 합(15596)
      • 셀프 넘버(4673)
      • 한수(1065)
    • 문자열
      • 아스키코드(11654)
      • 숫자의 합(11720)
      • 알파벳 찾기(10809)
      • 문자열 반복(2675)
      • 단어 공부(1157)
      • 단어의 개수(1152)
      • 상수(2908)
      • 다이얼(5622)
      • 크로아티아 알파벳(2941)
      • 그룹 단어 체커(1316)
    • 기본수학-1
      • 손익분기점(1712)
      • 벌집(2292)
      • 분수찾기(1193)
      • 달팽이는 올라가고 싶다(2869)
      • ACM 호텔(10250)
      • 부녀회장이 될테야(2775)
      • 설탕 배달(2839)
      • 큰 수 A+B(10757)
      • Fly me to the Alpha Centauri(1011)
    • 기본수학-2
      • 소수 찾기(1978)
      • 소수(2581)
      • 소인수분해(11653)
      • 소수 구하기(1929)
      • 베르트와 공존(4948)
    • 재귀
      • 하노이 탑 이동 순서(11729)
      • 피보나치 수 5(10870)
      • 별 찍기(2447)
    • 브루트 포스
      • 블랙잭(2798)
      • 분해합(2231)
      • 덩치(7568)
      • 체스판 다시 칠하기(1018)
      • 영화감독 슘(1436)
    • 집합과 맵
      • 숫자 카드(10815)
      • 문자열 집합(14425)
      • 숫자 카드2(10816)
      • 듣보잡(1764)
      • 대칭 차집합(1269)
      • 서로 다른 부분 문자열 갯수(11478)
    • 정렬
      • 수 정렬하기(2750)
      • 수 정렬하기 2(2751)
      • 수 정렬하기 3(10989)
      • 통계학(2108)
      • 소트인사이드(1427)
      • 좌표 정렬하기(11650)
      • 좌표 정렬하기2(11651)
      • 단어 정렬(1181)
      • 나이순 정렬(10814)
      • 커트라인(25305)
      • 좌표압축(18870)
    • 백트래킹
      • N과 M - 1(15649)
      • N과 M - 2(15650)
      • N과 M - 3(15651)
      • N과 M - 4(15652)
      • N-Queen(9663)
      • 스도쿠(2580)
      • 연산자 끼워넣기(14888)
      • 스타트와 링크(14889)
    • 이분 탐색
      • 수 찾기(1920)
    • 동적계획법
      • 피보나치 함수(1003)
      • 신나는 함수 실행(9184)
      • 01타일(1904)
      • 파도반 수열(9461)
      • RGB거리(1149)
      • 정수 삼각형(1932)
      • 계단 오르기(2579)
      • 1로 만들기(1463)
      • 쉬운 계단 수(10844)
      • 포도주 시식(2156)
      • 가장 긴 증가하는 부분 수열(11053)
      • 가장 긴 바이토닉 부분 수열(11504)
      • 전깃줄(2565)
      • LCS(9251)
      • 연속합(1912)
      • 평범한 배낭(12865)
      • 더하기(9095)
    • DFS와 BFS
      • 미로탐색(2178)
      • 바이러스(2606)
      • DFS와 BFS(1260)
      • 단지번호붙이기(2667)
      • 전쟁 - 전투(1303)
      • 숨바꼭질(1697)
      • 데스 나이트(16948)
      • 나이트의 이동(7562)
      • 녹색 옷 입은 애가 젤다지?(4485)
      • 음식물 피하기(1743)
      • A->B (16953)
      • 숨바꼭질 3(13549)
      • 숨바꼭질 2(12851)
    • 구현
      • 치즈(2636)
  • 프로그래머스 문제
    • SQL
      • Animal Table - Oracle
      • Animal Table - MySQL
      • Animal Table2 - Oracle
      • Animal Table 3,4 - Oracle
    • Lv1
      • 두 개 뽑아서 더하기
      • 제일 작은 수 제거하기
      • 문자열 내 p와 y의 개수
      • 예산
      • 자릿수 더하기
      • 두 정수 사이의 합
      • 같은 숫자는 싫어
      • 가운데 글자 가져오기
      • 수박수박수박수박수박수?
      • 나누어 떨어지는 숫자 배열
      • 2016년
      • 폰캣몬
      • 서울에서 김서방 찾기
      • 문자열을 정수로 바꾸기
      • 소수 만들기
      • 문자열 다루기 기본
      • 소수 찾기(에라토스테네스의 체)
      • 숫자 문자열과 영단어
      • 이상한 문자 만들기
      • 없는 숫자 더하기
      • 문자열 내림차순으로 배치하기
      • 문자열 내 마음대로 정렬하기
      • 약수의 개수와 덧셈
      • 콜라츠 추측
      • 자연수 뒤집어 배열로 만들기
      • 신규 아이디 추천
      • 비밀지도
      • 크레인 인형뽑기 게임
      • 실패율
      • 로또의 최고 순위와 최저 순위
      • 키패드 누르기
      • 정수 내림차순으로 배치하기
    • Lv2
      • 행렬의 곱셈
      • 영어 끝말잇기
      • 영어 끝말잇기
      • N개의 최소 공배수
      • 피보나치 수
      • 124 나라의 숫자
      • 짝지어 제거하기
      • 프린터
      • 다음 큰 숫자
      • 최댓값과 최솟값
      • 최소값 만들기
      • 숫자의 표현
      • JadenCase 문자열 만들기
      • 오픈채팅방
      • 영어 끝말잇기
      • 멀쩡한 사각형
      • 올바른 괄호
      • 위장
      • 기능개발
      • 더 맵게
      • 스킬트리
    • 완전탐색
      • 모의고사(Lv1)
      • 카펫(Lv2)
      • 소수 찾기(Lv2)
    • 정렬(Sorting)
      • K번째 수(Lv1)
      • 가장 큰 수(Lv2)
      • H-Index(Lv2)
    • 해시(Hash)
      • 완주하지 못한 선수(Lv1)
      • 전화번호 목록(Lv2)
    • 탐욕법(Greedy)
      • 체육복(Lv1)
      • 큰 수 만들기(Lv2)
      • 구명보트(Lv2)
    • 동적계획법(DP)
      • 정수 삼각형(Lv3)
    • 깊이/너비 우선 탐색(DFS/BFS)
      • 타겟 넘버(Lv2)
      • 네트워크(Lv3)
      • 단어 변환(Lv3)
  • 스프링부트 책
    • Day 1
    • Day 2
    • Day 3
    • Day 4
    • Day 5
    • Day 6
    • Day 7
    • Day 8
    • Day 9
    • Day 10
    • Day 11
    • Day 12
    • Day 13
    • Day 14
    • Day 15
    • Day 16
    • Day 17
  • JPA 책
    • 프로젝트 세팅 및 기본설정
    • 영속성 관리 개념
    • 엔티티 매핑
      • 실습 예제
    • 연관관계 매핑 기초
      • 실습 예제
    • 다양한 연관관계 매핑
      • 다대일, 일대다 관계
      • 일대일, 다대다 관계
      • 실습 예제
    • 고급 매핑
      • 상속 관계 매핑
      • @MappedSuperclass
      • 복합 키와 식별 관계 매핑
      • 조인 테이블
    • 프록시와 연관관계 관리
      • 프록시
      • 즉시 로딩과 지연 로딩
      • 영속성 전이, 고아 객체
    • 값 타입
      • 임베디드 타입
      • 값 타입과 불변 객체
      • 값 타입의 비교, 컬렉션
    • 객체지향 쿼리 언어
      • JPQL part1
      • JPQL part2
      • JPQL part3
      • QueryDSL
      • NativeSQL
      • 객체지향 쿼리 심화
    • 응용 애플리케이션
      • 엔티티 설정
    • 스프링 데이터 JPA
      • 공통 인터페이스
  • Kotlin In Action
    • 코틀린의 특징
    • 코틀린의 기초
    • 함수 정의와 호출
    • 클래스, 객체, 인터페이스
    • 람다 방식
    • 코틀린 타입 시스템
    • 연산자 오버로딩과 기타 관례
    • 고차함수
    • 제네릭스
    • 애노테이션과 리플렉션
    • 코루틴
  • Oracle
    • Oracle 기본
    • Oracle 심화
  • SQL_연습
    • Revising the Select Query
    • Basic Select
    • Advanced Select
    • Basic Select 2
  • SQL 첫걸음(책)
    • Day 1
    • Day 2
    • Day 3
    • Day 4
    • Day 5
    • Day 6
    • Day 7
    • Day 8
    • Day 9
    • Day 10
    • Day 11
    • Day 12
    • Day 13
    • Day 14
    • Day 15
    • Day 16
    • Day 17
    • Day 18
    • Day 19
    • Day 20
    • Day 21
    • Day 22
    • Day 23
    • Day 24
    • Day 25
    • Day 26
    • Day 27
    • Day 28
    • Day 29
    • Day 30
  • 더 자바 코드를 조작하는 다양한 방법
    • JVM 이해하기
    • 바이트코드 조작
    • 리플렉션
    • 다이나믹 프록시
    • 애노테이션 프로세서
  • 더 자바, 애플리케이션을 테스트하는 다양한 방법
    • JUnit5
    • Mockito
    • 도커와 테스트
    • 성능, 운영이슈, 아키텍처 테스트
  • 이펙티브 자바
    • item1 - 생성자 대신 정적 팩토리 메소드를 고려하라
    • item2 - 생성자에 매개변수가 많다면 빌더를 고려하라
    • item3 - 생성자나 열거타입으로 싱글턴임을 보증하라
    • item4 - 인스턴스화를 막기 위해선 private 생성자를 사용하라
    • item5 - 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라
    • item6 - 불필요한 객체 생성을 피하라
    • item7 - 다 쓴 객체 참조를 해제하라
    • item8 - finalizer와 cleaner 사용을 피하라
    • item9 - try-finally 보다 try-with-resources을 사용하라
    • item10 - equals는 일반 규약을 지켜 재정의하라
    • item11 - equals을 재정의하려면 hashCode도 재정의하라
    • item12 - toString을 항상 재정의하라
    • item13 - clone 재정의는 주의해서 진행하라
    • item14 - Comparable을 구현할지 고민하라
  • Elastic Search
    • 강의 Summary
    • Elastic Summary 개념 정리
    • Elastic Summary 적용 정리
  • 토비의 스프링 강의
    • 스프링부트 살펴보기
    • 독립 실행형 서블릿 애플리케이션
  • k8s
    • minikube 설치
    • jenkins 추가
  • Article
    • Choosing the Right MessageBroker
Powered by GitBook
On this page

Was this helpful?

  1. 이펙티브 자바

item13 - clone 재정의는 주의해서 진행하라

자바에서 제공해주는 clone()과 cloneable 인터페이스에 대해서 알아보자

clone()은 Object에 정의되어 있는 메소드이고, cloneable 이라는 인터페이스는 텅 비어있는 인터페이스이다 cloneable은 우선 아무것도 구현되어있지 않은 비어있는 메소드인데, 약간 이걸 implement 함으로써, clone()을 사용할 것이다 라고 선언하는 것과 같은 그러한 개념이다

clone() 메소드는, 이름과 같이 지정한 객체와 같은 객체를 생성하는 것이다 특징으로는 같은 객체이지만, 레퍼런스는 다른 객체이다 이렇게 clone()을 구현하는데 있어서 들어가야하는 규약은 몇가지가 존재한다

우선, 원본.clone() != 원본 의 결과값은 항상 TRUE 여야만 한다 요건 위에서 잠깐 이야기한 것 처럼, 내부의 값들은 같을 수 있어도, 완전히 새로운 객체를 생성하는 것이기 때문에 주소가 다르고 객체가 다를 수 밖에 없다고 볼 수 있다

두번째로, 원본.clone().getClass() == 복사된놈.getClass() 은 항상 TRUE 이여만 한다 객체 자체는 같은 객체를 복사하는 개념이기 때문에 원본과 복사본의 객체 타입인 클래스는 항상 같아야만 한다

세번째로, 원본.clone.equals(복사본) 은 TRUE가 아닐수도 있다 이것의 이유는 객체의 성질마다 다르다고 볼 수 있다 -> 만약 객체의 특징으로 객체가 각각의 독립적인 ID가 있다면 복제하는 순간, 다른 아이디를 가진 객체가 생성되기 떄문에 항상 true라고 볼 수는 없다

구현은 cloneable implements한 후, clone() 메소드를 override 하면서 재정의해주면 된다 주의해야할 점으로는, overriding 시, 구현하는 하위메소드의 접근지시자는 상위메소드의 접근지시자와 같거나 더 넓은 범위로 선언되어야 한다 그리고 clone() 메소드의 리턴 타입도 상속받는 Object의 객체가 아닌, 해당 메소드를 override 한 자식클래스의 타입으로 타입캐스팅을 해주고 넘겨주는 것도 가능하다 그리고 구현하는 과정에 있어서 꼭 super.clone()을 통해서 상위 clone()을 호출해줘야 한다 -> 만약 생성자를 활용해서 직접 구현하게되면 맨 처음에서의 규약이 깨지게 된다 규약이 깨지는 부분은 원본.getClass().equals(복사본.getClass()) 에서 깨지게 된다. clone()을 직접 구현한 부모메소드를 상속받아 부모메소드의 커스텀 clone()을 사용하는 자식 메소드에서 에러가 나게 된다 이유는 간단하다 자식클래스에서 부모클래스의 clone()을 사용한다고 보면, (부모)자식 이렇게 타입캐스팅은 가능하지만 (자식)부모 이렇게 타입캐스팅은 불가능하기 때문이다 이렇게 확인해야할 것은 2가지이다 clone() 메소드를 사용하기 위해서는 cloneable을 implements 받고, 재정의하는 과정에서 super.clone()을 사용하라

근데 가변객체는 어떻게 처리하냐 가변객체도 구현 방식은 같다 그냥 단순하게 cloneable을 implemnet하고 public으로 clone()을 overriding하면 된다 근데 다음으로 문제는 만약에 단순하게 이렇게만 구현하고 클론을 했다고 가정했을 때 문제는 원본과 복제본 모두가 같은 배열을 바라보는 이슈가 생긴다 이런 현상은 기본적으로 구현한 클론에서는 얕은 복사, shallow copy가 되기 때문이다. 복사하는데 해당 내부의 엘리먼트도 같이 새로이 복사되는 것이 아니라 내부의 인스턴스를 같은 인스턴스를 바라보는 이슈이다 물론 문제로써는, 복제본과 원본은 클론 이후에 완벽하게 독립된 객체여야 하는데, 둘 중에 하나만 변경되더라도 다른 객체에 영향이 가는 그러한 문제이다 그래서 방법으로는 얕은 복사가 아니라, deep copy를 해줘야 한다는 것이다

그러면 클론을 재정의하는 과정에서 필드도 클론을 따로 해주는 것이 방법이냐 -> 그것도 아니다 여전하게 얕은 복제라고 볼 수 있다 그럼 deep copy를 하는 것은 어떻게 하냐 그냥 새로운 배열을 new를 통해서 생성하고 하나하나 집어넣어주는 것이 하나의 방법이다 그리고 너무 재귀적으로 생성하지 않도록 주의하자 많이 재귀적으로 구현을 해버리면 stackoverflow 에러에게 노출될 수 있기 때문이다 그래서 deep copy를 구현할 때 어떻게 구현하는게 좋냐 어떻게 구현하기 좋은 방법 중 하나는 클론 내부에서 복잡한 메소드인 put이나 get 같은 클론이 무거워짐으로써 좋지 않은 퍼포먼스를 내는 이슈가 생긴다 그리고 클론 내부에 재정의할 수 있는 메소드는 넣지 말아야 한다 -> 만약 재정의할 수 있는 메소드가 들어가게 되면 재정의하면서 내부의 동작이 변경될 예정이기 때문이다 상속을 이용하는 경우에는 상위클래스에서 먼저 clone을 구현해두고 하위 클래스에다가는 clone을 재정의할 필요 없이 그냥 부모클래스의 clone을 사용하고 타입캐스팅을 통해서 클론을 사용하게 해줄 수 있다 마지막으로 클론이라는 메소드가 스레드로부터 안전하게 사용되어야 한다면, 클론을 재정의할때, synchronized 키워드를 붙혀서 도와주자

근데 막상 이렇게 주저리주저리 적었지만 결국은 clone이라는건 안쓰게 되고 결국은 생성자를 사용해서 객체를 새로 복사하든 작업을 진행하는데, 예시로 준 것은 Set 자료구조를 TreeSet의 생성자를 사용하면 TreeSet의 내부에 존재하는 클론을 통해서 객체를 복사할 수 있다 다른 객체에는 그런거 말고도 따로 클론을 해주는 클론 팩토리 메소드를 생성하는 것도 방법 중 하나이다

근데 클론같은걸 사용하기 위해서는 객체의 내부에 존재하는 final 같은 것들도 사용할 수 없다.. 그렇기 때문에 그렇게 막 좋다~ 이렇게 이야기하기는 조금 애매하고 사용하기도 애매하다고 생각된다 그래서 그냥 clone은 지양하고 생성자를 사용해서 객체의 복제를 진행하거나 따로 구현한 클론 팩토리 메소드를 사용하자

CheckedException, UncheckedException? UncheckedException 은 우리가 직접 구현하는 커스텀 Exception의 대부분이다. 즉 그 의미는 RuntimeException 이나 Error 을 상속받아서 구현한 예외나 그 예외 자체를 의미한다 근데 왜 이 exception을 자주 사용하는걸까? -> 물론 이유로는 단순하게 사용하기 간단해서이다 굳이 이 예외를 던질 때, 따로 예외를 잡을필요도 없고, Exception을 던질 수도 있다고 메소드에 선언하지 않아도 괜찮다 즉 이 메소드에서 예외가 던져지는지도 모르고 사용하는 면에서도 그냥 throw new 키워드를 통해서 예외를 표시할 수도 있고 아주 간단하다

그럼 checkedException 은 뭔가 -> Exception을 상속하거나 그 자체의 예외를 의미한다 일반적인 Exception이기 때문에 우선적으로 사용해버리면 컴파일러가 바로 잡아서 빨간줄을 띄워준다 그리고 이 빨간줄을 없애는 방법은, try-catch문을 통해서 예외를 잡아주던가, 아니면 메소드에 throws 키워드를 사용해서 예외를 던질 수도 있다는 것을 명시해줘야 한다. 사실 해당 메소드를 사용하는 곳에서도 처리해줘야 하는 것이다 일단 특징자체는 이러하다

근데 왜 checkedException은 존재하는걸까? 이 이유는 일단 exception을 명시해주는 것이 프로그래밍 인터페이스의 일부로, 해당 메소드를 사용하는 코드가 반드시 알아야 하는 정보라고 한다 그 의미는 예외가 발생하면 클라이언트 입장에서 처리하는 것이 가능해지기 때문이다 근데 왜 UncheckedException 은 따로 예외가 발생한 것에 대한 처리를 명시하지 않는걸까? -> 그 이유는 RuntimeException 이라는 예외는 애초에 해당 예외가 발생하면 어떻게든 복구할 수 없는 에러라고 판단하는 것이다. 즉, 이 예외가 발생해도 아무런 작업도 할 수 없다는 의미이다 그래서 클론에서 명시하면서 만약 에러가 발생하면 클라이언트가 어떻게 할 수 있는 것도 없는데, 왜 checkedException으로 구현했었나 라는 이야기가 있는 이유이다

이렇게 Exception이 나뉘어진 만큼, 사용해야하는 상황이 다르기 때문에 각각 상황에 맞춰서 사용하면 된다 만약에 예외상황을 클라이언트가 복구하는 것이 가능하다 checkedException 으로 구현을 해주고 예외상황으로부터 클라이언트가 할 수 있는 것이 없다면 그냥 uncheckedException 으로 구현을 해주면 된다

TreeSet : AbstractSet을 확장한 정렬되는 컬렉션 즉, 스택과 같이 값을 넣은 순서대로 값이 저장되는 것이 아니라 정렬되어서 저장되는 컬렉션이다 근데 왜 어떻게 정렬이 되는 것일까? -> 일단 우리가 아는 기본적인 value based data type 에는 각각이 정렬에 대한 구현이 내부에 되어있기 때문에 알아서 순서에 맞춰서 들어가게 된다 커스텀한 object 와 같은 경우는 어떻게 처리할 지 모르기 때문에 직접 정렬하는 것을 구현해줘야 한다 그리고 이것이 바로 Comparable 이라는 인터페이스이다 만약 구현하지 않고 TreeSet에 넣어주려고 하면 에러가 발생한다 그리고 이건 스레드로부터 안전하게 되어있지 않으며 기본적으로 오름차순으로 정렬되는 것이 특징이다

Red-Black tree? 이진탐색트리란, 자신의 왼쪽 서브트리엔 작은게, 오른쪽 서브트리엔 큰게 오는 구조를 의미한다 그리고 그렇게 구성된 이진탐색트리를 높이 상관없이 가장 왼쪽에 있는 거 부터 하나하나 뜯어보면 오름차순으로 정렬된 트리를 보는 것이 가능해진다

Previousitem12 - toString을 항상 재정의하라Nextitem14 - Comparable을 구현할지 고민하라

Last updated 2 years ago

Was this helpful?