Java의 정석 - String & String Buffer

원태연·2022년 5월 30일
0

Java의 정석

목록 보기
12/19
post-thumbnail

String

public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
//  ...
}

String은 문자형 배열을 저장하는 클래스이며, 이를 다룰수 있는 여러 메서드들을 제공한다.

String은 변경 불가능한 클래스이다.

String a = "A";
String b = "B";
a = a + b; //--1

이렇게 하면 A -> AB로 변하는 것 같지만, 실제 동작은 변경하지 않는다. --1의 수행 과정에서, 새로운 객체 AB라는 새로운 인스턴스가 생성되고, a가 더이상A가 아닌 AB를 가리키게 되는 것이다.

String클래스의 이러한 특성 때문에 기본형(int, double, char, ...)와 동일한 방법으로 작동하지 않는다. 보이기엔 비슷하게 작동하지만, 효율성을 높히고자 한다면 동작원리에 대해 알 필요가 있을 것이다.

String a1 = "A";  //--1
String a2 = "A";
String a3 = new String("A"); //--2
String a4 = new String("A");

--1--2의 결과는 같겠지만, --1의 방식이 권장된다. 프로그램이 동작하면, --1에 존재하는 Aconstant pool이라는 곳에 저장되고, 이를 재사용한다. 그래서 a1a2는 같은 인스턴스(?)를 가리키지만, 생성자(--2)를 통해 생성하면, a3a4가 각각 새로운 인스턴스를 생성하기 때문에 성능면에서 조금 떨어질 수 있다.

String 생성자

  • 생성자

    String(String s)

    String(char[] value) : char의 배열을 String으로 만듦

    char[] ab = {'A','B'};
    String s = new String(ab); //AB

    String(StringBuffer value) : StringBuffer를 String으로 만듦

String 메서드

  • 비교

    int compareTo(String str) : str과 사전순서로 비교하여 결과 반환, 정렬때 유용할 듯

    int i = "a".compareTo("b"); // -1  a < b 
    int i = "b".compareTo("a"); // 1   b > a
    int i = "aa".compareTo("aa"); // 0  aa == aa

boolean equals(Object obj) : 일치하는지 비교

String a = "A";
boolean same = a.equals("A"); //true
boolean diff = a.equals("a"); //false

//대소문자 구분 없이 비교할 경우
boolean ignoreCase a.equalsIgnoreCase("a"); //true
  • 검사

    boolean contains(CharSequence s) : s를 포함하는지 검사

    String a = "ABC";
    boolean b = a.contains("AB"); //true

int indexOf(int ch) : ch의 위치를 반환

String a = "HelloolleH";
int h1 = a.indexOf("H");    // 0,    맨 앞에서부터 찾음
int h2 = a.indexOf("H", 3); // 9,    3의 위치부터 찾음
int none = a.indexOf("K");  // -1,   없으면 -1
int s1 = a.indexOf("ll");   // 3    
 
int h3 = a.lastIndexOf("H");// 9,    뒤에서부터 찾아서 위치 반환

char loc = a.charAt(9);     //H,     9에 있는 문자를 반환

boolean startsWith(String str) : str로 시작하는지 확인

String a = "HelloWorld";
boolean starts = a.startWith("Hel"); // true
 
boolean ends = a.endsWith("ld"); //true 끝나는 문자 확인

int length() : 길이 반환

  • 슬라이싱

    String substring(int begin) : begin부터 나눈 문자열 반환

    String a = "HelloWorld !!!";
    String b = a.substring(5);   //World !!!
    String c = a.substring(0,5); //Hello  0~4까지

    String trim(): 양옆 공백 제거

    String a = "  Hello ab  ";
    String b = a.trim();		//Hello ab

    String[] split(String regex) : regex로 나누어 문자열 배열로 담기

    String a = "A,B,C";
    String[] aArr = a.split(",");
    //aArr[0] = A
    //aArr[1] = B
    //aArr[2] = C
    
    //join을 통해 결합하여 문자열로 만들 수 있다
    String aAgain1 = String.join(",", aArr);
    // A,B,C
    
    String aAgain2 = String.join("-", aArr);
    // A-B-C

    String concat(String str) : str을 붙히기

    String a = "A";
    String b = "B";
    String ab = a.concat(b); //AB
  • 다루기

    String toLowerCase() : 소문자로,

    String toUpperCase() : 대문자로

String과 형변환

기본형을 문자열로 변환 하는 경우 :String.valueOf()를 통해 변환 가능

public class playGround {
    public static void play(){
        int integer = 10;
        char character = 'A';
        boolean isTrue = true;
        double doubleNumber = 10.12;
        System.out.println(String.valueOf(integer));      //10
        System.out.println(String.valueOf(character));    //A
        System.out.println(String.valueOf(isTrue).toUpperCase());       //TRUE
        System.out.println(String.valueOf(doubleNumber)); // 10.12
      
      
      	String a = number + "";
      	String b = String.valueof("10");
      //동일한 결과지만, valueOf의 성능이 더 우세함
    }
}

반대의 경우도 valueOf()를 사용하지만, 변환하려는 타입에 맞는 래퍼클래스를 통해 사용해야한다.

public class playGround {
    public static void play(){
        String number = "10";
        String doubleNumber = "10.12";
        System.out.println(Integer.valueOf(number) + Double.valueOf(doubleNumber)); //20.119999999999997
      //int와 double의 연산
     		int a = number + "";
      	int b = Integer.valueof("10");
    }
}

StringBuffer

String클래스와 유사하게 문자열을 저장할 수 있지만, 변경에 용이한 클래스이다.

char[]를 좀더 유연하게 사용하여 문자 편집에 용이하다. 기본적인 크기(16)가 존재하고, 필요에 맞게 조절할 수 있다.

생성자

public class playGround {
    public static void play(){
        StringBuffer sb = new StringBuffer("abc"); //--1
        System.out.println(sb.capacity()); //19
        System.out.println(sb.length());   //3
      	StringBuffer sb2 = new StringBuffer(10);   //--2
      	System.out.println(sb2.capacity()); //10
    }
}

StringBuffer 인스턴스를 만들어야 한다.

이때, 문자열을 주면(--1) 예상대로 동작한다. 문자열의 길이에 추가적으로 기본크기인 16이 추가되어 문자열을 담은 char[]의 길이가 19(16 + 3)이 된다.

(--2)처럼 정수값을 주면, 기본값이 아닌 원하는 길이의 char[]이 생성된다.

.capacity().length()의 차이도 코드를 통해 확인할 수 있다.

StringBuffer 메서드

  • StringBuffer append() : 매개변수로 입력된 값을 문자열로 변환하여 맨 뒤에 추가한다

    public class playGround {
      public static void play(){
        StringBuffer sb = new StringBuffer("abc");
        sb.append(123);
        sb.append(true);
        System.out.println(sb);  //abc123true
      }
    }
  • StringBuffer delete(int start, int end) : start ..< end까지의 문자를 제거한다

    sb.delete(3, 6);
    System.out.println(sb); //abctrue
    sb.deleteCharAt(3); // 위치가 3인 문자 제거
    //abcrue
  • StringBuffer insert(int pos, any): pos위치에 any를 삽입한다

    sb.insert(3,"t");
    //abctrue
  • StringBuffer reverse(): 배열을 뒤집는다

    sb.reverse();
    //eurtcba
  • StringBuffer setLength : 배열의 길이를 변경한다

    public class playGround {
      public static void play(){
        StringBuffer sb = new StringBuffer("abcdefg");
        sb.setLength(5);
        System.out.println(sb); //abcde (fg는 짤림)
        sb.setLength(12);
        System.out.println(sb); //abcde      (남은 공간은 공백으로 채워짐)
        System.out.println(sb.charAt(8)); // 공백
      }
    }

StringBuilder

StringBuffer와 동일한 기능을 가진 클래스이다.

쓰레드의 동기화 유무이다. 멀티쓰레드로 작동하는 경우, 데이터들간의 동기화가 필요한데 StringBuffer는 동기화가 자동으로 된다. 그래서 싱글쓰레드로 작동하는 프로그램의 경우에는 불필요한 성능이 될 수 있다. 큰 차이는 없을 수 있지만, 프로그램에 따라 성능향상을 고려해본다면 StringBuilderStringBuffer의 차이를 알아두는 것이 좋을 것 같다.

profile
앞으로 넘어지기

0개의 댓글