[TIL] 2025-01-13_레코드

Yuri·2025년 1월 13일

TIL

목록 보기
27/59
post-thumbnail

✏️ 키오스크 과제를 구현하며 겪은 문제점과 해결방법, 새로 알게된 점을 기록합니다.

1. 레코드(recode) 클래스

속성(필드), 생성자, 기능(메서드)를 가진 클래스를 IDE가 레코드 클래스로 변환할 것을 제안하였다.

레코드(Recode)

  • 불변(immutable) 객체를 쉽게 생성할 수 있도록 하는 유형의 클래스이다.
    • enum과 같은 특별한 형태의 클래스이다.
    • 간단하게 데이터를 저장하고 옮기는 역할
    • 생성자, getter, hashCode, equals(), toString()을 제공해준다.
  • JDK14에서 preview로 등장하여 JDK16에서 정식 스펙으로 포함되었다.

▶︎ 기존 클래스(MenuItem) → 레코드 클래스 변환

예시와 같이 메서드는 커스텀 할 수 있다.

▶︎ MenuItem 필드 호출

System.out.println("선택한 메뉴 :" + item.name() + ", " + item.price() + ", " + item.description());

✨ 특징

  1. 생성자는 모든 field를 포함한다.
  2. toString()도 모든 field를 포함한다.
  3. equals(), hashCode() 메서드는 invokedynamic based mechanism을 사용한다.
  4. getter는 field의 이름과 유사한 이름으로 생성된다. (menuItem 필드 호출 참고)
  5. 기본적으로 java.lang.Recode 클래스를 상속받기 때문에 다른 class를 상속받을 수 없다.
  6. class가 final이기 때문에 다른 subclass를 생성할 수 없다. (extends 불가)
  7. 모든 field는 불변이기 때문에 setter는 제공하지 않는다.

활용 예시

  1. DTO(data transfer object)나 domain model class에 사용한다.
  2. 일시적으로 데이터를 저장할 때 사용한다.
  3. 데이터를 저장하고 싶지만 긴 코드를 작성하고 싶지 않을 때 사용한다.
  4. 불변적인 데이터를 저장할 때 적합하다.

MenuItem 클래스에서 모든 필드를 생성자에서 초기화하며 별도의 setter를 작성하지 않아 레코드의 조건을 만족하여 IDE 에서 레코드 클래스로 변환 제안을 한 것이다. 필드 캡슐화와 생성자, getter, equals(), toString() 등을 자동으로 생성하여 불변객체 클래스를 쉽게 만들 수 있지만, 다른 객체의 상속이 불가능하기 때문에 주의를 기울여야 한다.

2. String.format()

반복문을 활용해 menuItems를 탐색하면서 하나씩 접근 및 출력하는 기능

@Override
public String toString() {
    return name + " | W " + price + " | " + description;
}

위와 같이 toString()을 오버라이딩 후 실행
메뉴명 길이가 다르기 때문에 콘솔에 찍었을 때 메뉴 양식이 예쁘게 출력되지 않는다. → 문자열의 형태를 지정하는 메서드로 양식에 맞게 출력하자
String.format() 은 리턴되는 문자열의 형태를 서식에 따라 지정하는 메서드이며 서식 문자열 앞에 %를 붙여 사용하면 그 변수의 값을 형식화 하여 대입할 수 있다.

서식분류설명
%b참,거짓boolean 지정
%h16진수hex(16진수) 지정
%s문자열string 지정
%c문자char 지정
%d정수decimal(10진수) 정수 지정
%o정수octal(8진수) 정수 지정
%x정수hex(16진수) 정수 지정
%e부동 소수점10진수(가수와 진수)로 표시
%f부동 소수점10진수 표시
%g부동 소수점10진수(반올림) 표시
%a부동 소수점16진수(가수와 진수)로 표시
%t날짜, 시간날짜 및 시간 서식 지정
%n줄 구분개행문자

▶︎ String.format() 적용

@Override
public String toString() {
	return String.format("%-12s | W %.1f | %s", name, price, description);
}
명령어설명
%[최소길이]s최소길이만큼 문자열을 출력하며, 왼쪽에서부터 공백으로 채웁니다. (오른쪽 정렬)
%-[최소길이]s최소길이만큼 문자열을 출력하며, 오른쪽에서부터 공백으로 채웁니다. (왼쪽 정렬)

명령어설명
%0.0f소수점 앞 0칸만큼 채워서 출력, 소수점 뒤 0칸까지 출력 (이하 소수점은 반올림)

▶︎ 결과

3. iteration → addAll()

가변 길이의 매개변수를 받아 MenuItem을 관리하는 리스트에 전달받은 값을 저장하는 생성자를 선언

향상된 for문(Iteration)으로 배열을 순회하며 리스트에 add 한다.
⇢ IDE: Iteration이 bulk 'Collection.addAll()'로 대체 가능하다

public Kiosk(MenuItem... menuItem) {
	this.menuItems.addAll(Arrays.asList(menuItem));
}

addAll()
- ArrayList에 다른 ArrayList를 통째로 붙이기 위한 메서드
- 인자로 Collection 객체를 받고 그 Collection에 있는 아이템들을 리스트에 모두 추가한다.

▶︎ 코드 해석

가변 매개변수는 배열이므로 addAll의 인자로 받기 위해 Arrays.asList() 메서드로 배열 → 리스트로 변환 후 해당 객체를 menuItems 리스트에 통째로 붙인다.

⭐️ 순회하며 하나씩 저장하는 iteration 형태는 데이터의 양이 많아지면 지연 시간이 길어진다. bulk insert는 대용량 데이터의 저장 방식에 적합하다.

🔗 참고자료
[JAVA 문법] Record Class
[JAVA] String.format() - 문자열 형식 지정


📝 TO-DO

  1. 키오스크 필수과제 (Lv1 ~ Lv5) 통합 테스트
  2. 키오스크 도전과제 (Lv6) 구현
  3. 트러블슈팅 및 README 작성
  4. 자바 강의 - 기술 아카이브 정리

💭 Diary

3주차가 되어 새로운 프로그래밍 과제가 주어졌다. 지난주 계산기 과제보다 꽤 빠른 속도로 과제가 진행되고 있다.☺️ 놓치는 부분이나 더 개선할 부분은 없는지 꼼꼼히 살펴보며 진행해야겠다.

profile
안녕하세요 :)

0개의 댓글