문자열 연산 최적화
산학 프로젝트 냉시피 개발 중 내가 크롤링한 값을 저장하기 위해 어떤 자료형을 쓸 지 많이 고민을 했는데,
그 과정 중 알게된 java StringBuilder에 대해 정리해보려고 한다.
처음에는 크롤링값: [재료이름, 재료수량]을 Map으로 묶어서 리스트로 저장을 하려고 했다.
하지만 걱정되었던 것이
1. 크롤링 자동화가 안되었는데 복잡도가 O(n)이면 성능 상 좋지않다.(크롤링 시 N=6만을 넘고, 그 이상이 될 확률이 매우매우 높은 상황.)
2. 이걸 도메인으로 구현을 해야하는데 어떤 column 값에 리스트를 어떻게 저장할까
였고, 이 문제를 해결하기 위한 조사를 통해 StringBuilder라는걸 알게 되었다.
결론적으로 [재료이름, 재료수량]을 하나의 문자열로 결합해야 한다.
java에서 문자열을 합칠 때 "+" 연산자를 사용하는데, 여기에는 성능 관련한 문제가 발생할 수 있다.
이유를 알아보자.
먼저 String에 대해서 알아보자.
java의 spring은 클래스이고 객체를 생성하여 사용한다.
아래 두 코드는 객체 생성 방식에 차이가 있다.
// 1번 코드
String a = "abc";
// 2번 코드
String b = new String("abc");
1번 코드) 문자열 리터럴인 "abc"를 사용하여 스트링 객체 생성한다. java에서 동일한 리터럴을 가진 문자열은 동일한 객체로 취급된다. 변수 a는 리터럴 "abc"를 참조한다.
2번 코드) new 키워드를 사용하여 String 객체를 생성한다. 변수 b는 이러한 새로운 객체를 참조하고, 클래스의 생성자를 호출하여 새로운 문자열 객체를 명시적으로 생성한다.
문자열을 리터럴을 사용한 경우 동일한 리터럴을 가진 문자열은 동일한 객체로 취급되므로 'a'와 'b'는 동일한 문자열 객체를 참조하는 반면, 생성자를 통해 객체를 생성한 경우에는 항상 새로운 객체가 생성되므로 'b'는 'a'와 다른 객체를 참조한다.
String은 선언 방식에 따라 인스턴스(객체)를 생성하고, 이렇게 생성된 객체는 이후 변경할 수 없다. 따라서 "+" 연산자를 통해 문자열 결합을 수행하면, 기존 문자열의 내용이 변경되는 게 아니라 내용이 합쳐진 새로운 String 인스턴스가 생성된다.
만약 재료명과 재료 수량을 "+" 연산을 통해 결합하여 저장한다면 😱 절망적인 성능을 가져다 줄 것이다...........
그래서 StringBuilder를 활용하는 것이 답이라는 결론을 내리게 되었다!
StringBuilder
StringBuilder는 변경 가능한 문자열을 만들어서 String 불변 객체의 문제를 해결한다.
StringBuilder sb = new StringBuilder();
sb.append("abc");
System.out.println(sb.toString());
위와 같이 StrignBuilder 객체(sb)를 생성하고, 활용하는 형식으로 많이 사용한다.
StirngBuilder 또한 하나의 자료형이기 때문에 내가 원하는 String 형식으로 사용을 하기위해서는 toString() 메소드를 활용할 수 있다.
StringBuilder 관련 메소드
append()
- 문자열 삽입!
capacity()
- char[] 배열이 가진 사이즈 정보 반환
- length()는 실제 데이터값, 즉 문자열 자체의 길이고 catpacity는 배열 사이즈를 반환한다.
- append()로 문자열을 결합할 때 배열 사이즈는 자동으로 변경된다.( String은 immutable, 수정 불가능, 길이 고정)
delete()
- parameter = 인덱스 시작점, 인덱스 끝점 + 1
StringBuilder sb = new StringBuilder();
sb.append("wanttosleep");
sb.delete(0,3);
System.out.println(sb.toString()); // 0, 1, 2 문자 삭제 후 ttosleep 출력
insert()
- parameter = 특정 위치, 문자열
- 특정 위치에 문자열을 삽입해준다.
얼른 구현을 끝내고 자동화 공부를 하고싶다,,,,😇 할일이 태산 갈길이 멀다
Reference
https://www.codejava.net/java-core/the-java-language/why-use-stringbuffer-and-stringbuilder-in-java
https://docs.oracle.com/javase/8/docs/api/java/lang/String.html
'언어 > JAVA' 카테고리의 다른 글
[JAVA] Effective JAVA. 9장 일반적인 프로그래밍 원칙 1편(item 57, 58, 59, 60) (0) | 2024.03.24 |
---|---|
[JAVA] 날짜/시간 클래스 알아보기(Date, LocalDateTime, ZoneDateTime) (1) | 2024.03.08 |
[JAVA] Effective Java. 6장 열거 타입과 애너테이션 (2) | 2024.01.12 |
[JAVA] 익명 클래스(Anonymous Class), 람다식(Lambda) (1) | 2023.10.22 |