문자열 (String) 관련 메소드들
https://docs.oracle.com/javase/8/docs/api/java/lang/String.html
- 문자열 메소드는 꼭 정독해보세요.
- 매개변수의 의미, 동작의 의미, 리턴값의 의미 꼭 숙지해주세요
- 인스턴스 메소드 인지, 클래스 메소드(static)인지 구분
package com.lec.java.string01;
import java.util.Arrays;
import java.util.Scanner;
/* 문자열 (String) 관련 메소드들
*
* https://docs.oracle.com/javase/8/docs/api/java/lang/String.html
* - 문자열 메소드는 꼭 정독해보세요.
* - 매개변수의 의미, 동작의 의미, 리턴값의 의미 꼭 숙지해주세요
* - 인스턴스 메소드 인지, 클래스 메소드(static) 인지 구분
*/
public class String01Main {
public static void main(String[] args) {
System.out.println("String 클래스의 메소드들");
String str1 = "AbCdEfg";
String str2 = "안녕하세요~";
System.out.println();
System.out.println("length()"); // 문자의 개수
System.out.println("str1 길이: " + str1.length());
System.out.println("str2 길이: " + str2.length());
System.out.println();
System.out.println("concat()"); // 문자열 연결 (concatenation)
System.out.println(str1.concat(str2));
System.out.println(str2.concat(str1));
System.out.println(str1.concat(str2).concat(str1));
// ★주의★
// 문자열(String) 은 변경불가(immutable) 이기 때문에
// 메소드 수행했다고 하여 원본이 변경되지 않는다.
str1.concat(str2);
System.out.println(str1); // <-- str1 은 변경 안되었다.
str1 = str1.concat(str2); // <-- 변경하려면 이와 같이 덮어쓰기 해야 한다.
System.out.println(str1);
// ★주의★
// empty 문자열과 null 은 다르다
// null 인 경우 메소드 수행하면 NullPointerException 발생!
String str3 = ""; // empty 문자열, 문자열 객체가 존재하나 비어있는 문자열
System.out.println(str3.length());
str3 = null; // null, 문자열 객체가 존재하지 않음.
// System.out.println(str3.length()); // NullPointerException (NPE)
System.out.println();
System.out.println("charAt(index)"); // 문자열 안의 특정위치(index)의 문자 리턴, 인덱스 범위 벗어나면 StringIndexOutOfBoundsException
// 문자열 인덱스는 0 부터 시작!
System.out.println(str1.charAt(0));
System.out.println(str1.charAt(1));
// System.out.println(str1.charAt(20)); // StringIndexOutOfBoundsException
System.out.println();
System.out.println("indexOf(char), indexOf(String)"); // 문자열 안에서 특정 문자(char) 혹은 문자열(String)의 위치(index), 발견 못하면 -1 리턴
System.out.println(str1.indexOf('C'));
System.out.println(str1.indexOf('c')); // -1
System.out.println(str2.indexOf('요'));
System.out.println(str2.indexOf("하세"));
System.out.println();
System.out.println("toUpperCase(), toLowerCase"); // 대문자 변환, 소문자 변환
System.out.println(str1.toUpperCase());
System.out.println(str1.toLowerCase());
System.out.println();
System.out.println("startWith()"); // 문자열이 주어진 prefix문자열로 시작하는지 여부 true/false 리턴
String prefix = "http://";
String url = "www.google.com";
System.out.println(url.startsWith(prefix));
if(!url.startsWith(prefix)) {
String newUrl = prefix.concat(url);
System.out.println(newUrl);
}
// endsWith(postfix)
System.out.println();
System.out.println("split(regex)"); // 문자열을 주어진 문자열로 쪼개어 String[] 리턴
String str4 = "HH:MM:SS";
String [] strings = str4.split(":");
System.out.println(Arrays.toString(strings));
// 공백기준으로 쪼갤때는 정규표현식의 \s+ 사용하기 : 공백, 탭, 줄바꿈
str4 = " Hello\t \n \t My \n\n World";
strings = str4.split("\\s+");
System.out.println(Arrays.toString(strings));
// 단! "|" 을 할경우는 주의, ※ split(정규표현식) 을 사용하는 메소드임
String str5 = "HH|MM|SS";
// strings = str5.split("|"); // <-- 이렇게 하면 결과 이상해진다. (내부적으로 "|"는 정규표현식에서 boolean (OR)와 같은 동작함. 따라서 아래와 같이 escaping 해야 함)
strings = str5.split("\\|");
System.out.println(Arrays.toString(strings));
// String.join()
// 문자열들, 문자열 배열 --> 하나의 문자열로 합하기 split() 과 반대
System.out.println();
System.out.println("String.join(delimeter, elements ...)");
String[] str7 = {"Alice", "Bob", "Carol"};
System.out.println(String.join("-", str7));
System.out.println();
System.out.println("substring(beginIndex, endIndex)"); // 문자열의 일부분 추출 beginIndex ~ endIndex직전 까지, 인덱스 범위 벗어마면 IndexOutOfBoundsException
String str8 = "Hello Java";
System.out.println(str8.substring(2, 5)); // 2 부터 5전까지
System.out.println(str8.substring(6)); // 6 부터 끝까지
System.out.println();
System.out.println("trim()"); // 좌우의 여백 제거
String str9 = " 김동후 ";
System.out.println("[" + str9 + "]");
System.out.println("[" + str9.trim() + "]");
System.out.println();
System.out.println("replace(target, replacement)"); // 문자열 치환 target → replacement
String str10 = "Hello Language My Language";
System.out.println(str10.replace("My", "Our"));
System.out.println(str10.replace("Language", "Java")); // 매칭되는 것 모두 치환
System.out.println();
System.out.println("replaceAll(regex, replacement), replaceFirst(regex, replacement)"); // 정규표현식 사용버젼 , replaceAll() 매칭되는것 전부 치환, replaceFirst() 첫매칭만 치환
System.out.println(str10.replaceAll("Language", "자바")); // 매칭되는것 전부 치환
System.out.println(str10.replaceFirst("Language", "자바")); // 첫번째 매칭만 치환
System.out.println();
System.out.println("equals(), equalsIgnoreCase()"); // 문자열 비교
String str11 = "Java";
String str12 = "java";
System.out.println(str11.equals("Java"));
System.out.println(str11.equals(str12)); // 대소문자 구분
System.out.println(str11.equalsIgnoreCase(str12)); // 대소문자 구분없이 비교
System.out.println();
System.out.println("String.format()");
// TODO
// 연습 : id /pw 입력받고요
// 로그인 성공 여부를 출력해주세요
Scanner sc = new Scanner(System.in);
// TODO
sc.close();
System.out.println("\n프로그램 종료");
} // end main()
} // end class
String 생성자, String literal(상수)
연산자는 실제 문자열이 같은 지 다른 지를 비교하는 것이 아니고,
참조 변수(지역 변수) str3과 str4에 저장된 값(주소)가 같은 지 다른 지를 비교하는 것임.
문자열 비교를 == 으로 하지 말것
문자열 비교는 equals() 사용하자. 참고로 equals() 는 Object 의 메소드다.
생성자는 호출될 때마다 새로운 인스턴스를 힙에 생성하게 됨
str3과 str4는 서로 다른 인스턴스를 가리키게 됨
즉, str3과 str4에는 서로 다른 값이 저장되게 됨
package com.lec.java.string02;
/* String 생성자, String literal(상수)
*/
public class String02Main {
public static void main(String[] args) {
System.out.println("String 생성자, literal(상수)");
int num1 = 1;
int num2 = 1;
if (num1 == num2) {
System.out.println("같은 숫자");
} else {
System.out.println("다른 숫자");
}
System.out.println();
System.out.println("[1] String literal 사용");
// "Hello"는 literal이기 때문에, 한 번 만들어지면 재사용됨
// 그래서, str1과 str2는 같은 곳(주소)에 있는 문자열 "Hello"를 가리키게 됨
// 즉, str1과 str2에는 같은 값이 저장되게 됨
String str1 = "Hello";
String str2 = "Hello";
// TODO
System.out.println();
System.out.println("[2] String 생성자 사용");
// 생성자는 호출될 때마다 새로운 인스턴스를 힙에 생성하게 됨
// str3과 str4는 서로 다른 인스턴스를 가리키게 됨
// 즉, str3과 str4에는 서로 다른 값이 저장되게 됨
String str3 = new String("Hello");
String str4 = new String("Hello");
// TODO
// == 연산자는 실제 문자열이 같은 지 다른 지를 비교하는 것이 아니고,
// 참조 변수(지역 변수) str3과 str4에 저장된 값(주소)가 같은 지 다른 지를 비교하는 것임.
// 문자열 비교를 == 으로 하지 말것!!!!
System.out.println();
System.out.println("[3] String equals() 메소드");
// 문자열 비교는 equals() 사용하자. 참고로 equals() 는 Object 의 메소드다.
// TODO
System.out.println();
System.out.println("[4] String compareTo() 메소드");
// compareTo() 는 두 문자열의 문자코드량 의 비교 (lexicographical comparison based on the Unicode value)
// 이경우 유니코드 값을 비교하게 됨.
// TODO
String str5 = "A";
String str6 = "C";
// TODO
str5 = "AaAa";
str6 = "aAaA";
// TODO
System.out.println("\n프로그램 종료");
} // end main()
} // end class
StringBuffer, StringBuilder
String 클래스는 immutable 클래스이고,
StringBuffer, StringBuilder는 mutable 클래스임
StringBuffer:
Java ver 1.0부터 있던 클래스
쓰레드에 안전(thread-safe), 속도가 느림
StringBuilder:
Java 5부터 생긴 클래스
쓰레드에 안전하지 않다(thread-unsafe), 속도가 빠름.
그 외에는 StringBuffer와 StringBuilder는 같은 기능(메소드)을 갖고 있음
** 웹 프로그래밍 등에선 문자열을 '붙여 나가며' 완성하는 동작을 많이 함
실무에서는
String 을 concat() (혹은 + 연산)하기 보다는
StringBuffer 를 append() 하는 것을 더 많이 사용함 (성능 UP)
public class String03Main {
public static void main(String[] args) {
System.out.println("[1] StringBuffer, StringBuilder");
// String 클래스는 immutable 클래스이고,
// StringBuffer, StringBuilder는 mutable 클래스임
System.out.println("[String: immutable]");
String str1 = "Hello";
String str2 = str1;
System.out.println("str1 = " + str1);
System.out.println("str2 = " + str2);
System.out.println((str1 == str2) ? "동일참조" : "다른참조"); // 동일 참조
str1.concat("Java"); // immutable 객체인 str1 은 안바뀝니다! concat() 의 결과로 새로운 String 객체 생성
System.out.println("str1:" + str1); // 현재 str1 값은???
str1 = str1.concat("Java"); // str1 을 바꾸려면 덮어쓰기 해야 한다.
System.out.println("str1:" + str1); // 현재 str1 값은???
System.out.println("str2:" + str2);
System.out.println((str1 == str2) ? "동일참조" : "다른참조"); // 동일 참조
System.out.println();
System.out.println("[StringBuffer: mutable]");
StringBuffer buff1 = new StringBuffer("Hello");
StringBuffer buff2 = buff1;
System.out.println("buff1 = " + buff1);
System.out.println("buff2 = " + buff2);
buff1.append("Java"); // mutable 객체의 메소드는 동일한 동작이라도 immutable과 이름이 다르게 설계되어 있다
// String.concat() vs StringBuffer.append()
System.out.println("buff1 = " + buff1);
System.out.println("buff2 = " + buff2);
System.out.println((buff1 == buff2) ? "동일참조" : "다른참조");
System.out.println();
buff1.insert(3, "ABCD");
System.out.println(buff1);
System.out.println(buff1.reverse());
System.out.println(buff1);
buff1.delete(3, 7); // 인덱스 3 ~ 6까지 삭제
System.out.println(buff1);
// StringBuffer:
// Java ver 1.0부터 있던 클래스
// 쓰레드에 안전(thread-safe), 속도가 느림
// StringBuilder:
// Java 5부터 생긴 클래스
// 쓰레드에 안전하지 않다(thread-unsafe), 속도가 빠름.
// 그 외에는 StringBuffer와 StringBuilder는 같은 기능을 갖고 있음
// TODO
System.out.println("\n프로그램 종료");
} // end main()
} // end class
StringTokenizer 클래스
token ? : '규칙'에 의해 구분된 더 이상 나눌수 없는 문자요소(문자열)
(문법적으로 더 이상 나눌 수 없는 기본적인 언어요소)
public class String04Main {
public static void main(String[] args) {
System.out.println("StringTokenizer 클래스");
// token <- '규칙'에 의해 구분된 문자덩어리(문자열)?
String str1 = "13:46:12";
// TODO
System.out.println();
String str2 = "abc:def:ghi:jkl:mno"; // : 로 토큰분리
// TODO
System.out.println();
String str3 = "2015/04/08"; // / 로 토큰분리
// TODO
System.out.println();
String str4 = "2015년-4월-8일"; // - 으로 토큰분리
// TODO
System.out.println();
String str5 = "2015-04-08 14:10:55";
// TODO
System.out.println();
// StringTokenizer 생성자의 세번째 매개변수를 true 로 주면
// delimiter 도 token 으로 추출된다
String str6 = "num += 1";
// TODO
// 실습]
// 다음과 같은 수식이 있을때 토큰들을 분리해네세요
// 연산자 + - / * 괄호 ( )
// 10 + (name * 2) / num8- (+3)
// 힌트]
// 일단 공백으로 분리 split()
// 그리고 나서 각각을 StringTokenizer 함
System.out.println();
System.out.println("수식 분석기");
String expr = "10 + (name * 2) / num8- (+3)";
// TODO
System.out.println("\n프로그램 종료");
} // end main()
} // end class
'JAVA' 카테고리의 다른 글
[JAVA] Collection (0) | 2022.02.17 |
---|---|
[JAVA] Wrapper 클래스 (0) | 2022.02.17 |
[JAVA] 정규표현식 (0) | 2022.02.17 |
[JAVA] 예외처리 (0) | 2022.02.16 |
[JAVA] 다형성, 추상 클래스, 인터페이스 (0) | 2022.02.09 |