String

-String은 불변의 속성을 갖는다.

-String클래스는 불변하기 때문에 문자열을 수정하는 시점에 새로운 String인스턴스가 생성된다.

-문자열의 빈번한 추가, 수정, 삭제의 연산이 이루어지면 Heap영역에 많은 임시의 Garbage가 생성되며,

  Heap Memory부족으로 인한 어플리케이션 성능 저하로 이어진다.

 

 

StringBuilder / StringBuffer

-이러한 String의 문제를 해결하기 나온 것이 StringBuilder와 StringBuffer이다.

-StringBuilder와 StringBuffer 클래스는 가변의 속성을 갖는다.

-append(), delete()와 같은 메서드를 이용하여 동일한 객체내에서 문자열을 변경할 수 있다.

-문자열의 빈번한 추가, 수정, 삭제와 같은 연산을 할 때는 StringBuilder와 StringBuffer를 사용하는것이 유리하다.

 

 

StringBuilder VS StringBuffer

<StringBuilder>

-StringBuilder와 StringBuffer의 차이는 동기화의 유무이다.

-StringBuilder는 동기화를 지원하지 않아 멀티쓰레드 환경에서 사용하는 것은 적합하지 않지만 단일쓰레드 환경에서는   StringBuffer보다 뛰어나다.

 

<StringBuffer>

-StringBuffer는 동기화를 지원하여 멀티쓰레드 환경에서 안전성을 가지고 있다.

Array

Array는 고정 길이의 배열로서 초기화시 배열의 크기를 지정한다. 배열을 초기화시 메모리가 할당되어 

속도가 빠르다는 장점이 있다. 또한 데이터의 순서가 있고 또 데이터의 중복을 허용한다.

 

public static void main(String []args) {
		int [] arr  = new int[5];
		arr[0] = 1;
		arr[1] = 5;
		arr[2] = 3;
		arr[3] = 1;
		arr[4] = 6;
		
		for(int i=0; i<arr.length; i++) {
			System.out.println("Array의 "+ i + "번째 데이터 : "+arr[i]);
		}
}        
        
Array의 0번째 데이터 : 1
Array의 1번째 데이터 : 5
Array의 2번째 데이터 : 3
Array의 3번째 데이터 : 1
Array의 4번째 데이터 : 6

 

 

ArrayList

ArrayList는 List 컬렉션 인터페이스의 한 종류로서 배열의 크기를 실행 타임에 정하는 가변 길이를 갖는 배열이다.

그렇기 때문에 메모리가 재할당되어 Array의 비해 속도가 느리다는 단점이 있다.

또한 Array와 마찬가지로 데이터의 순서가 있으며 데이터의 중복을 허용한다.

 

List <Integer> arrList = new ArrayList<>();
		arrList.add(5);  //add 데이터 입력
		arrList.add(5);
		arrList.add(7);
		arrList.add(20);
		
		
		arrList.set(0, 100); //set 데이터 수정
		arrList.set(1, 200);
		arrList.remove(3); //remove 데이터 삭제
	
		for(int i=0; i<arrList.size(); i++) {
			System.out.println("ArrayList의 "+ i +"번째 데이터" + arrList.get(i));
		}
ArrayList의 0번째 데이터100
ArrayList의 1번째 데이터200
ArrayList의 2번째 데이터7

우선 ==는 객체의 주소값을 비교한다. 

 

예를들어 

 

String a = "java";

String b = a;

String c = new String("java"); 가 있다고 본다면 우선  

 

a == b의 결과는 true이다. 왜냐하면 ==는 주소값을 비교한다고 했는데 String b= a 라고 선언해놨기 때문이다.

그렇다면 a == c는 어떤 결과가 나올까 ? 결과는 false이다.

 

이유는 String a = "java"; 와 String c = new String("java"); 는 서로 저장되는 위치가 다르기 때문이다.

우선 우리가 자주 사용하는 String a = "java"와 같은 리터럴 방식은 Heap영역의 String constant pool이라는 리터럴 상수값을 저장하는 공간에 저장이되고

String c = new String("java");는 Heap영역에 저장이되기 때문에 서로 저장되는 주소값이 다르다.

 

즉!  a와 b는 같으므로 임의의 주소값 100을 할당받고 c는 임의의 주소값 200을 할당받아 

a=b //true 

a=c //false

b=c //false 라는 결과가 나오게 된다.

 

또한

 

String str1 = "hello";

String str2 = "hello"; 가 있다고 했을 때 

 

str1==str2는 어떤 결과가 나올까? 결과는 true이다.

==연산자는 주소값을 비교한다고 했는데 true라는 결과가 나온 이유는 String은 불변성(Immutable)이라는 성질을 가지고 있기 때문이다. 즉 같은 값의 문자열에 대해서는 단 하나의 문자열 객체만을 생성하도록 설계 되어있기 때문이다.

 

또한 Java의 Heap영역에는 String객체들을 관리하는 String pool이라는 영역이 있다. 이 String객체를 생성하면

String pool에 기존에 같은 값을 가지고 있는 String 객체가 있는지 검사를 한다. 만약 같은 값을 가진 객체가 있다면 그 객체의 참조값을 리턴하고 같은 값을 가진 객체가 없다면 새로운 String객체를 생성하고 그 참조값을 리턴한다.

 

다음은 equals이다.

equals는 객체의 내용, 즉 값을 비교하는 메서드이다.

 

아까와 같이 

String a = "java";

String b = a;

String c = new String("java"); 가 있다고 본다면

 

a.equals(b) // true  

a.equlas(c) // true

c.equals(b) // true

 

값은 모두 "java"로 동일하므로 eqauls()메서드로 비교했을 때 모두 true가 출력되는 것을 확인할 수 있다.

 

 

<결론>

 

*String은 불변성(immutable)속성을 가짐 ->  같은 값의 문자열에 대해서는 단 하나의 문자열 객체만을 생성

 

*String a = "hello" -> Heap영역의 String Constant Pool(리터럴 상수값을 저장하는 곳)에 저장

*String b = new String("world!") -> Heap영역에 저장

 

*== -> 객체의 주소값을 비교

*equals() -> 객체의 값(내용)을 비교

 

 

Call By Value(CBV)

 

- CBV는 기본적으로 대상에 주소값을 가지지 않는 것으로 값을 할당받는 형태로 사용한다.

- int, float, double, byte와 같은 primitive type(기본형 타입)에 해당.  -> 실제값은 Stack 메모리에 저장됨!

- 예를들어 int p1 = 1 이라고 했을 때 메소드에 인자를 받을 때 p의 주소값을 받는 것이 아닌 p의 값 1을 직접

  받는 것을 말한다.   

 

 

Call By Reference(CBR)

 

- CBR은 대상을 선언했을 때 주소값이 부여가 되는데 어떤 객체를 호출했을 때 그 객체의 주소값을 불러온다.

- String, Array, Date, file, Class, Object와 같은 Reference Type(참조형 타입) -> 주소값은 Heap 메모리에 저장됨!

 

'JAVA' 카테고리의 다른 글

[JAVA] Array와 ArrayList의 차이  (0) 2021.03.12
[JAVA] == 와 equals의 차이점  (0) 2021.03.11
[JAVA] 쓰레드(Thread) 네모박스 튕기기 - 3  (0) 2020.10.03
[JAVA] 쓰레드(Thread) -2  (0) 2020.10.03
[JAVA] 쓰레드(Thread) -1  (0) 2020.10.03
package Thread;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Random;

public class ThreadRectDraw extends Frame implements Runnable {
	int x = 0;
	int y = 20;
	boolean xOrient, yOrient;
	Random ran;

	public ThreadRectDraw(String title) {
		super(title);
		ran = new Random();
		setSize(300, 300);
		setVisible(true);
		addWindowListener(new WindowAdapter() {
			public void windowClostin(WindowEvent e) {
				System.exit(0);
			}
		});
	}

	public void paint(Graphics gr) {
		Dimension d = this.getSize();
		if (xOrient) {
			x--;
			if (x < 0) {
				x = 0;
				xOrient = false;
			}
		} else {
			x++;
			if (x >= d.width - 20) {
				x = d.width - 20;
				xOrient = true;
			}
		}
		if (yOrient) {
			y--;
			if (y < 0) {
				y = 0;
				yOrient = false;
			}
		} else {
			y++;
			if (y >= d.height - 20) {
				y = d.height - 20;
				yOrient = true;
			}
		}
		int r = ran.nextInt(255);
		int g = ran.nextInt(255);
		int b = ran.nextInt(255);
		gr.setColor(new Color(r, g, b));
		gr.drawRect(x, y, 20, 20);

	}

	public void update(Graphics g) {
		paint(g);
	}

	@Override
	public void run() {
		while (true) {
			repaint();
			try {
				Thread.sleep(5);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ThreadRectDraw thread = new ThreadRectDraw("ThreadRect");
		Thread task = new Thread(thread);
		task.start();

	}

}

 

'JAVA' 카테고리의 다른 글

[JAVA] == 와 equals의 차이점  (0) 2021.03.11
[JAVA] Call By Value / Call By Reference  (0) 2021.03.11
[JAVA] 쓰레드(Thread) -2  (0) 2020.10.03
[JAVA] 쓰레드(Thread) -1  (0) 2020.10.03
[JAVA] IO (FileInputStream) (3)  (0) 2020.10.01

1)java.lang.thread 클래스 사용

public class ThreadEx extends Thread {

	public void run() {
		while(true){
			try {
			Thread.sleep(1000);
			}catch(InterruptedException e) {
				e.printStackTrace();
			}
 			System.out.println("쓰레드 테스트..");
 		}
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ThreadEx thread = new ThreadEx();
		thread.start();
		System.out.println("main 실행");

	}

}

이 코드는 쓰레드 사용법 중 java.lang.Thread 클래스를 사용한 코드이다. 

우선 extends Thread로 스레드를 상속받고 쓰레드를 사용하고 싶은 곳에 run()메소드로 오버라이딩을 한다.

그 후 해당 클래스 인스턴스를 생성하고 클래스 객체의 start()메소드로 호출한다.

 

여기서 Thread.sleep(1000)은 스레드를 잠시 일시 중단시키는 메서드인데 1000은 1초를 나타낸다.

이렇게 해서 코드를 실행시키게 되면 run메소드에 있는 "쓰레드 테스트.."가 1초 간격으로 계속 출력된다.


2. Runnable 인터페이스 사용

package Thread;

public class ThreadEx3 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Thread thread = new Thread(new Runnable() {
			public void run() {
				while(true) {
					try{
						Thread.sleep(100);
					}catch(InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("실행단위");
				}
			}
		});
		thread.start();
	}
}

Runnable 인터페이스를 구현한 클래스를 정의하고 구현하고 싶은 코드를 run() 메소드 안으로 넣는다. 

클래스 객체를 Thread클래스 생성자의 매개변수로 넘겨서 새로운 스레드 객체를 만들고 그 객체에서 start()메소드를 호출한다. 

+ Recent posts