📌java.lang 패키지
클래스 | 용도 |
Object | -자바 클래스의 최상위 클래스로 사용 |
System | -표준 입력 장치(키보드)로부터 데이터를 입력받을 때 사용 -표준 출력 장치(모니터)로 출력하기 위해 사용 -자바 가상 기계를 종료시킬 때 사용 -쓰레기 수집기를 실행 요청할 때 사용 |
Class | -클래스를 메모리로 로딩할 때 사용 |
String | -문자열을 저장하고 여러 가지 정보를 얻을 때 사용 |
StringBuffer, StringBuilder | -문자열을 저장하고 내부 문자열을 조작할 때 사용 |
Math | -수학 함수를 이용할 때 사용 |
Wrapper (Byte, Short, Character, Integer, Float, Double, Boolean |
-기본 타입의 데이터를 갖는 객체를 만들 때 사용 -문자열을 기본 타입으로 변환할 때 사용 -입력값 검사에 사용 |
📌Object 클래스
상속(extends)을 했던 하지 않았던 기본적으로 java.lang.Object 클래스를 상속하게 된다.
즉 자바에서 모든 클래스는 Object 클래스의 자식이거나 자손 클래스이다. Object는 자바의 최상위 부모 클래스에 해당한다.
1) public String toString()
Object 클래스의 toString() 메소드는 객체의 문자열 표현을 리턴한다.
public String toString(){
return getClass().getName()+"@"+Integer.toHexString(hashCode());
}
toString()메소드는 일반적으로 오버라이딩(재정의)하여서 사용하여야 하는 메서드이다. 클래스를 작성할 때 toString()을 오버라이딩하지 않는다면, 위와 같은 내용이 그대로 사용될 것이다. 즉, toString()을 호출하면 클래스이름에 16진수의 해시코드를 얻게 될 것이다.
하지만 많이 쓰이는 경우는 오버라이딩이 미리 되어있다.
예를 들어
String클래스의 toString()은 String인스턴스가 갖고 있는 문자열을 반환하도록 오버라이딩 되어있고
Date클래스의 경우, Date인스턴스가 갖고 있는 날짜와 시간을 문자열로 변환하여 반환하도록 오버라이딩 되어 있다.
이처럼 toString()은 일반적으로 인스턴스나 클래스에 대한 정보 또는 인스턴스 변수들의 값을 문자열로 변환하여 반환하도록 오버라이딩되는 것이 보통이다.
toString()을 직접 호출하지 않아도 어떤 객체를 System.out.println()로 호출하면 자동으로 toString()이 호출되도록 약속돼 있다.
ex) Card클래스를 만들어서 toString()을 오버라이딩하는 예시
class Card{
String kind;
int number;
public String toString(){
return "kind: "+kind+ ",number: "+number; //Card인스턴스의 kind와number를 문자열로 반환
}
}
2) public boolean equals(Object obj)
equals()메소드는 두 개의 객체를 비교하는 API이다. (같으면 true를 반환)
class Human{
String name;
Student(String name){
this.name = name;
}
public boolean equals(Object obj) {
Human _obj = (Human)obj; //(Human)obj는 메소드 equals로 전달된 obj의 데이터 타입이
//Object이기 때문에 이를 Human 타입으로 형 변환하는 코드이다.
return name == _obj.name; //현재 객체의 변수 name과 equals의 인자로 전달된 객체의 변수
//name을 비교한 결과를 Boolean 값으로 리턴하고 있다.
//이 값에 따라 두 개의 객체는 같거나 다른 것이 된다.
}
}
class ObjectEquals {
public static void main(String[] args) {
Human h1 = new Human("gildong");
Human h2 = new Human("gildong");
System.out.println(h1 == h2); //false
System.out.println(h1.equals(h2)); //true
}
}
h1과 h2가 서로 다른 객체이기 때문에 h1==h2는 당연히 false이다.
equals() 메서드는 객체를 비교할 때 같은 객체이건 다른 객체이건 상관없이 객체가 저장하고 있는 데이터가 동일하면 true를 리턴한다.
이것이 가능한 이유는 비교하고자 하는 클래스를 오버라이딩해서 번지 비교가 아닌 데이터 비교로 변경했기 때문이다.
위 코드를 보면 Human 클래스에서 Object 클래스의 메소드인 equals() 메소드를 오버라이딩 한 것을 확인할 수 있다.
3) protected Object clone()
이 메소드는 원본 객체의 필드값과 동일한 값을 가지는 새로운 객체를 생성하는 것을 말한다. 객체를 복제하는 이유는 원본 객체를 안전하게 보호하기 위해서이다. 예를 들면, 어떤 인스턴스에 대해 작업을 할 때, 원래의 인스턴스는 보존하고 clone메서드를 이용해서 새로운 인스턴스를 생성하여 작업을 하면 작업이전의 값이 보존되므로 작업에 실패해서 원래의 상태로 되돌리거나 변경되기 전의 값을 참고하는데 도움이 될 것이다.
Object클래스에 정의된 clone()은 단순히 인스턴스변수의 값만을 복사하기 때문에 참조타입의 인스턴스 변수가 있는 클래스는 완전한 인스턴스 복제가 이루어지지 않는다. (얕은 복제)
예를 들어 배열의 경우 복제된 인스턴스도 같은 배열의 주소를 갖기 때문에 복제된 인스턴스의 작업이 원래의 인스턴스에 영향을 미치게된다. 이런 경우 마찬가지로 clone()도 오버라이딩해서 새로운 배열을 생성하고 배열의 내용을 복사하도록 해야 한다.
또한 Cloneable인터페이스를 구현한 클래스에서만 clone()을 호출할 수 있다. Cloneable 인터페이스를 implement 하더라도 메소드 선언을 추가적으로 해주지 않아도 된다. 그럼에도 불구하고 Cloneable 인터페이스를 명시적으로 구현하는 이유는 클래스 설계자가 복제를 허용한다는 의도적인 표시를 하기 위해서이다. 반대로 클래스 설계자가 복제를 허용하지 않는다면 Cloneable 인터페이스를 구현하지 않으면 된다.
Cloneable 인터페이스를 구현하지 않고 clone()을 호출하면 CloneNotSupportedException 예외가 발생하여 복제가 되지 않는다. 추가적으로 clone() 메서드는 CloneNotSupportedException 예외 처리가 필요한 메소드이기 때문에 try-catch 구문이 필요하다.
얕은 복제의 경우 참조 타입 필드는 번지만 복제되기 때문에 원본 객체의 필드와 복제 객체의 필드는 같은 객체를 참조하게 된다. 즉 복제 객체에서 참조 객체를 변경하면 원본 객체도 변경된 객체를 갖게 된다는 의미이다.
그럼 참조하고 있는 객체도 복제하고 싶을때는 어떻게 해야할까? 일단 이를 깊은 복제라 하는데 깊은 복제를 하려면 clone() 메소드를 오버라이딩(재정의)해서 참조 객체를 복제하는 코드를 직접 작성해야 한다.
4) protected void finalize()
이 finalize()메소드는 객체가 소멸되기 직전에 호출된다. -> 사용하지 않는 데이터를 램에서 반납하기 위해
메모리가 부족할 때 그리고 CPU가 한가할 때에 JVM에 의해서 자동 실행된다.
5) public final Class getClass()
getClass()는 객체가 어떤 클래스로 생성되었는지에 대한 정보를 반환한다.
ex)
class Car{
}
public class CarTest{
public static void main(String[] args){
Car obj = new Car();
System.out.println("obj is of type " + obj.getClass().getName());
} //객체를 생성한 클래스 이름을 반환한다.
}
//출력 : obj is of type Car
6) public int hashCode()
객체에 대한 해시 코드를 반환한다. 객체 해시 코드란 객체를 식별할 하나의 정수값을 말한다. Object클래스에 정의된 hashCode() 메소드는 객체의 주소값(메모리 번지)을 이용해서 해시코드를 만들어 리턴하기 때문에 서로 다른 두 객체는 다른 해시코드 값을 갖게된다.
equal() 메소드처럼 클래스의 인스턴스 변수 값으로 객체의 같고 다름을 판단해야하는 경우라면 hashCode메소드도 적절히 오버라이딩해야한다.
→해싱기법을 사용하는 HashMap이나 HashSet과 같은 클래스에 저장할 객체라면 반드시 hashCode메서드를 오버라이딩 해야 한다.
📌Objects 클래스
Object 클래스와 유사한 이름을 가진 java.util.Objects 클래스는 정적 메소드들로 구성된 Object의 유틸리티 클래스다.
1) int compare(T a, T b, Comparator<T> c)
compare(T a, T b, Comparator c) 메소드는 두 객체를 비교자(Comparator)로 비교해서 int 값을 리턴한다.
ex)
Class StudentComparator implements Comparator<Student> {
@Override
public int compare(Student a, Student b) {
if(a.sno < b.sno) return -1; //간단하게 다음 코드로 대체 가능하다.
else if(a.sno == b.sno) return 0; //return Integer.compare(a.sno, b.sno);
else return 1;
}
}
.....
int result = Objects.compare(s1, s2, new StudentComparator());
2) boolean equals()와 deepEquals()
Objects.equals(Object a, Object b)는 두 객체의 동등을 비교한다.
a | b | Objects.equals(a,b) |
not null | not null | a.equals(b)의 리턴값 |
null | not null | false |
not null | null | false |
null | null | true |
Objects.deepEquals(Object a, Object b)
a | b | Objects.equals(a,b) |
not null (not array) | not null (not array) | a.equals(b)의 리턴값 |
not null (array) | not null (array) | Arrays.deepEquals(a,b) |
null | not null | false |
not null | null | false |
null | null | true |
3) 해시코드 생성 (hash(), hashCode())
4) null 여부 조사 (isNull(), nonNull(), requireNonNull())
Objects.isNull(Object obj) | 매개값이 null일 경우 true를 리턴한다. |
Objects.nonNull(Object obj) | 매개값이 not null일 경우 true를 리턴한다. |
Objects.requireNonNull(T obj) Objects.requireNonNull(T obj, String message) Objects.requireNonNull(T obj, Supplier<String> msgSupplier) |
첫 번째 매개값이 not null이면 첫 번째 매개값을 리턴하고, null이면 모두 NullPointerException을 발생시킨다. 두 번째 매개값은 NullPointerException의 예외 메시지를 제공한다. |
5) 객체 문자 정보(toString())
Objects.toString()은 객체의 문자 정보를 리턴한다.
toString(Object o)
toString(Object o, String nullDefault)
첫 번째 매개값이 not null이면 toString()으로 얻은 값을 리턴하고, null이면 "null"또는 두 번째 매개값이 nullDefault를 리턴한다.
📌System 클래스
Java 프로그램은 운영체제상에서 바로 실행되는 것이 아니라 JVM 위에서 실행되기 때문에 운영체제의 모든 기능을 자바 코드로 직접 접근하기가 어렵다.
java.lang 패키지에 속하는 System 클래스를 이용하면 운영체제의 일부 기능을 이용할 수 있다.
System 클래스의 모든 필드와 메소드는 정적(static) 필드와 정적(static)메소드로 구성되어 있다.
1) System.exit(0);
프로그램 종료, 강제적으로 JVM을 종료시킨다. exit 메소드의 매개값으로는 정상 종료일 경우 0으로 지정하고, 비정상 종료일 경우 0 이외의 다른 값을 준다.
2) System.gc();
자바는 개발자가 메모리를 직접 코드로 관리하지 않고 JVM이 알아서 자동으로 관리한다. 바로 Garbage Collector 이를 해주지만, 이는 개발자가 직접 코드로 실행할 수 없고, JVM에게 가능한 빨리 실행해달라고 요청할 수 있다. 그것이 바로 System.gc() 메서드 이다.
3) System.currentTimeMillis(); System.nanoTime();
컴퓨터의 시계로부터 현재 시간을 읽어서 밀리세컨드(1/1000초) 단위와 나노세컨드(1/109초) 단위의 long 값을 리턴한다.
4) System.getProperty(시스템 프로퍼티의 키 이름);
시스템 프로퍼티는 JVM이 시작할 때 자동 설정되는 시스템의 속성값을 말한다. 예를 들어 운영체제의 종류 및 자바 프로그램을 실행시킨 사용자 아이디, JVM의 버전, 운영체제에서 사용되는 파일 경로 구분자 등이 여기에 속한다.
시스템 프로퍼티는 key와 value로 구성되어 있다.
키(key) | 설명 | 값(value) |
java.version | 자바의 버전 | 1.8.0.275 |
java.home | 사용하는 JRE의 파일 경로 | <jdk 설치경로>\jre |
os.name | Operating system name | Windows 10 |
file.separator | File separator ("/" on Unix) | \ |
user.name | 사용자의 이름 | 사용자 계정 |
user.home | 사용자의 홈 디렉터리 | C:\Users\사용자의 계정 |
user.dir | 사용자가 현재 작업 중인 디렉터리 경로 |
5) Systemgetenv(String name);
자바 프로그램에선 환경 변수의 값이 필요할 경우 System.getenv() 메소드를 사용한다. 매개값으로 환경 변수 이름을 주면 값을 리턴한다.
📌Class 클래스
1) getClass(), forName()
Class 객체 얻는 방법이 있다. 첫 번째는 바로 getClass() 메소드를 이용하면 된다. 이 메소드는 해당 클래스로 객체를 생성했을 때만 사용할 수 있다.
getClass.getName() : 클래스 전체 이름
getClass.getSimpleName() : 클래스의 간단한 이름
getClass.getPackage().getName() 패키지 이름
두 번째로 객체를 생성하기 전 직접 Class 객체를 얻을 수도 있는데 이땐, 정적 메소드인 forName()을 이용해야 한다.
forName() 메소드는 클래스 전체 이름(패키지가 포함된 이름)을 매개값으로 받고 Class 객체를 리턴한다.
Class.forName() 메소드는 매개값으로 주어진 클래스를 찾지 못하면 ClassNotFoundException 예외를 발생시키기 때문에 예외 처리가 필요하다.
2) 리플렉션 (getDeclaredConstructors(), getDeclaredFields(), getDeclaredMethods())
Class 객체를 이용하면 클래스의 생성자, 필드, 메소드 정보를 알아낼 수 있다. 이것을 리플렉션이라고 한다.
📌String 클래스
String클래스는 문자열을 저장하고 이를 다루는데 필요한 메서드를 제공한다.
변경 불가능한(immutable) 클래스
String클래스에는 문자열을 저장하기 위해서 문자열 배열 변수(char[]) value를 인스턴스 변수로 정의해놓고 있다. 인스턴스 생성 시 생성자의 매개변수로 입력받는 문자열은 이 인스턴스변수(value)에 문자형 배열(char[])로 저장되는 것이다.
public final class String implements java.io.Serializable, Comparable{
private char[] value;
...
[참고]String클래스는 앞에 final이 붙어 있으므로 다른 클래스의 조상이 될 수 없다.
한번 생성된 String인스턴스가 갖고 있는 문자열은 읽어 올 수만 있고, 변경할 수는 없다.
예를 들어 두 문자열에 '+'연산자를 이용해서 문자열을 결합하는 경우 인스턴스내의 문자열이 바뀌는 것이 아니라 새로운 문자열이 담긴 String인스턴스가 생성된다.
(다른 예) replace() 메소드가 리턴하는 문자열도 원래 문자열의 수정본이 아니라 완전히 새로운 문자열이다.)
덧셈연산자'+'를 사용해서 문자열을 결합하는 것은 매 연산 시 마다 새로운 문자열을 가진 String인스턴스가 생성되어 메모리공간을 차지하게 되므로 가능한 한 결합횟수를 줄이는 것이 좋고, 문자열간의 결합이나 추출 등 문자열을 다루는 작업이 많이 필요한 경우에는 String클래스 대신 StringBuffer클래스를 사용하는 것이 좋다.
StringBuffer인스턴스에 저장된 문자열은 변경이 가능하므로 하나의 StringBuffer인스턴스만으로도 문자열을 다루는 것이 가능하다.
*문자열을 만드는 방법
문자열을 만들때는 두 가지 방법이 있다. 첫번째는 문자열 리터럴을 지정하는 방법과 String클래스의 생성자를 사용해서 만드는 방법이 있다.
String str1 = "abc"; //문자열 리터럴 "abc"의 주소가 str1에 저장됨
String str2 = "abc"; //문자열 리터럴 "abc"의 주소가 str2에 저장됨
String str3 = new String("abc") //새로운 String인스턴스를 생성
String str4 = new String("abc") //새로운 String인스턴스를 생성
String클래스의 생성자를 이용한 경우에는 new연산자에 의해서 메모리할당이 이루어지기 때문에 항상 새로운 String인스턴스가 생성된다. 그러나 문자열 리터럴은 이미 존재하는 것을 재사용하는 것이다.
빈 문자열("", empty String)
String s = "";
이렇게 선언되면 길이가 0인 문자열, 내용이 없는 문자열을 생성할 수 있다.
char형 배열도 길이가 0인 배열을 생성할 수 있고, 이 배열을 내부적으로 가지고 있는 문자열이 바로 빈 문자열이다.
[참고] 크기가 0인 배열을 생성하는 것은 어느 타입이나 가능하다. (자바에서 가능)
ex) char[ ] chArr = new char[0]; //길이가 0인 char 배열
int[ ] iArr = { }; //길이가 0인 int배열
String클래스의 생성자와 메서드
이 중 사용 빈도수가 높은 메소드는 다음과 같다.
- char charAt(int index)
- boolean equals(Object anObject)
- byte[] getBytes()
- byte[] getBytes(Charset charset)
- int indexOf(String str)
- int length()
- String replace(char old, char new)
- String substring(int beginIndex)
- String substring(int beginIndex, int endIndex)
- String toLowerCase()
- String toUpperCase()
- String trim()
- String valueOf(기본 타입)
join( )과 StringJoiner
join()은 여러 문자열 사이에 구분자를 넣어서 결합한다.
구분자로 문자열을 자르는 split()과 반대의 작업을 한다고 생각하면 이해하기 쉽다.
java.util.StringJoiner클래스를 사용해서 문자열을 결합하는 거는 아래 예시를 보면 이해하기 쉽다.
/*join*/
String animals = "dog,cat,bear";
String[] arr = animals.split(","); /*문자열을 ','를 구분자로 나눠서 배열에 저장*/
String str = String.join("-",arr); /*문자열을 '-'로 구분해서 결합*/
System.out.println(str); /*dog-cat-bear*/
/*java.util.StringJoiner*/
StringJoiner sj = new StringJoiner("," , "[" , "]" );
String[] strArr = {"aaa", "bbb", "ccc"};
for(String s : strArr)
sj.add(s.toUpperCase());
System.out.println(sj.toString()); // [AAA,BBB,CCC]
String.format()
format( )은 형식화된 문자열을 만들어내는 간단한 방법이다. printf( )하고 사용법이 완전히 똑같으므로 사용하는데 별 어려움은 없다.
String str = String.format("%d 더하기 %d는 %d입니다.", 3, 5, 3+5);
System.out.println(str); //3 더하기 5는 8입니다.
기본형 값을 String 변환
바꾸는 방법 (방법2가 더 빠름)
int i = 100;
String str1 = i + ""; //String으로 변환하는 방법1
String str2 = String.valueOf(i); //String으로 변환하는 방법2
String을 기본형 값으로 변환
int i = Integer.paresInt("100"); // String을 기본형으로 변환하는 방법1
int i2 = Interger.valueOf("100"); //String을 기본형으로 변환하는 방법2
원래 valueOf의 반환타입은 int가 아니라 Integer인데, 곧 배울 오토방식에 의해 Integer가 int로 자동 변환된다.
예전에는 parseInt()와 같은 메서드를 많이 썼는데, 메서드의 이름을 통일하기 위해 valueOf()가 나중에 추가되었다.
pareseInt()나 parseFloat()같은 메서드는 문자열에 공백 또는 문자가 포함되어 있는 경우 반환 시 예외가 발생할 수 있다.
그래서 문자열 양끝의 공백을 제거해주는 trim()을 습관적으로 같이 사용하기도 한다.
ex)
int val = Integer.parseInt(" 123 ".trim()); //문자열 양 끝의 공백을 제거 후 변환
📌StringTokenizer 클래스
문자열을 StringTokenizer 클래스를 사용하면 손쉽게 문자열(토큰:token)을 분리해 낼 수 있다.
StringTokenizer st = new StringTokenizer("문자열", "구분자");
만약 구분자를 생략하면 공백이 기본 구분자가 된다. 예를 들어 문자열이 "/"로 구분되어 있을 경우, 다음과 같이 사용할 수 있다.
String text = "홍길동/임꺽정/엄복동";
StringTokenizer st = new StringTokenizer(text,"/");
이렇게 해서 StringTokenizer 객체가 생성되면 부분 문자열을 분리해 낼 수 있다. 그리고 메소드를 통해 이를 다룰 수 있다.
메서드 | 설명 |
int countTokens() | 꺼내지 않고 남아 있는 토큰의 수 |
boolean hasMoreTokens() | 남아 있는 토큰이 있는지 여부 |
String nextToken() | 토큰을 하나씩 꺼내옴 |
📌StringBuffer클래스와 StringBuilder클래스
String클래스는 인스턴스를 생성할 때 지정된 문자열을 변경할 수 없지만 StringBuffer 클래스, StringBuilder 클래스는 변경이 가능하다.
쉽게 풀어서 설명하자면 문자열을 결합하는 + 연산자를 많이 사용하면 할수록 그만큼 String 객체의 수가 늘어나기 때문에, 프로그램 성능을 느리게 하는 요인이 된다. 따라서 문자열을 변경하는 작업이 많을 경우에는 String 클래스를 사용하는 것보다는 java.lang 패키지의 String Buffer 또는 StringBuilder 클래스를 사용하는 것이 좋다. 이 두 클래스는 내부 버퍼에 문자열을 저장해두고 추가, 수정, 삭제 작업을 할 수 있도록 설계되어 있기 때문에 String 처럼 새로운 객체를 만들지 않고도 문자열을 조작할 수 있다.
StringBuffer 클래스와 StringBuilder 클래스의 사용 방법은 동일한데 차이점은 StringBuffer는 멀티 스레드 환경에서 사용할 수 있도록 동기화가 적용되어 있어 스레드에 안전하고, StringBuilder는 단일 스레드 환경에서만 사용하도록 설계되어 있다.
StringBuilder 메소드
메소드 | 설명 |
append(...) | 문자열 끝에 주어진 매개값을 추가 |
insert(int offset, ...) | 문자열 중간에 주어진 매개값을 추가 |
delete(int start, int end) | 문자열의 일부분을 삭제 |
deleteCharAt(int index) | 문자열에서 주어진 index의 문자를 삭제 |
replace(int start, int end, String str) | 문자열의 일부분을 다른 문자열로 대치 |
StringBuilder reverse() | 문자열의 순서를 뒤바꿈 |
setCharAt(int index, char ch) | 문자열에서 주어진 index의 문자를 다른 문자로 대치 |
StringBuffer의 생성자
StringBuffer클래스의 인스턴스를 생성할 때, 적절한 길이의 char형 배열이 생성되고, 이 배열은 문자열을 저장하고 편집하기 위한 공간(buffer)으로 사용된다.
StringBuffer인스턴스를 생성할 때는 생성자 StringBuffer(int length)를 사용해서 StringBuffer인스턴스에 저장될 문자열의 길이를 고려하여 충분히 여유있는 크기로 지정하는 것이 좋다. StringBuffer인스턴스를 생성할 때, 버퍼의 크기를 지정해주지 않으면 16개의 문자를 저장할 수 있는 크기의 버퍼를 생성한다.
(버퍼가 작으면 성능 저하 - 작업 중에 더 큰 배열의 생성이 필요하다.)
public StringBuffer(int length){
value = new char[length];
shared = false;
}
public StringBuffer(){
this(16); //버퍼의 크기를 지정하지 않으면 버퍼의 크기는 16이 된다.
}
public StringBuffer(String str){
this(str.length() + 16); //지정한 문자열의 길이보다 16이 더 크게 버퍼를 생성한다.
append(str);
}
StringBuffer의 변경
String과 달리 StringBuffer는 내용을 변경할 수 있다.
StringBuffer sb = new StringBuffer("abc");
그리고 sb에 문자열 "123"을 추가하면,
sb.append("123"); //sb의 내용 뒤에 "123"을 추가한다.
append()는 반환타입이 StringBuffer인데 자신의 주소를 반환한다. 그래서 만약 아래와 같이하면
String sb2 = sb.append("ZZ") //sb의 내용뒤에 "ZZ"를 추가한다.
System.out.println(sb); //abc123ZZ
System.out.println(sb2); //abc123ZZ
sb에 새로운 문자열이 추가되고 sb자신의 주소를 반환하여 sb2에는 sb의 주소값이 저장된다.
StringBuffer의 비교
String클래스와 달리 equals()를 오버라이딩하지 않았다.
StringBuffer sb = new StringBuffer("abc");
StringBuffer sb2 = new StringBuffer("abc");
System.out.println(sb==sb2); //false
System.out.println(sb.equals(sb2)); //false
그래서 StringBuffer인스턴스에 담긴 문자열을 비교하기 위해서는 StringBuffer인스턴스에 toString()을 호출해서 String인스턴스를 얻은 다음, 여기에 equals메서드를 사용해서 비교해야한다.
String s = sb.toString();
String s2 = sb2.toString();
System.out.println(s.equals(s2)); //true
StringBuffer클래스의 생성자와 메서드
📌Pattern 클래스
문자열이 정해져 있는 형식으로 구성되어 있는지 검증해야 하는 경우가 있다. 예를 들어, 이메일, 전화번호, 날짜 입력 등을 사용자가 제대로 입력했는지 검증해야 할 대 정규 표현식과 비교하면 된다. 정규 표현식을 위해 작성할 수 있는 기호들은 다음과 같다.
[ ] [abc] [^abc] [a-zA-Z] |
한 개의 문자 a, b, c 중 하나의 문자 a, b, c 이외의 하나의 문자 a~z, A~Z 중 하나의 문자 |
\d | 한 개의 숫자, [0-9]와 동일 |
\s | 공백 |
\w | 한 개의 알파벳 또는 한개의 숫자, [a-zA-Z_0-9]와 동일 |
? | 없음 또는 한 개 |
* | 없음 또는 한 개 이상 |
+ | 한 개 이상 |
{n} | 정확히 n개 |
{n,} | 최소한 n개 |
{n, m} | n개에서부터 m개까지 |
( ) | 그룹핑 |
(02|010) | 02 또는 010 |
- | - 포함 |
\d{3,4} | 3자리 또는 4자리 숫자 |
\d{4} | 4자리 숫자 |
\w+ | 한 개 이상의 알파벳 또는 숫자 |
@ | @ |
\. | . |
(\.\w+)? | \.\w+이 없거나 한 번 더 올 수 있음 |
Q1.) 02-123-1234 또는 010-1234-5678 같은 전화번호를 위한 정규 표현식
(02|010)-\d{3,4}-\d{4}
Q2.) white@naver.com 과 같은 이메일 정규 표현식
\w+@\w+\.\w+(\.\w+)?
Pattern 클래스 사용법
문자열을 정규 표현식으로 검증하는 기능은 java.util.regex.Pattern 클래스의 정적 메소드인 matches( ) 메소드를 사용하면 된다.
boolean result = Pattern.matches("정규식", "검증할 문자열");
String regExp = "\\w+@\\w+\\.\\w+(\\.\\w+)?"
String data = "dutmdcjf@naver.com"
boolean result = Pattern.matches(regExp, data);
if(result) System.out.println("정규식과 일치");
else System.out.println("정규식과 불일치");
📌Arrays 클래스
int binarySearch(배열, 찾는값) | 전체 배열 항목에서 찾는 값이 있는 인덱스 리턴 |
타겟 배열 copyOf(원본배열, 복사할 길이) | 원본 배열의 0번 인덱스에서 복사할 길이 만큼 복사한 배열 리턴, 복사할 길이는 원본 배열의 길이보다 커도 되며, 타겟 배열의 길이가 된다. |
타겟 배열 copyOfRange(원본 배열, 시작인덱스, 끝인덱스) | 원본 배열의 시작 인덱스에서 끝 인덱스까지 복사한 배열 리턴 |
boolean deepEquals(배열, 배열) | 두 배열의 깊은 비교(중첩 배열의 항목까지 비교) |
boolean equals(배열, 배열) | 두 배열의 얕은 비교(중첩 배열의 항목은 비교하지 않음) |
void fill(배열, 값) | 전체 배열 항목에 동일한 값을 저장 |
void fill(배열, 시작인덱스, 끝인덱스, 값) | 시작 인덱스부터 끝 인덱스까지의 항목에만 동일한 값을 저장 |
void sort(배열) | 배열의 전체 항목을 오름차순으로 정렬 |
String toString(배열) | "[값1, 값2, ... ]" 와 같은 문자열 리 |
📌Math 클래스
Math클래스의 생성자는 접근 제어자가 private이기 때문에 다른 클래스에서 Math인스턴스를 생성할 수 없도록 되어있따. 그 이유는 클래스 내에 인스턴스변수가 하나도 없어서 인스턴스를 생성할 필요가 없기 때문이다. Math클래스의 메서드는 모두 static이며, 아래와 같이 2개의 상수만 정의해 놓았다.
Random 클래스
Math.random() 메소드는 0.0~1.0 사이의 double 난수를 얻는다면,
Random 클래스는 boolean, int, long, float, double 난수를 얻을 수 있다. 또한 Random 클래스는 종자값(seed)을 설정할 수 있다. 종자값은 난수를 만드는 알고리즘에 사용되는 값으로 종자값이 같으면 같은 난수를 얻는다.
Random 객체 생성
Random( ) | 호출 시마다 다른 종자값(현재시간 이용)이 자동 설정된다. |
Random(long seed) | 매개값으로 주어진 종자값이 설정된다. |
Random 클래스의 메소드
boolean nextBoolean() | boolean 타입의 난수를 리턴 |
double nextDouble() | double 타입의 난수를 리턴(0.0 <= ... < 1.0) |
int nextInt() | int 타입의 난수를 리턴(-2^32 <= ... <= 2^32-1) |
int nextInt(int n) | int 타입의 난수를 리턴(0 <= ... < n) |
EX1) 1~45 범위의 정수 숫자만 선택 : nextInt(45)+1
📌Wrapper(포장) 클래스
기본형을 클래스로 정의한 것. 기본형 값도 객체로 다뤄줘야 할 때가 있기 때문이다.
예를 들면, 매개변수로 객체를 요구할 때, 기본형 값이 아닌 객체로 저장해야할 때, 객체 간의 비교가 필요할 때 등등의 경우에는 기본형 값들을 객체로 변환하여 작업을 수행해야 한다.
-내부적으로 기본형 변수를 가지고 있다.
public final class Integer extends Number Implements Comparable{
...
private int value;
...
}
📌Number클래스
숫자를 멤버변수로 갖는 클래스의 조상( 추상클래스 )
'Java' 카테고리의 다른 글
[Java] TCP 네트워킹 - (4)스레드 병렬 처리 (0) | 2022.06.06 |
---|---|
[Java] IO 기반 입출력 - (1)입력 스트림과 출력 스트림 (0) | 2022.06.05 |
BufferedReader / BufferWriter (0) | 2022.04.01 |
[Java] 스트림(stream) (0) | 2021.08.07 |
[Java] 람다식 (Lambda expression) (0) | 2021.08.07 |