KH/JAVA

# 32 String

오늘의 진 2022. 7. 25. 14:33

 String

 

자바에서 문자열을 저장하는데 사용되는 객체는 String, StringBuilder, stringBuffer 세가지가 있다.

문자는 char cc = 'A' 처럼 작은 따옴표를 사용하지만 문자열은 String str = "seoul" 처럼 큰 따옴표로 처리한다.

프로그램에서 문자열을 많이 사용해 String 클래스는 마치 기본자료형 처럼 사용된다.

String 클래스는 한번 생성되면 변하지 않는 문자열 즉 상수 문자열을 처리하는 클래스이다.(값 변경 불가)

계속 변하는 문자열은 StringBuffer 클래스를 이용해 처리하는것이 좋다. 

자바는 String 클래스를 사용할때 내부적으로 StringBuffer 클래스로 벼형되어 처리한다. 

 

 

[ 문자열 저장 객체비교 ]

종류 특징 성능
String  불변하는 문자열 저장시 사용 가장낮다
StringBuilder 수시로 변하는 문자열 사용시 사용 가장 높다
StringBuffer 다른 스레드간 동기화가 필요한경우 StringBuilder 대신 사용

 

 

(예시)

package ja_0725;

public class String_1 {
	public static void main(String[] args) {

		char[] ss = { 'k', 'o', 'r', 'e', 'a' };

		String str1 = "Hello"; // 문자열대입

		String str2 = new String("java"); // 문자열생성자
		String str3 = new String(ss); // 문자 배열을 이용한 생성자

		System.out.println(ss);
        //원래는 주소값이 나오는데 char 배열은 예외적으로 각 요소가 구분자 없이 그대로 출력됨
        
        
		System.out.println(str1);
		System.out.println(str2);
		System.out.println(str3);
		System.out.println(str1 + str2 + str3);
		System.out.println();
		System.out.println(ss.hashCode());
		System.out.println(str1.hashCode());
		System.out.println(str2.hashCode());
		System.out.println(str3.hashCode());

		String kbs1 = "Hello";
		System.out.println(kbs1.hashCode());
		String kbs2 = new String("Hello");
		System.out.println(kbs2.hashCode());

		// String은 스트링 풀에 저장되어 똑같은 String이 요청된다면 다시만들지 않고 이미 저장된 값을 반환한다.
		// https://velog.io/@jeb1225/JAVA-String-Pool
		System.out.println();
		if (str1 == kbs1) {
			System.out.println("(==)str과 kbs1은 같다.");
		} else {
			System.out.println("(==)st1과 kbs1은 다르다.");
		}

		if (str1.equals(kbs1)) { // equals는 내용비교
			System.out.println("str과 kbs1은 같다.");
		} else {
			System.out.println("st1과 kbs1은 다르다.");
		}

		if (str1 == kbs2) {
			System.out.println("(==)str과 kbs2은 같다.");
		} else {
			System.out.println("(==)st1과 kbs2은 다르다.");
		}

		if (str1.equals(kbs2)) {
			System.out.println("str과 kbs1은 같다.");
		} else {
			System.out.println("st1과 kbs1은 다르다.");
		}

	}
}

 

s2 = new "cat" ;  이렇게 생성된 cat 는 같은 내용이더라도 

String pool 이 아니라 여러개의 객채가 각각 heap 영역에 저장된다. 

hashCode  : 내용이 같으면 같은 수를 보여줌

     equals  : hashCode  즉 내용비교
 == :  주소값 비교 

 

 

 

 

(예시) - String 타입의 연산

package ja_0725;

public class String_2 {
	public static void main(String[] args) {

		int ii = 77;
		float ff = 45.78f;

		String str = "점수 : ";

		System.out.println(str + ii + ',' + ff); // String + 다른타입 = String
		System.out.println(2 + 0 + 2 + 2 + " 년"+2+0+2+2); // 앞에서 부터 연산 즉 int끼리연산이 끝난후 +String
		System.out.println("년도 : " + 2 + 0 + 2 + 2); // String +int 이므로 String으로 연산됨
        //앞에서부터 연산함으로 어디서 부터 시작하는지 순서대로 확인
		
	}

}

 

 

 

 

 

 

(예시) - String 배열의 복사

package ja_0725;

public class String_3 {
	public static void main(String[] args) {
		
		char[] char_str = new char[15];
		
		String str = "오늘 날씨가 참 시원합니다.";
		
		for (int i = 0; i < char_str.length; i++) {
			char_str[i]=(char)(65+i);
		}
		System.out.println();
		for (int i = 0; i < char_str.length; i++) {
			System.out.print(char_str[i]);
		}
		
		System.out.println("\nstr 문자 : "+str);
		System.out.println("str 문자수 : "+str.length());//String에서 문자열의 길이를 알려줌. 메소드임
		
		str.getChars(3, 10, char_str, 0);//3번부터 10 앞번까지가져옴
		//str.getChars(7, 11, char_str, 11); 11번부터들어감  ABCDEFGHIJK참 시원 출력됨
		
		System.out.println("char_str 문자수 : "+char_str.length);
		
		for (int i = 0; i < char_str.length; i++) {
			System.out.print(char_str[i]);
		}	
	}

}

 

 

 

 

 

str.getChars(str에서 복사를 시작할 인덱스 번호, i번 앞까지 복사함, 복사한 것을 집어 넣을 배열 cstr,복사값을 넣기 시작할cstr의 인덱스번호 );

 


▶▶ charAt( )

String str = acbde ; 

str . charAt ( i )     : str의 i번째 인덱스값을 반환

public class String_4 {

	public static void main(String[] args) {

		int i;
		String str = "2022 WorldCup Korea";

		System.out.println("정상 문자열 : " + str);
		System.out.println("문자열 뒤집기 : ");
		for (i = str.length() - 1; i >= 0; i--) {
			System.out.print(str.charAt(i));
		}

		System.out.println("\n 짝수문자열 : ");

		for (int j = 0; j < str.length(); j++) {

			if (j % 2 != 0) {
				System.out.print(str.charAt(j));
			} else {
				System.out.print(" ");
			}
		}
	}
}

 

 

 

 

 

(예시) charAt을 이용하여  배열에서 주민 등록 번호가 남자인지 여자인지 판별하기

package ja_0726;

public class String_5 {
	public static void main(String[] args) {

		String[] joor = { "8003231523645", "8210112523645", "8402162524445", "8612031523645", "8709172553645",
				"9803252453544" };

		System.out.println();

		for (int i = 0; i < joor.length; i++) {

			if (joor[i].charAt(6) % 2 == 0) {
               // joor[i].charAt(6)은 char형 이므로 =='2' 이런식으로 형을 맞춰주어야함
				System.out.println(joor[i] + " : 여자입니다.");
			} else {
				System.out.println(joor[i] + " : 남자입니다.");
			}
		}
	}
}

 

 

 

 

 

(방법2)

package ja_0726;

public class String_5 {
	public static void main(String[] args) {

		String[] joor = { "8003231523645", "8210112523645", "8402162524445", "8612031523645", "8709172553645",
				"9803252453544" };

		System.out.println();

		for (int i = 0; i < joor.length; i++) {

			if (joor[i].charAt(6) == '2' || joor[i].charAt(6) == '4') {
				System.out.println(joor[i] + " : 여자입니다.");
			} else if (joor[i].charAt(6) == '1' || joor[i].charAt(6) == '3') {
				System.out.println(joor[i] + " : 남자입니다.");
			} else {
				System.out.println(joor[i] + " : 사람이 아닙니다.");
			}
		}
	}
}

joor[i].charAt[6] 의 리턴타입은 char 이므로 =="2" 라고 하면 에러가 나온다. 

같은 리턴타입을가지도록 == '2'   이런식으로 작성하여 주어야 한다. 

 

package ja_0726;

public class String_8 {
	public static void main(String[] args) {

		String str = "몇 개의 단어가 포함되어 있나요!";

		int count = 0;

		for (int i = 0; i < str.length(); i++) {
			if (str.charAt(i) == 32) {
            //(str.charAt(i)==' ') 라고해도 된다. 
            // char 은 내부에서 숫자로 바뀜 
				//32는 스페이스바의 아스키코드(str앞뒤에 공백이 없다는 가정하에)
				count++;
			}
		}
		System.out.println("단어의 갯수 : " + (count + 1)); //공백수 +1
	}
}
단어의 갯수 : 5

 

 

 

 

▶▶ startsWith   , endsWith   (리턴타입 : boolean)

 

(예제)

package ja_0726;

public class String_6 {
	public static void main(String[] args) {

		String str = "나는 초보다. 자바 별거 아니네!";

		boolean flag = str.startsWith("나는 고수다!");
		System.out.println(flag);

		flag = str.startsWith("나는");
		System.out.println(flag);

		flag = str.endsWith("별거 아니네");
		System.out.println(flag);

		flag = str.endsWith("별거 아니네!");
		System.out.println(flag);
	}
}

 

 

 

 

 

 

 

 

 

 

▶▶ indexOf ( )  / lastIndexOf ( )  (리턴타입 : int   / 인덱스 번호를 반환한다. )

 

package ja_0725;

public class String_7 {
	public static void main(String[] args) {

		String[] juju = { "9406251623444", "9906254623444", "9606252623444", 
				"9806251623444", "9406253623444","9106252623444" };

		for (int i = 0; i < juju.length; i++) {
			if (juju[i].indexOf("2", 6) == 6 || juju[i].indexOf("4", 6) == 6) {
				System.out.println(juju[i] + "는 여자입니다.");
			} else {
				System.out.println(juju[i] + "는 남남자입니다.");
			}
		}

	}
}
[ indexOf( ) ]
- indexOf(String str)
- indexOf(int ch)  
- indexOf(int ch, int fromIndex) 
- indexOf(String str, int fromIndex)

indexOf( ) 는 특정문자나 문자열이 앞에서부터 처음 발견되는 인덱스를 반환하며 만약 찾지 못했을 경우 "-1"을 반환한다.

 

      . indexOf("찾을 특정문자" , "시작할 위치") 

: 시작할 위치는 생략이 가능하다. (찾은 위치의 인덱스 번호를 반환한다.)

(예)  str = Hello world     

        str.indexOf("o") = 4    /   str.indexOf("o" ,5) = 13

 

[ lastIndexOf( )  ]

- lastIndexOf(String str) 
lastIndexOf(int ch)
- lastIndexOf(int ch, int fromIndex)
- lastIndexOf(String str, int fromIndex)

lastindexOf() 는 특정 문자나 문자열이 에서부터 처음 발견되는 인덱스를 반환하며

만약 찾지 못했을 경우 "-1"을 반환 한다. 사용법은 indexOf와 동일

 

뒤에서부터 찾기 시작해서 찾았을경우 인덱스를 반환하는데

오른쪽에서 몇번째 위치하는지를 반환하는게 아니라 말그래도 인덱스

왼쪽에서 몇번째 위치하는지를 인덱스로 반환한다.

public static void main(String[] args){

		String indexOfTestOne = "Hello world";

		System.out.println( indexOfTestOne.lastIndexOf("o") );  // 7
		System.out.println( indexOfTestOne.lastIndexOf("x") );  // -1
		System.out.println( indexOfTestOne.lastIndexOf("o",5) );  // 4

	}

 

 

(예)

public class String_14 {
	public static void main(String[] args) {

		String str = "높이 나는 새가 멀리 본다. 일찍 나는 새가 모이를 줍는다.";
		System.out.println("검색할 문자열 : \n" + str);
		System.out.println("indexOf(새) : " + str.indexOf("새"));
		System.out.println("indexOf(새,10) : " + str.indexOf("새", 10));
		System.out.println("lastindexOf(새) : " + str.lastIndexOf("새"));
		System.out.println("lastindexOf(새,10) : " + str.lastIndexOf("새", 10));

	}
}

 

 

 

 

 

 

 

 

 

▶▶ concat(  )

문자열 . concat(str) : 현재문자열에 str로 설정된 문자열을 결합한다.

public class String_9 {
	public static void main(String[] args) {

		String str = "민국";
		System.out.println("대한".concat(str));   // 대한민국 출력
		// concat : 현재 문자열에 str로 설정된 문자열을 결합
	}
}

 

(예) equals와 ==

public class String_10 {
	public static void main(String[] args) {

		String str_1 = "korea";
		String str_2 = "korea";

		System.err.println("str_1 :" + System.identityHashCode(str_1));
		System.err.println("str_2 :" + System.identityHashCode(str_2));
		
		System.err.println("str_1 h :" + str_1.hashCode());
		System.err.println("str_2 h :" + str_2.hashCode());
		

		System.out.println("String str_1 = \"korea\" ");
		System.out.println("String str_2 = \"korea\" ");

		if (str_1 == str_2) {
			System.out.println("str_1 == str_2 = true");
		} else
			System.out.println("str_1 == str_2 = false");

		if (str_1.equals(str_2)) {
			System.out.println("str_1.equals(str_2) = true");
		} else
			System.out.println("str_1.equals(str_2) = false");

		System.out.println();

		String str_3 = new String("seoul");
		String str_4 = new String("seoul");

		System.out.println();

		System.out.println("String str_3 = \"seoul\" ");
		System.out.println("String str_4 = \"seoul\" ");

		if (str_3 == str_4) {
			System.out.println("str_3 == str_4 = true");
		} else
			System.out.println("str_1 == str_2 = false");

		if (str_3.equals(str_4)) {
			System.out.println("str_3.equals(str_4) = true");
		} else
			System.out.println("str_3.equals(str_4) = false");
		
		System.out.println();
		
		System.err.println("str_3 :" + System.identityHashCode(str_3));
		System.err.println("str_4 :" + System.identityHashCode(str_4));
		System.err.println("str_3 h :" + str_3.hashCode());
		System.err.println("str_4 h :" + str_4.hashCode());

	}
}

정확한 주소값을 통해 비교해주고자 한다면 haschCode가 아니라 

identityHashCode 를 이용하는 것이 정확하다. 

hashCode를 사용하고자 한다면 오버라이딩 하여 사용하여야함.

 

 

 

 

 

 

 

 

 

 

 

 

 

▶▶ toUpperCase( )  /  toLowerCase()

package ja_0726;

public class String_11 {
	public static void main(String[] args) {

		String str = "Http:Java.Sun.COM";

		System.out.println("원본 : " + str);
		System.out.println("대문자 : " + str.toUpperCase());
		System.out.println("소문자 : " + str.toLowerCase());
	}
}

 

 

▶▶ equalsIgnoreCase (  )

: 대소문자를 무시하고 비교하겠다는 의미

package ja_0726;

public class String_12 {
	public static void main(String[] args) {

		String str_1 = "java";
		String str_2 = "JAva";
		String str_3 = "java";

		System.out.println("문자열 1 :" + str_1);
		System.out.println("문자열 2 :" + str_2);

		System.out.println("JAVA == java : " + ((str_1 == str_2) ? "동일일" : "틀림"));
		System.out.println("JAVA equals java : " + ((str_1.equals(str_2)) ? "동일일" : "틀림"));
		System.out.println("JAVA equalsIgnoreCase java : " + ((str_1.equalsIgnoreCase(str_2)) ? "동일일" : "틀림"));

		System.err.println("str_1 :" + System.identityHashCode(str_1));
		System.err.println("str_2 :" + System.identityHashCode(str_2));
		System.err.println("str_3 :" + System.identityHashCode(str_3));
		System.out.println();
		System.out.println("str_1 : " + str_1.hashCode());
		System.out.println("str_2 : " + str_2.hashCode());
		System.out.println("str_3 : " + str_3.hashCode());

	}
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(예제) String 과 rapperclass

package ja_0726;

public class String_15 {
	public static void main(String[] args) {

		String[] numbers = { "34.5", "21.5","37.5", "45.5", "58.5" };
		String result_1 = "";
		Integer result_2 = 0;
		Double result_3 = 0.0;

		for (int i = 0; i < numbers.length; i++) {

			result_1 += numbers[i] + ", ";
			result_2 += (int) (Double.parseDouble(numbers[i])); 
			//string 타입인 number[i]를 double로 변환하여서 다시 int로 변환
			//int로 변형하니 소숫점 이하 절삭
			result_3 += Double.parseDouble(numbers[i]);
		}

		System.out.println("result_1 : " + result_1);
		System.out.println("result_2 : " + result_2);
		System.out.println("result_3 : " + result_3);
	}
}

 

 

 

 

 

 

 

▶▶ valueOf (  )

package ja_0726;

public class String_16 {
	public static void main(String[] args) {

		double d = 10.3;
		char ch[] = { '오', '늘', '날', '씨', ' ', '온', '도', '는' };

		String str = String.valueOf(ch) + " " + String.valueOf(d);
		System.out.println(str); //오늘날씨 온도는 10.3 출력

	}
}

 

 

▶▶ intern (  )

intern( ) 메소드는 새롭게 만들어진 String 객체를 상수화 시켜준다.

만들어진 String 객체가 이미 상수로 만들어진 문자열이라면, 지금 만들어진 것을 버리고 상수를 가르키게 한다.

즉, Heap에 새롭게 만들어진 객체를 버리고 상수를 재활용 하도록 하게 하는것이다.

 

public class String_17 {
	public static void main(String[] args) {

		String str_1 = "AAA"; // 상수로 만들어짐
		String str_2 = new String("AAA");

		if (str_1 == str_2) {
			System.out.println("str_1 == str_2 = true");
		} else
			System.out.println("str_1 == str_2 = flase");

		System.out.println();
		System.err.println("str_1 : " + System.identityHashCode(str_1));
		System.err.println("str_2 : " + System.identityHashCode(str_2));

		str_2 = str_2.intern();
		// 이미 만들어진 상수인 str_1이 있음으로 지금만들어진 str_2를 버리고 str_1을 가르키게 한다.
		// 즉 str_2는 str_1을 가르게함.

		System.out.println("intern() 메소드 호출 후 \n");

		if (str_1 == str_2) {
			System.out.println("str_1 == str_2 = true");
		} else
			System.out.println("str_1 == str_2 = flase");
	}
}

 

 

 

 

 

 

 

 

 

▶▶ substring (  )  

- 리턴타입 : String

. substring ( int a , intb) ; 

인덱스 번호가 a 인것부터 인덱스 번호가 b것 앞까지(a이상 b 미만) 뽑아오겠다. 

 

(예)  str = abcdefg ; 

        str.substring(2 , 5)    // cde 반환 

package ja_0726;

public class String_18 {
	public static void main(String[] args) {

		String[] fullName = { "Korea.java", "seoul.com", "abc12345.789", "789asd.xyz", "king.queen" };

		for (int i = 0; i < fullName.length; i++) {

			// '.'의 위치를 찾는다.
			int index = fullName[i].indexOf('.');
			System.out.println(index);

			// fullName의 첫번째 글짜부터 '.'이 있는 곳 까지의 문자열을 추출
			String fileName = fullName[i].substring(0, index); //index앞까지 추출

			// '.' 다음 문자부터 시작 문자열 끝까지 추출
			String ext = fullName[i].substring((index + 1), fullName[i].length());

			System.out.println(fullName[i] + "의 확장자를 제외한 이름 : " + fileName);
			System.out.println(fullName[i] + "의 확장자 : " + ext);
			System.out.println();

		}
	}
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(예) 주민등록번호로 남녀 판별하기.

package ja_0726;

public class Test26 {
	public static void main(String[] args) {

		String[] joomin = { "9003231523645", "9821011252364", "9402162524445",
				"9612031523645", "9909172553645","9803232345322" };

		for (int i = 0; i < joomin.length; i++) {

			String id = joomin[i].substring(6, 7);

			if (id.equals("2")) {
				System.out.println(joomin[i] + ": 여자입니다.");
			} else if (id.equals("1")) {
				System.out.println(joomin[i] + ": 남자입니다.");
			} else {
				System.out.println("사람이 아닙니다.");
			}
		}
	}
}

주의할점 : 문자열 끼리 비교할떄는 equals 를 이용한다. 

 

 

▶▶compareTo (  )  & 셀렉션 정렬

- 내림차순정렬 / 오름차순 정렬

-리턴타입 int

eng[i].compareTo(eng[j]) i번에서 j번을 뺀값

두개의 String형의 정렬했을때의 순서를 기준으로 빼준다.

compare(여기는 string형만 올 수 있다.)  즉, 문자열을 정렬상 순서를 비교할때 사용한다. 

 

(예제) - 문자열의 내림차순정렬

package ja_0726;

public class Sort_1 {
	public static void main(String[] args) {

		String[] eng = { "사랑", "자바", "Love", "LOVE", "愛" };

		System.out.println("\n************   정렬전 문자열   ************");

		for (int i = 0; i < eng.length; i++) {
			System.out.print(eng[i] + "\t");
		}

		System.out.println("\n\n************   정렬후 문자열   ************");
		// 셀렉션 정렬
		// 내림차순 정리
		for (int i = 0; i < eng.length-1; i++) {
			for (int j = i + 1; j < eng.length; j++) {
				if (eng[i].compareTo(eng[j]) < 0) {
					// 리턴타입 : int
					// eng[i].compareTo(eng[j]) i번에서 j번을 뺀값
					// 오름차순은 >0으로 해주면된다.
					String temp = eng[i];
					eng[i] = eng[j];
					eng[j] = temp;
					// 뺀값이 <0 이면 i번칸이랑 j번 칸의 값을 바꿔라
				}
			}
		}

		for (int i = 0; i < eng.length; i++) {
			System.out.print(eng[i] + "\t");
		}

	}

}

 

(예) - 숫자의 오름차순 정렬

package ja_0726;

public class Test26 {
	public static void main(String[] args) {

		int[] num = { 78, 66, 43, 89, 94, 54, 37 };

		System.out.println("===========전==============");
		for (int i = 0; i < num.length; i++) {
			System.out.print(num[i] + "\t");
		}
		System.out.println();

		System.out.println("===========후==============");

		for (int i = 0; i < num.length-1; i++) {
                                //num.length까지 돌려도 되지만 필요없는 한번이 돈다.
			for (int j = i + 1; j < num.length; j++) {

				if (num[i] - num[j] > 0) {
					int temp = num[i];
					num[i] = num[j];
					num[j] = temp;
				}
			}
		}

		for (int i = 0; i < num.length; i++) {
			System.out.print(num[i] + "\t");
		}
	}
}

 

<셀렉션 정렬의 포인트>

 오름차순정렬 내림차순정렬
for (int i = 0; i < num.length-1; i++) {
for (int j = i + 1; j < num.length; j++) {

if (num[i] - num[j] > 0) {
                      
int temp = num[i];
num[i] = num[j];
num[j] = temp;

}
}
}
for (int i = 0; i < num.length-1; i++) {
for (int j = i + 1; j < num.length; j++) {

if (num[i] - num[j] < 0) {
                     
int temp = num[i];
num[i] = num[j];
num[j] = temp;

}
}
}
 num[i]-num[j] > 0 일때 if문이 작동하는데
if문은 num[i]안의 내용과 num[j]안의 내용의 자리를 바꿔준다. 
즉 j가 더 작을떄 작용해서 크기가 작은 j를 앞으로 보내줌
오름차순 정렬을 하게한다. 
num[i]-num[j] <0 일때 if문이 작동하는데
if문은 num[i]안의 내용과 num[j]안의 내용의 자리를 바꿔준다. 
즉 j가 더 클떄 작용해서 크기가 큰 j를 앞으로 보내줌
내림차순 정렬을 하게한다. 

 

'KH > JAVA' 카테고리의 다른 글

# 34 Math.random( ) , Random Class  (0) 2022.07.27
# 33 StringBuffer , StringTokenizer  (0) 2022.07.27
# 31 Wrapper Class  (0) 2022.07.25
# 29 동기화( Synchronization ) / ATM 만들기  (0) 2022.07.22
# 28 Thread (쓰레드)  (0) 2022.07.20