StringBuilder는 문자열의 저장 및 변경을 위한 메모리 공간을 지닌 클래스이다.

 문자열 데이터의 추가를 위한 append와 중간에 삽입을 위한 insert 메소드를 제공한다.

append는 문자열을 순서대로 저장할 때

insert는 문자열을 중간에 저장할 때



위의 메소드를 통해 메모리 버퍼에 문자열을 쌓고나서 toString을 이용해 문자열을 만든다.

 기본 16개의 문자저장 메모리 버퍼를 생성한다. 물론 아래와 같이 임의로 지정할 수도 있다.

public StringBuilder(int capacity);     // capacity 만큼의 문자저장 버퍼를 생성

 문자열이 들어간 버퍼를 만들수도 있다.

public StringBuilder(String str);    // 문자를 저장한 문자저장 버퍼를 생성



 StringBuilder는 무조건 두개의 인스턴스만을 생성한다.

ex. String str4 = 1 + "Lemon" + 2;

new StringBuilder().append(1).append("Lemon").append(2).toString();

new StringBuilder() 하나, toString 하나해서 2개의 인스턴스만을 생성 ->??



StringBuffer는 멀티쓰레드에 안전(thread safe)하도록 동기화 되어 있다. 아직은 멀티쓰레드나 동기화에 대해서 배우지 않았지만, 동기화가 StringBuffer의 성능을 떨어뜨린다는 것만 이해하면 된다. 멀티쓰레드로 작성된 프로그램이 아닌 경우, StringBuffer의 동기화는 불필요하게 성능만 떨어뜨리게 된다. 그래서 StringBuffer에서 쓰레드 동기화만 뺀 StringBuilder가 새로 추가되었다.

StringBuilder는 StringBuffer와 완전히 똑같은 기능으로 작성되어 있어서 소스코드에서 StringBuffer대신에 StringBuilder로 바꾸기만 하면 된다. 즉, StringBuffer타입의 참조변수를 선언한 부분과 StringBuffer의 생성자만 바꾸면 된다.

StringBuffer도 충분히 성능이 좋기 때문에 성능향상이 반드시 필요한 경우를 제외하고 StringBuffer를 StringBuilder로 바꿀 필요가 없다.


String

-  짧은 문자열을 더할 경우 사용


StringBuilder 

단일 스레드에서 안전성만을 보장한다.

- 스레드에 안전여부에 전혀 관계 없는 프로그램을 개발할 때 사용하면 좋음

- 메서드 내에 변수를 선언했다면, 해당 변수는 그 메서드 내에서만 살아있으므로 이 클래스를 사용해야함


StringBuffer

- 스레드에 안전하게 설계되어 있으므로, 여러 개의 스레드에서 하나의 StringBUffer 객체를 처리해도 전혀 문제가 되지 않는다.

- 개발 중인 시스템이 스레드에 안전한지 모를경우 사용하면 좋음

- 클래스에 static으로 선언한 문자열을 변경하거나, singleton 으로 선언된 클래스에 선언된 문자열일 경우 이 클래스를 사용해야함


응답시간

String > StringBuffer > StringBuilder


메모리

String >StringBuffer == StringBuilder



출처: https://clairdelunes.tistory.com/46 [거꾸로 바라본 세상]


String클래스는 불변 객체이기 때문에 문자열 연산이 많은 프로그래밍이 필요할 때 계속해서 인스턴스를 생성하므로 성능이 떨어지지만 조회가 많은 환경, 멀티쓰레드 환경에서 성능적으로 유리합니다.

StringBuffer클래스와 StringBuilder클래스는 문자열 연산이 자주 발생할 때 문자열이 변경가능한 객체기 때문에 성능적으로 유리합니다.

StringBuffer와 StringBuilder의 차이점은 동기화지원의 유무이고 동기화를 고려하지 않는 환경에서 StringBuilder가 성능이 더 좋고, 동기화가 필요한 멀티쓰레드 환경에서는 StringBuffer를 사용하는 것이 유리합니다.

* StringBuffer와 StringBuilder는 성능으로 따졌을 때 2배의 속도차이가 있다고 하지만 참고사이트의 속도 차이 실험 결과 append()연산이 약 1억6천만번 일어날 때 약 2.6초의 속도차이를 보인다고 합니다.

(String은 +연산이 16만번이상 넘어가게 되면 10초이상 걸리면서 못 쓸정도의 성능을 보입니다.)

따라서 문자열연산이 많지만 엄청나게 일어나지 않는 환경이라면 StringBuffer를 사용해서 thread-safe한 것이 좋다는 생각입니다.

* JDK1.5이상부터 String에서 +연산으로 작성하더라도 StringBuilder로 컴파일하게 만들어 놨다지만 여전히 String클래스의 객체 생성하는 부분을 동일하므로 StringBuffer,StringBuilder 사용이 필요함.

+ StringBuffer, StringBuilder의 경우 buffer size를 초기에 설정해야하는데 이런 생성, 확장 오버로드가 걸려 버퍼사이즈를 잘못 초기화할 경우 성능이 좋지 않을 수 있음.

+ String클래스가 컴파일러분석단계에서 최적화될 가능성이 있기때문에 간혹 성능이 잘나오는 경우도 있음. 문자열 연산이 많지 않은 경우는 그냥 사용해도 무방.

런타임에서 문자열조합이 많아질 경우 String은 여전히 성능이 아주 안좋기 때문에!

+, concat을 사용하는 사고(?)를 치면 안된다. 특히 현업에서....



출처: https://jeong-pro.tistory.com/85 [기본기를 쌓는 정아마추어 코딩블로그]


String a = "hello";
String a2 = "hello";

System.out.println(a);
System.out.println(a.concat(" world"));
System.out.println(a); //그대로 hello출력


//그냥 String클래스보다 성능면에서 더 좋다. 메모리 할당과 메모리 해제를 발생 시키며 더하는 연산이 많아진다면 성능적으로 좋지 않다.
//StringBuilder는 String문자열을 더할 때 새로운 객체를 생성하는 것이 아니라
// 기존의 데이터에 더하는 방식을 사용하기 때문에 속도도 빠르며 상대적으로 부하가 적다. 현업에서는 sb.concat안됨
StringBuilder sb = new StringBuilder();
sb.append("hello");
sb.append(" world");
System.out.println(sb.toString());


System.out.println("start");
String str = "";
for (int i = 0 ; i < 1000000; i++) {
str += i;
sb.append(i); //for문안에선 stringbuilder가 빠르지만 string은 느리다... 100000을 돌려 봤을때
}
System.out.println("end");


StringBuffer클래스와 StringBuilder 클래스의 공통점


-> 메소드의 수(생성자 포함)

-> 메소드의 기능

-> 메소드의 이름과 매개변수 형


StringBuilder클래스를 StringBuffer클래스로 변경하여도 컴파일 및 실행이 정상적으로 됩니다.


StringBuffer클래스와 StringBuilder클래스의 차이점

StringBuffer는 쓰레드에 안전,

StringBuilder는 쓰레드에 불안정

변수(variable) : 하나의 값을 저장하기 위한 공간

상수(constant): 값을 한번만 저장할 수 있는 공간

리터럴(literal) : 그 자체로 값을 의미하는 것


int year(변수) = 2014;(리터럴)

final int MAX_VALUE(상수) = 100;(리터럴)


상수가 필요한 이유


상수는 리터럴에 '의미 있는 이름'을 붙여서 코드의 이해와 수정을 쉽게 만든다. 


final int WIDTH = 20;//폭

final int HEIGHT = 10; //높이


int triangleArea = (WIDTH * HEIGHT) / 2;     //삼각형의 면적을 구하는 공식

int triangleArea = WIDTH * HEIGHT; //사각형의 면적을 구하는 공식


리터럴의 타입이 있어서 기본형 변수에 접미사가 있는것이다.


논리형은 접미사 없음

정수형 L

실수형 f,d

문자형 없음

문자열 없음


**문자 리터럴과 문자열 리터럴


char ch = 'J';

String name = "JAVA";


String str  = ""//가능 내용이 없는 빈 문자열

char ch = ''; //에러 ' ' 안에 반드시 하나의 문자가 필요

char ch = ' '; //가능 공백 문자로 변수 ch 초기화 


원래 String은 클래스라서 객체 생성하는 연산자 new를 이용해야 하지만 특별히 String str = ""도 가능

String name = new String("JAVA");


기본형과 참조형의 구별 없이 어떤 타입의 변수도 문자열과 덧셈연산을 수행하면 그 결과가 문자열이 된다.

문자열 _+ any type = 문자열 + 문자열  = 문자열

any type + 문자열 = 문자열 + 문자열 = 문자열


String name = "Ja" + "va";
String str = name + 8.0;

System.out.println(name);
System.out.println(str);
System.out.println(7 + " ");
System.out.println(" " + 7);
System.out.println(7 + "");
System.out.println("" + 7);
System.out.println("" + "");
System.out.println(7 + 7 + "");
System.out.println("" + 7 + 7);
System.out.println("Hello World!");
System.out.println("중고나라" + 10 + 20);
System.out.println(10 + 20 + "중고나라");

Java

Java8.0

 7

7

7


14

77

Hello World!

중고나라1020

30중고나라


정수타입 리터럴

​8진수 : 0으로 시작 하는 숫자는 8진수 정수

16진수 : 0x으로 시작한느 숫자는 16진수 정수

10진수 : 0으로 시작하지 않은 보통 수는 10진수 정수

2진수 : 0b로 시작하는 숫자는 2진수 정수


그러므로 15,015,0x15는 다른 의미를 가집니다.

015   =>    8진수로 10진수로 변환하면 13

0x15  =>   16진수로서 10진수로 변환하면 21

15     =>  10진수 15


자바에서 모든 정수 타입 리터럴은 int타입으로 처리합니다. 만일 리터럴을 long 타입으로 하고자 한다면 숫자 뒤에 L또는 l을 붙이면 됩니다.

ex)   24L   ,   3578l


정수 타입 리터럴을 변수와 합계 사용하는 예

1
2
3
4
int n = 15;
int m = 015;
int k = 0x15;
 
cs


실수 타입 리터럴

​실수 타입 리터럴은 부동 소수점을 갖는 수를 표시 합니다. 숫자에 소수점에 찍어 표시하거나 지수(exponent)로 표현 합니다.

12.혹은 12.0

.1234, 0.1234, 1234E-4


자바에서 모든 실수 타입 리터럴은 double 타입으로 처리 합니다. 그러나 숫자뒤에 f또는 F를 붙이면 float타입으로 , d 또는 D를 붙이면 double 타입으로 지정할수도 있습니다.

0.1234, 0.1234d, 0.1234D       =>    double 타입

0.1234f,   0.1234F                  => float 타입


오류발생 예

1
2
3
float w = 0.1234;     //컴파일 오류
float f = .1234F;     //컴파일 정상
double d = 23.45;     //컴파일 정상
cs



문자 타입 리터럴

문자 타입 리터럴은 문자 한개를 표현하는 것입니다.

- 단일 인용부호 (' ') 로 정상적인 문자 하나 표현

 'a','W','가','*','3','글'

-\u 다음에 네자리 16진수로 2바이트의 유니코드 표현

  \u0041 -> 문자 'A' 의 유니코드 (0041)

  \uae00 -> 한글 문자 '글'의 유니코드(ae00)


특수 문자 리터럴도 있습니다. 백슬래스 (\) 다음에 특수 기호를 붙여서 표현하며, 이를 이스케이프 시퀀스(escape ceauence)라고도 합니다.

 

특수문자 리터럴                         의미

      '\b'                             백스페이스

      '\t'                                   탭

      '\n'                          다음 줄로 넘어감

      '\f'                                폼 피드

      '\r'                             캐리지 리턴

      '\"'                            이중 인용부호

      '\''                            단일 인용부호

      '\\'                            백슬래시


****유니코드는 2바이트(16비트) 체계의 전세계의 모든 문자 집합을 표현할수 있도로 만든 산업 표준 코드 체계로 유니코드 현회 가 제정한다. 유니코드에는 ISO 10646문자 집합, 문자 인코딩, 문자 정보 데이터베이스 , 문자를 처리하기 위한 알고리즘 등이 포함 되어있습니다.



논리 타입 리터럴과 boolean 타입

논리 타입 리터럴은 true, false 두개 밖에 없습니다. boolean 타입의 변수가 가질수 있는 값은 참과 거짓 뿐이며, true는 참값을, false는 거짓값을 표현합니다.

1
2
3
boolean b = true;
boolean a = 10>0;     //10>0이 참이므로 true값을 리턴 
 
cs



******기본 데이터 타입 이외의 리터럴

자바 기본 타입 리터럴 외에 자주 사용되는 다음 두가지 리터럴이 있습니다.

1) null 리터럴

null 은 어떠한 레퍼런스 타입의 값으로도 사용될수 있고, 기본 타입을 제외한 어떠한 타입의 변수에도 대입될수 있스비낟.

1
2
3
int n = null;          //오류 기본타입에 null값을 지정할수 없습니다.
String str = null;     //정상
 
cs


2) 문자열 (String) 리터럴

문자열 리터럴은 "Hello"와 같이 이중 인용 부호로 묶어서 표현 합니다.

"Good","Morning","자바","3.19","26","a"

문자열 리터럴은 기본 타입의 리터럴로 오해하는 경우가 있는데 , 자바에서 문자열은 String 클래스의 객체이므로 기본 타입이 아닙니다. 문자열 리터럴은 다음과 같이 String 객체가 저장 하는 값입니다.

1
2
3
4
String str1 = "Welcome";
String str2 = null;
System.out.println(str1);
 
cs

https://m.blog.naver.com/PostView.nhn?blogId=kimkwon429&logNo=220737895687&proxyReferer=https%3A%2F%2Fwww.google.com%2F

'


자바 8 부터 지원되는 것들

  • Lambda Expressions
  Arrays.asList( "a", "b", "d" ).forEach( e -> {
    System.out.println( e )
  });
  • Method References

  • Streams

  • Enhanced Interfaces

  • New Date and Time API



+ Recent posts