Java공부(코딩)

코딩초보의 자바(Java)공부 16일차 { String 클래스 }

동곤일상 2024. 12. 29. 18:38
반응형
오랜만에 올립니다....
목금토 놀러가서
올리지 못했네요 ㅠ

오늘은 String클래스에 대해
알아볼게요 !!






1) String 클래스

자바에서 문자열을 다루는

대표적인 타입은

char , String 

 

char : 

문자하나를 저장할 수 있음

단어를 저장하려면

char[]의 형태로 저장해야함

 

 

String :

단어를 저장할 수도있음

참조형 클래스임!

 

`String` 클래스다.

`int` , `boolean` 같은 기본형이 아니라 참조형이다. 따라서 `str1` 변수에는 `String` 인스턴

스의 참조값만 들어갈 있다.

 

문자열은 매우 자주 사용된다. 그래서 편의상 쌍따옴표로 문자열을 감싸면 자바 언어에서 `new String("hello")`

같이 변경해준다. ( 경우 실제로는 성능 최적화를 위해 문자열 풀을 사용하는데, 부분은 뒤에서 설명한다.)

String str1 = "hello"; //기존

String str1 = new String("hello"); //변경


 

1-1) String 클래스-구조

public final class String {

//문자열 보관

private final char[] value;// 자바 9 이전

private final byte[] value;// 자바 9 이후//여러 메서드

public String concat(String str) {...}

public int length() {...}

...

}

```

클래스이므로 속성과 기능을 가진다.

 

속성 :

private final byte[] value;

 

 

**기능(메서드)**

`String` 클래스는 문자열로 처리할 있는 다양한 기능을 제공한다.

기능이 방대하므로 필요한 기능이 있으면 검색하거나 API 문서를 찾아보자. 주요 메서드는 다음과 같다.

`length()` : 문자열의 길이를 반환한다.

`charAt(int index)` : 특정 인덱스의 문자를 반환한다.

`substring(int beginIndex, int endIndex)` : 문자열의 부분 문자열을 반환한다.

`indexOf(String str)` : 특정 문자열이 시작되는 인덱스를 반환한다.

`toLowerCase()` , `toUpperCase()` : 문자열을 소문자 또는 대문자로 변환한다.

`trim()` : 문자열 끝의 공백을 제거한다.

`concat(String str)` : 문자열을 더한다.

 


1-2) String 클래스-비교

문자열 비교할 땐 항상 eqauls() 사용하자

 

**동일성(Identity)**: `==` 연산자를 사용

  객체의 참조가 동일한 객체를 가리키고 있는지 확인

 

**동등성(Equality)**: `equals()` 메서드를 사용

  객체가 논리적으로 같은지 확인

 

코드를 통해 알아보자

public class StringEqaulsMain1 {

public static void main(String[] args) {

String str1 = new String("hello");

String str2 = new String("hello");

System.out.println("new String() == 비교: " + (str1 == str2));

System.out.println("new String() equals 비교: " + (str1.equals(str2)));

 

 

String str3 = "hello";

String str4 = "hello";

System.out.println("리터럴 == 비교: " + (str3 == str4));

System.out.println("리터럴 equals 비교: " + (str3.equals(str4)));

 

}}

 

new String("hello")처럼

인스턴스를 만들어 비교하는경우

==  :  false

(서로다른인스턴스이므로 동일성X)

 

equals : true

 

 

str3 = "hello";

처럼 문자열리터럴을 만들어 

비교하는 경우

자바에서 메모리효율 등을 위해

 

문자열 풀 사용

(==비교 , eqauls비교 모두 true)

: 자원이 모여있는 곳

 

즉 자바에서 미리 만들어둔것을

사용한단 뜻 !!

그냥 문자열의 비교에는

eqauls()를 사용하자 !!


1-3) String 클래스-불변객체

 

String클래스는 불변객체다

아까 메서드중에 concat()이라는 문자열을 더하는메서드로

예를 들어보자

public class ImmutableMain1 {

 

public static void main(String[] args) {

String str1 = "my name is";

String str2 = "donggon";

System.out.println("변경 전 str1 : "+str1);

str1.concat(str2);

System.out.println("변경 후 str1 : "+str1);}}

 

출력

변경 전 str1 : my name is

변경 후 str1 : my name is

 

어라 분명 concat으로 str1 뒤에 str2를 붙인것같은데???

String은 불변객체입니다

필요한 경우 기존값을 변경할 수는 없고

새로운값을 반환할수는 있습니다

String concat = str1.concat(str2);

System.out.println("변경 후 str1 : "+concat);

이런식으로요!!

 

구조는 이렇습니다

기존의값은 변경할 수 없어요!!

 


1-3) String 클래스-주요메서드 

 

다 설명하기엔 너무 길고 주요한메서드몇개만

코드로 나타내보겠습니다!

public class MethodMain {

 

public static void main(String[] args) {

 

String str = "donggon, java!!";

System.out.println("문자열의 길이: " + str.length());

System.out.println("문자열이 비어 있는지: " + str.isEmpty());

System.out.println("문자열이 비어 있거나 공백인지1: " + str.isBlank()); //Java11

System.out.println("문자열이 비어 있거나 공백인지2: " + " ".isBlank());

char c = str.charAt(7);

System.out.println("7번 인덱스의 문자: " + c);

 

}}

 

문자열의 길이: 15

문자열이 비어 있는지: false

문자열이 비어 있거나 공백인지1: false

문자열이 비어 있거나 공백인지2: true

7번 인덱스의 문자: ,

 

 

비교메서드

equals(Object anObject)` : 문자열이 동일한지 비교한다.

`equalsIgnoreCase(String anotherString)` : 문자열을 대소문자 구분 없이 비교한다.

`compareTo(String anotherString)` : 문자열을 사전 순으로 비교한다.

`compareToIgnoreCase(String str)` : 문자열을 대소문자 구분 없이 사전적으로 비교한다.

`startsWith(String prefix)` : 문자열이 특정 접두사로 시작하는지 확인한다.

`endsWith(String suffix)` : 문자열이 특정 접미사로 끝나는지 확인한다

public class MethodEqauls {

public static void main(String[] args) {

String str1 = "HelLo, JavA!"; //대문자 일부 있음

String str2 = "hello, java!"; //대문자 없음 모두 소문자

String str3 = "Hello, World!";

System.out.println("str1 equals str2: " + str1.equals(str2));

System.out.println("str1 equalsIgnoreCase str2: " +

str1.equalsIgnoreCase(str2));

 

System.out.println("'b' compareTo 'a': " + "b".compareTo("a")); // b와a가 얼마나 차이나냐?

System.out.println("str1 compareTo str3: " + str1.compareTo(str3));

 

System.out.println("str1 compareToIgnoreCase str2: " +

str1.compareToIgnoreCase(str2));

 

System.out.println("str1 starts with 'HelLo': " +

str1.startsWith("HelLo"));

 

System.out.println("str1 ends with 'Java!': " + str1.endsWith("Java!"));

}}

 

출력

 

str1 equals str2: false

str1 equalsIgnoreCase str2: true //대소문자구분없이 비교

'b' compareTo 'a': 1  // a 다음에 b 이므로 1

str1 compareTo str3: -32

str1 compareToIgnoreCase str2: 0 

str1 starts with 'HelLo': true  //

str1 ends with 'Java!': false //JavA 로 끝나므로 false

 


문자열 검색

public class StringSearchMain {

public static void main(String[] args) {

String str = "Hello, Java! Welcome to Java world.";

System.out.println("문자열에 'Java'가 포함되어 있는지: " +

str.contains("Java"));

System.out.println("'Java'의 첫 번째 인덱스: " + str.indexOf("Java"));

System.out.println("인덱스 10부터 'Java'의 인덱스: " + str.indexOf("Java",

10));

System.out.println("'Java'의 마지막 인덱스: " + str.lastIndexOf("Java"));

 

}}

 

문자열에 'Java'가 포함되어 있는지: true

'Java'의 첫 번째 인덱스: 7

인덱스 10부터 'Java'의 인덱스: 24

'Java'의 마지막 인덱스: 24

 

public static void main(String[] args) {

String str = "Hello, Java! Welcome to Java";

System.out.println("인덱스 7부터의 부분 문자열: " + str.substring(7));

 

System.out.println("인덱스 7부터 12까지의 부분 문자열: " +

str.substring(7,12));

 

System.out.println("문자열 결합: " + str.concat("!!!"));

 

System.out.println("'Java'를 'World'로 대체: " //출력시에만 나타남 실제반영X

+ str.replace("Java","World"));

 

System.out.println("첫 번째 'Java'를 'World'으로 대체: " +

str.replaceFirst("Java", "World"));//출력시에만 나타남 실제반영X

}

 

인덱스 7부터의 부분 문자열: Java! Welcome to Java

인덱스 7부터 12까지의 부분 문자열: Java!

문자열 결합: Hello, Java! Welcome to Java!!!

'Java'를 'World'로 대체: Hello, World! Welcome to World

첫 번째 'Java'를 'World'으로 대체: Hello, World! Welcome to Java

 

 

 

public static void main(String[] args) {

String strWithSpaces = " Java Programming ";

System.out.println("소문자로 변환: " + strWithSpaces.toLowerCase());

System.out.println("대문자로 변환: " + strWithSpaces.toUpperCase());

System.out.println("공백 제거(trim): '" + strWithSpaces.trim() + "'");

System.out.println("공백 제거(strip): '" + strWithSpaces.strip() + "'");

System.out.println("앞 공백 제거(strip): '" + strWithSpaces.stripLeading()

+ "'");

System.out.println("뒤 공백 제거(strip): '" + strWithSpaces.stripTrailing()

+ "'");

}

 

소문자로 변환: java programming

대문자로 변환: JAVA PROGRAMMING

공백 제거(trim): 'Java Programming'

공백 제거(strip): 'Java Programming'

공백 제거(strip): 'Java Programming '

공백 제거(strip): ' Java Programming'

 

 

 

public static void main(String[] args) {

String str = "Apple__Banana__Orange";

// split()

String[] splitStr = str.split("__"); //__을 기준으로 나눈다!

for(String s : splitStr) {

System.out.println(s);

}

// join()

// join()

String joinedStr = String.join("@@", "A", "B", "C");

System.out.println("연결된 문자열: " + joinedStr);

 

// 문자열 배열 연결

String result = String.join("**", splitStr);

System.out.println("result = " + result);

 

출력

Apple

Banana

Orange

연결된 문자열: A@@B@@C

result = Apple**Banana**Orange

 


2)StringBuilder -가변String-

 

불변인 `String` 내부 값은 변경할 없다.

따라서 변경된 값을 기반으로 새로운 `String` 객체를 생성한다.

 

이런 문제를 해결하기 위해 자바는 `StringBuilder` 라는 가변 `String` 제공한다.

물론 가변의 경우 사이드 이펙트에 주의해서 사용해야 한다.

StringBuilder의 사용 예를 보자

public class StringBuilderMain1 {

public static void main(String[] args) {

StringBuilder sb = new StringBuilder();

sb.append("my ").append("name ").append("is Donggon").toString()

//메서드체이닝 사용 

 

System.out.println("sb : "+sb);

 

sb.insert(2, "하하");//2번인덱스에 "하하"추가

System.out.println("sb : "+sb);

 

sb.delete(2, 4);//2번인덱스 ~ 3번인덱스 ( 4번은삭제X) 까지 삭제

System.out.println("sb : "+sb);

 

sb.replace(0, 4, "헤헤"); //0번부터 3번인덱스를지우고 해당 문자열로 변경

System.out.println("sb : "+sb);

 

sb.reverse();

System.out.println("sb : "+sb);

 

String string = sb.toString(); //불변객체로 다시 만듬

System.out.println(string);}}

 

출력

sb : my name is Donggon

sb : my하하 name is Donggon

sb : my name is Donggon

sb : 헤헤ame is Donggon

sb : noggnoD si ema헤헤

noggnoD si ema헤헤

 

`StringBuilder` 객체를 생성한다.

`append()` 메서드를 사용해 여러 문자열을 추가한다.

`insert()` 메서드로 특정 위치에 문자열을 삽입한다.

`delete` () 메서드로 특정 범위의 문자열을 삭제한다.

`reverse()` 메서드로 문자열을 뒤집는다.

마지막으로 `toString` 메소드를 사용해 `StringBuilder` 결과를 기반으로 `String` 생성해서 반환한

.

 

StringBuilder 직접 사용하는 것이 좋은 경우**

반복문에서 반복해서 문자를 연결할

조건문을 통해 동적으로 문자열을 조합할

복잡한 문자열의 특정 부분을 변경해야

매우 대용량 문자열을 다룰

 

 

 


문제와풀이

문제1 - startsWith

`startsWith()` 사용해서 `url` `https://`

시작하는지 확인해라.

public class StartWithEx {

 

public static void main(String[] args) {

 

String url = "https://www.example.com";

 

 

System.out.println(url.startsWith("https://"));}}

 

 

문제2 - length()

**문제 설명**

`length()` 사용해서 `arr` 배열에 들어있는 모든 문자열의 길이 합을 구해라.

public class ArrEx {

 

public static void main(String[] args) {

String[] arr = {"hello", "java", "jvm", "spring", "jpa"};

int result =0;

for (String string : arr) {

result += string.length();

System.out.println(string +" : "+string.length());

}

System.out.println("총 length : "+result);}}

 

출력

hello : 5

java : 4

jvm : 3

spring : 6

jpa : 3

총 length : 21


문제3 - indexOf()

**문제 설명**

hello.txt

` 에서 `".txt"` 문자열이 언제부터 시작하는지 위치를 찾아서 출력해라.

`indexOf()` 사용해라.

public class InderofEx {

 

public static void main(String[] args) {

String str = "hello.txt";

int index = str.indexOf(".txt");

System.out.println(".txt : "+index+" 부터 시작");

}}

출력

.txt : 5 부터 시작


 

문제4 - substring()

**문제 설명**

`substring()` 사용해서, `hello` 부분과 `.txt` 부분을 분리해라.

indexOf()를 응용해도 좋다

public class SubStringEx {

 

public static void main(String[] args) {

String str = "hello.txt";

int b = str.indexOf(".txt");

System.out.println(str.substring(0, b)); //0부터b까지의부분문자열반환

System.out.println(str.substring(b)); //b부터의 문자열반환

}}

출력

hello

.txt


문제6 - 검색 count

**문제 설명**

start hello java, hello spring, hello jpa

` 에서

`hello`문자의 수를 출력해라.

`indexOf()` 반복문과 함께 풀면 된다.

public static void main(String[] args) {

String str = "start hello java, hello spring, hello jpa";

String key = "hello";

 

int count = 0;

int index = str.indexOf(key);

 

System.out.println(index);

 

int index1 = str.indexOf(key,(index+1));

System.out.println(index1); //count ==1

 

int index2 = str.indexOf(key,(index1+1));

System.out.println(index2);//count ==2

 

int index3 = str.indexOf(key,(index2+1));

System.out.println(index3);//count ==3 --> index가 -1 이 되면서 루프종료

 

while(index>=0) {

index = str.indexOf(key,(index+1)); //key를 찾은 인덱스 +1 부터 찾음(중복방지)

 

count++;

}

 

System.out.println("count : "+count);

}

 

출력

6

18 // count 1 

32 //count 2

-1 //count 3 되면서 종료

count : 3


문제7 - 공백 제거

**문제 설명**

문자의 양쪽 공백을 제거해라. ) `" Hello Java "` `"Hello Java"`

public class TrimEx {

 

public static void main(String[] args) {

String str = " My name is doggon ";

 

System.out.println("'"+str+"'");

 

String trim = str.trim();

System.out.println("'"+trim+"'");

 

String strip = str.strip(); //trim과 같은 역할 해줌

System.out.println("'"+strip+"'");}}

 

출력

' My name is doggon '

'My name is doggon'

'My name is doggon'