Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 스프링 mvc2 - 타임리프
- 자바의 정석 기초편 ch13
- 자바의 정석 기초편 ch7
- 코드로 시작하는 자바 첫걸음
- jpa - 객체지향 쿼리 언어
- 스프링 고급 - 스프링 aop
- 자바의 정석 기초편 ch2
- @Aspect
- 스프링 db2 - 데이터 접근 기술
- 스프링 mvc1 - 스프링 mvc
- 자바의 정석 기초편 ch12
- 자바의 정석 기초편 ch3
- 자바의 정석 기초편 ch4
- 2024 정보처리기사 수제비 실기
- 자바의 정석 기초편 ch6
- 자바의 정석 기초편 ch1
- 자바의 정석 기초편 ch8
- 스프링 mvc2 - 로그인 처리
- 스프링 입문(무료)
- 2024 정보처리기사 시나공 필기
- 자바의 정석 기초편 ch9
- 자바의 정석 기초편 ch5
- 자바의 정석 기초편 ch14
- jpa 활용2 - api 개발 고급
- 스프링 mvc2 - 검증
- 타임리프 - 기본기능
- 스프링 db1 - 스프링과 문제 해결
- 스프링 mvc1 - 서블릿
- 게시글 목록 api
- 자바의 정석 기초편 ch11
Archives
- Today
- Total
나구리의 개발공부기록
자바의 정석 기초편 ch9 - 12 ~ 20[join()과 StringJoiner, 문자열과 기본형 변환, StringBuffer클래스, StringBuffer클래스의 생성자와 메서드] 본문
유튜브 공부/JAVA의 정석 기초편(유튜브)
자바의 정석 기초편 ch9 - 12 ~ 20[join()과 StringJoiner, 문자열과 기본형 변환, StringBuffer클래스, StringBuffer클래스의 생성자와 메서드]
소소한나구리 2023. 12. 6. 16:391) join()
- String클래스의 static 메서드
- 배열이나 컬렉션에 담겨있는 여러 문자열 사이에 구분자를 넣어서 결합할 수 있음
String animals = "dog,cat,bear";
// 문자열을 arr 배열에 ',' 구분자로 나눠서 저장
String[] arr = animals.split(",");
// str에 arr배열의 문자열을 '-' 구분자로 구분하여 결합
String str = String.join("-", arr);
System.out.println(str);
// 출력 결과
// dog-cat-bear
2) 문자열과 기본형간의 변환
(1) String으로 형변환
- valueOf()메서드나 빈문자열과의 + 연산으로 형변환
int i = 100;
String str1 = i + ""; // 숫자를 문자열로 변환 방법 1 -> 편리, 가독성 좋음
String str2 = String.valueOf(i) // 숫자를 문자열로 변환 방법 2 -> 속도 빠름
(2) 문자열을 기본형으로변환
- Integer.parseInt() : String -> int로 변환
- Long.parseLong() : String -> long으로 변환
- Integer, Long 등의 클래스는 래퍼클래스라고함
- 아래 이미지의 내용을 참고하여 사용
int i = Integer.parseInt("100"); // 문자열을 숫자로 변환 방법 1(오래된 방법 -> 기본형으로 반환)
// 반환타입이 원래는 Integer이지만 int(기본형)으로도 가능함
int i2 = Integer.valueOf("100"); // 문자열을 숫자로 변환 방법 2(새로운 방법 -> 참조형으로 반환)
// valueOf로 반환한 타입은 참조형으로 반환되지만 기본형으로 반환해도 언박싱이 적용 되어 괜찮음
// 언박싱 -> 참조형을 기본형으로 자동 변환하는 기능, 이후에 배움
(3) 문자형의 형변환 정리
- parse타입() 메서드는 기본형으로만 반환되며 원래 존재했던 메서드, 타입별로 메서드이름이 달라서 사용에 번거로움
- 래퍼클래스.valueOf()로 모든 문자열을 기본형으로 반환하는 메서드가 나온 이후로 valueOf를 더 많이 사용하며 참조형으로 반환되며 기본형으로도 반환할 수 있음(언박싱 -> 이후에 배움)
(4) 예제
class Ex9_10 {
public static void main(String[] args) {
int iVal = 100;
String strVal = String.valueOf(iVal); // int를 String으로 변환
double dVal = 200.0;
String strVal2 = dVal + ""; // double을 String으로 변환
// String을 숫자타입으로 변환하여 연산
double sum = Integer.parseInt(strVal)
+ Double.parseDouble(strVal2);
double sum2 = Integer.valueOf(strVal) + Double.valueOf(strVal2);
// 아래의 두가지는 동일하게 출력되지만 join메서드가 + 결합보다 성능이 더 좋음
System.out.println(String.join("",strVal,"+",strVal2,"=")+sum);
System.out.println(strVal+"+"+strVal2+"="+sum2);
}
}
3) StringBuffer클래스
- 문자열을 저장하고 다루기 위한 클래스
- 문자열 조작이 많은 경우에 사용됨
- String처럼 문자형 배열(char[])을 내부적으로 가지고 있음
- String과 달리 내용을 변경할 수 있음(mutable)
- append() - 추가 , delete() - 삭제 , insert() - 삽입 등의 메서드들을 가지고 있음
(1) 예제
- StringBuffer는 값이 변경이되어도 새로운 객체가 아닌 같은 객체의 참조값을 반환함
- 메서드체인방식을 사용하여 메서드를 한줄에 여러개 호출할 수 있음
StringBuffer sb = new StringBuffer("abc"); // 변경 가능한 문자열 abc 생성
sb.append("123"); // 123문자열 추가
StringBuffer sb2 = sb.append("ZZ"); // sb에 ZZ문자열을 추가후 참조값을 sb2에 저장
// 메서드들의 반환 타입이 StringBuffer이므로 값이 변동 되어도 원래 객체의 주소를 반환
System.out.println(sb); // abc123ZZ 출력값 동일
System.out.println(sb2); // abc123ZZ 출력값 동일
// 메서드 체인 방식으로 메서드를 호출할 수 있음
StringBuffer sb = new StringBuffer("abc");
sb.append("123").append("ZZ");
(2) StringBuffer의 동작 방식
- 내부적으로 char[]로 문자열 데이터를 저장하며 이 문자배열이 버퍼 역할을 함
- 배열은 길이 변경 불가능하므로 공간이 부족하면 내부적인 로직으로 새로운 문자타입 배열을 생성하여 할당해야 함
- 만일 StringBuffer 타입에 기존 생성된 배열보다 더 큰값이 들어오면 배열생성(기존길이보다 약 2배의 길이 or 기존 길이 + 새로운 문자열의 길이 중 택1) -> 내용 복사 -> 참조변경(주소값 변경) 순으로 3단계로 진행되어 성능 문제가 발생할 수 있음
- StringBuffer는 저장할 문자열의 길이를 고려해서 적절한 크기로 미리 생성하여 사용하는 것이 성능에 좋을 수 있음
// StringBuffer 객체 생성시 인자값으로 크기를 지정할 수 있음
public StringBuffer(int length) {
value = new char[length];
shared = false;
}
// 버퍼의 크기를 지정하지않고 객체를 생성하면 16으로 생성됨
public StringBuffer() {
this(16);
}
// 문자열로 객체를 생성할 경우 +16 더크게 생성되도록 정의 되어있음
public StringBuffer(String str) {
this(str.length() + 16);
append(str);
}
(3) StringBuffer는 equals()가 오버라이딩 되어있지않음
- 즉 Object클래스의 equals() 처럼 참조값을 비교하므로 실제 값을 비교하고자 할 경우 String으로 형변환 하여 비교하면 됨
- 스트링버퍼의 toString()메서드는 스트링버퍼의 값을 String으로 반환하도록 오버라이딩 되어있음
// Stringbuffer 타입의 sb, sb2 변수
System.out.println(sb.equals(sb2)); // 주소비교 false
String s = sb.toString(); // sb, sb2를 String으로 변환
String s2 = sb2.toString();
System.out.println(s.equals(s2)); // 내용비교 true
4) StringBuffer의 생성자와 메서드
(1) 생성자
- StringBuffer() - 버퍼의 길이가 16인 StringBuffer 인스턴스를 생성
- StringBuffer(int length) - 버퍼의 길이가 인자의 값으로 생성된 StringBuffer 인스턴스를 생성
- StringBuffer(String str) - 버퍼의 길이가 인자의 길이(length)값으로 생성된 StringBuffer 인스턴스를 생성
// 기본생성자 - 길이가 16인 버퍼 생성
StringBuffer sb = new StringBuffer();
// 길이가 10인 버퍼 생성
StringBuffer sb1 = new StringBuffer(10);
// Hi 문자열을 버퍼에 저장, 길이가 2
StringBuffer sb2 = new StringBuffer("Hi");
(2) 메서드
- StringBuffer append(boolean b)
- StringBuffer append(char c)
- StringBuffer append(char[] str)
- StringBuffer append(double d)
- StringBuffer append(float f)
- StringBuffer append(int i)
- StringBuffer append(long l)
- StringBuffer append(Object obj)
- StringBuffer append(String str)
- 인자로 입력된 값을 문자열로 변환하여 StringBuffer 인스턴스가 저장하고 있는 문자열 뒤에 덧붙힘
- 모두 반환타입은 StringBuffer
StringBuffer sb = new StringBuffer("abc");
StringBuffer sb2 = sb.append(true);
sb.append('d').append(10.0f);
StringBuffer sb3 = sb.append("ABC").append(123);
// 결과
// sb = "abctrued10.0ABC123"
// sb2 = "abctrued10.0ABC123"
// sb3 = "abctrued10.0ABC123"
- int capacity() - StringBuffer 인스턴스의 버퍼 길이를 반환
- int length() - StringBuffer 인스턴스에 담긴 문자열의 길이를 반환
StringBuffer sb = new StringBuffer(100);
sb.append("abcd")
int bufferSize = sb.capacity(); // 버퍼의 길이
int stringSize = sb.length(); // 버퍼에 담긴 문자열의 길이
// 결과
// bufferSize = 100
// stringSize = 4 //(담긴 문자열 "abcd"의 길이)
- char charAt(int index) - 입력된 인자값의 인덱스번호 값을 문자타입으로 반환
StringBuffer sb = new StringBuffer("abc");
char c = sb.charAt(2);
char b = sb.charAt(1);
// 결과
// c = 'c'
// b = 'b'
- StringBuffer delete(int start, int end)
- 문자를 n개 제거(인덱스 start의 위치부터 인덱스 end - 1위치까지)
- 첫번째 인자값의 위치부터 두번째 인자값이 사이에있는 문자를 제거(두번째 인자값의 위치에있는 값은 제거대상이 아님)
- StringBuffer deleteCharAt(int index)
- 문자를 1개 제거
- 인자값으로 들어온 위치의 문자를 제거(인덱스 번호의 위치)
StringBuffer sb = new StringBuffer("0123456")
StringBuffer sb2 = sb.delete(3,6)
StringBuffer ib = new StringBuffer("0123456")
ib.deleteCharAt(3);
// 결과
// sb = "0126"
// sb2 = "0126"
// ib = "012456"
- StringBuffer insert(int pos, boolean b)
- StringBuffer insert(int pos, char c)
- StringBuffer insert(int pos, char[] str)
- StringBuffer insert(int pos, double d)
- StringBuffer insert(int pos, float f)
- StringBuffer insert(int pos, int i)
- StringBuffer insert(int pos, long l)
- StringBuffer insert(int pos, Object obj)
- StringBuffer insert(int pos, String str)
- 두 번째 매개변수로 받은 값을 문자열로 변환하여 첫번째 인자값의 위치(인덱스 번호)에 추가
StringBuffer sb = new StringBuffer("0123456");
sb.insert(4,'.'); // 인덱스 4번에 .을 추가
// 결과
// sb = "0123.456"
- StringBuffer replace(int start, int end, String str)
- 치환 메서드(인덱스 start ~ 인덱스 end -1 까지의 값을 str문자열로 변경)
- 첫번째 인자값의 위치부터 두번째 인자값이 사이에있는 문자를, 세번째 인자값의 문자열로 치환
- 두번째 인자값의 인덱스 번호는 치환 대상이 아니지만 문자열의 길이(인덱스의 마지막 번호)와 동일하면 대상으로 적용됨
** 참고
- 메서드의 두번째 인자값이 적용 대상에서 빠지지만, 해당 값이 전체의 길이의 값(즉, 마지막 인덱스의 값)과 일치하면 적용 대상에 포함되도록 메서드가 설계된 것은 Java에서 일반적으로 적용되는 방식임
- 문서의 설명에 적혀있지 않아도 이러한 기능을 가진 Java의 새로운 메서드나, 기존의 새로운 메서드도 위의 방식이 적용된다고 보면 됨
StringBuffer sb = new StringBuffer("0123456")
sb.replace(3, 6, "AB") // 버퍼문자열의 인덱스 3번째부터 5번째까지의 문자를 "AB"로 치환
// 결과
// sb = "012AB6" // 345가 "AB"로 변경
- StringBuffer reverse()
- StringBuffer의 값을 거꾸로 뒤집음(문자열 뒤집기)
- 맨 첫번째 문자부터 순차적으로 변경됨
StringBuffer sb = new StringBuffer("0123456")
sb.reverse()
// 결과
// sb = "6543210"
- void setCharAt(int index, char ch) - 첫번째 인자값의 인덱스 번호 문자를 두번째 인자값(문자타입)으로 변경
StringBuffer sb = new StringBuffer("0123456")
sb.setCharAt(5, 'o') // 버퍼문자열의 인덱스 5번째부터 문자를 문자'o'으로 변경
// 결과
sb = "01234o6"
- void setLength(int newLength)
- 인자값으로 버퍼의 길이를 다시 설정
- 길이가 늘어난 경우 빈 공간을 '\u0000' (기본값 - null)로 초기화하고 길이가 줄어들면 값손실이 발생함
StringBuffer sb = new StringBuffer("0123456")
sb.setLength(5) // 버퍼문자열 sb의 길이를 5로 변경
StringBuffer sb2 = new StringBuffer("0123456")
sb2.setLength(10) // 버퍼문자열 sb2의 길이를 10으로 변경
// 양끝의 공백을 .trim()으로 제거 후 toString()으로 문자열 호출
String str = sb2.toString().trim()
// 결과
// sb = "01234" // 버퍼의 길이가 5로 줄어들어 값손실이 발생
// sb2 = "0123456 " // 버퍼의 길이가 10으로 재설정 되어 빈 공간은 null로 설정됨
// str = "0123456"
- String toString()
- StringBuffer의 값을 새로운 String 참조변수에 반환
- 위의 equals() 설명을 참고
- String substring(int start)
- String substring(int start, int end)
- String클래스의 substring과 로직이 동일하며 반환타입이 String임
StringBuffer sb = new StringBuffer("0123456")
// sb의 인덱스번호 3부터 끝까지를 String으로 반환
String str = sb.substring(3);
// sb의 인덱스번호 3부터 5-1(4)까지의 값을 String으로 반환
String str2 = sb.substring(3,5);
// 결과
// str = "3456"
// str2 = "34"
(3) 예제
class Ex9_12 {
public static void main(String[] args) {
// 참조변수 sb가 가리키는 StringBuffer객체에 문자열 01을 저장
StringBuffer sb = new StringBuffer("01");
// sb의값 맨끝에 23을 붙이고 sb2에 참조값을 저장, sb와 sb2는 같은 참조값을 가리킴
StringBuffer sb2 = sb.append(23);
// 메서드체이닝으로 append()를 호출, sb의값 맨끝에 456을 덧붙임
sb.append('4').append(56);
// sb의값 맨끝에 78을 붙이고 sb3에 참조값을 저장, sb, sb2, sb3는 같은 참조값을 가리킴
StringBuffer sb3 = sb.append(78);
// sb3의 값 맨끝에 9.0을 덧붙임
sb3.append(9.0);
// 출력, 모두 같은 참조값을 가리키므로 같은값이 출력됨
System.out.println("sb ="+sb);
System.out.println("sb2="+sb2);
System.out.println("sb3="+sb3);
// 10번 index에 있는 문자 삭제
System.out.println("sb ="+sb.deleteCharAt(10));
// 3번 ~ 5번 index에 있는 문자 삭제(6미포함)
System.out.println("sb ="+sb.delete(3,6));
// 3번 인덱스에 있는 문자를 "abc"문자열로 대체하여 삽입
System.out.println("sb ="+sb.insert(3,"abc"));
// 6번 인덱스부터 마지막인덱스까지의 문자를 "END" 문자열로 치환
// 2번째 인자값이 문자열의 마지막 인덱스번호와 일치하면 해당 인덱스도 포함되서 적용됨
System.out.println("sb ="+sb.replace(6, sb.length(), "END"));
// StringBuffer의 길이 출력
System.out.println("capacity="+sb.capacity());
// 저장된 문자열의 길이 출력
System.out.println("length="+sb.length());
}
}
/*
실행
sb =0123456789.0
sb2=0123456789.0
sb3=0123456789.0
sb =01234567890
sb =01267890
sb =012abc67890
sb =012abcEND
capacity=18 // 최초생성 16 + 문자열 2
length=9
*/
** 출처 : 남궁성의 정석코딩_자바의정석_기초편 유튜브 강의