JAVA


형변환(Casting)

변환(Conversion)

변환(Conversion)

List <-> Array 간 형변환


1. List → Array 형변환

List 타입

변환 방법

List<String>

list.toArray(new String[0])

List<Integer>

list.toArray(new Integer[0])

List<Integer>int[]

반복문으로 수동 변환 필요


1) List → Array (참조형, 예: Integer, String 등)
List<String> list = Arrays.asList("a", "b", "c");
String[] arr = list.toArray(new String[0]);
List<Integer> list = Arrays.asList(1, 2, 3);
Integer[] arr = list.toArray(new Integer[0]);


2) List → Array (기본형, 예: int)
List<Integer> list = Arrays.asList(1, 2, 3);
int[] arr = new int[list.size()];

for (int i = 0; i < list.size(); i++) {
    arr[i] = list.get(i);  // 언박싱 자동 수행
}




2. Array → List 형변환


변환 방법

String[]

Arrays.asList(arr)

Integer[]

Arrays.asList(arr)

int[]

Arrays.stream(arr).boxed.collect(Collectors.toList())


1) 참조형 배열 → List (예: String[], Integer[] 등)
String[] arr = {"a", "b", "c"};
List<String> list = Arrays.asList(arr);
List<String> modifiableList = new ArrayList<>(Arrays.asList(arr));


2) 기본형 배열 → List (예: int[], double[] 등)
int[] arr = {1, 2, 3, 4};

List<Integer> list = Arrays.stream(arr)  // IntStream 생성
                           .boxed()      // int → Integer (박싱)
                           .collect(Collectors.toList());



변환(Conversion)

int -> String, char 변환


1. int → String 변환

​아래와 같은 세 가지 방법이 있다.

✅ 방법 1. String.valueOf(int)

가장 범용적으로 쓰이고, null 처리가 가능하다.

int num = 3;
String str = String.valueOf(num);
System.out.println(str);  // 출력: "3"


✅ 방법 2. Integer.toString(int)

오직 int → String 변환에만 사용된다.

int num = 3;
String str = Integer.toString(num);
System.out.println(str);  // 출력: "3"


✅ 방법 3. 문자열 더하기 (+ 연산자)

가장 짧고 직관적이지만 권장 방식은 아니다.

int num = 3;
String str = num + "";  // 문자열과 더하면 문자열로 변환됨
System.out.println(str);  // 출력: "3"


2. int → char 변환

✅ 방법 1. '0'을 더한다.
int num = 3;
char ch = (char) (num + '0');  // '0'의 아스키 값은 48
System.out.println(ch);  // 출력: '3'

📌 왜 이렇게 될까?


✅ 방법 2. Character.forDigit()
int num = 3;
char ch = Character.forDigit(num, 10);
System.out.println(ch);  // 출력: '3'

🔎 Character.forDigit(value, radix)는 정수 값을 해당 진법(radix)의 문자로 바꿔​준다.


❌ int → char 변환시 주의사항

아래과 같이 단순 캐스팅은 잘못된 것이다.

int num = 3;
char ch = (char) num;  // ❌ 결과: 이상한 제어문자 (아스키 3 → ETX)




변환(Conversion)

String, char > int 변환


1. int → String 변환

자바에서 문자열(String) '123'을 정수(int) 로 바꾸는 방법이다.

✅ 방법 1. Integer.parseInt()

가장 많이 쓰이는 방법이다.

String str = "123";
int num = Integer.parseInt(str);
System.out.println(num);  // 출력: 123


✅ 방법 2. Integer.valueOf()

Integer.valueOf()는 Integer 객체를 반환하지만, 필요하면 int로 자동 변환된다.

String str = "123";
int num = Integer.valueOf(str); // 반환 타입은 Integer (객체)

int primitive = Integer.valueOf(str); // 자동 언박싱됨


✅ 방법 3. 예외 처리 (안전하게 변환하기)

사용자가 입력한 문자열이 숫자가 아닐 수도 있으니 예외 처리를 하는 것이 권장된다.

String str = "123";
try {
    int num = Integer.parseInt(str);
    System.out.println(num);
} catch (NumberFormatException e) {
    System.out.println("유효한 숫자가 아닙니다.");
}

❌ 이런 건 에러가 난다.

String str = "12a3";
int num = Integer.parseInt(str);  // ❌ NumberFormatException


2. char → int 변환

자바에서 '3'과 같은 문자(char) 를 정수(int) 로 바꾸는 방법이다.

✅ 방법 1. '0'을 빼기 (가장 일반적이고 직관적)
char ch = '3';
int num = ch - '0';  // 결과: 3

📌 왜 이렇게 될까?


✅ 방법 2. Character.getNumericValue()
char ch = '3';
int num = Character.getNumericValue(ch);  // 결과: 3

이 방식은 'A' → 10, 'B' → 11 같은 16진 문자도 지원한다.

단, '0'~'9'만 처리할 거라면 첫 번째 방법이 더 간단하고 빠르다.


✅ 방법 3. String으로 바꿔서 Integer.parseInt()

문자열로 바꿔서 정수화하는 방법인데 이건 다소 무거운 방법이고 잘 쓰지 않는다.

char ch = '3';
int num = Integer.parseInt(String.valueOf(ch));  // 결과: 3




연산자

연산자

삼항 연산자 (Ternary Operator)


1. 개요

1.1 삼항 연산자란?

삼항 연산자(Ternary Operator)는 조건에 따라 값을 선택하는 Java의 축약 표현식이다. 일반적인 if-else 구문보다 간결하게 작성할 수 있으며, 값을 반환하는 표현식으로 활용된다.

int max = (a > b) ? a : b;

1.2 사용 목적


2. 문법

조건식 ? 참일 때의 값 : 거짓일 때의 값;

2.1 예시

int age = 20;
String type = (age >= 18) ? "성인" : "미성년자";  // 출력: 성인

3. 삼항 연산자 vs if-else

3.1 차이점

항목

삼항 연산자

if-else 구문

반환 가능 여부

✅ 값 반환 (표현식)

❌ 문(statement)

간결함

✅ 매우 간결

❌ 구조적으로 길어질 수 있음

가독성

✅ 단순 조건일 때만

✅ 복잡 조건/로직에 적합

3.2 비교 예시

// 삼항 연산자
int max = (a > b) ? a : b;

// 동일한 if-else
int max;
if (a > b) {
    max = a;
} else {
    max = b;
}

4. 중첩 삼항 연산자

4.1 기본 중첩 예제

int score = 85;
String grade = (score >= 90) ? "A" :
               (score >= 80) ? "B" :
               (score >= 70) ? "C" : "F";
System.out.println(grade);  // 출력: B

4.2 주의사항


5. 실전 예제 모음

5.1 나이 판별

int age = 16;
String result = (age >= 18) ? "성인" : "미성년자";
System.out.println(result);  // 출력: 미성년자

5.2 최대값 구하기

int a = 25, b = 17;
int max = (a > b) ? a : b;
System.out.println("최대값: " + max);  // 출력: 25

5.3 짝수/홀수 판별

int num = 9;
String parity = (num % 2 == 0) ? "짝수" : "홀수";
System.out.println(parity);  // 출력: 홀수

5.4 로그인 상태 메시지

boolean isLoggedIn = false;
String message = isLoggedIn ? "환영합니다!" : "로그인이 필요합니다.";
System.out.println(message);  // 출력: 로그인이 필요합니다.

5.5 다중 조건 - 세금율 계산 예시

double income = 45000;
double taxRate = (income > 80000) ? 0.35 :
                  (income > 40000) ? 0.25 : 0.15;
System.out.println("세율: " + taxRate);
// 출력: 세율: 0.25

✅ 요약

특징

설명

장점

간결한 조건 처리, 변수 할당 가능

단점

복잡한 로직에는 가독성 저하

사용 추천

UI 메시지, 단순 조건 분기, 코드 압축

사용 주의

중첩 사용은 피하고 if-else 대체로 제한

삼항 연산자는 작고 간단한 판단 로직에 매우 유용하지만, 가독성을 해치는 복잡한 분기에는 적합하지 않다는 점을 기억하자.


String(문자열)


String(문자열)

Java: String이란?


1. 개요

String은 Java에서 문자들의 연속(문자열) 을 표현하는 대표적인 클래스이며, java.lang 패키지에 포함되어 있어 별도의 import 없이 바로 사용할 수 있다.


2. 주요 특징

2.1 문자열은 객체다

String str = "hello";  // str은 String 클래스의 인스턴스

2.2 불변성 (Immutable)

String a = "hi";
a += "!";
System.out.println(a);  // hi!

"hi"는 그대로 있고 "hi!"는 새 객체로 Heap에 생성됨.

2.3 문자열 리터럴은 상수 풀(String Constant Pool)에 저장

String s1 = "java";
String s2 = "java";
System.out.println(s1 == s2);  // true → 같은 주소 참조

→ 동일한 리터럴은 JVM 내의 String Constant Pool에서 공유됨


3. 문자열 생성 방법

3.1 리터럴 방식 (권장)

String s = "Hello";

3.2 생성자 방식 (비권장)

String s2 = new String("Hello");

📌 사용 예시

String a = "abc";
String b = new String("abc");

System.out.println(a == b);       // false (주소 비교)
System.out.println(a.equals(b));  // true  (내용 비교)

4. 문자열 비교

4.1 == vs .equals()

String a = "test";
String b = "test";
String c = new String("test");

System.out.println(a == b);         // true (상수 풀에서 공유)
System.out.println(a == c);         // false (Heap에 새 객체 생성)
System.out.println(a.equals(c));    // true (내용 비교)

비교 방식

설명

==

객체의 주소값 비교 (레퍼런스)

.equals()

객체가 가진 내용값 비교


5. 문자열 길이와 메서드

String s = "hello world";
System.out.println(s.length());         // 11
System.out.println(s.charAt(0));        // h
System.out.println(s.substring(0, 5));  // hello
System.out.println(s.toUpperCase());    // HELLO WORLD
System.out.println(s.replace(" ", "_")); // hello_world

6. 기타 특징 및 내부 구조

6.1 String 내부 구조

public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
    private final char value[];
    private final int offset;
    private final int count;
    ...
}

6.2 문자열 연결 (Concatenation)

String a = "Hello";
String b = "World";
String c = a + " " + b;  // Hello World
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
System.out.println(sb.toString());  // Hello World

7. 정리

항목

String

불변성

✅ 한 번 생성된 값은 변경 불가

생성 방식

리터럴(권장), 생성자(비권장)

비교 방식

== 주소 비교 / .equals() 값 비교

내부 구조

Java 9 이전: char[]

연결 방식

+, concat(), StringBuilder 사용

사용 시기

고정된 문자열, 메시지, 상수 등



String(문자열)

Java: String의 주요 메서드


1. String의 인스턴스 메서드

1.1 개요

String 클래스의 인스턴스 메서드는 문자열 객체를 통해 호출하는 메서드입니다. 즉, "hello".length()처럼 문자열 인스턴스를 기준으로 작동합니다.


1.2 주요 인스턴스 메서드 + 메모리 작동

Java의 String 클래스는 다양한 문자열 조작 기능을 제공하는 인스턴스 메서드를 포함하고 있다. 아래는 자주 사용되는 메서드들의 설명과 예시이다. 모든 String 인스턴스 메서드는 원본 문자열을 절대 수정하지 않으며, 필요한 경우 항상 새로운 문자열 객체를 Heap에 생성한다. (*불변성(immutability)*)

















1.3 특징


2. String의 클래스 메서드

2.1 개요

String 클래스의 클래스 메서드는 static 메서드이며, 객체 생성 없이 String.으로 호출할 수 있다.

주로 타입 변환이나 문자열 생성에 사용된다.


2.2 주요 클래스 메서드 목록

Java의 String 클래스는 객체 없이도 호출 가능한 클래스 메서드(static method)들을 제공한다. 자주 쓰이는 타입 변환, 문자열 생성, 서식 처리 작업을 편리하게 처리하기 위해 고안되었다.







2.3 특징





String(문자열)

Java: String의 불변성 (Immutability)


1. 개요

Java의 String 클래스는 불변 객체(Immutable Object) 로 설계되어 있다.


2. 왜 불변(Immutable)한가?

불변성은 단순히 설계 철학이 아니라, 실제 Java 플랫폼의 안정성과 효율성을 위한 필수적인 요소이다.

2.1 보안(Security)

String dbUrl = "jdbc:mysql://localhost";
dbUrl.replace("localhost", "hacker-site.com");  // String은 수정되지 않음

2.2 성능(Performance)

String a = "hello";
String b = "hello";
System.out.println(a == b);  // true → 동일 객체 공유

2.3 스레드 안전성(Thread Safety)


3. 작동 방식 – 변경은 실제로 “새 객체 생성”

3.1 코드 예시

String a = "hello";
String b = a;

a = a + " world";

System.out.println(a);  // hello world
System.out.println(b);  // hello

3.2 메모리 구조 흐름

[초기 상태]
a ───▶ "hello"
b ───┘

[수정 후]
a ───▶ "hello world"
b ───▶ "hello"

📌 변경이 아닌 “대체”다. 기존 객체는 절대 바뀌지 않음!


4. 불변 객체의 특징 요약

항목

설명

변경 가능 여부

❌ 불가능 – 항상 새로운 객체 생성됨

스레드 안전성

✅ 동기화 없이 공유 가능

공유 가능 여부

✅ 문자열 리터럴 풀에서 객체 공유 가능

메모리 구조

Heap 영역 + String Constant Pool 최적화

관련 API 특징

replace()

,

concat()

등 모두 새 객체 반환


5. 관련 클래스 구분

5.1 불변 객체 (Immutable)

5.2 가변 객체 (Mutable)

📝 불변 클래스는 equals(), hashCode() 재정의에 유리하며, 객체 캐싱 및 보안 측면에서도 장점을 가짐.


6. 성능상의 주의점

6.1 반복 연결 시 성능 저하

String s = "";
for (int i = 0; i < 1000; i++) {
    s += "a";  // 매 반복마다 새 객체 생성
}

→ 이 방식은 1000개의 String 객체를 생성
→ 해결 방법: StringBuilder 사용

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append("a");
}
String result = sb.toString();

7. 결론



String(문자열)

Java: StringBuilder 클래스


1. 개요

StringBuilder는 Java에서 가변(mutable) 문자열을 처리하기 위한 클래스이다.

StringBuilder sb = new StringBuilder("Hello");
sb.append(" World");
System.out.println(sb);  // 출력: Hello World

2. 주요 특징

항목

설명

가변성

✅ 내부 문자열을 직접 수정 (객체 생성 없음)

동기화

❌ 지원하지 않음 (→ 단일 스레드에서만 안전)

성능

StringBuffer보다 빠름

내부 구조

char[] 배열을 이용한 버퍼

기본 크기

초기 용량 16 → 필요 시 자동 확장됨


3. 생성자 종류

StringBuilder sb1 = new StringBuilder();               // 초기 버퍼 크기 16
StringBuilder sb2 = new StringBuilder(50);             // 초기 버퍼 크기 지정
StringBuilder sb3 = new StringBuilder("Hello");        // 초기 문자열 지정

4. 주요 메서드 정리

메서드

설명

append(String)

문자열 끝에 추가

insert(int, String)

특정 위치에 문자열 삽입

delete(int, int)

지정 구간 문자 삭제

deleteCharAt(int)

지정 인덱스 문자 삭제

replace(int, int, String)

지정 구간을 문자열로 대체

reverse()

문자열을 뒤집음

toString()

최종 문자열로 변환 (String으로 반환)

length()

현재 문자열 길이 반환

capacity()

내부 버퍼의 총 용량 반환

ensureCapacity(int)

최소 버퍼 크기 확보

setCharAt(int, char)

특정 위치 문자 변경

charAt(int)

특정 인덱스 문자 반환


5. 사용 예제

public class StringBuilderExample {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("Hello");

        sb.append(" World");                     // Hello World
        sb.insert(5, ",");                       // Hello, World
        sb.replace(0, 5, "Hi");                  // Hi, World
        sb.delete(3, 4);                         // Hi World
        sb.reverse();                            // dlroW iH

        System.out.println(sb.toString());       // 출력: dlroW iH
    }
}

6. 성능 비교: String vs StringBuilder

// 느린 방식: String
String str = "";
for (int i = 0; i < 10000; i++) {
    str += "a";  // 매 반복마다 새 객체 생성
}

// 빠른 방식: StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
    sb.append("a");  // 동일 객체 안에서 처리
}

StringBuilder는 수천 배 빠를 수 있으며 GC 부담도 낮다.


7. 주의 사항


8. 요약

항목

StringBuilder

불변성

❌ 가변

스레드 안전성

❌ 비동기 (단일 스레드만 안전)

성능

✅ 매우 빠름

용도

반복적인 문자열 연결/수정에 최적

권장 사용 환경

루프 내 문자열 처리, 대용량 로그 조립 등




String(문자열)

Java: StringBuilder의 주요 메서드


1. StringBuilder의 인스턴스 메서드

1.1 개요

StringBuilder 클래스는 가변 문자열 처리를 위해 설계된 클래스이다. 모든 메서드는 StringBuilder 객체 자체를 수정하며, 새로운 객체를 생성하지 않는다. 이는 String과의 가장 큰 차이점이다.

StringBuilder sb = new StringBuilder("hello");
sb.append(" world");  // 같은 객체 내에서 문자열을 수정

1.2 주요 메서드 + 내부 동작

모든 메서드는 시간복잡도가 평균적으로 O(1) 또는 **O(n)**이며, 대부분 String보다 빠름.
대부분 메서드가 return this를 통해 메서드 체이닝을 지원한다.


🔹 append(String str)


🔹 insert(int offset, String str)


🔹 delete(int start, int end)


🔹 deleteCharAt(int index)


🔹 replace(int start, int end, String str)


🔹 reverse()


🔹 toString()


🔹 setCharAt(int index, char c)


🔹 charAt(int index)


🔹 length()


🔹 capacity()


🔹 ensureCapacity(int minimumCapacity)


2. 메서드 체이닝 예시

StringBuilder sb = new StringBuilder();
String result = sb.append("Hi")
                  .append(" ")
                  .append("there")
                  .replace(0, 2, "Bye")
                  .reverse()
                  .toString();

System.out.println(result);  // "ereht eyB"

3. 주의 사항

주의 포인트

설명

null

값 전달

append(null)

은 문자열

"null"

로 처리됨

✅ 내부 수정

객체 내부 수정 → 참조가 유지됨

❌ 멀티스레드 비안전

멀티스레드 환경에서는

StringBuffer

사용


✅ 마무리 요약

메서드

설명

append()

문자열 끝에 추가

insert()

중간에 삽입

delete()

구간 삭제

replace()

문자열 교체

reverse()

문자열 뒤집기

charAt()

문자 추출

setCharAt()

문자 수정

toString()

최종 문자열 반환

capacity()

내부 버퍼 용량 확인

ensureCapacity()

버퍼 미리 확장





String(문자열)

Java: StringBuffer 클래스


1. 왜 필요한가? (등장 배경 및 필요성)

1.1 StringBuffer

📌 문제 상황

✅ 등장 이유

→ 그래서 등장한 것이 StringBuffer (JDK 1.0부터 존재)

(후속으로 성능 개선 목적의 StringBuilder는 JDK 1.5에 등장)


1.2 StringTokenizer

📌 문제 상황

✅ 등장 이유

→ 그래서 등장한 것이 StringTokenizer (JDK 1.0)

→ 이후 등장한 split()에 비해 속도는 빠르지만 정규표현식은 불가


1.3 split() (String 클래스의 메서드)

📌 문제 상황

✅ 등장 이유

→ 그래서 등장한 것이 split() 메서드 (JDK 1.4부터 안정화)


2. StringBuffer – 선언 방법 및 주요 사용법

2.1 선언 방법

StringBuffer sb1 = new StringBuffer();              // 빈 버퍼 (기본 용량 16)
StringBuffer sb2 = new StringBuffer(50);            // 초기 버퍼 크기 지정
StringBuffer sb3 = new StringBuffer("Hello");       // 초기 문자열 지정

2.2 주요 메서드 예제

StringBuffer sb = new StringBuffer("Java");

sb.append(" is awesome");   // "Java is awesome"
sb.insert(4, " 8");         // "Java 8 is awesome"
sb.delete(0, 5);            // "8 is awesome"
sb.reverse();               // "emosewa si 8"

System.out.println(sb.toString());

3. StringTokenizer – 선언 방법 및 사용법

3.1 선언 방법

StringTokenizer st = new StringTokenizer("a,b,c", ",");

3.2 반복 사용법

while (st.hasMoreTokens()) {
    System.out.println(st.nextToken());
}

출력

a
b
c

3.3 기타 특징

특징

설명

기본 구분자

공백 (

" \t\n\r\f"

)

성능

split()

보다 빠름

정규식 지원 여부

❌ 불가능


4. split() – 선언 방법 및 사용법

4.1 기본 사용법

String str = "one,two,three";
String[] result = str.split(",");

4.2 정규표현식 사용 예

String s = "apple  banana   melon";
String[] arr = s.split("\\s+");  // 공백 하나 이상 기준

출력

apple
banana
melon

4.3 특수 문자 분리 (예: |, . 등)

String s = "a|b|c";
String[] arr = s.split("\\|");  // |는 정규식 특수문자라 \\로 이스케이프 필요

5. 코딩 테스트 실전 예제

5.1 공백 구분 숫자 입력

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] input = br.readLine().split(" ");
int a = Integer.parseInt(input[0]);
int b = Integer.parseInt(input[1]);
System.out.println(a + b);

5.2 빠른 입력 + 반복 분리 (StringTokenizer)

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int sum = 0;
while (st.hasMoreTokens()) {
    sum += Integer.parseInt(st.nextToken());
}
System.out.println(sum);

6. 요약 비교

항목

StringBuffer

StringTokenizer

split()

용도

가변 문자열 조작

문자열 구분자 분할

정규식 기반 문자열 분할

동기화

✅ 있음

❌ 필요 없음

❌ 필요 없음

성능

중간

빠름

약간 느림

정규표현식

✅ 지원

등장 시기

오래됨 (JDK 1.0)

오래됨 (JDK 1.0)

나중에 도입됨 (JDK 1.4 이후)

사용 추천 환경

멀티스레드 조작

빠른 단순 입력 분할

복잡한 기준 분할 or 가독성 우선


7. 결론





String(문자열)

Java: StringBuffer 주요 메서드 정리


1. StringBuffer란?


2. 주요 메서드 + 내부 동작

아래 메서드들은 StringBuilder와 메서드명이 동일하며, 내부적으로 synchronized 블록을 포함한다는 점만 다름.


🔹 append(String str)


🔹 insert(int offset, String str)


🔹 delete(int start, int end)


🔹 deleteCharAt(int index)


🔹 replace(int start, int end, String str)


🔹 reverse()


🔹 toString()


🔹 setCharAt(int index, char c)


🔹 charAt(int index)


🔹 length()


🔹 capacity()


🔹 ensureCapacity(int minimumCapacity)


3. 체이닝 예시

StringBuffer sb = new StringBuffer("Hi");
String result = sb.append(" there")
                  .replace(0, 2, "Bye")
                  .reverse()
                  .toString();
System.out.println(result);  // "ereht eyB"

4. 주의사항

항목

설명

스레드 안전성

synchronized로 멀티스레드 환경에서 안전

성능

StringBuilder보다 약간 느림

내부 수정

✅ 같은 객체 내에서 수정

메서드 반환값

대부분 this → 체이닝 가능


✅ 요약 테이블

메서드

설명

시간복잡도

리턴값

append(String)

문자열 끝에 추가

O(1~n)

StringBuffer

insert(int, str)

중간에 삽입

O(n)

StringBuffer

delete(start, end)

구간 삭제

O(n)

StringBuffer

deleteCharAt(idx)

문자 하나 삭제

O(n)

StringBuffer

replace(s, e, str)

구간 대체

O(n)

StringBuffer

reverse()

문자열 뒤집기

O(n)

StringBuffer

charAt(int)

문자 조회

O(1)

char

setCharAt(i, c)

문자 수정

O(1)

void

length()

문자열 길이

O(1)

int

capacity()

버퍼 크기 조회

O(1)

int

ensureCapacity(n)

최소 용량 확보

O(n)

void

toString()

문자열 객체 반환

O(n)

String



String(문자열)

Java 코딩 테스트: StringBuilder 활용 사례 모음


1. 왜 StringBuilder를 쓸까?

코딩 테스트에서 문자열을 다룰 때는 String보다 StringBuilderStringBuffer를 활용하는 것이 성능 면에서 매우 유리하다.

1.1 String은 불변 (immutable)

1.2 StringBuilder는 가변 (mutable)

📌 참고: StringBuildersynchronized아닌 대신 더 빠르다. 멀티스레드가 아니면 StringBuffer보다 성능상 유리하다.


2. 자주 나오는 활용 패턴

2.1 문자열 뒤집기 (문제 유형: 팰린드롬 판단, 좌우 비교)

String str = "hello";
String reversed = new StringBuilder(str).reverse().toString();
System.out.println(reversed);  // 출력: "olleh"

2.2 대량 문자열 이어붙이기 (문제 유형: 문자열 압축, 변환 등)

StringBuilder sb = new StringBuilder();
for (char c : arr) {
    sb.append(Character.toUpperCase(c)).append(", ");
}
String result = sb.toString();

2.3 조건에 따라 문자열 조립 (문제 유형: 포맷팅, 규칙 변환)

StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 5; i++) {
    sb.append("[").append(i).append("]");
    if (i < 5) sb.append("-");
}
System.out.println(sb.toString());  // 출력: [1]-[2]-[3]-[4]-[5]

2.4 문자열 일부 제거 (문제 유형: 특정 문자 제거, 구간 삭제)

StringBuilder sb = new StringBuilder("abcdef");
sb.delete(2, 4);  // 인덱스 2~3 삭제 → "abef"
System.out.println(sb);

3. 코딩 테스트 팁

상황

추천 도구

이유

문자열을 자주 수정/누적할 때

StringBuilder

가변 객체, 빠른 속도

문자열을 뒤집을 때

StringBuilder.reverse()

메서드 하나로 간단 처리

멀티스레드 고려 필요 없음

StringBuilder

동기화 없음 → 더 빠름

🧠 참고: 코테에서 StringBuilder를 쓰는 것이 대부분 OK, StringBuffer는 멀티스레드 환경에서만 고려


✅ 마무리 요약

코테에서 성능이 중요한 대형 문자열 문제에서는 StringBuilder는 최고의 무기




String(문자열)

Java: String.split() 정규식 예제 모음

✅ 기본 문법

String[] result = 문자열.split("정규표현식");

split()은 인자로 정규표현식(String regex) 을 받기 때문에, 메타 문자(예: . | *)는 반드시 이스케이프 해야 한다.


1. 공백 기준 분할

1.1 공백 하나

String s = "hello world";
String[] arr = s.split(" ");

1.2 공백 여러 개 (1개 이상)

String s = "hello   world  java";
String[] arr = s.split("\\s+");  // \\s = 공백 문자, +는 1개 이상

1.3 탭 또는 공백

String s = "a\tb c";
String[] arr = s.split("[ \t]+");

2. 콤마(,) 기준 분할

String s = "apple,banana,grape";
String[] arr = s.split(",");

2.1 콤마 + 공백 제거 (CSV 정리)

String s = "apple, banana,  grape";
String[] arr = s.split(",\\s*");  // , 뒤 공백 무시

3. 특수 문자 기준 분할

정규표현식에서 특수 문자는 반드시 이스케이프(\) 필요!

문자

정규표현식에서 의미

split에 쓰는 방식

.

모든 문자

"\\."

`

`

OR (또는)

*

반복자

"\\*"

(

)

[

]

그룹 지정

"\\(", "\\["

3.1 마침표(.) 기준

String s = "www.example.com";
String[] arr = s.split("\\.");

3.2 파이프(|) 기준

String s = "red|green|blue";
String[] arr = s.split("\\|");

4. 숫자/문자 기준 분할

4.1 숫자만 기준으로 나누기

String s = "abc123def456ghi";
String[] arr = s.split("\\d+");  // 숫자(1개 이상) 기준 나눔

4.2 문자 기준 나누기

String s = "123abc456def";
String[] arr = s.split("[a-zA-Z]+");  // 알파벳 기준 나눔

5. 복수 구분자 분리

5.1 콤마(,) 또는 세미콜론(;) 또는 공백

String s = "apple,banana;grape orange";
String[] arr = s.split("[,; ]");

5.2 AND/OR 조건 키워드 분리

String s = "red and blue or green";
String[] arr = s.split("\\s+(and|or)\\s+");  // 공백 포함한 and/or 기준

6. 문장 끝 단위 분리 (구두점)

String s = "Hi. I am John! Nice to meet you?";
String[] arr = s.split("[.!?]\\s*");  // . ! ? 뒤 공백까지 포함

7. 빈 문자열 처리

String s = "a,,b,c";
String[] arr = s.split(",", -1);  // -1 옵션으로 빈 항목도 유지
System.out.println(Arrays.toString(arr));
// 출력: [a, , b, c]

🧾 보너스: 정규표현식 요약표

패턴

의미

예시

\\s

공백 문자 (스페이스, 탭 등)

"\\s+"

→ 연속된 공백

\\d

숫자 (0~9)

"\\d+"

→ 숫자 1개 이상

\\w

문자/숫자/밑줄

"\\w+"

.

아무 문자 한 개

"a.b"

→ "acb", "a1b" 가능

[abc]

a 또는 b 또는 c

"a[bc]d"

→ "abd", "acd"

[^abc]

a,b,c 제외한 문자

"[^0-9]"

→ 숫자 제외

+

앞의 패턴 1번 이상 반복

"\\s+"

*

0번 이상 반복

"a*"

`

`

OR


✅ 결론




String(문자열)

Java: String vs StringBuilder 비교


1. 개요

자바에서 문자열을 다룰 수 있는 대표 클래스는 StringStringBuilder이다. 두 클래스 모두 문자열을 표현하는 데 사용되지만, **불변성(immutability)**과 메모리 구조, 성능 면에서 근본적인 차이가 존재한다.

이러한 차이로 인해, 문자열 처리 방식에 따라 두 클래스의 선택은 전혀 달라져야 한다.


2. 메모리 관점에서의 차이

2.1 String – 불변 객체의 메모리 동작

String 클래스는 한 번 생성된 이후로 내용을 절대 변경할 수 없는 불변 객체이다. 문자열을 수정할 때마다 새로운 객체가 생성되어 Heap 메모리에 누적된다.

예시

String s = "hi";
s = s + "!";  // "hi!"라는 새로운 String 객체가 생성됨

메모리 흐름

[Heap Memory]
"hi"       ← 초기 객체
"hi!"      ← 새로운 객체 (변수 s가 참조)

→ 기존 객체는 GC 대상이 되기 전까지 Heap에 남아 있음
→ 반복적인 수정 시 객체 수 증가 → GC 부하 및 메모리 낭비

주요 특징


2.2 StringBuilder – 가변 객체의 효율적 구조

StringBuilder는 내부에 동적으로 크기 조절이 가능한 char[] 버퍼를 가지고 있으며, 문자열 조작 시 이 버퍼를 직접 수정한다. 불필요한 객체 생성이 없고, 성능과 메모리 측면에서 뛰어나다.

예시

StringBuilder sb = new StringBuilder("hi");
sb.append("!");
System.out.println(sb);  // 출력: hi!

메모리 흐름

[Heap Memory]
StringBuilder 객체
 └─ char[] buffer = ['h', 'i', '!'] ← 내부 버퍼가 직접 수정됨

→ 동일 객체 내에서 작업 → 메모리 재사용
→ 객체 수 증가 없음 → GC 부담 없음

내부 구조 예시

public final class StringBuilder {
    char[] value;
    int count;

    public StringBuilder append(String str) {
        ensureCapacityInternal(count + str.length());
        str.getChars(0, str.length(), value, count);
        count += str.length();
        return this;
    }
}

3. 성능 차이 비교

3.1 코드 성능 테스트

// String (비효율적 방식)
String s = "";
for (int i = 0; i < 1000; i++) {
    s += "a";  // 매번 새로운 객체 생성됨
}
// StringBuilder (효율적 방식)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append("a");  // 내부 버퍼만 수정됨
}

3.2 성능 분석

항목

String

StringBuilder

메모리 구조

불변 객체, 매번 새 객체 생성

가변 객체, 하나의 버퍼 사용

연결 방식

+

또는

concat()

호출마다 새 객체

append()

는 동일 객체에 누적

GC 부하

심함

적음

속도

느림

빠름

💡 결론: 루프나 재귀에서 문자열을 누적해야 할 경우, StringBuilder가 수십 배 빠를 수 있음.


3.3 스레드 안전성 관점

// 멀티스레드 환경에서 StringBuilder는 위험
StringBuilder sb = new StringBuilder();

Runnable task = () -> {
    for (int i = 0; i < 1000; i++) {
        sb.append("x");  // 동기화 안 되어 경합 발생 가능
    }
};

→ 해결책: StringBuffer 또는 synchronized 블록 사용


4. 결론 및 실무 가이드라인

4.1 어떤 클래스가 적절한가?

사용 상황

적절한 클래스

이유

고정된 문자열 / 변경 없음

String

불변성으로 안전하고, 메모리 캐싱 가능

루프 내 문자열 누적 / 대량 조작

StringBuilder

메모리 효율 및 성능 우수

멀티스레드 환경에서 동기화가 필요한 경우

StringBuffer

메서드 동기화로 스레드 안전성 확보

4.2 실전 팁




String(문자열)

Java: String vs StringBuilder vs StringBuffer 비교


1. 개요

자바에서 문자열을 다룰 때 흔히 사용하는 세 가지 클래스인 String, StringBuilder, StringBuffer는 모두 CharSequence 인터페이스를 구현하지만, 불변성, 동기화, 성능 측면에서 명확한 차이를 보인다.

이 문서에서는 다음과 같은 관점에서 세 클래스의 차이점을 심층 분석한다.


2. String

2.1 불변 객체(Immutable)의 특징

String str = "hello";
str += " world";
// 실제로는 "hello", "hello world" 두 개의 객체가 Heap에 존재

이유

2.2 성능 및 메모리 측면

2.3 사용 예시


3. StringBuilder

3.1 가변 객체(Mutable) + 비동기 환경에 적합

StringBuilder sb = new StringBuilder("hello");
sb.append(" world");
System.out.println(sb.toString());  // hello world

3.2 주요 메서드

sb.append("a");
sb.insert(2, "x");
sb.replace(1, 3, "yz");
sb.delete(0, 2);
sb.reverse();

3.3 성능 테스트 예시

public class BuilderTest {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 100_000; i++) {
            sb.append("abc");
        }
        long end = System.currentTimeMillis();
        System.out.println("StringBuilder 소요 시간: " + (end - start));
    }
}

3.4 사용 시점


4. StringBuffer

4.1 가변 객체(Mutable) + 스레드 안전(Thread-safe)

StringBuffer sb = new StringBuffer("safe");
sb.append(" thread");
System.out.println(sb);  // safe thread

4.2 내부 구조

public synchronized StringBuffer append(String str) {
    super.append(str);
    return this;
}

4.3 성능 비교

4.4 멀티스레드 예시

public class BufferThreadTest {
    static StringBuffer sb = new StringBuffer();

    public static void main(String[] args) throws InterruptedException {
        Runnable task = () -> {
            for (int i = 0; i < 1000; i++) {
                sb.append("a");
            }
        };

        Thread t1 = new Thread(task);
        Thread t2 = new Thread(task);
        t1.start(); t2.start();
        t1.join(); t2.join();

        System.out.println("최종 길이: " + sb.length());  // 2000 보장됨
    }
}

5. 성능 및 메모리 비교 요약

항목

String

StringBuilder

StringBuffer

변경 가능 여부

❌ 불변

✅ 가변

✅ 가변

동기화 지원

❌ 없음

❌ 없음

synchronized 지원

성능

느림 (매번 객체 생성)

빠름

중간 (동기화 오버헤드 존재)

메모리 효율성

낮음

높음

중간

적합한 환경

상수, 설정값, 로그 ID 등

단일 스레드 문자열 조작

멀티스레드 문자열 조작


6. 결론 및 실무 팁

StringBuilder vs StringBuffer – 언제 뭐 써야 해?

항목

StringBuilderStringBuffer

스레드 안전성

❌ 비동기(스레드 안전 아님)

✅ 동기화(synchronized, 스레드 안전)

속도

빠름

상대적으로 느림

코딩 테스트/일반 개발

✅ 단일 스레드 환경에서 최적

❌ 보통 코테에선 불필요한 오버헤드 발생

멀티스레드 환경

❌ 사용 시 동기화 문제 생길 수 있음

✅ 멀티스레드 환경에서 안전하게 사용 가능

사용 예

코딩테스트, 파일 파싱, 로그 누적, 텍스트 생성

서버에서 공유 자원 처리, 멀티스레드 로그 등

💡 JDK 1.5 이상에서는 StringBuilder를 기본으로 고려하고, 동기화가 꼭 필요한 경우에만 StringBuffer를 선택하자.




String(문자열)

Java: 기본형(int) vs String(불변 객체)의 메모리 구조 비교


1. Java의 메모리 구조

Java 프로그램은 크게 세 가지 메모리 공간을 사용한다:

1.1 Stack 영역

1.2 Heap 영역

1.3 String Constant Pool (리터럴 풀)


2. 기본형 변수 (예: int)

기본형은 값 그 자체가 Stack 메모리에 저장된다. 변수 간의 대입은 값 복사이며, 변수 간 영향이 없다.

2.1 코드 예시

int a = 10;
int b = a;
a = 20;

2.2 메모리 흐름

초기 상태:
[Stack]
a → 10
b → 10  (값 복사됨)

a = 20; 이후:
a → 20
b → 10  (영향 없음)

📌 int값 자체(value) 를 저장하며, 변수 간 대입은 값 복사다.
값을 변경해도 기존 변수나 참조에 영향을 주지 않는다.


3. String (불변 객체)

String참조형(reference type) 객체이며, Stack에는 참조만 저장되고 실제 문자열은 Heap 또는 Constant Pool에 존재한다.

3.1 코드 예시

String s1 = "hello";
String s2 = s1;
s1 = s1 + " world";

3.2 메모리 흐름

[초기 상태]
[Stack]        [Heap (String Pool)]
s1 ─┐          "hello"
    └────────▶
s2 ─┘          (s1, s2 둘 다 "hello" 참조)

[변경 후]
[Stack]        [Heap]
s1 ──────────▶ "hello world"   ← 새 객체 생성
s2 ──────────▶ "hello"         ← 원본 유지

→ s1 + " world" 는 기존 "hello"를 수정하는 것이 아니라
   **"hello world"라는 새로운 객체를 생성**

📌 String불변(immutable) 이기 때문에 수정이 아닌 새 객체 생성 방식으로 동작한다.
따라서 반복 수정이 많으면 Heap에 객체가 누적 → GC 부담 증가 가능.


4. 예제 비교 요약

// 기본형
int a = 10;
int b = a;
a = 20;        // b는 여전히 10

// 참조형 (String)
String s1 = "hi";
String s2 = s1;
s1 = s1 + "!"; // s2는 여전히 "hi"

항목

기본형 (int 등)

참조형 (String)

저장 위치

Stack

Stack(참조), Heap(객체)

대입 방식

값 복사

참조값 복사

수정 시 영향

원본과 무관

불변 → 새 객체 생성

메모리 부담

없음

반복 수정 시 Heap 객체 증가 가능


5. 요약 및 실무 팁

// 비효율 (String)
String result = "";
for (int i = 0; i < 1000; i++) {
    result += "a";  // 1000개 객체 생성
}

// 효율적 (StringBuilder)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append("a");
}
String result = sb.toString();  // 단 1개 객체 사용

6. 관련 참고

📌 불변성 덕분에 String은 안정적이고 안전하지만, 반복 수정 시에는 가변 객체 사용이 메모리 효율에 유리하다.

1. Java 의 메모리 구조

세 가지 메모리 영역


2. 기본형 변수(int 등)

값 자체가 Stack에 저장됨

int a = 10;
int b = a;
a = 20;

📌 메모리 흐름:

[Stack]
a → 10
b → 10   (복사됨)

a = 20;  이후
a → 20
b → 10   (영향 없음)


3 . String (불변 객체)

참조값이 Stack에, 실제 값은 Heap/String Pool에 저장

String s1 = "hello";
String s2 = s1;
s1 = s1 + " world";

📌 메모리 흐름:

초기 상태:
[Stack]           [Heap (String Pool)]
s1 ─┐             "hello"
    └────────────▶

s2 ─┘

변경 후:
[Stack]           [Heap]
s1 ──────────────▶ "hello world"   ← 새 객체 (불변성)
s2 ──────────────▶ "hello"         ← 원본은 그대로 유지


4. 예제 비교

// 기본형
int a = 10;
int b = a;
a = 20;  // b는 여전히 10

// String
String s1 = "hi";
String s2 = s1;
s1 = s1 + "!";  // s2는 여전히 "hi"

이 불변성 덕분에 String은 안정적이고 안전하지만, 반복 수정이 많을 땐 StringBuilder를 쓰는 게 더 효율적이다.




String(문자열)

Java: 문자열 리터럴 vs new String() 객체 생성 차이


1. 개요

Java에서 문자열은 두 가지 방식으로 생성할 수 있다:

String s1 = "hello";             // 리터럴 방식
String s2 = new String("hello"); // new 키워드 방식

두 방식은 겉보기에는 동일한 문자열 값을 가지지만, 내부 메모리 구조, 생성 방식, 비교 결과, 성능 등에서 중요한 차이를 가진다.


2. 메모리 구조 차이

2.1 리터럴 방식 (String s = "hello")

예시

String a = "hello";
String b = "hello";

System.out.println(a == b);      // true (같은 객체 참조)
System.out.println(a.equals(b)); // true (내용도 동일)

같은 상수 풀 객체를 참조하고 있기 때문에 a == btrue.


2.2 new 연산자 방식 (String s = new String("hello"))

예시

String a = "hello";
String b = new String("hello");

System.out.println(a == b);      // false (다른 참조)
System.out.println(a.equals(b)); // true  (내용은 같음)

== 결과는 false, .equals()true


3. 객체 비교 방식

3.1 == 연산자 (참조 비교)

3.2 .equals() 메서드 (값 비교)

String s1 = "test";
String s2 = new String("test");

System.out.println(s1 == s2);      // false
System.out.println(s1.equals(s2)); // true

4. 성능 및 메모리 효율

항목

리터럴 방식 (

"hello"

)

new 방식 (

new String("hello")

)

메모리 위치

Constant Pool (Method Area)

Heap 영역

객체 중복 여부

없음 (공유됨)

항상 새 객체 생성

==

비교 결과

true (동일 참조)

false (서로 다른 참조)

.equals()

결과

true

true

메모리 효율

높음

낮음

성능

빠름

느림 (GC 대상 증가)

GC 부담

낮음

높음

사용 권장 여부

✅ 일반적으로 권장

❌ 특별한 경우에만 사용


5. 실제 사용 시 차이

5.1 리터럴 방식 – 일반적으로 권장

if (userRole.equals("ADMIN")) {
    // 권한 체크
}

5.2 new 방식 – 특수 목적용

String s = new String("hello").intern();  // Constant Pool 등록

6. 정리: 리터럴 vs new String()

비교 항목

리터럴 방식 (

"hello"

)

new 방식 (

new String("hello")

)

저장 위치

String Constant Pool

Heap 메모리

객체 공유 여부

✅ 공유됨 (중복 방지)

❌ 매번 새 객체 생성

==

비교 결과

true

false

.equals()

결과

true

true

성능

빠름

느림

메모리 효율

높음

낮음

GC 부담

낮음

높음

사용 추천 여부

✅ 일반적 상황에서 적극 권장

⚠️ 특별한 목적이 없으면 지양


7. 결론


이 정리는 Java 메모리 구조, 성능 최적화, 참조와 객체 비교에 대해 정확한 이해를 돕기 위한 위키 스타일

자바에서 문자열은 두 가지 방법으로 생성할 수 있다.

String str = "hello";와 String str = new String("hello"); 두 가지 방식은 같아 보이지만, 작동 방식, 메모리 구조, 성능, 객체 비교 등 여러 측면에서 차이가 난다.

String s1 = "hello";                    // 리터럴 방식
String s2 = new String("hello");        // new 연산자 사용

두 방식은 겉보기에는 같은 값을 가지지만, 메모리 처리, 비교 방법, 성능 등의 측면에서 분명한 차이가 존재한다.


1. 메모리 구조 차이

1.1 리터럴 방식: String s1 = "hello";

문자열 리터럴은 String Constant Pool에 저장된다.

JVM은 동일한 문자열 리터럴이 여러 번 등장하더라도 중복을 제거하여 하나의 객체만 저장한다.

메모리 효율이 높고, 비교 연산 시 빠르다.

📌 예시

String a = "hello";
String b = "hello";

System.out.println(a == b);  // true (같은 상수 풀 객체)

1.2 new 연산자 방식: String s2 = new String("hello");

new 키워드를 사용하면 Heap에 새로운 객체가 강제로 생성된다.

비록 내부적으로 "hello"라는 리터럴이 사용되더라도, Constant Pool의 객체를 복제한 별도 인스턴스가 Heap에 만들어진다.

따라서 리터럴과는 다른 참조값을 가진다.

📌 예시

String a = "hello";
String b = new String("hello");

System.out.println(a == b);      // false (주소 다름)
System.out.println(a.equals(b)); // true  (값 같음)


2. 객체 비교 (== vs equals())

2.1 == (참조 비교)

리터럴 방식은 JVM이 Constant Pool을 공유하므로 == 결과가 true일 수 있다.

new 키워드는 항상 새로운 객체를 생성하므로 == 비교 시 false가 된다.


2.2 .equals() (내용 비교)

두 방식 모두 문자열 내용을 같게 만들면 .equals()는 항상 true를 반환한다.

문자열 비교에서는 항상 .equals()를 사용하는 것이 안전하다.


3. 성능 및 메모리 효율

3.1 리터럴 방식

3.2 new 방식


4. 실제 사용 시 차이점

4.1 리터럴 방식의 사용 예

if (userRole.equals("ADMIN")) { ... }

4.2 new 방식의 사용 예

String s = new String("hello").intern();  // 풀로 보냄


5. 정리


리터럴 방식 ("hello")

new 방식 (new String("hello"))

메모리 위치

Constant Pool (Method Area)

Heap 영역

객체 중복 여부

없음 (공유됨)

항상 새 객체 생성

== 비교 결과

true (같은 참조)

false (다른 객체)

.equals() 결과

true

true

메모리 효율

높음

낮음

성능

빠름

느림

GC 부담

낮음

높음

사용 권장 여부

일반적으로 권장

특별한 경우에만 사용



6. 결론





String(문자열)

Java: BufferedReader

String(문자열)

Java: BufferedWriter

Stream