java.lang 패키지
- 자바에서 기본이 되는 패키지
- 자주 사용되는 자바 클래스와 인터페이스가 위치함
- 별도의 import 없이도 접근 가능한 패키지
- Object, String, Integer, System 등이 위치함
Object 클래스
- 자바의 모든 클래스의 최상위 슈퍼클래스
- 별도로 클래스를 상속받지 않으면 자동으로 상속되는 클래스 따라서, 모든 클래스는 Object 클래스의 멤버를 사용 가능
- 대표적인 메서드
- equals() : 두 객체가 같은지 비교 후 결과값 리턴
- 같은 주소를 참조하는지 동등 비교(==) 수행함
- 일반적으로 두 객체가 같은지를 비교하는 것은두 객체의 멤버변수 값이 같은지를 비교하는 것이므로 Object 클래스의 equals() 메서드를 그대로 사용하지 않고 오버라이딩하여 객체 내의 참조변수 비교를 수행하도록 함
- 자바에서 제공되는 API 의 대부분의 클래스들은 equals() 메서드가 오버라이딩 되어 있으므로 두 객체 간의 실제 데이터에 대한 동등 비교가 가능 ex. String, Wrapper 클래스들...
- 예제
- toString() : 어떤 객체의 정보를 문자열로 리턴
- 일반적으로 개발자 입장에서 객체의 정보는 객체가 갖는 멤버변수들에 저장된 값을 의미하지만, Object 클래스의 toString() 메서드는 객체의 멤버변수 값이 아닌 객체 고유의 값(주소값)을 문자열로 리턴해준다.
- 따라서, 개발자가 원하는 멤버변수 값을 리턴받기 위해서는 toString() 메서드를 오버라이딩하여, 멤버변수들을 문자열로 결합하여 리턴하도록 해야함
- 만약, 출력문에 참조변수명.toString() 메서드를 전달하면 객체의 정보를 문자열로 리턴받아 출력하는데, 이 때, 출력문에는 toString() 메서드 호출 부분 생략 가능
- 자바에서 제공하는 API 대부분은 해당 객체의 값을 리턴하도록 toString() 메서드가 오버라이딩 되어 있다 ex. String, Date 클래스 등...
- 자동 생성 단축키 : Alt + Shift + S -> S
- equals() : 두 객체가 같은지 비교 후 결과값 리턴
class Person {
String name;
int age;
String jumin;
public Person(String name, int age, String jumin) {
super();
this.name = name;
this.age = age;
this.jumin = jumin;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (jumin == null) {
if (other.jumin != null)
return false;
} else if (!jumin.equals(other.jumin))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
class Person2 {
String name;
int age;
String jumin;
public Person2(String name, int age, String jumin) {
super();
this.name = name;
this.age = age;
this.jumin = jumin;
}
// toString() 메서드 오버라이딩
// @Override
// public String toString() {
// // 현재 클래스의 멤버변수를 문자열로 결합하여 리턴
//// return name + ", " + age + ", " + jumin;
// // 식별이 용이하도록 문자열을 추가하여 결합 가능
// return "이름 : " + name + ", 나이 : " + age + ", 주민번호 : " + jumin;
// }
// toString() 메서드 자동 오버라이딩 단축키 : Alt + Shift + S -> S
@Override
public String toString() {
return "Person2 [name=" + name + ", age=" + age + ", jumin=" + jumin + "]";
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (jumin == null) {
if (other.jumin != null)
return false;
} else if (!jumin.equals(other.jumin))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
Person p = new Person("홍길동", 20, "901010-1234567");
System.out.println("Person 클래스 객체 p 의 정보 : " + p.toString());
// => 객체 p 가 갖는 정보를 문자열로 리턴받아 출력
// 이 때, 객체의 정보는 참조변수의 값이 아닌 고유값이 출력됨
System.out.println("Person 클래스 객체 p 의 정보 : " + p);
// => toString() 메서드를 생략하고 "출력문에 참조변수만 사용"해도
// toString() 메서드 사용한 것과 동일한 결과가 출력됨 = 생략 가능
// getClass() : 해당 객체의 클래스 정보를 리턴
System.out.println("p.getClass() : " + p.getClass());
// getClass() 메서드의 리턴타입은 Class 클래스 타입이며
// 해당 객체의 getName() 메서드 호출 시 클래스명만 리턴받을 수 있음
System.out.println("p.getClass().getName() : " + p.getClass().getName());
// hashCode() : 해당 객체의 고유 식별값(해시코드값 != 주소값)
System.out.println("p.hashCode() : " + p.hashCode());
// 결국 Object 클래스의 toString() 메서드가 리턴하는 값은
// getClass().getName() 의 리턴값과 '@' 기호와
// hashCode() 리턴값을 16진수로 변환한 값을 문자열로 결합한 값이다.
System.out.println("===================================");
Person2 p2 = new Person2("홍길동", 20, "901010-1234567");
// 오버라이딩 된 toString() 메서드 호출
System.out.println("Person 클래스 객체 p2 의 정보 : " + p2.toString());
// 출력문 내에서 toString() 메서드는 생략 가능
System.out.println("Person 클래스 객체 p2 의 정보 : " + p2);
// toString() 리턴값이 String 타입이므로 String 타입 변수 저장도 가능
String info = p2.toString();
// String info = p2; // 오류 발생!
// => 변수에 toString() 메서드 리턴값 저장 시 toString() 생략 불가
System.out.println(info);
System.out.println("===============================");
// toString() 메서드가 오버라이딩 되어 있는 API 예 : Date 클래스
// Date 클래스 : 날짜 정보를 관리하는 클래스
Date d1 = new Date();
// 날짜 정보를 출력문을 사용하여 출력
System.out.println(d1.toString());
System.out.println(d1);
// ArrayList 클래스
ArrayList list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
System.out.println("list 객체에 저장된 데이터 : " + list);
String str = "홍길동";
System.out.println(str.toString());
System.out.println(str);
String 클래스
- 다양한 생성자 및 메서드를 통해 문자열을 관리하는 클래스
- 문자열을 생성하는 방법 2가지
- new 연산자로 String 객체를 생성하여 문자열을 할당하는 방법 String str = new String("문자열"); 동일한 문자열이더라도 매번 Heap 공간에 새로 객체 생성
- 리터럴을 사용하여 문자열을 할당하는 방법(주로 사용) String str = "문자열"; **상수 풀(Constant pool)**에 동일한 문자열이 존재할 경우 해당 문자열의 주소값만 리턴하므로, 메모리 낭비가 없음
- 문자열은 큰 따옴표("")를 사용하여 표기
- String 객체는 불변 객체이다 문자열 변경 시 기존에 저장된 문자열이 직접 변경되지 않고, 변경된 새로운 문자열을 다시 새로운 공간에 저장 문자열에 대한 조작이 빈번할 경우 메모리 낭비가 커지므로 StringBuilder 또는 StringBuffer 클래스를 활용해야한다
// String 클래스를 사용하여 문자열을 생성하는 방법
// 1. new 연산자로 String 객체를 생성하여 문자열을 할당하는 방법
String str1 = new String("자바");
String str2 = new String("자바");
// str1 과 str2 의 주소값 비교
// => new 연산자를 두 번 사용했으므로 주소값이 다르다!
if(str1 == str2) {
System.out.println("str1, str2 주소값이 같다!");
} else {
System.out.println("str1, str2 주소값이 다르다!");
}
// str1 과 str2 의 저장된 문자열 비교
// => 객체가 달라도 문자열 내용이 같으므로, equals() 비교 시 같다!
if(str1.equals(str2)) {
System.out.println("str1, str2 문자열이 같다!");
} else {
System.out.println("str1, str2 문자열이 다르다!");
}
System.out.println("----------------------------------");
// 2. 리터럴을 사용하여 문자열을 할당하는 방법(주로 사용)
String str3 = "자바";
String str4 = "자바";
// str3 과 str4 의 주소값 비교
// => 리터럴을 직접 할당할 경우 상수 풀(pool)에서 저장할 문자열이
// 이미 존재하는지 판별한 후 존재하지 않으면 새로 생성하고,
// 존재할 경우 기존 문자열의 주소값만 리턴
// => 즉, 동일한 문자열을 여러 변수에 할당해도 메모리 낭비가 없다!
if(str3 == str4) {
System.out.println("str3, str4 주소값이 같다!");
} else {
System.out.println("str3, str4 주소값이 다르다!");
}
// str3 과 str4 의 저장된 문자열 비교
// => 객체가 달라도 문자열 내용이 같으므로, equals() 비교 시 같다!
if(str3.equals(str4)) {
System.out.println("str3, str4 문자열이 같다!");
} else {
System.out.println("str3, str4 문자열이 다르다!");
}
String 클래스의 다양한 메서드
public class Ex3 {
public static void main(String[] args) {
String s1 = "Java Programming!";
String s2 = " 아이티윌 부산 교육센터 ";
String s3 = "김태희/전지현/송혜교";
// int length() : 문자열 길이 리턴
System.out.println("s1.length() : " + s1.length());
// boolean equals(Object o) : 문자열 비교(대소문자 구별)
System.out.println("s1 과 JAVA PROGRAMMING! 은 같은 문자열인가? "
+ s1.equals("JAVA PROGRAMMING!"));
// boolean equalsIgnoreCase(Object o) : 문자열 비교(대소문자 구별 없음)
System.out.println("s1 과 JAVA PROGRAMMING! 은 같은 문자열인가? "
+ s1.equalsIgnoreCase("JAVA PROGRAMMING!"));
// char charAt(int index) : 인덱스(index) 위치의 문자 1개 리턴
// => 인덱스 번호는 자동으로 부여되며, 0 ~ 문자열길이-1 까지 사용
System.out.println("s1 의 5번 인덱스 문자 : " + s1.charAt(5));
// System.out.println("s1 의 17번 인덱스 문자 : " + s1.charAt(17));
// => 오류 발생! 배열과 마찬가지로 존재하지 않는 인덱스일 경우
// StringIndexOutOfBoundsException 발생함!
// int indexOf(String str 또는 int ch) : 특정 문자 또는 문자열의 인덱스 리턴
// => 만약, 찾는 문자열이 없을 경우 -1 리턴
// => 문자열의 처음(앞)부터 탐색(정방향 탐색)
System.out.println("s1 문자열에 Program 의 인덱스는? " +
s1.indexOf("Program"));
// char 타입으로도 파라미터 전달 가능(문자 1개)
System.out.println("s1 문자열에 a 의 인덱스는? " + s1.indexOf('a'));
// int lastIndexOf(String str 또는 int ch)
// => 문자열의 마지막(뒤)부터 탐색(역방향 탐색) = 인덱스 번호는 동일
System.out.println("s1 문자열에 a 의 인덱스는? " +
s1.lastIndexOf('a'));
// boolean contains(CharSequence s) : 문자열 존재(포함) 여부 리턴
System.out.println("s1 문자열에 Program 이 존재하는가? " +
s1.contains("Program"));
System.out.println("s1 문자열에 JSP 가 존재하는가? " +
s1.contains("JSP"));
// String replace(char, char) 또는 String replace(String, String)
// => 문자 또는 문자열 치환
System.out.println("s1 문자열의 a 를 @ 로 치환 : " +
s1.replace('a', '@'));
System.out.println("s1 문자열의 Java 를 JSP 로 치환 : " +
s1.replace("Java", "JSP"));
// substring() : 부분 문자열 추출
// substring(int beginIndex) : beginIndex 부터 끝까지 추출
System.out.println("s1 의 5번 인덱스부터 끝까지 추출 : " +
s1.substring(5));
// substring(int beginIndex, int endIndex)
// => beginIndex ~ endIndex-1 까지 추출
System.out.println("s1 의 5번 인덱스부터 끝까지 추출 : " +
s1.substring(5, 12));
// toUpperCase() : 문자열(영문자)을 모두 대문자로 변환
System.out.println("s1.toUpperCase() : " + s1.toUpperCase());
// toLowerCase() : 문자열(영문자)을 모두 소문자로 변환
System.out.println("s1.toLowerCase() : " + s1.toLowerCase());
// concat() : 문자열 결합(연결연산자 + 에 비해 결합 속도가 빠름)
System.out.println("s1.concat() : " + s1.concat(" ITWILL"));
// trim() : 문자열 앞 뒤의 불필요한 공백 제거
System.out.println("s2.trim() : " + s2.trim() + "!");
// String[] split(String regex)
// => 구분자(분리자 = Delimeter)를 사용하여 문자열 분리
// => 구분자는 정규표현식 문법을 사용
String[] tokens = s3.split("/");
// => 슬래시기호(/)를 기준으로 문자열 분리하여 String[] 배열에 저장
// => 주의! 마침표(.) 를 기준으로 지정하려면 "\\." 형태로 지정
for(String token : tokens) {
System.out.println(token);
}
// valueOf() : 기본 데이터타입 데이터 -> 문자열로 변환
int num = 20;
String str2 = String.valueOf(20);
// String str = num.toString(); // 기본타입 변수는 메서드 호출 불가
String str = num + ""; // 기본타입 -> 문자열로 변환(널스트링 결합)
// -------------------------------------------
// format(String str, Object...args)
// => 문자열 내에 형식 지정 문자를 사용하여 전달된 데이터를
// 형식에 맞는 문자열로 포맷을 변환
// => String str 파라미터에 형식 문자를 지정하고
// Object...args 의 가변인자는 형식 지정문자 자리에 전달될
// 데이터를 형식 지정 문자 갯수에 맞춰 전달
// => printf() 메서드와 동일한 역할을 수행하며,
// printf() 메서드는 출력용으로만 사용 가능하지만,
// format() 메서드는 String 타입 변수에 문자열 저장이 가능
String formatString =
String.format("이름 : %s, 나이 : %d, 키 : %f",
"홍길동", 20, 180.5);
System.out.println(formatString);
System.out.printf("이름 : %s, 나이 : %d, 키 : %f", "홍길동", 20, 180.5);
System.out.println("=======================================");
// String 클래스는 불변 클래스이므로
// 어떤 작업을 수행하더라도 원본 문자열은 변하지 않는다!
// => 작업 결과가 대부분 새로운 문자열로 생성됨
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
// String 클래스의 리턴타입이 String 타입인 경우
// 결과값에 이어서 바로 다른 메서드 호출 가능
System.out.println(s2.trim().substring(0, 5).indexOf("아이티윌"));
// => trim() 메서드로 공백을 제거한 뒤, 바로 0 ~ 4번 추출 후
// "아이티윌"을 검색하여 0번 인덱스 리턴
// (공백이 제거됐으므로 아이티윌은 0번부터 시작)
}
}
StringBuilder 클래스와 StringBuffer 클래스
- java.lang 패키지에 위치
- String 클래스와 마찬가지로 문자열을 처리하는 클래스
- String 클래스는 문자열 변경 시 새로운 공간에 저장되지만 StringBuilder 또는 StringBuffer 클래스는 버퍼라는 공간을 사용하여 문자열을 저장한 뒤 해당 버퍼에서 문자열을 직접 변경하므로 문자열 변경 시 메모리 낭비가 적어서, 조작이 빈번할 경우 유리
- 문자열 생성할 때, String 클래스와 달리 무조건 new 를 사용해야함
- StringBuilder 와 StringBuffer 는 기본적인 사용법은 거의 동일하며 내부 구조에 따른 차이만 존재한다. (Thread 지원 유무에 따른 차이)
- String 과 StringBuffer(StringBuilfer)는 상속 관계가 없으므로 String -> StringBuffer(StringBuilder)로 변환 시 생성자에 문자열을 전달하여 변환하고, StringBuffer(StringBuilder) -> String 으로 변환 시 toString() 메서드를 호출하여 변환
// StringBuffer(String str) : 문자열 str 을 사용하여 객체 생성
// StringBuffer sb = new StringBuffer("ITWILL");
// StringBuffer() : 아무런 문자열을 갖지 않는 객체 생성
StringBuffer sb = new StringBuffer();
System.out.println("버퍼 크기 : " + sb.capacity());
// append() 메서드를 사용하여 버퍼에 데이터 추가 가능
// => 문자열 뿐만 아니라 거의 모든 데이터를 문자열로 변환하여 추가
// sb.append("정수 : ");
sb.append(10); // 정수도 문자열 결합을 통해 추가됨
sb.append(20);
// toString() 메서드가 오버라이딩되어 있으므로 저장된 문자열을
// 문자열로 쉽게 변환하여 출력 가능
System.out.println("저장된 문자열 : " + sb.toString());
System.out.println("저장된 문자열 : " + sb);
// insert() 메서드를 사용하여 원하는 위치에 문자열 삽입 가능
// => append() 메서드는 문자열의 맨 뒤에 추가
sb.insert(2, "+");
System.out.println("저장된 문자열 : " + sb);
// 리턴타입이 항상 자기 자신일 때
// 빌더 패턴(Builder Pattern)을 활용하여 메서드 결과를 다시
// 메서드 호출용으로 사용 가능 = 메서드의 연쇄적 호출 가능
sb.append("+").append(30).append("+").append(40);
System.out.println("저장된 문자열 : " + sb);
sb.append("+").append(30).append("+").append(40);
System.out.println("버퍼 크기 : " + sb.capacity());
// delete() 메서드를 사용하여 원하는 범위의 문자열 삭제 가능
// => 시작인덱스 ~ 끝인덱스-1 까지 삭제
sb.delete(0, 3);
System.out.println("저장된 문자열 : " + sb);
// reverse() : 문자열 반전
sb.reverse();
System.out.println("저장된 문자열 : " + sb);
// ------- 부가 설명 -------
// => 만약 String 타입을 사용하여 문자열을 반전시킬 경우
String str = "Hello";
// 반복문을 사용하여 문자열 마지막 인덱스부터 0번까지 반복
String str2 = ""; // 역순으로 문자열을 저장할 변수
for(int i = str.length() - 1; i >= 0; i--) {
str2 += str.charAt(i);
}
System.out.println(str + ", " + str2);
// --------------------------
// String 타입 문자열 수정을 위해 StringBuffer 로 변환할 때
StringBuffer sb2 = new StringBuffer(str2); // 생성자에 전달
System.out.println(sb2);
// 만약, 문자열 조작이 끝난 후 String 타입으로 다시 변환할 경우
// str2 = sb2; // String 과 StringBuffer 는 상속관계가 아니므로 오류
str2 = sb2.toString();
System.out.println(str2);
Wrapper 클래스
자바의 기본데이터타입 8가지에 대응하는 8개 클래스들의 모음
기본 데이터 타입명 | Wrapper 클래스명 |
byte | Byte |
short | Short |
char | Character |
int | Integer |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
- 기본데이터타입 변수로 할 수 있는 작업은 데이터 관리뿐이지만 Wrapper 클래스를 활용하여 객체(참조데이터타입)로 관리하게 되면 Wrapper 클래스가 제공하는 메서드, 상수 등의 활용 가능하므로 보다 다양한 데이터 처리가 가능해진다.
- 기본데이터타입 -> 참조데이터타입으로 변환하는 과정 = 박싱 => 스택 영역의 값을 힙 영역(박스)에 포장 참조데이터타입 -> 기본데이터타입으로 변환하는 과정 = 언박싱 => 힙 영역(박스)의 내용물을 꺼내서 스택 영역에 전달
- 박싱과 언박싱은 컴파일러에 의해 자동으로 변환되어 질 수 있으므로 오토박싱, 오토언박싱이라고도 함(Java 1.5 부터 가능)
- 객체를 별도로 생성하지 않아도, Wrapper 클래스의 static 멤버인 다양한 메서드 및 상수가 제공되어 여러 작업 수행 가능 (Wrapper클래스명.XXX 형태로 접근 가능)
// 각 Wrapper 클래스에서 제공되는 static 멤버 활용
// 상수를 활용하여 미리 생성되어 있는 값 활용 가능
System.out.println("byte 타입 최소값 : " + Byte.MIN_VALUE);
System.out.println("byte 타입 최대값 : " + Byte.MAX_VALUE);
System.out.println("short 타입 최소값 : " + Short.MIN_VALUE);
System.out.println("short 타입 최대값 : " + Short.MAX_VALUE);
System.out.println("int 타입 최소값 : " + Integer.MIN_VALUE);
System.out.println("int 타입 최대값 : " + Integer.MAX_VALUE);
System.out.println("long 타입 최소값 : " + Long.MIN_VALUE);
System.out.println("long 타입 최대값 : " + Long.MAX_VALUE);
// 메서드를 활용하여 다양한 데이터 처리 수행 가능
System.out.println("10, 20 중 최대값 : " + Integer.max(10, 20));
int age = Integer.parseInt("20");
System.out.println("=====================================");
int num1 = 10; // 기본 데이터타입 변수 선언 및 초기화
System.out.println("int num1 = " + num1);
// 기본 데이터타입(스택) -> 참조 데이터타입(힙)으로 변환
// int -> Integer
// => Integer 객체 생성 시 파라미터로 int형 데이터 전달하여 변환
Integer n1 = new Integer(num1); // int -> Integer 박싱(Boxing)
System.out.println("Integer n1 = " + n1.toString());
num1 = 99;
n1 = num1; // int -> Integer 오토박싱(Auto Boxing)
// => int형 변수 값을 Integer 타입 변수에 그냥 대입하면
// 컴파일러에 의해 자동으로 박싱 과정이 수행되므로
// 기본데이터타입이 참조데이터타입(객체)으로 자동으로 변환됨
// ------------------------------------------------------------
Integer n2 = 100;
// => int형 리터럴을 직접 Integer 타입 변수에 대입 가능
// => 변수와 동일하게 오토박싱이 일어남
// 참조 데이터타입(힙) -> 기본 데이터타입(스택)으로 변환
// Integer -> int
// => Integer 객체 생성 시 파라미터로 int형 데이터 전달하여 변환
// Integer -> int 형으로 변환할 때
// intValue() 메서드 호출하여 변환 = 언박싱(Unboxing)
int num2 = n2.intValue();
System.out.println(n2 + ", " + num2);
num2 = n2; // Integer -> int 로 자동 변환 = 오토 언박싱
// Wrapper 클래스타입 객체와 기본데이터타입 값 비교하는 방법
// 1. Wrapper 클래스타입 객체의 equals() 메서드 사용하여 비교
if(n2.equals(num2)) {
System.out.println("n2 와 num2 는 같다!");
} else {
System.out.println("n2 와 num2 는 다르다!");
}
// 2. 동등비교연산자를 사용하여 비교
// => 주의! Wrapper 클래스타입 객체끼리 동등비교연산 사용 금지!
// => 객체의 주소값을 비교하게 되므로
if(n2 == num2) { // n2 를 언박싱 후 num2 와 비교
System.out.println("n2 와 num2 는 같다!");
} else {
System.out.println("n2 와 num2 는 다르다!");
}
Character 클래스를 활용한 문자 처리
- Character 클래스의 메서드를 활용하여 문자데이터에 대한 다양한 처리 가능
- isXXX() 메서드를 활용하여 문자에 대한 판별을 수행하고 toXXX() 메서드를 활용하여 문자에 대한 변환을 수행할 수 있다.
char ch = ' ';
System.out.println("ch 는 대문자인가? " + Character.isUpperCase(ch));
System.out.println("ch 는 소문자인가? " + Character.isLowerCase(ch));
System.out.println("ch 는 문자인가? " + Character.isLetter(ch));
System.out.println("ch 는 숫자인가? " + Character.isDigit(ch));
System.out.println("ch 는 공백문자인가? " + Character.isSpace(ch));
// => deprecated 처리된 메서드로 다른 메서드 제공 또는 보안상 사용 X
System.out.println("ch 는 공백문자인가? " + Character.isWhitespace(ch));
System.out.println("==============================");
char ch2 = 'a';
System.out.println(
ch2 + " -> 대문자로 변환 : " + Character.toUpperCase(ch2));
ch2 = 'A';
System.out.println(
ch2 + " -> 소문자로 변환 : " + Character.toLowerCase(ch2));
Math 클래스
- 수학 관련 기능을 제공하는 클래스
- final 클래스이므로 상속 불가하며 모든 멤버는 static 으로 선언되어 있으므로 클래스명만으로 접근
int num1 = -10;
System.out.println("num1 의 절대값 : " + Math.abs(num1));
int num2 = 10, num3 = 20;
System.out.println("num1 과 num2 의 최대값 : " + Math.max(num2, num3));
System.out.println("num1 과 num2 의 최소값 : " + Math.min(num2, num3));
// 소수점 첫째자리를 기준으로 올림, 내림, 반올림 수행
// double num4 = 3.141592;
// System.out.println(Math.ceil(num4)); // 올림 => 실수 리턴
// => 파이 값을 미리 Math 클래스에서 상수(PI)로 만들어 제공
System.out.println("파이값 : " + Math.PI);
System.out.println(Math.ceil(Math.PI)); // 올림 => 실수 리턴
System.out.println(Math.floor(Math.PI)); // 내림 => 실수 리턴
System.out.println(Math.round(Math.PI)); // 반올림 => 정수 리턴
// Math.pow(x, y) : x 의 y 승 값(멱승)을 계산
System.out.println(Math.pow(2, 2)); // 2^2 = 4.0
System.out.println(Math.pow(10, 2)); // 10^2 = 100.0
System.out.println(Math.pow(10, 3)); // 10^3 = 1000.0
System.out.println("==================================");
/*
* 난수(임의의 수) 발생
* - Math.random() 메서드 사용
* - 난수 x 의 범위 : 0.0 <= x < 1.0 (double 타입)
* - 주로 난수의 자릿수를 지정하여 정수화시킨 후 활용
* (ex. 난수의 소수점 6자리까지 정수화 = 6자리 정수형 난수)
* - 하한값n ~ 상한값m까지의 난수 발생 공식
* => (int)(Math.random() * 상한값m) + 하한값n
*/
// 0.0 <= x < 1.0 범위의 난수 발생
// System.out.println("기본 난수 : " + Math.random());
// 0.0 <= x < 10.0 범위의 난수 발생
// System.out.println(Math.random() * 10);
// 0 <= x < 10(0 ~ 9) 범위의 난수 발생(정수화)
// System.out.println((int)(Math.random() * 10));
// 1 <= x <= 10(1 ~ 10) 범위의 난수 발생(정수화)
// System.out.println((int)(Math.random() * 10) + 1);
// 1 <= x <= 20(1 ~ 20) 범위의 난수 발생(정수화)
// System.out.println((int)(Math.random() * 20) + 1);
for(int i = 1; i <= 10; i++) {
System.out.println((int)(Math.random() * 20) + 1);
}
Random 클래스
- 난수 관련 기능을 제공하는 클래스
- Math 클래스의 random() 메서드와는 달리 객체 생성 후 메서드 호출을 통해 난수 발생 nextXXX() 메서드 사용(XXX : 데이터타입)
Random r = new Random();
for(int i = 1; i <= 10; i++) {
// 1. boolean 타입 범위의 난수 발생
// System.out.println(r.nextBoolean());
// 2. double 타입 범위의 난수 발생
// System.out.println(r.nextDouble()); // Math.random() 과 동일
// 3. int 타입 범위의 난수
// System.out.println(r.nextInt());
// 4-1. int 타입 범위 중 0 ~ x-1 까지의 난수 발생
// System.out.println(r.nextInt(10)); // 0 ~ 9 까지의 난수 발생
// 4-2. int 타입 범위 중 1 ~ x 까지의 난수 발생
System.out.println(r.nextInt(10) + 1); // 1 ~ 10 까지의 난수 발생
}
Date 클래스
- 날짜 및 시각 정보를 처리하는 클래스
- 일반적으로 Calendar 클래스를 사용하여 날짜 정보를 조작, Date 클래스를 사용하여 날짜 정보를 표현
// 현재 날짜 및 시각 정보를 갖는 Date 객체 생성
Date d = new Date();
System.out.println(d); // toString() 생략 가능(날짜 정보 표시)
// Date 객체에서 연, 월, 일 등의 개별 정보를 가져올 경우
// getXXX() 메서드를 호출(XXX 은 각 항목 정보 이름)
int year = d.getYear() + 1900; // 1900년 기준으로 표시됨
int month = d.getMonth() + 1; // 0 ~ 11월 기준으로 표시됨
int day = d.getDate(); // getDay() 는 요일
System.out.println(year + "년 " + month + "월 " + day + "일");
// 실제 사용하진 않지만 연, 월, 일 정보를 전달하여 객체 생성 가능
// => 단, 연도는 1900년을 기준으로 덧셈 수행하므로
// 만약 2000년도를 지정해야할 경우 100 지정
// 월은 0 ~ 11 사이의 범위 값을 사용하므로 1 ~ 12월 지정 시
// 실제 값 -1 값을 전달해야함(가져올 때는 +1 값을 사용해야함)
// Date d2 = new Date(2000, 1, 1); // 3900년 2월 1일
Date d2 = new Date(100, 0, 1); // 2000년 1월 1일
System.out.println(d2);
// long 타입 값을 파라미터로 갖는 Date(long) 생성자 호출
// => 1900년 1월 1일을 기준으로 long 값을 밀리초(ms) 단위로 사용하여
// 해당 날짜 및 시각 정보를 설정
Date d3 = new Date(1500000000000L);
System.out.println(d3);
// getTime() 메서드를 사용하여 1970년 1월 1일을 기준으로
// 밀리초 단위의 날짜 및 시각 정보를 가져올 수 있다.
// => 초, 분, 시간, 일 단위로 변환 시
// 한꺼번에 계산하기 보다 각 단위별로 따로 변환을 추천
long gap = d.getTime() - d3.getTime();
System.out.println("d 와 d3 의 날짜 차이 : " + gap + "밀리초");
long gapSec = gap / 1000;
System.out.println("d 와 d3 의 날짜 차이 : " + gapSec + "초");
long gapMin = gap / 1000 / 60;
System.out.println("d 와 d3 의 날짜 차이 : " + gapMin + "분");
long gapHour = gap / 1000 / 60 / 60;
System.out.println("d 와 d3 의 날짜 차이 : " + gapHour + "시간");
long gapDay = gap / 1000 / 60 / 60 / 24;
System.out.println("d 와 d3 의 날짜 차이 : " + gapDay + "일");
System.out.println("=====================================");
/*
* SimpleDateFormat 클래스
* - 날짜 형식을 지정하여 표현 가능한 클래스
* - 형식 지정문자 사용하여 표현할 형식 지정
* yyyy : 연도 4자리
* MM : 월 2자리
* dd : 일 2자리
* EEEE : 요일(전체), EE : 요일(약식 한글 1글자)
*
* HH : 0 ~ 23시간(KK : 0 ~ 11시간)
* hh : 1 ~ 12시간(kk : 1 ~ 24시간)
* mm : 분 2자리
* ss : 초 2자리
*/
SimpleDateFormat sdf =
new SimpleDateFormat("yyyy년 MM월 dd일 EEEE hh시 mm분 ss초");
System.out.println(sdf.format(d));
Calendar 클래스
- 날짜 및 시각 정보를 관리하는 클래스
- 추상클래스이므로 인스턴스 생성이 불가능하며 static 메서드인 getInstance() 메서드로 객체 리턴받아 사용
- get() 메서드 : Calendar 객체로부터 정보 가져오기 파라미터로 Calender.XXX 상수를 사용하여 가져올 정보 지정 ex) get(Calendar.YEAR) = 연도 정보 리턴
- set() 메서드 : Calendar 객체의 정보 설정
// 객체 생성 대신 시스템으로부터 생성된 객체 정보 가져오기
Calendar cal = Calendar.getInstance();
// get() 메서드를 호출하여 해당 정보 가져오기
// => Calendar.XXX 상수를 파라미터로 전달하여 정보의 종류 지정
int year = cal.get(Calendar.YEAR); // 연도
int month = cal.get(Calendar.MONTH) + 1; // 월(0 ~ 11) => +1 필요
int day = cal.get(Calendar.DAY_OF_MONTH); // 일
int week = cal.get(Calendar.DAY_OF_WEEK); // 요일
// 요일이 정수값으로 사용되므로 문자열 변환을 위해
// switch-case 또는 if문을 통해 Calendar.요일명 상수와 비교 필요
String strWeek = "";
switch (week) {
case Calendar.MONDAY: strWeek = "월"; break;
case Calendar.TUESDAY: strWeek = "화"; break;
case Calendar.WEDNESDAY: strWeek = "수"; break;
case Calendar.THURSDAY: strWeek = "목"; break;
case Calendar.FRIDAY: strWeek = "금"; break;
case Calendar.SATURDAY: strWeek = "토"; break;
case Calendar.SUNDAY: strWeek = "일";
}
System.out.println(year + "년 " + month + "월 " + day + "일 " + strWeek + "요일");
int hour = cal.get(Calendar.HOUR); // 12시간제(0 ~ 11)
// int hour = cal.get(Calendar.HOUR_OF_DAY); // 24시간제(0 ~ 23)
int min = cal.get(Calendar.MINUTE);
int sec = cal.get(Calendar.SECOND);
int amPm = cal.get(Calendar.AM_PM);
// 오전/오후 정보가 정수로 리턴되므로 문자열 변환 시
// Calendar.AM 상수와 비교하여 오전 여부 판별 가능
// 1. 삼항연산자 사용할 경우
// String strAmPm = amPm == Calendar.AM ? "오전" : "오후";
// 2. if문 사용할 경우
String strAmPm = "";
if(amPm == Calendar.AM) {
strAmPm = "오전";
} else {
strAmPm = "오후";
}
System.out.println(strAmPm + " " + hour + "시 " + min + "분 " + sec + "초");
// ============================================
// Date d = new Date(); // Date 객체 생성
Calendar cal2 = Calendar.getInstance(); // Calendar 객체 가져오기
// Calendar 객체의 set() 메서드를 호출하면 날짜 및 시각 설정 가능
// 1. set(필드명, 값)
// => 필드명에 해당하는 정보를 전달받은 값으로 설정(변경)
cal2.set(Calendar.YEAR, 2000); // 연도를 2000년으로 변경
System.out.println(cal2.get(Calendar.YEAR));
// 2. set(연, 월, 일, 시, 분, 초) => 해당 값으로 날짜 및 시각 변경
cal2.set(1999, 11, 31, 23, 59, 59); // 주의! 12월은 11로 설정
// Calendar 객체 -> Date 객체로 변환 후 날짜 및 시각 정보 출력
Date d = cal2.getTime(); // Calendar 객체로부터 Date 객체 얻어오기
// SimpleDateFormat 클래스를 활용하여
// XXXX년 XX월 XX일 X요일 XX시 XX분 XX초 형식으로 출력
SimpleDateFormat sdf =
new SimpleDateFormat("yyyy년 MM월 dd일 EEEE hh시 mm분 ss초");
System.out.println(sdf.format(d));
java.time 패키지
- Date, Calendar 클래스 등 기본 클래스들의 단점을 보완한 별도의 클래스를 제공하는 패키지
- **LocalDate(날짜), LocalTime(시각), LocalDateTime(날짜 및 시각)**등의 클래스 등 제공
- toString() 메서드가 오버라이딩 되어 있으므로 출력이 간편
- 객체를 직접 생성하지 않고, 시스템으로부터 생성된 객체를 static 메서드인 now() 메서드를 호출하여 리턴받아 사용
- of() 메서드를 호출하여 날짜 정보를 간편하게 설정 가능
- 각종 메서드를 사용하여 날짜 및 시각 비교, 계산 등이 쉬움
// 1. 날짜 정보를 관리하는 LocalDate 클래스
LocalDate date = LocalDate.now(); // 현재 시스템 날짜 정보 가져오기
System.out.println(date);
LocalDate date2 = LocalDate.of(1999, 12, 31); // 연, 월, 일 설정
System.out.println(date2);
// 2. 시각 정보를 관리하는 LocalTime 클래스
LocalTime time = LocalTime.now(); // 현재 시스템 시각 정보 가져오기
System.out.println(time);
LocalTime time2 = LocalTime.of(23, 50, 10); // 시(0 ~ 23), 분, 초 설정
System.out.println(time2);
// 3. 날짜 및 시각 정보를 관리하는 LocalDateTime 클래스
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
// 연, 월, 일, 시, 분, 초 직접 지정하여 변경하는 방법
LocalDateTime now2 = LocalDateTime.of(1999, 12, 31, 23, 50, 10);
// LocalDate 객체와 LocalTime 객체를 사용하여 변경하는 방법
// LocalDateTime now2 = LocalDateTime.of(date2, time2);
System.out.println(now2);
System.out.println("=====================================");
// getXXX(), isXXX() 메서드를 호출하여 각종 정보 처리 가능
// => LocalDate, LocalTime, LocalDateTime 객체의 메서드
// 공통메서드와 전용메서드로 구분됨
System.out.println(now2.getYear() + "년");
System.out.println(now2.getMonthValue() + "월");
System.out.println(now2.getDayOfMonth() + "일");
// plusXXXs(), minusXXXs() 메서드를 사용하여 날짜 더하기, 빼기
// => XXX 은 증감할 항목명(Year, Month, Day)
// => 증감 시 월, 연도 등이 연쇄적으로 변경될 수 있음
System.out.println(now2.plusDays(1));
// 1일 더하기 시 31일에서 1일로 변경되면서 연도, 월이 증가됨
System.out.println(now2.plusMonths(1));
// 1월 더하기 시 12월에서 1월로 변경되면서 연도가 증가됨
System.out.println("=====================================");
System.out.println("now = " + now + ", now2 = " + now2);
// 날짜 및 시각 정보에 대한 비교
// 자신객체.isXXX(대상객체)
// => 자신의 객체가 대상 객체의 XXX 날짜 및 시각인지 판별
// 1. 자신이 대상보다 미래인지 판별
System.out.println("now 가 now2 보다 미래인가? " + now.isAfter(now2));
// 2. 자신이 대상보다 과거인지 판별
System.out.println("now 가 now2 보다 과거인가? " + now.isBefore(now2));
// 3. 자신이 대상과 같은지 판별
System.out.println("now 가 now2 와 같은가? " + now.isEqual(now2));
// 4. 자신이 대상과 비교했을 때 빠른지(미래) 느린지(과거) 판별
// => 양수 : 빠름, 음수 : 느림, 0 : 동일
System.out.println(now.compareTo(now2));
// 5. 자신을 기준으로 대상과의 차이 리턴
// (연, 월, 일 등 세부 항목 차이 계산 가능)
// => 음수이면 대상 정보는 과거, 양수이면 미래
System.out.println(now.until(now2, ChronoUnit.YEARS)); // 연도 차이
System.out.println(now.until(now2, ChronoUnit.DAYS)); // 일수 차이
long yearsGap = now.until(now2, ChronoUnit.YEARS);
if(yearsGap < 0) {
yearsGap = -yearsGap;
System.out.println((yearsGap) + "년 지났습니다!");
} else if(yearsGap > 0) {
System.out.println(yearsGap + "년 남았습니다!");
} else {
System.out.println("올해입니다!");
}
System.out.println("===============================");
// 날짜 및 시각 정보의 계산
LocalDate date3 = LocalDate.of(2000, 1, 1);
LocalDate date4 = LocalDate.now(); // 2020년 10월 5일
// Period.between() : 연도, 월, 일에 대한 차이 계산(단위별 연산)
Period period = Period.between(date3, date4);
System.out.println(period); // PxxYxMxD => P20Y9M4D 출력됨
System.out.println("연도 차이 : " + period.getYears() + "년");
System.out.println("월 차이 : " + period.getMonths() + "개월");
System.out.println("일 차이 : " + period.getDays() + "일");
// ChronoUnit.XXX.between() 메서드를 호출하여 전체 차이 계산
// => XXX 은 연도(YEARS), 월(MONTHS) 등 항목에 대한 Enum 상수 사용
long yearGap = ChronoUnit.YEARS.between(date3, date4);
System.out.println("총 몇 년 차이 : " + yearGap + "년");
long monthGap = ChronoUnit.MONTHS.between(date3, date4);
System.out.println("총 몇 개월 차이 : " + monthGap + "개월");
long dayGap = ChronoUnit.DAYS.between(date3, date4);
System.out.println("총 몇 일 차이 : " + dayGap + "일");
DateTimeFormatter 클래스
포맷팅 Formatting
- 특정 객체를 원하는 형식의 문자열로 변환
파싱 Parsing
- 문자열을 객체로 변환
// 문자열로 된 날짜를 LocalDate 객체로 변환(파싱 = Parsing)
String strDate = "2020-10-06"; // "연도-월-일" 형식으로 지정
LocalDate date1 = LocalDate.parse(strDate); // LocalDate 타입 객체로 변환
System.out.println(date1);
// 문자열로 된 시각을 LocalTime 객체로 변환
String strTime = "09:18:30"; // "시:분:초" 형식으로 지정
LocalTime time1 = LocalTime.parse(strTime);
System.out.println(time1);
- 날짜 및 시각에 대한 형식 지정 클래스
- 사용자가 특정 형식을 지정하여 해당 형식에 맞게 문자열을 읽어옴
- 형식 지정문자는 SimpleDateFormat 클래스의 형식지정문자와 동일
주의! 기본 형식에 맞지 않은 문자열을 파싱할 경우 오류 발생!
// String strDate2 = "2020-10-06(화)";
// LocalDate date2 = LocalDate.parse(strDate2);
// => java.time.format.DateTimeParseException 예외 발생
// 기본 형식이 아닌 문자열을 파싱해야할 경우
// DateTimeFormatter 클래스를 사용하여 해당 문자열의 형식을 지정해야함
String strDate2 = "2020-10-06(화)";
// 연도 4자리 : yyyy
// 월 2자리 : MM(1 ~ 9월의 경우 01 ~ 09로 표기해야함)
// 만약, 0을 제외하고 싶으면 M 한 글자로 표기
// 일 2자리 : dd(월과 표기법 동일)
// 요일 1자리 : E(요일 3자리(ex. 화요일)의 경우 EEEE 사용)
String pattern = "yyyy-MM-dd(E)"; // 읽어올 날짜의 형식을 지정
// 지정된 형식문자열을 DateTimeFormatter.ofPattern() 메서드에 전달
DateTimeFormatter dtf = DateTimeFormatter.ofPattern(pattern);
// LocalDate.parse() 메서드의 파라미터로 날짜와 패턴을 전달
LocalDate date2 = LocalDate.parse(strDate2, dtf);
System.out.println(date2);
System.out.println(date2.getDayOfWeek());
// ----------------------------------------
String strTime2 = "오후 09:18:30";
// 시 2자리 : HH(0 ~ 23시) 또는 KK(0 ~ 11시)
// 분 2자리 : mm
// 초 2자리 : ss
// => 시, 분, 초 2자리 표기를 위해 1자리 단위는 0 필요
// 만약, 한자리에서 0을 제외할 경우 H 또는 K 등 한 글자 사용
// 오전/오후 표기 : a
String pattern2 = "a KK:mm:ss";
DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern(pattern2);
LocalTime time2 = LocalTime.parse(strTime2, dtf2);
System.out.println(time2);
// ----------------------------------------
String strDateTime = "2020년 10월 6일 화요일 오전 09시 38분 10초";
String pattern3 = "yyyy년 MM월 d일 EEEE a KK시 mm분 ss초";
DateTimeFormatter dtf3 = DateTimeFormatter.ofPattern(pattern3);
LocalDateTime dateTime = LocalDateTime.parse(strDateTime, dtf3);
System.out.println(dateTime);
java.util 패키지
StringTokenizer 클래스
- 특정 문자열을 **구분자(Delimeter)**를 통해 파싱하는 클래스
- 분리된 각각의 문자열을 **토큰(Token)**이라고 하며, 각각의 토큰들이 StringTokenizer 객체에 저장됨 이 때, 분리할 때 사용되는 문자열을 구분자(분리자)라고 함
- 파싱된 문자열에 접근하기 위한 메서드가 제공됨
- String 클래스의 split() 메서드와 기능적으로 유사함
String str = "김태희/송혜교/전지현";
// 1. String 클래스의 split() 메서드를 사용하여 문자열을 분리
String[] strArr = str.split("/");
for(String s : strArr) {
System.out.println(s);
}
// 2. StringTokenizer 클래스를 사용하여 문자열 분리
// => 분리를 위해 사용되는 문자를 구분자(분리자, Delimeter)라고 함
StringTokenizer st = new StringTokenizer(str, "/");
// 분리된 문자열은 StringTokenizer 객체에 저장되어 있음
// 객체 내의 문자열에 접근하기 위해서는 메서드 활용
// 2-1. 분리된 토큰 갯수 : countTokens()
System.out.println("분리된 토큰 갯수 : " + st.countTokens());
// 2-2. StringTokenizer 객체에 분리된 토큰 존재 여부 확인
// - hasMoreTokens() => 주로 while() 문 내에서 사용
while(st.hasMoreTokens()) {
// 2-3. StringTokenizer 객체에 분리된 토큰 1개 꺼내기
// - nextToken()
String token = st.nextToken();
System.out.println("토큰 : " + token);
}
System.out.println("==================================");
// 만약, 구분자(Delimeter) 가 2종류 이상일 때
String str2 = "자바&JSP/HTML5&CSS3.안드로이드";
// => & 기호와 / 기호를 모두 구분자로 지정해서 분리할 경우
// 문자열로 모든 구분자를 결합하면 하나씩 모두 구분자로 사용
// 이 때, 구분자 각각의 순서는 무관함
// => String 클래스의 split() 메서드와 달리 마침표(.) 도 사용 가능
StringTokenizer st2 = new StringTokenizer(str2, "&/.");
while(st2.hasMoreTokens()) {
System.out.println("토큰 : " + st2.nextToken());
}
정규 표현식 Regular Expression = Regex
- 패턴을 기반으로 특정 조건에 맞는 문자를 검색, 치환 등 수행
ex) 패스워드 복잡도(안전도) 검사, 전화번호 양식 검사 등
Validation 체크(입력값 검증) - 언어 등 도구와 관계 없이 동일한 패턴을 사용
ex) 자바, 자바스크립트, SQL, 네트워크 프로그래밍 등
정규 표현식 패턴 문자
정규 표현식 패턴 문자
[ 기본 패턴 ]
^x : x 로 시작하는 문자열 => x, xa, xb, xxy 등(단, ax, bx 등은 사용 불가)
x$ : x 로 끝나는 문자열 => x, ax, bx, yyx 등(단, xa, xb 등은 사용 불가)
.x : x 앞에 어떤 문자 한 개가 존재 => ax, bx 등
x+ : x 가 1번 이상 반복될 수 있음 => x, xx, xxx 등
x* : x 가 0번 이상 반복될 수 있음 => a, x, xx, xxx 등
x? : x 가 나오거나 안 나올 수 있음 => a, x 등
x|y : x 또는 y 가 올 수 있음 => x, y
예) xa?y$ : 시작 무관, x 뒤에 a 는 있을 수도 있고, 없을 수도 있으며 마지막은 y 로 끝남(x 뒤에 a 는 무관하고 y로 끝나는 문자열)
=> xy(O), hixy(O), hixay(O), xaay(X)
x|a?y$ : 시작 무관, x 또는 a?y$ 가 적용된 문자열 => xy(O), hixay(O), ay2(X)
[ 괄호의 활용 ]
- 소괄호() : 괄호 안의 내용을 하나의 문자열로 그룹화 (xy) : xy 가 하나의 조건으로 묶임
- 중괄호{} : 중괄호 앞의 문자열에 대한 반복 횟수 지정 x{n} : x가 n번 반복됨 x{n,} : x가 n번 이상 반복됨 x{n,m} : x가 n번 이상, m번 이하 반복됨
- 대괄호[] : 대괄호 안의 문자열 중 하나를 포함 [xyz] : x 또는 y 또는 z [AZ] : 대문자 A 또는 대문자 Z [A-Z] : 대문자 1글자(A 부터 Z 까지 문자 중 1개) [0-9] : 숫자 1개 [가-힣] : 한글 1글자 [!@#$%] : 특수문자 !@#$% 중 1개 [^x] : 대괄호 내에서의 ^ 기호는 부정의 의미로 사용됨 따라서, x가 아닌 문자를 뜻함 ex) [^0-9] : 숫자가 아닌 문자 1개
예) (02|051|010) : 02 또는 051 또는 010
^(abc)(def)+(ghi)$ => abc 로 시작하고, def 가 1번 이상 반복되며, ghi 로 끝나는 문자열 abcdefghi(O), abcdefdefghi(O), abcdeghi(X)
(a1){2}b{2,4}c{2,} => a1 이 2번 반복되고, b 가 2~4번 반복, c 가 2번 이상 반복
a1a1bbcc(O), a1a1bbbbccccc(O) a1a1bbbbbcc(X), a1a1bbc(X)
예2) 영문자(대문자, 소문자) 2자리 ~ 4자리만 포함되어야 함 (즉, 영문자로 시작하고 영문자로 끝남) ^[A-Za-z]{2,4}$
(영문자 또는 숫자 또는 한글) 4자리 ^[A-Za-z0-9가-힣]{4}$
[a-z]{2}[0-9][가-힣][^A-Z] => 소문자 2글자, 숫자 1개, 한글 1글자, 대문자가 아닌 것 1개
aa1홍a(O), aa1홍2(O), aa1홍A(X)
[ 예외 문자 처리 ] \ 기호를 사용하여 특정 문자를 예외 문자로 처리
(=> 특수한 용도로 사용하기 위한 기호로 처리)
예를 들어, ? 기호나 . 기호 등을 문자로 사용해야할 때 \? \. 형태로 사용
(=> 주의! 자바에서 문자열로 지정해야할 경우 \ 는 이스케이프 문장지므로 \\? \\. 형태로 사용해야함)
\d : 숫자(0 ~ 9) 1개 = [0-9] 와 동일
\D : 숫자가 아닌 것 1개 = [^0-9] 와 동일
\s : 공백문자 1개
\S : 공백이 아닌 문자 1개
\w : 알파벳(대소문자), 숫자, _ 기호 1개
\W : 알파벳, 숫자, _ 기호를 제외한 문자 1개
================================================
예) 휴대폰 번호 검증
=> 앞자리 숫자 3자리로 시작(010 또는 011)
=> 가운데 자리는 숫자 3자리 또는 4자리
=> 뒷자리는 숫자 4자리로 끝
=> 단, 각 자리 사이에는 하이픈(-) 기호 또는 공백이 올 수도 있고 안 올 수도 있음
^(010|011)
[0-9]{3,4} 또는 \d{3,4}
[0-9]{4}$ 또는 \d{4}$
[-\s]?
=> ^(010|011)[-\s]?[0-9]{3,4}[-\s]?[0-9]{4}$
=> ^(010|011)[-\s]?\d{3,4}[-\s]?\d{4}$
=> ^(010|011)(-|\s)?\d{3,4}(-|\s)?\d{4}$
패스워드 검증
대문자, 소문자, 숫자, 언더스코어() 포함 8 ~ 16글자
^[A-Za-z0-9]{8,16}$
IP 주소(x.x.x.x ~ xxx.xxx.xxx.xxx)
4개의 옥텟별 10진수 정수 1자리 ~ 3자리씩 마침표(.)를 기준으로 구분
^[0~9]{1,3}\.[0~9]{1,3}\.[0~9]{1,3}\.[0~9]{1,3}$
[ 플래그 ]
=> /x/플래그 형식으로 사용
g : 문자열 내의 모든 패턴 검색
i : 문자열의 대소문자 구별하지 않고 검색
m : 문자열이 행이 바뀌더라도 검색
예)
---문자열---
"Hello Java Lily"
/l/ : Hello 의 세번째 문자 l 이 조건에 만족함
/l/g : Hello 의 소문자 l 2개와 Lily 의 소문자 1개가 조건에 만족
/l/gi : Hello 의 소문자 l 2개와 Lily 의 대문자 L, 소문자 l 이 조건에 만족
- Matcher 클래스는 패턴을 해석하고, 입력 문자열에 대한 부분 또는 전체 일치 여부 등 검사
Pattern 클래스
- Pattern 클래스는 정규표현식을 컴파일해서 관리하며, 입력 문자열에 대한
전체 일치 여부 검사 등을 수행
matches() : 문자열이 정규표현식에 부합되는지 검사
// 정규표현식 작성
// 알파벳(대소문자) 2 ~ 4글자
// String regex = "^[A-Za-z]{2,4}$";
// String input = "abc1";
// (영문자 또는 숫자 또는 한글) 4자리
String regex = "^[A-Za-z0-9가-힣]{4}$";
String input = "1234";
// Pattern 클래스의 static 메서드 matches() 를 호출하여
// 정규표현식 문자열과 검사할 문자열을 파라미터로 전달
// => 해당 문자열이 정규표현식에 부합되는지를 boolean 타입으로 리턴
boolean checkRegex = Pattern.matches(regex, input);
System.out.println(input + " 검사 결과 : " + checkRegex);
Matcher 클래스
- 패턴을 해석하고, 입력 문자열에 대한 일치 여부 판별 기능 제공
- 별도의 생성자가 없고, Pattern 클래스의 matcher() 메서드를 통해 Matcher 객체를 얻어와서 사용
- Pattern 클래스는 문자열이 정규표현식 부합 여부만 판별하지만, Matcher 클래스는 정규표현식 내용이 포함되는지 여부와 위치 등 좀 더 복잡한 판별을 수행 가능
String sourceStr = "Java and Javascript has no relation";
String regex = "Java";
// Pattern.compile() 메서드는 정규표현식을 갖는 Pattern 객체 리턴
Pattern pattern = Pattern.compile(regex);
// Pattern 객체를 사용하여 matcher() 메서드를 호출하면
// Matcher 타입 객체를 얻어올 수 있음
// => 파라미터로 검사에 사용될 대상 문자열 전달
Matcher matcher = pattern.matcher(sourceStr);
// => 이미 Pattern 객체에 정규표현식이 포함되어 있으므로
// Matcher 객체는 정규표현식과 검사할 문자열을 모두 포함하게 됨
// Matcher 객체의 여러 메서드를 호출하여 원본문자열에 대한
// 정규표현식을 통해 여러 작업 수행 가능
// 1. matches() : Pattern 클래스의 matches() 메서드와 동일
System.out.println("정규표현식과 완전히 일치하는가? " + matcher.matches());
// 2. lookingAt() : 정규표현식 문자열로 시작하는지 검사
System.out.println("정규표현식으로 시작하는가? " + matcher.lookingAt());
// 3. find() : 정규표현식을 포함하는지 검사
System.out.println("정규표현식을 포함하는가? " + matcher.find());
// 4. replaceAll() : 정규표현식에 일치하는 문자열을 모두 치환
// => String 클래스의 replaceAll() 과 기능 동일함
System.out.println(matcher.replaceAll("자바"));
// 5. replaceFirst() : 정규표현식에 일치하는 첫 문자열을 치환
// => String 클래스의 replaceFirst() 와 기능 동일함
System.out.println(matcher.replaceFirst("자바"));
// =======================================================
// Pattern 객체 생성 -> Matcher 객체 리턴 -> 메서드 호출 작업을
// 하나의 문장으로 결합할 경우
System.out.println("정규표현식을 포함하는가? " +
Pattern.compile(regex).matcher(sourceStr).find());
java.text 패키지
형식화 클래스
SimpleDateFormat 클래스
- 날짜/시각 정보에 대한 패턴을 사용하여 파싱/포맷팅 처리
- 파싱 : 문자열을 Date 타입으로 변환 => parse() 메서드 포맷팅 : Date 타입 객체를 문자열로 변환 => format() 메서드
// 1. SimpleDateFormat 클래스
Date d = new Date();
// 포맷팅 및 파싱에 사용될 형식문자열 지정
SimpleDateFormat sdf =
new SimpleDateFormat("yyyy년 MM월 dd일(E) a KK:mm:ss");
// 지정된 형식에 맞게 Date 타입을 문자열로 변환 = 포맷팅
String strDate = sdf.format(d);
System.out.println(strDate);
// 지정된 형식에 맞게 문자열을 Date 타입으로 변환 = 파싱
Date parsedDate = sdf.parse(strDate);
System.out.println(parsedDate);
DecimalFormat 클래스
- 숫자에 대한 패턴을 사용하여 파싱/포맷팅 처리
- 메서드는 SimpleDateFormat 클래스와 동일
- 형식 지정 문자(패턴)만 다름 0 : 0 ~ 9 사이 숫자 1자리(값이 없으면 0으로 채움)
# : 0 과 동일하나 값이 없으면 0으로 채우지 않음
, : 천 단위 구분 기호
// 2. DecimalFormat 클래스
double originalNum = 123.55; // 원본 숫자
// DecimalFormat 클래스의 객체 생성 시 형식 지정문자(패턴) 설정
DecimalFormat df = new DecimalFormat("₩#,###.#");
// DecimalFormat df = new DecimalFormat("₩0,000.0");
// => 맨 앞에 통화기호 뒤에 정수와 실수 지정
// 정수는 3자리마다 콤마(,) 표기, 실수는 1자리로 표기
String formatNum = df.format(originalNum); // 숫자 -> 문자열 포맷팅
System.out.println(formatNum);
// 문자열로 된 숫자를 형식에 맞게 읽어들여 수치데이터타입으로 파싱
// => 리턴타입이 Number 타입이므로 알맞은 데이터타입으로 형변환 필요
double parsedNum = (double)df.parse(formatNum);
System.out.println(parsedNum);
MessageFormat 클래스
// 3. MessageFormat 클래스
// 특정 패턴을 사용하여 데이터를 변수처럼 지정한 후 파싱, 포맷팅에 사용
// "이름 : 홍길동, Java : 90, JSP : 100, DB : 80"
// "이름 : 이순신, Java : 50, JSP : 50, DB : 50"
// "이름 : 강감찬, Java : 80, JSP : 70, DB : 100"
String name = "홍길동";
int java = 90, jsp = 100, db = 80;
// 메세지 패턴 생성 => 패턴에 포함될 데이터가 들어갈 자리를
// 중괄호{} 로 지정하고, 중괄호 안에 패턴 데이터 번호(0부터) 지정
String pattern = "이름 : {0}, Java : {1}, JSP : {2}, DB : {3}";
// => 패턴 문자열 내부에 데이터가 들어갈 부분이 4군데
String parsedStr = MessageFormat.format(pattern, name, java, jsp, db);
System.out.println(parsedStr);
String originalStr = "홍길동:90:100:80,이순신:50:50:50,강감찬:80:70:100";
String[] strArr = originalStr.split(",");
for(String str : strArr) {
// System.out.println(str);
System.out.println(MessageFormat.format(pattern, str.split(":")));
'프로그래밍 언어 > JAVA' 카테고리의 다른 글
[JAVA] 자바 컬렉션 프레임워크 - List 편 (0) | 2021.01.19 |
---|---|
[JAVA] 자바 컬렉션 프레임워크 - Set 편 (0) | 2021.01.19 |
[JAVA] 자바의 예외처리 Exception (0) | 2021.01.19 |
[JAVA] 자바의 인터페이스 Interface (0) | 2021.01.19 |
[JAVA] 자바의 상수 Constant (0) | 2021.01.19 |