Search

반응형

'자바'에 해당되는 글 51건

  1. 2020.05.03 [자바]StringBuffer vs. String 메모리 관리하기.
  2. 2020.04.23 [자바]super, this, super(), this() 키워드에 대해 알아봅니다.
반응형

즐코딩 하고 계시나요?

코딩은 즐겁게 해야 시간도 잘갑니다. ㅎㅎ

이번 포스팅은 StringBufferString 타입에 대해 설명해봅니다.

예전에 자바 초보시절 겪었던 일입니다.

그때는 나름 한다고 생각했지만 사실 초보였지요.

 델파이(Delphi)나 비주얼베이직(VB) 개발자에서 자바로 건너온 지 그리 오래 되지 않았었고,

깊이 있게 자바를 생각하지 않고 사용하던 시절이었네요..ㅋㅋ

여튼 자동으로 HTML을 만드는 프로그램을 만들던 중 문자 데이터를 결합해야 하는데..

그냥 String으로 선언하고 그 변수에 += 로 계속 이어 나갔습니다.

어떤 결과가 나왔을지 여러분은 아시겠죠?

메모리 오버나고 속도 개 느려지고 ㅋㅋ ..

왜 그럴까? 이게 안되는게 말이 되나? 그럼 어쩌란말인가?

라면서 고민하던 중 큰 실수를 했다는 것을 알았답니다.

String 변수에 +나 += 로 계속 문자열을 붙이면 선언한 변수 하나에 붙여지는게 아니라,

새로 메모리를 차지하면서 중복되는 정보가 계속 쌓이는 구조였습니다.

그래서 여러개의 문자열을 대량으로 이어 붙이는 경우 (네트워크 전송 데이터 등)

String으로 사용하면 안되는거에요.

하나의 변수에 대량의 문자열들을 이어 붙이기 위해서는 StringBuffer 클래스의 객체를 이용하면 됩니다.

그러면 단 하나의 객체로 데이터가 쭉 이어져서 붙여집니다.

예를 통해서 StringBuffer 클래스로 객체도 생성하고 해당 메소드의 사용법도 살펴보겠습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
StringBuffer sb1 = new StringBuffer();
 
sb1.append("abcde");
System.out.println(sb1.toString()); 
 
sb1.delete(24);
System.out.println(sb1.toString()); 
 
sb1.deleteCharAt(0);
System.out.println(sb1.toString()); 
 
sb1.insert(0"a");
sb1.insert(2"cd");
System.out.println(sb1.toString()); 
 
System.out.println(sb1.indexOf("c"));
 
System.out.println(sb1.indexOf("f"));
        
System.out.println(sb1.lastIndexOf("d"));
 
sb1.replace(34"234");        
 
System.out.println(sb1.toString());
 
System.out.println(sb1.substring(2));
 
System.out.println(sb1.length());
 
 
StringBuffer sb2 = new StringBuffer();
 
sb2.append("abcdefabcdef");
 
System.out.println(sb2.indexOf("c"));
System.out.println(sb2.indexOf("c"5));
 
System.out.println(sb2.lastIndexOf("c"));
System.out.println(sb2.lastIndexOf("c"8));
System.out.println(sb2.lastIndexOf("c"7));
cs

 

코딩에 필요하면 복사해서 사용하면 됩니다. ^^

우선 StringBuffer 객체를 생성합니다.

 

StringBuffer sb1 = new StringBuffer();

이렇게요.

sb1에 원하는 문자열들을 집어 넣습니다.

 

sb1.append("abcde");

append 메서드는 제일 마지막 부분에 입력한 문자열을 붙입니다.

결과를 확인할 때는 sb1이 객체이므로 toString() 메서드를 이용합니다.

 

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

결과는 "abcde"가 나옵니다.

이 상태에서 sb1.append("fgh");를 하면 제일 뒤에 "fgh"를 붙여서 "abcdefgh"가 됩니다.

 

sb1.delete(24);

delete메소드는 문자열을 삭제하는 기능입니다.

파라메터는 문자열 시작 인덱스에서 삭제하고 싶은 문자열 다음 인덱스로 설정합니다.

(2, 4)로 2에서 시작하니 "c"부터 삭제하면서 4 앞까지 삭제하니 "d"까지 삭제하겠네요.

결과는 "abe"가 나옵니다. 주의할 점은 두번째 파라메터인 4까지가 아니라 4 앞까지입니다.

 

sb1.deleteCharAt(0);

문자 한개의 위치를 지정해서 삭제합니다. 위치 인덱스가 0이므로 "a"만 삭제 됩니다.

 

sb1.insert(0"a");

sb1.insert(2"cd");

insert 메서드는 원하는 위치에 문자 또는 문자열을 추가할 수 있습니다.

두번째 (2, "cd")는 2번 인덱스와 3번 인덱스 사이에 "cd"를 넣는거에요. 3번이 뒤로 밀려납니다.

 

sb1.indexOf("c");

sb1에서 c의 위치 인덱스를 반환합니다. 

결과는 "2"가 나옵니다.

 

sb1.indexOf("f");

"f"를 찾지만 문자열에 없습니다. 

결과가 없는 경우는 "-1"을 리턴합니다.

 

System.out.println(sb1.lastIndexOf("d"));

lastIndexOf 메서드는 "d"를 찾을 때 처음부터 찾는게 아니라 문자열 제일 뒤에서부터 찾습니다.

그리고 위치가 확인되면 위치 인덱스는 앞에서부터 계산해서 보여줍니다.

결과는 "3"이 나옵니다. 

sb1.replace(34"234");

replace 메서드는 지정한 위치에 원하는 문자열을 대체하는 겁니다.

insert는 기존 문자열 사이에 집어 넣지만 replace는 지정한 위치의 문자 대신해서 넣는데 지정한 길이보다 길어도 변환이 됩니다.

결과는 "abc234e"가 나옵니다.

 

sb1.substring(2);

원하는 인덱스 위치를 넣으면 그 위치부터 뒤로 끝까지 문자들을 반환합니다.

결과는 "c234e"가 나옵니다.

 

sb1.length();

문자열 전체 길이를 반환합니다.

결과는 "7"이 나옵니다.

 

sb2.indexOf("c"5);

이 경우는 문자 "c"를 5번째 인덱스부터 찾아서 반환하라는 의미입니다.

결과는 두번째 "c"의 위치인 "8"이 반환됩니다. 첫번째 "c"의 인덱스는 2이지만 5부터 찾으라고 했기 때문입니다.

 

sb2.lastIndexOf("c"8);

이 메서드는 "c"문자를 8번째 문자열부터 시작해서 찾습니다. 두번째 "c"의 위치가 8이기에 두번째 위치인 "8"이 나옵니다.

 

sb2.lastIndexOf("c", 7);

이렇게 7로 바꾸게 되면 8번째 "c"가 포함되지 않기에 2번 인덱스의 "c"가 검색됩니다.

그래서 결과는 "2"가 나옵니다.

네트워크 전송 데이터를 결합하거나 또는 긴 문자열을 다룰 때는 StringBuffer를 사용해보세요.

즐코딩하세요~

 

반응형
반응형

자바를 처음 접한 게 1999년도이니 20년이 훌쩍 넘었네요.

한참 개발을 할때가 jdk1.4였고 다시 한번 되짚어보고 개념 잡기를 위해 공부 중인 노땅 개발자입니다.

처음 객체지향 프로그램을 접하고 공부하면서 super와 this 사용에 혼동이 종종 있었답니다.

개념은 알겠는데 JSP를 이용해 UI쪽 개발을 자주 하던 터라 막상 자주 사용할 일이 없기도 했지만 가끔 사용법에 어려움을 느끼곤 했었답니다.

사실 별거 없는데 말이죠. ㅋㅋ

개념을 다시 잡고 되돌아보는 기분으로 정리해봤습니다.

그럼 시작해보겠습니다.

객체지향 프로그램을 하다 보면 상속을 하게 됩니다. extends 키워드를 사용해서 부모 클래스(슈퍼클래스)를 상속받게 되는 거죠.

super는 현재 슈퍼클래스를 상속받은 서브클래스에서 슈퍼클래스에서 상속받은 클래스 변수와 메서드에 접근하기 위해 사용합니다.

사용법은 super에 .을 붙이고 슈퍼클래스의 메서드를 실행하거나 변수에 값을 할당하면 됩니다.

상속된 변수와 메서드를 활용해서 추상화된 기능을 사용할 수 있는 겁니다.

this는 현재 인스턴스화 된 객체의 자신을 가리키게 됩니다.

사용법은 super와 같습니다.

다음 예를 통해 확인해볼게요.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class TiboySuper {
    protected String item;
    protected int price;
    
    public TiboySuper(String nm, int p) {
        item = nm;
        price = p;
    }
    
    public String getInfo() {
        String rtn = "super : " + item + ", " + price;
        return rtn;
    }
 
}
cs

우선 슈퍼클래스(TiboySuper)를 간단하게 만들었습니다. 

클래스 변수로 item과 price를 정의하고 생성자에서 초기화했습니다.

nm과 p로 입력 파라미터를 선언한 생성자를 직접 만들었습니다.

그리고 getInfo() 메서드를 만들어서 정보 출력을 만들었습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class TiboySub extends TiboySuper {
    protected int cnt;
    
    public TiboySub(String item, int price, int cnt) {
        super(item, price);
        this.cnt = cnt;
        // TODO Auto-generated constructor stub
    }
    
    public String getInfo() {
        String rtn = "sub : " + item + ", " + price + ", " + cnt;
            return rtn;        
    }    
    
    public void showData() {
        System.out.println(super.getInfo());
        System.out.println(this.getInfo());
    }
}
cs

슈퍼클래스인 TiboySuper를 상속받은 서브클래스인 TiboySub클래스입니다.

슈퍼클래스의 두 변수와 메소드 1개를 이어받게 됩니다.

그리고 cnt라는 변수 하나를 추가 선언했네요.

선언된 변수 명인 cnt와 생성자의 파라미터 명인 cnt가 같습니다.

그래서 생성자에서 현재 객체의 변수인 cnt에 파라미터로 넘어온 cnt를 할당해야 하는데 이름이 같기에 this 접근자를 사용하게 됩니다.

슈퍼클래스에서 입력 파라미터 2개를 받은 생성자를 구현했기에 상속받은 서브클래스에서도 호출을 해야 합니다.

그래서 서브클래스의 생성자에서 파라미터를 받고 그대로 슈퍼클래스의 생성자를 super를  사용해 호출했습니다.

또한 showData()를 사용해서 슈퍼클래스의 메서드(super.getInfo())와 서브클래스의 메서드(this.getInfo())를 호출하도록 구현했습니다.

1
2
3
4
5
6
7
8
9
10
public class TiboyTest {
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        TiboySub tSub = new TiboySub("apples"10005);
        
        tSub.showData();
    }
 
}
cs

 

메인 메서드에서 서브클래스의 객체 tSub를 생성 후 인스턴스화 했습니다.

그리고 서브클래스의 showData() 메서드를 호출하게 됩니다.

결과는 어떻게 나올까요?

super : apples, 1000
sub : apples, 1000, 5

예상한 대로 나왔나요?

정리해보겠습니다.

this()는 현재 인스턴스화 된 객체의 생성자를 호출하게 됩니다.

바로 public TiboySub(String item, int price, int cnt) {} 겠지요?

생성자에서 해당 서브클래스의 변수에 접근하기 위해 this.cnt를 사용했습니다.

슈퍼클래스에서 상속받아 재 구현한 서브클래스의 getInfo() 메서드는 이름이 같습니다.

서브클래스의 메서드를 실행하기 위해서는 현재 인스턴스화 된 객체의 메서드임을 표시하는 this.getInfo()로 구현하면 됩니다.

super도 마찬가지입니다.

슈퍼클래스의 생성자를 호출할 때는 super()를 사용하고,

슈퍼클래스의 변수에 접근하기 위해서 super.item으로 사용하면 되고,

슈퍼클래스와 서브클래스의 메서드명이 같지만 슈퍼클래스의 메서드에 접근하기 위해서는 super.getInfo()로 구현하면 됩니다. 물론 상속받은 서브클래스에서 말입니다.

지금까지 사실 별거 아닌 superthis의 사용법에 대해 알아봤습니다.

클래스를 설계하거나 플레인 자바 개발자 또는 서버 개발자라면 당연히 잘 알고 자주 접하게 되는 접근자입니다.

그런 재미있는 프로젝트는 어디에 있을까요? ㅋㅋ

즐 코딩하세요.

반응형