2011년7월27일_JAVA String Class, toString(), charAt(), equals(), substring() 메소드를 사용한 예제4개




● String Class로 객체를 만드는 법과 초기화

① String str = new String( ); 
    str = “Hello”;
② String str = new String(“Hello”);
③ String str = “Hello”;

①번은 new(C언어에서 malloc( )와 비슷)를 사용해 메모리 heap영역에 객체를 생성하고,
         메모리 String영역에 객체가 들어갈 공간을 가리키도록 하고 그 heap영역의 객체를 레퍼런스변수가 가리키도록 한다.
         ( Stack영역의 str → heap영역의 String객체(?) → String영역 )
         이렇게 생성된 String영역의 객체는 아무런 값도 가지고 있지 않는다. 
         str을 통해 String영역에 있는 객체(문자열)를 연결하고 싶으면 상기와 같이 문자열 연결 연산자 ‘=’를 사용하여 연결한다.

②번은 String Class의 생성자를 이용해 객체를 생성한 뒤에 레퍼런스변수 str에 연결하여 초기화까지 한 줄에 끝낸다.

③번은 메모리 String영역에 있는 객체를 Stack영역에 있는 레퍼런스변수 str이 바로 가르키도록 하여,
         ②번과 같이 객체의 생성과 초기화를 한 번에 하는 방법이다.




● J2SE 6 documentation에서 Class String에는 어떤 메소드가 있는지 알아보자.


image <- 클릭하여 도움말을 열자.

도움말 파일이 없는 분들은 http://www.allimant.org/javadoc/ 에서 다운받으세요.




image

색인을 클릭하여 string을 입력하면 String클래스에 대한 설명과 인터페이스를 알 수 있다.
구글번역의 힘을 빌리면..

The String class represents character strings. All string literals in Java programs, such as "abc", are implemented as instances of this class.
“String 클래스는 문자 문자열을 나타냅니다. 예 : "ABC"로 Java 프로그램, 모든 문자열 리터럴이 클래스의 인스턴스로 구현됩니다.”

리터럴은 이름이 없는 상수(컴퓨터는 문자도 숫자)이고,
인스턴스는 일반적으로 어떤 집합에 대해서, 그 집합의 개별적인 요소. 객체 지향 프로그래밍(OOP)에서, 어떤 등급에 속하는 각 객체를 인스턴스라고 한다. 예를 들면 ‘목록(list)’이라는 등급을 정의하고 그 다음에 ‘본인 목록(my list)’이라는 객체를 생성(기억 장치 할당)하면 그 등급의 인스턴스가 생성된다. 또한 변수가 포함되어 있는 어떤 논리식의 변수에 구체적인 값을 대입하여 식을 만들면 원래 식의 인스턴스가 만들어진다. 이런 의미에서 인스턴스를 실현치라고 한다.  - 네이버지식백과

뭔가 더 아리송하다. –_-;



● 자주 사용하는 메소드들

image
image

charAt( )은 객체의 index – 1번째 문자만 잘라내 반환한다.
              신기한 점은 한글 2Bytes나 영문 1Bytes 모두 한 글자로 취급한다는 점이다.
              (C언어에서와 같이 생각하면 안 되겠다.)
compareTo( )는 현재 객체(문자열)와 다른 객체(문자열)를 비교하는 메소드이다.
concat( )에 대한 번역은 댓글을 달아주세요. :D
format( )은 sprintf( )와 비슷하게 문자열을 일정형식에 맞춰 주는 메소드인듯하다.




● 예제1

   1: // 20110727 
   2: package kr.ac.busanit;
   3:  
   4: class A {
   5:     
   6: }
   7:  
   8: public class StringTest1 {
   9:     public static void main(String[] args) {
  10:         // TODO Auto-generated method stub
  11:         String str = new String("Hello JAVA");        //객체생성과 동시에 초기화
  12:         String str4 = new String();                    //객체만 생성.
  13:         
  14:         //System.out.println(str4.charAt(0));  //이렇게 하면 에러남.
  15:                 
  16:         for(int i = 0 ; i < str.length(); i++) {    //한 글자씩 출력.
  17:             System.out.println(str.charAt(i));
  18:         }
  19:         
  20:         //해쉬코드확인
  21:         StringTest1 st1 = new StringTest1();        //객체만 생성.
  22:         System.out.println(st1.toString());            //객체가 가진 값을 문자열로 바꾸어 출력.
  23:         
  24:         A a = new A();                                //Class A 객체 a 생성.
  25:         System.out.println("a: " + a.toString());    //해쉬코드를 16진수로 출력.
  26:         System.out.println("a: " + a.hashCode());    //해쉬코드를 10진수로 출력.
  27:         A b = new A();                                //Class A 객체 b 생성.
  28:         System.out.println("b: " + b.hashCode());    
  29:         A c = new A();
  30:         System.out.println("c: " + c.hashCode());
  31:         
  32:         //해쉬코드가 같은 예
  33:         String str1 = new String("Java");
  34:         System.out.println("str1: " + str1.hashCode());
  35:         String str2 = new String("Java");
  36:         System.out.println("str2: " + str2.hashCode());
  37:         String str3 = new String("Java");
  38:         System.out.println("str3: " + str3.hashCode());        
  39:         //해쉬코드가 다른 예
  40:         String str5 = new String("Java1");
  41:         System.out.println("str5: " + str5.hashCode());
  42:         String str6 = new String("Java2");
  43:         System.out.println("str6: " + str6.hashCode());
  44:         String str7 = new String("Java3");
  45:         System.out.println("str7: " + str7.hashCode());        
  46:     }
  47: }


<실행결과>

image


<설명>

a, b, c, str, str1~7은 모두 객체가 아닌 레퍼런스 변수이다.
a, b, c는 class A틀에 찍은 객체로 모두 고유번호(해퀴코드)를 가지고 있어 각각 다르고,
str1~3은 같은 하나의 객체를 참조하고 있는 객체를 가리킨다.
생성자에 각기 다른 문자를 넣은,
str5~7은 서로 다른 객체를 참조하고 있는 객체를 가리킨다.

☆ hashcode는 JVM이 class를 실행할 때 부여하는 고유한 ID와 같은 숫자이다.


● 예제2 

   1: // 20110727
   2: package kr.ac.busanit;
   3:  
   4: public class StringTest2 {
   5:     public static void main(String[] args) {
   6:         // TODO Auto-generated method stub
   7:         String str1 = "자바";
   8:         String str2 = "자바";
   9:         
  10:         System.out.println(str1.hashCode());
  11:         System.out.println(str2.hashCode());
  12:         
  13:         if(str1 == str2)
  14:             System.out.println("같음");
  15:         else
  16:             System.out.println("다름");        
  17:  
  18:         if(str1.equals(str2))
  19:             System.out.println("같음");
  20:         else
  21:             System.out.println("다름");    
  22:     }
  23: }

<실행결과>

image


<설명>

image

str1과 str2는 모두 메모리 stack영역에 위치하고 있고, 선언과 동시에 메모리 String영역의 문자열 “자바” 객체를 가리킨다.
모두 같은 값을 가지고 있으니 수치비교연산자로 비교하면 논리값이 참(true)이 된다.
equal( ) 메소드를 사용해도 가리키는 곳의 해쉬코드가 동일하므로 비교하면 논리값이 참(true)이 된다.



● 예제3

   1: // 20110727
   2: package kr.ac.busanit;
   3:  
   4: public class StringTest3 {
   5:     public static void main(String[] args) {
   6:         String str1 = new String("자바");
   7:         String str2 = new String("자바");
   8:                         
   9:         System.out.println(str1.hashCode());
  10:         System.out.println(str2.hashCode());
  11:         
  12:         if(str1 == str2)                //heap영역의 객체가 가리키는 곳의 문자열은 같으나
  13:             System.out.println("같음");    //stack영역의 레퍼런스변수의 값은 다르다.
  14:         else
  15:             System.out.println("다름");
  16:         
  17:         if(str1.equals(str2))            //equals메소드는 해쉬코드가 같은가 비교하는 함수
  18:             System.out.println("같음");
  19:         else
  20:             System.out.println("다름");
  21:         
  22:         StringBuffer sb1 = new StringBuffer("자바");
  23:         StringBuffer sb2 = new StringBuffer("자바");
  24:         
  25:         System.out.println(sb1.hashCode());
  26:         System.out.println(sb2.hashCode());
  27:         
  28:         if(sb1.equals(sb2))                //equals메소드는 해쉬코드가 같은가 비교하는 함수로
  29:             System.out.println("같음");    //만약 내용을 비교한다면 같다는 결과가 나와야 하나,
  30:         else                            //결과를 보면 다르다.
  31:             System.out.println("다름");    //해쉬코드가 다르기 때문에 이런 결과가 나온다.
  32:     }
  33:  
  34: }



<실행결과>

image


<설명>

image


메모리 String영역에 있는 문자열 “자바” 객체가 있으면,
new를 통해 메모리 heap영역에 그 객체를 가리키는 객체1과 객체2를 생성하고 객체를 가리킨다.
그 다음 메모리 stack영역에 레퍼런스 변수들을 생성하고 각 객체를 가리키도록 한다.

단순히 수치비교연산자를 사용해 레퍼런스 변수들을 비교하면 서로 다른 값을 가지고 있으므로 논리값이 거짓(false)가 된다.
equals( ) 메소드를 사용해 비교를 하면 최종적으로 가리키고 있는 String영역의 객체의 해쉬코드는 동일하므로 참(true)이 된다.

equals( ) 메소드가 내용을 비교하는 메소드가 아니란 것을 증명하기 위해...
StringBuffer클래스로 객체를 만들어 equals( )메소드로 해쉬코드가 다른 객체를 비교하니 논리값은 거짓(false)이 되었다.
즉, equals( )메소드는 내용을 비교하는 메소드가 아니라 해쉬코드가 같은지 알아보는 메소드이다.

☆ 책을 100% 믿지 말고 참고만 하자.
    이런 equals( ) 메소드와 같은 문제는 의심이 가면 직접 실험을 해보자. (아직은 기초지식이 부족해 조금 무리일듯함.)


● 예제4

   1: // 20110727
   2: package kr.ac.busanit;
   3:  
   4: public class StringTest4 {
   5:     public static void main(String[] args) {
   6:         // TODO Auto-generated method stub
   7:         String str = "뇌를 자극하는 자바";
   8:         
   9:         System.out.println(str.substring(3));
  10:         System.out.println(str.substring(3, 7));
  11:         System.out.println(str.charAt(9));
  12:         
  13:         str = "뇌를 자극하지 않는 자바";
  14:         
  15:         System.out.println(str);
  16:     }
  17: }

<실행결과>

image


<설명>

image

문자열의 인덱스는 0부터 시작하는 것에 주의하고,
substring( ) 메소드의 사용법은…


substring
public String substring(int beginIndex,
                        int endIndex)
Returns a new string that is a substring of this string. The substring begins at the specified beginIndex and extends to the character at index endIndex - 1. Thus the length of the substring is endIndex-beginIndex.

Examples:

 "hamburger".substring(4, 8) returns "urge"
 "smiles".substring(1, 5) returns "mile"
Parameters:
beginIndex - the beginning index, inclusive.
endIndex - the ending index, exclusive.
Returns:
the specified substring.
Throws:
IndexOutOfBoundsException - if the beginIndex is negative, or endIndex is larger than the length of this String object, or beginIndex is larger than endIndex.



뭔가 복잡해 보인다.
간단히 인자를 하나만 넣으면 그 인덱스의 문자부터 문자열의 끝까지 반환하고,
         인자를 두 개 넣으면 첫 인자의 인덱스부터 두 번째 인자의 인덱스까지 문자열을 잘라내 반환한다.