java.lang 패키지

  • 자바 프로그래밍에서 가장 기본이 되는 클래스들을 포함

    • import문 없이 사용할 수 있음
  • 자주 사용되는 클래스

    • Object 클래스 / String 클래스 / StringBuffer & StringBuilder 클래스 / Math 클래스 / 래퍼(wrapper)클래스



Object 클래스

  • 모든 클래스의 최고 부모(조상/시조)클래스

  • Object 클래스의 멤버들은 모든 클래스에서 바로 사용 가능

  • 멤버변수는 없고 11개의 메서드만 가지고 있음

Object 클래스의 메서드 설명
protected Object clone() 객체 자신의 복사본을 반환
→ 객체 자신의 복사본(참조변수의 경우는 주소)를 복사(얕은 복사)하기 때문에 완전한 복사를 위해서는 overriding해서 사용할 것(깊은 복사)
→ 사용하려면
→→ 복제할 클래스가 Cloneable 인터페이스를 구현해야 함
→→→ Cloneable 인터페이스를 구현해야만 복제를 허용한다는 의미
→→ 접근 제어자를 protected에서 public으로 변경
→→ 부모클래스의 clone()을 호출하는 try-catch문을 작성
공변반환타입(JDK 1.5 ~ : covariant return type)
→ 오버라이딩할 때 부모메서드의 반환타입을 자식클래스의 타입으로 변경 허용
→ 부모클래스의 반환타입이 아닌, 반환되는 자식클래스의 타입으로 반환할 수 있어서 번거로운 형 변환이 줄어듦
public boolean equals(Object obj) 객체 자신과 객체 obj가 같은 객체인지 알려줌
같으면 true, 다르면 false 반환
→ 두 개의 참조변수가 같은 객체를 참조하고 있는지 판단(주소값)
→→ 내용을 비교하고 싶다면 overriding해서 사용할 것
protected void finalize() 객체가 소멸될 때 가비지 컬렉터에 의해 자동적으로 호출
이 때 수행되어야 하는 코드가 있을 때 오버라이딩(거의 사용 안함)
public Class getClass() 객체 자신의 클래스 정보를 담고있는 Class 인스턴스를 반환
public int hashCode() 객체 자신의 해시코드를 반환
→ 해싱(hashing)기법에 사용되는 해시함수 구현
→→ 해싱 : 데이터관리기법, 다량의 데이터릉 저장하고 검색하는데 유용
→ Object클래스에 정의된 hashCode메서드는 객체의 구조값을 이용해 해시코드 생성 = 서로 다른 두 객체는 서로 다른 hashCode
→→ 내용을 비교하기 위해 equlas를 overriding할 때 적절히 같이 해줘야 함
→ String은 문자열의 내용이 같으면, 동일한 해시코드를 반환하도록 overriding되어있음(String 객체 hashCode로 비교시 같은 응답 나옴)
→→ System.identityHashCode(Object x)는 객체의 주솟값으로 해시코드를 생성 = 모든 객체에 항상 다른 해시코드를 반환할 것을 보장 (String 객체 둘 비교시 다른 응답 나옴)
public String toString() 객체 자신의 정보를 문자열로 반환
→ 기본 : Class명@hashCode
→ 일반적으로 인스턴스나 클래스에 대한 정보 또는 인스턴스 변수의 값을 문자열로 변환하여 반환하도록 overriding
public void notify() 객체 자신을 사용하려고 기다리는 쓰레드를 하나만 깨움
public void notifyAll() 객체 자신을 사용하려고 기다리는 모든 쓰레드를 깨움
public void wait()
public void wait(long timeout)
public void wait(long timeout, int nanos)
다른 쓰레드가 notify()나 notifyAll()을 호출할 때까지 현재 쓰레드를 무한히 또는 지정된 시간(timeout, nanos)동안 기다리게 함
time = 1/1000, nonos = 1/10^9



Object 클래스 - clone의 사용 예

int[] arr = {1, 2, 3, 4, 5};

// clone을 이용한 복사
int[] arrCloneA = arr.clone();

// System.arraycopy()를 이용한 복사
int[] arrCloneB = new int[arr.length];              // 배열 생성
System.arraycopy(arr, 0, arrCloneB, 0, arr.length); // 배열 복사


/* clone을 이용한 복사 대상
 * array(배열)
 * java.util 패키지의 Vector, ArrayList, LinkedList, HashSet, TreeSet
 *                   , HashMap, TreeMap, Calendar, Data
 * Cloneable 인터페이스를 구현한 클래스
 */
ArrayList listA = new ArrayList();
              ...
ArrayList listB = (ArrayList)list.clone();



Object 클래스 - class 객체

  • 클래스의 모든 정보를 담고 있음

  • 클래스 당 1개만 존재

  • 클래스 파일이 클래스로더(ClassLoader)에 의해 메모리에 올라갈 떄 자동으로 생성됨

  • 클래스로더(ClassLoader)

    • 실행 시에 필요한 클래스를 동적으로 메모리에 로드

    • 기존에 생성된 클래스 객체가 메모리에 존재하는지 확인

    • 메모리에 존재하면 객체의 참조를 반환
      메모리에 존재하지 않으면 클래스 패스(classpath)에 지정된 경로를 따라서 클래스 파일을 찾음

    • 클래스 파일을 찾으면 해당 클래스 파일을 읽어서 Class 객체로 변환
      클래스 파일을 못찾으면 ClassNotFoundException 발생

    • 클래스 파일을 메모리에 로드하고 변환

  • 파일 형태로 저장되어 있는 클래스를 읽어서 Class 클래스에 정의된 형식으로 변환하는 것

  • 클래스 파일을 읽어서 사용하기 편한 형태로 저장해놓은 것

/* Class 객체 얻기 */
Class cObj = new Sunny().getClass(); // 생성된 객체로부터 얻기
Class cObj = Sunny.class;            // 클래스 리터럴(.*class)로부터 얻기
Class cobj = Class.forName("Sunny"); // 클래스 일므으로 부터 얻기

/* 객체 생성하기 */
Sunny s = new Sunny();               // new 연산자를 이용해 객체 생성
Sunny s = Sunny.class.newInstance(); // Class 객체를 이용해 객체 생성
  //newInstance()는 InstantiationException 발생 가능하므로 예외처리 필요

// 추가 동적으로 객체 생성 및 메서드를 호출하는 방법 : 리플렉션API(reflection API) 검색
// Java API문서에서 Class 객체를 찾아보면 클래스의 정보를 얻을 수 있는 많은 수의 메서드가 있음



String 클래스

  • Java에서 제공하는 문자열을 위한 클래스

    • 문자열을 저장하고 이를 다루는데 필요한 메서드를 제공
  • 변경 불가능한(immutable) 클래스

    • 앞에 final이 붙어있으므로 상속 불가

    • String클래스는 문자열을 저장하기 위해서 문자열 배열 변수(char[]) value를 인스턴스 변수로 정의

    • 인스턴스 생성 시 생성자의 매개변수로 입력받는 문자열은 이 인스턴스 변수(value)에 문자형 배열(char[])로 저장

    • 한번 생성된 String 인스턴스가 갖고 있는 문자열은 읽어올 수만 있고, 변경할 수는 없음



String 클래스 - 문자형 결합

  • 새로운 문자열이 담긴 String 인스턴스를 생성하는 것 → 결합 횟수를 줄이는 것이 좋음

  • 문자열을 다루는 작업이 많이 필요하다면

    • String 사용시 새로운 인스턴스를 계속 생성하여 메모리공간을 차지

    • StringBuffer클래스를 사용하는 것이 좋음(문자열 변경 가능하기 때문)



String 클래스 - 문자형 비교 방법 2가지

  • 문자열 리터럴을 지정

  • 이미 존재하는 리터럴을 재사용함

    • String strA = “abc”; // 문자열 리터럴 “abc”의 주소가 strA, strB에 저장됨
      String strB = “abc”; // 같은 주소값 저장

    • strA.equals(strB) → true : 값 비교
      strA==strB → true : 주소값 비교

  • String 클래스의 생성자를 사용

    • new 연산자에 의해서 메모리 할당이 이루어짐 (늘 새로운 String 인스턴스)

    • String strA = new String(“abc”); // 새로 String 인스턴스가 생성되기 때문에
      String strB = new String(“abc”); // 다른 주소값

    • strA.equals(strB) → true : 값 비교
      strA==strB → false : 주소값 비교



String 클래스 - 문자열 리터럴

  • 자바 소스파일에 포함된 모든 문자열 리터럴은 컴파일 시에 클래스 파일에 저장

    • 클래스파일에 소스파일에 포함된 모든 리터럴의 목록이 있음

    • 해당 클래스파일이 클래스 로더에 의해 메모리에 올라갈 때, 이 리터럴의 목록에 있는 리터럴들이 JVM내에 있는 상수 저장소(constant pool)에 저장

  • 같은 내용의 문자열 리터럴은 한 번만 저장

    • 문자열 리터럴도 String 인스턴스이고, 한 번 생성하면 내용을 변경할 수 없으니 하나의 인스턴스를 공유하면 되기 때문



String 클래스 - 빈 문자열(empty string)

  • char형 배열도 길이가 0인 배열을 생성할 수 있고, 이 배열을 내부적으로 가지고 있음

    • (길이가 0인 배열은 존재할 수 있음 - C언어는 불가)
  • String s = “”; 일 때, 참조변수 s가 참조하고 있는 String 인스턴스는 내부에 ‘new char[0]’같이 길이가 0인 char형 배열을 저장

    • char c = ‘‘;는 불가 → char는 반드시 한 개의 문자를 지정해야 함 > char c = ‘ ‘;
  • String의 초기화

    • 보통 각 타입의 기본값으로 초기화함

    • String은 기본값인 null보다는 빈 문자열로, char는 기본값인 ‘\u000’대신 공백으로 초기화하는 것이 보통



String 클래스 - 자주 쓰는 생성자와 메서드

메서드 / 설명 예제 결과
String(String s)
: 문자열을 갖는 인스턴스 생성
String s = new String(“Sunny”); s = “Sunny”
String(char[] value)
: 문자배열을 문자열로 생성
char[] c = {‘S’, ‘u’, ‘n’, ‘n’, ‘y’};
String s = new String(c);
s = “Sunny”
String(StringBuffer buf)
: StringBuffer와 같은 문자열 생성
StringBuffer sb = new StringBuffer(“Sunny”);
String s = new String(sb);
s = “Sunny”
char charAt(int index)
: 문자열의 index번째 문자 출력
String s = “Sunny”;
String n = “12345”;
char c1 = s.charAt(1);
char
c2 = n.charAt(1);
c1 = ‘u’
c2 = ‘2’
int compareTo(String str)
: 주어진 문자열과 사전기준 정렬 비교
-1 (이전) / 0 (동일) / 1 (이후)
int i1 = “aaa”.compareTo(“bbb”);
int i2 = “bbb”.compareTo(“bbb”);
int i3 = “ccc”.compareTo(“bbb”);
i1 = -1
i2 = 0
i3 = 1
String concat(String str)
: 문자열을 덧붙임
String s1 = “Su”;
String s2 = s.concat(“nny”);
s1 = Su
s2 = Sunny
boolean contains(CharSequence s)
: 지정된 문자열이 포함되었는지 검사
* CharSequence
=> String이 구현하고 있는 Interface임(StringBuffer/StringBuilder 등도)
String s = “Sunny”;
boolean b = s.contains(“un”);
b = true
boolean endsWith(String suffix)
: 주어진 문자열로 끝나는지 검사
String file = “Sunny.txt”;
boolean b = file.endWith(“txt”);
b = true
boolean equals(Object obj)
: 주어진 문자열 값을 비교
값이 다르면 false
주어진게 문자열이 아니면 false
String s = “Sunny”;
boolean b1 = s.equals(“Sunny”);
boolean b2 = s.equals(“sunny”);
boolean b3 = s.equals(123);
b1 = true
b2 = false
b3 = false
boolean equalsIgnoreCase(String str)
: 주어진 문자열과 대소문자 구분없이 값을 비교
String s = “Sunny”;
boolean b1 = s.equals(“Sunny”);
boolean b2 = s.equals(“suNny”);
b1 = true
b2 = true
int indexOf(int ch)
: 주어진 문자가 존재하는지 확인하여 위치(index)를 알려줌, 없으면 -1를 반환
String s = “Sunny”;
int idx1 = s.indexOf(‘y’);
int idx2 = s.indexOf(‘z’);
idx1 = 4
idx2 = -1
int indexOf(int ch, int pos)
: 주어진 문자가 존재하는지 지정된 위치부터 확인하여 위치(index)를 알려줌, 없으면 -1 반환
String s = “Sunny”;
int idx1 = s.indexOf(‘n’, 0);
int idx2 = s.indexOf(‘n’, 3);
int idx3 = s.indexOf(‘n’, 4);
idx1 = 2
idx2 = 3
idx3 = -1
int indexOf(String str)
: 주어진 문자열이 존재하는지 확인하여 그 시작위치(index)를 알려줌, 없으면 -1 반환
String s = “Sunny”;
int idx1 = s.indexOf(‘un’);
int idx2 = s.indexOf(‘Suni’);
idx1 = 1
idx2 = -1
String intern()
: 문자열을 상수풀(constant pool)에 등록, 이미 상수풀에 같은 내용의 문자열이 있을 경우 그 문자열의 주소값을 반환
String s1 = new
String(“Sunny”);
String s2 = new String(“Sunny”);
boolean b1 = (s1==s2);
boolean b2 = s1.equals(s2);
boolean b3 = (s.intern()=s2.intern());
b1 = false
b2 = true
b3 = true
int lastIndexOf(int ch)
: 지정한 문자 또는 문자코드를 문자열의 오른쪽 끝에서부터 찾아서 위치(index)를 알려줌, 못찾으면 -1
String s = “Sunny”;
int inx1 = s.lastIndexOf(‘n’);
int inx2 = s.indexOf(‘n’);
idx1 = 3
idx2 = 2
int lastIndexOf(String str)
: 지정된 문자열을 문자열의 오른쪽 끝에서부터 찾아서 위치(index)를 알려줌, 못찾으면 -1
String s = “SunnySun”;
int inx1 = s.lastIndexOf(“Sun”);
int inx2 = s.indexOf(“Sun”);
idx1 = 5
idx2 = 0
int length()
: 문자열의 길이 반환(이루어진 문자수)
String s = “Sunny”;
int length = s.length();
length = 5
String replace(char old, char nw)
: old 문자를 nw문자로 모두 치환(변경)
String s1 = “Sunny”;
String s2 = s1.replace(‘S’, ‘F’);
s2 = “Funny”
String replace(CharSequence old, CharSequence nw)
: old 문자열을 nw문자열로 모두 치환
String s1 = “SunnySunday”;String s2 = s1.replace(“Sun”, “Mon”); s2 = “MonnyMonday”
String replaceAll(String regex, String replacement)
: 문자열 중 지정된 문자열(regex:정규식식지원)을 새로운 문자열로 치환
String s1 = “Sunny”;
String s2 = s1.replaceAll(“n”, “O”);
s2 = “SuOOy”
String replaceFirst(String regex, String replacement)
: 문자열 중 지정된 문자열(regex:정규식지원)과 일치하는 것 중 첫 번재 문자열만 새로운 문자열로 치환
String s1 = “Sunny”;
String s2 = s1.replaceFirst(“n”, “O”);
s2 = “SuOny”
String[] split(String regex)
: 문자열을 지정된 분리자로 나누어 문자열 배열에 담아 반환
String s1 = “Su,n”;
String[] s2 = s1.split(“,”);
String[] s3 = s1.split(“”);
s2[0] = “Su”, s2[1] = “n”
s3[0] = “S”, s3[1] = “u”,
s3[2] = “,”, s3[3] = “n”
String[] split(String regex, int limit)
: 문자열을 지정된 분리자로 나누어 문자열 배열에 담아 반환, 단 문자열 배열의 사이즈는 limit로, 초과될 경우 마지막배열에서는 나누지 않음
limit이 음수라면 0 length String도 포함
limit이 0이라면, 0 length String은 포함하지 않음
String weather = “Sunny,Cloudy,Windy,,”;
String[] s1 = weather.split(“,”,2);
String[] s2 = weather.split(“,”,-1);
String[] s3 = weather.split(“,”,0
s1[0] = “Sunny”
s1[1] = “Cloudy,Windy,,”
s2[0] = “Sunny”
s2[1] = “Cloudy”
s2[2] = “Windy”
s2[3] = ““
s2[4] = ““
s3[0] = “Sunny”
s3[1] = “Cloudy”
s3[2] = “Windy”
boolean startsWith(String prefix)
: 주어진 문자열로 시작하는지 검사
String s = “Sunny”;
boolean b1 = s.startsWith(“Sun”);
boolean b2 = s.startsWith(“Mon”);
b1 = true
b2 = false
String substring(int begin)
String substring(int begin, int end)

: 주어진 시작 위치 begin부터 끝 위치(end)의 범위에 포함된 문자열 추출
끝 위치 명시안되면, 맨 끝까지
시작위치 <= 문자열 < 끝위치
String s1 = “Sunny”;
String s2 = s.substring(3);
String s3 = s.substring(2,4);
s2 = “ny”
s3 = “nn”
String toLowerCase()
: 모든 문자열을 소문자로 변환 반환
String s1 = “SuNny”;
String s2 = s1.toLowerCase();
s2 = “sunny”
String toString()
: String인스턴스에 저장된 문자열 반환
String s1 = “SuNny”;
String s2 = s1.toString();
s2 = “SuNny”
String toUpperCase()
: 모든 문자열을 대문자로 변환 반환
String s1 = “SuNny”;
String s2 = s1.toUpperCase();
s2 = “SUNNY”
String trim()
: 왼쪽 오른쪽 공백 제거
가운데 공백은 제거하지 않음
String s1 = “ Su Nny “
String s2 = s1.trim();
s2 = “SuNny”
static String valueOf(boolean b)
static String valueOf(char c)
static String valueOf(int i)
static String valueOf(long l)
static String valueOf(float f)
static String valueOf(double d)
static String valueOf(Object o)

: 지정된 값을 문자열로 변환하여 반환
참조변수의 경우, toString()을 호출한 결과를 반환
String b = String.valueOf(true);
String c = String.valueOF(‘a’);
String i = String.valueOF(100);
String l = String.valueOF(100L);
String f = String.valueOF(10.0f);
String d = String.valueOF(10.0);
java.util.Date dd = new java.util.Date();
String date = String.valueOf(dd);
b = “true”
c = “a”
i = “100”
l = “100”
f = “10.0”
d = “10.0”
date = “Fri Aug 09 18:13:25 KST 2019”



String 클래스 - join()과 StringJoiner (JDK 1.8~)

  • join : 여러 문자열 사이에 구분자를 넣어서 결합

    • split과 반대의 작업
  • StringJoiner : 구분자, 시작문자, 끝문자 지정해놓고 문자열을 add해서 추가

/* String의 join(String str) 메서드 */
String weather = "Sunny,Cloudy,Windy";
String[] arr = weather.split(",");  // weather 문자열을 ','를 구분자로 나눠서 배열에 저장
String str = String.join("&", arr); // arr 배열의 문자열을 "&"로 구분 결합
System.out.println(str);            // Sunny-Cloudy-Windy

/* java.util.StringJoiner 클래스 */
import java.util.StringJoiner // import 필요

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 클래스 - 유니코드의 보충문자

  • String의 매개변수 타입이 char인 것이 있고 int 인 것이 있음

    • char ch : 문자 지원

    • int ch: 문자 지원 + 보충문자 지원

  • 보충문자(supplementary characters)

    • 유니코드는 원래 2byte, 즉 16bit 문자체계인데, 이걸로 모자라서 20비트로 확장하게 됨(JDK 1.5~)

    • 확장한 문자는 하나의 char타입으로 다루지 못하고, int 타입으로밖에 다루지 못함



String 클래스 - 문자 인코딩 변환

  • getBytes(String charsetName)를 사용하면, 문자열의 문자 인코딩을 다른 인코딩으로 변경할 수 있음

  • 문자 인코딩

    • 자바 : UTF-16 사용

    • 문자열 리터럴에 포함되는 문자 : OS의 인코딩

    • 한글 윈도우즈 : CP949(MS949) 사용

  • 한글 인코딩

    • UTF-8 : 한글 한 글자를 3 byte로 표현 / ‘가’ : ‘0xEAB080’

    • CP949(MS949) : 한글 한 글자를 2 byte 표현 / ‘가’ : ‘0xB0A1’

  • 사용 가능한 문자 인코딩 목록

    • System.out.println(java.nio.charset.Charset.availableCharsets());로 모두 출력 가능
  • 문자열을 UTF-8로 변경하기

    • byte[] utf8_str = “가”.getBytes(“UTF-8”); // 문자열을 UTF-8로 변환

    • String str = new String(utf8_str, “UTF-8”); // byte 배열을 문자열로 변환



String 클래스 - String.format()

  • 형식화된 문자열을 만들어내는 간단한 방법

  • pritnf와 사용법이 완전히 동일

  • 예제

String str = String.format("%s는 %s입니다.", "날씨", "맑음");
System.out.println(str)  날씨는 맑음입니다.



String 클래스 - 기본형 값을 String으로 변환

  • 숫자 + ““(빈 문자열)

    • 사용이 편리 (많이 씀)
  • valueOf(숫자)

    • 성능이 더 좋음



String 클래스 - 참조형 값을 String으로 변환

  • 참조변수 + String

    • 참조변수가 가리키는 인스턴스의 toString()을 호출하여 String을 얻어온 후 결합
기본형 → 문자형 문자형 → 기본형
String String.valueOf(boolean b)
String String.valueOf(char c)
String String.valueOf(int i) // byte, short도
String String.valueOf(long l)
String String.valueOf(float f)
String String.valueOf(double d)
boolean Booelan.parseBoolean(String s)
byte Byte.parseByte(String s)
short Short.parseShort(String s)
int Integer.parseInt(String s)
→ int Integer.parseInt(String s, int radix)
→→ 진법적용 변환 // 16진법이면 a,b,c,d,e,f 사용 가능
→→→ (“a”, 16) = 10 (10진법으로 치환되어 값이 나옴)
long Long.pasreLong(String s)
float Float.parseFloat(String s)
double Double.parseDouble(String s)
// 부호 접두사 “+”, “-“ 사용 가능
// 소수는 소수점을 의미하는 “.” 사용 가능
// 각자 자기에 맞는 자료형 접미사 사용 가능

char ch = String.charAt(0); // 첫번째 글자만



StringBuffer & StringBuilder 클래스 - StringBuffer 개념

  • String 클래스는 인스턴스 내부를 수정할 수 없지만 StringBuffer는 변경 가능

    • 내부적으로 문자열 편집을 위한 버퍼(buffer)를 가지고 있음

    • StringBuffer 인스턴스 생성시 크기 지정 가능

  • Buffer 크기는 문자열 길이를 고려하여 적당히 잡아줘야 함

    • 편집중인 문자열이 버퍼의 길이를 넘어서면, 길이를 늘려주는 작업이 추가로 수행되어야 하기 때문에 효율이 떨어짐

    • 버퍼가 너무 크면, 메모리를 많이 차지

  • String 클래스와 비슷하게 문자열을 저장하기 위한 char형 배열의 참조변수를 인스턴스 변수로 선언

  • StringBuffer 인스턴스가 생성될 때, char형 배열이 생성되고, 이 때 생성된 char형 배열을 인스턴스변수가 참조하게 됨



StringBuffer & StringBuilder 클래스 - StringBuffer 생성자

  • StringBuffer클래스의 인스턴스를 생성

    • 적절한 길이의 char형 배열이 생성

    • 문자열을 저장하고 편집하기 위한 공간(buffer)으로 사용

  • 생성시에는 생성자 StringBuffer(int length)를 사용하여 충분히 여유있는 크기로 지정하는 것이 좋음

    • 지정하지 않을 경우 16개의 문자를 저장할 수 있는 크기의 버퍼 생성

    • StringBuffer(String str)을 사용하면 문자열의 길이 + 16개의 문자를 저장할 수 있는 크기의 버퍼 생성

  • 버퍼의 크기가 사용하려는 것보다 작으면

    • 배열의 길이는 변경될 수 없으므로 새로운 길이의 배열을 생성한 후 이전 배열의 값을 복사



StringBuffer & StringBuilder 클래스 - StringBuffer 변경

  • String과 달리 StringBuffer는 내용을 변경할 수 있음

  • StringBuffer명.append(String str);

    • StringBuffer명에 str를 추가함

    • 반환타입은 StringBuffer : 자신의 주소를 반환(값 반환 X)



StringBuffer & StringBuilder 클래스 - StringBuffer 비교

  • equals

    • String클래스 : equals 메서드를 오버라이딩해서 문자열의 내용을 비교하도록

    • StringBuffer클래스 : equals 메서드를 오버라이딩하지 않음

    • equals와 ==이 결과가 같음

  • toString()

    • StringBuffer클래스 : 오버라이딩 되어있음

    • 담고 있는 문자열을 String으로 변환

  • StringBuffer 인스턴스끼리 문자열을 비교하려면?

    • StringBuffer인스턴스의 toString() 메소드 호출 후 equals 메서드로 비교



StringBuffer & StringBuilder 클래스 - 생성자와 메서드

  • String클래스와 유사한 메서드가 많음

  • 추가, 변경, 삭제와 같이 저장된 내용을 변경할 수 있는 메서드들이 추가로 제공

메서드 / 설명 예제 결과
StringBuffer()
:16문자를 담을 수 있는 버퍼를 가진 StringBuffer 인스턴스 생성
StringBuffer sb = new StringBuffer(); sb = “”
StringBuffer(int length)
: length 개수의 문자를 담을 수 있는 버퍼를 가진 StringBuffer 인스턴스 생성
StringBuffer sb = new StringBuffer(5); sb = “”
StringBuffer(String str)
: 문자열 값을 갖고 추가로 16문자를 담을 수 있는 StringBuffer 생성
StringBuffer sb = new StringBuffer(“abc”); sb = “abc”
StringBuffer append(boolean b)
StringBuffer append(char c)
StringBuffer append(char[] str)
StringBuffer append(double d)
StringBuffer append(float f)
StringBuffer append(int i)
StringBuffer append(long l)
StringBuffer append(Object obj)
StringBuffer append(String str)

: 매개변수로 입력된 값을 문자열로 변환 후 StringBuffer 인스턴스가 저장하고 있는 문자열의 뒤에 덧붙임
StringBuffer sb1 = new StringBuffer(“abc”);
String Buffer sb2 = sb1.append(true);
sb1.append(‘d’).append(10.0f);
StringBuffer sb3 = sb1.append(“ABC”).append(123);
sb1 = “abctrued10.0ABC123”
sb2 = “abctrued10.0ABC123”
sb3 = “abctrued10.0ABC123”

// StringBuffer는 주소값을 return하기 때문에 세 참조변수가 같은 주소를 바라보고 있음
int capacity()
: StringBuffer 인스턴스의 버퍼 크기를 알려줌
StringBuffer sb = new StringBuffer(77);
sb.append(“Sunny”);
int bufferSize = sb.capacity();
int StringSize = sb.length();
BufferSize = 100
int length()

: StringBuffer 인스턴스에 저장되어 있는 문자열의 길이를 반환
StringSize = 5
char CharAt(int index)
: 지정된 위치(index)의 문자열 반환
StringBuffer sb = new StringBuffer(“SunNyDaY”);
char c = sb.charAt(3);
c = ‘N’
StringBuffer delete(int start, int end)
: 시작위치 <= 문자열 < 끝위치
에 해당하는 문자열 제거
StringBuffer sb1 = new StringBuffer(“SunNyDaY”);
StringBuffer sb2 = sb1.delete(4,7);
sb1 = “SunNY”;
sb2 = “SunNY”;
StringBuffer insert(int pos, boolean b)
StringBuffer insert(int pos, char c)
StringBuffer insert(int pos, char[] str)
StringBuffer insert(int pos, double d)
StringBuffer insert(int pos, float f)
StringBuffer insert(int pos, int i)
StringBuffer insert(int pos, long l)
StringBuffer insert(int pos, Object obj)
StringBuffer insert(int pos, String str)

: 두 번째 매개변수로 받은 값을 문자열로 반환하여 지정된 위치(pos-index)에 추가
StringBuffer sb = new StringBuffer(“SunnyDay”);
sb.insert(5, ‘-‘);
sb = “Sunny-Day”
StringBuffer replace(int start, int end, String str)
: Start <= 지정된 범위 < end
지정된 범위의 문자열을 주어진 문자열로 변경 → 지정된 범위 문자열이 제거되고 주어진 문자열이 삽입된 모양
StringBuffer sb = new StringBuffer(“SunnyDay”);
sb.replace(2, 5, “77”);
sb = “Su77Day”
// 2, 5에 해당되는 nny가 77로 바뀜
StringBuffer reverse()
: 문자열 순서 거꾸로 저장
StringBuffer sb = new StringBuffer(“Sunny”);
sb.reverse();
sb = “ynnuS”
void setCharAt(int index, char ch)
: 지정된 위치의 문자를 주어진 문자(ch)로 변경
StringBuffer sb = new StringBuffer(“Sunny”);
sb.setCharAt(3, ‘o’);
sb = “Sunoy”
void setLength(int newLength)
: 지정된 길이로 문자열의 길이를 변경
→ 길이를 늘일 때 나머지 빈 공간을 널 문자 ‘\u0000’로 채움
→ 길이를 줄일 때는 제거
StringBuffer sb1 = new StringBuffer(“Sunny”);
sb1.setLenth(6);

StringBuffer sb2 = new StringBuffer(“Sunny”);
sb1.setLenth(1);
sb1 = “Sunny “
sb2 = “S”
String toString()
: StringBuffer 인스턴스의 문자열을 String으로 반환
StringBuffer sb = new StringBuffer(“Sunny”);
String str = sb.toString()
str = “Sunny”
String substring(int start)
String substring(int start, int end)
: 시작위치 <= 지정된 범위 < 끝위치(없으면 맨 끝)
지정된 범위 내의 문자열을 String으로 반환

StringBuffer sb = new StringBuffer(“Sunny”);
String str1 = sb.substring(2);
String str2 = sb.substring(2, 4);
str1 = “nny”
str2 = “nn”



StringBuffer & StringBuilder 클래스 - StringBuilder

  • StringBuffer vs StringBuilder

    • StringBuffer : 멀티쓰레드에 안전(thread safe)하도록 동기화

    • 동기화가 StringBuffer의 성능을 떨어뜨림

    • 멀티쓰레드로 작성된 프로그램이 아닌 경우, 동기화는 불필요하게 성능만 떨어뜨림

    • 충분히 성능이 좋기 때문에 성능 향상이 반드시 필요한 경우를 제외하면 굳이 StringBuilder로 바꿀 필요는 없음

  • StringBuilder : StringBuffer에서 쓰레드 동기화 제거

    • 기능은 동일



Math 클래스

  • 기본적인 수학계산에 유용한 메서드로 구성

  • 생성자의 접근제어가 private이므로 다른 클래스에서 Math인스턴스 생성 불가

  • 메서드는 모두 static

  • 상수 2개 선언되어 있음

    • 자연로그의
      public static final double E = 2.7182818284590452354;

    • 원주율
      public static final double PI = 3.14159265358979323846;

  • 삼각함수와 지수, 로그

    • sqrt() : 제곱근 계산

    • pow() : n제곱 계산

    • 삼각함수 제공



Math 클래스 - 예외를 발생시키는 메서드

  • 메서드 이름에 ‘Exact’가 포함된 메서드들이 JDK 1.8부터 새로 추가

  • 일반 연산자와 차이

    • 일반 연산자 : 단지 결과를 반환할 뿐, 오버플로우의 발생여부에 대해 알려주지 않음

    • 예외를 발생시키는 메서드 : 오버플로우 발생시 예외(ArimeticException)를 발생

  • 종류

    • int addExact(int a, int b) // a + b

    • int subtractExact(int a, int b) // a - b

    • int multiplyExact(int a, int b) // a * b

    • int incrementExact(int a) // a++

    • int decrementExact(int a) // a–

    • int negateExact(int a) // -a - 부호를 바꾸는 식은 -a +1이니까 오버플로우 발생가능

    • int toIntExact(long value) // (int)value - int로의 형변환



Math 클래스 - StrictMath클래스

  • Math클래스는 최대한의 성능을 얻기 위해 JVM이 설치된 OS의 메서드를 호출해서 사용

  • 즉, OS 의존적

  • 부동소수점 계산을 예로 들면, 반올림의 처리방법 설정이 OS마다 다를 수 있기 때문에 자바로 작성된 프로그램임에도 컴퓨터마다 결과가 다를 수 있음

  • Math 클래스의 위와 같은 차이를 없애기 위해 성능을 다소 포기하는 대신,
    어떤 OS에서 실행되어도 항상 같은 결과를 얻도록 Math클래스를 재작성한 것이 StrictMath 클래스



Math 클래스 - 자주 쓰이는 메서드

메서드 / 설명 예제 결과
static double abs(double a)
static float abs(float f)
static int abs(int f)
static long abs(long f)

: 주어진 값의 절댓값 반환
int i = Math.abs(-10);
double d = Math.abs(-10.0);
i = 10
d = 10.0
static double ceil(double a)
: 주어진 값을 일의 자리로 올림 반환
double d1 = Math.ceil(10.1);
double d2 = Math.ceil(-10.1);
double d3 = Math.ceil(10.0000015);
d1 = 11.0
d2 = -10.0
d3 = 11.0
static double floor(double a)
: 주어진 값을 일의 자리로 내림 반환
double d1 = Math.floor(10.8);
double d2 = Math.floor(-10.8);
d1 = 10.0
d2 = -11.0
static double max(double a, double b)
static float max(float a, float b)
static int max(int a, int b)
static long max(long a, long b)

: 주어진 두 값을 비교하여 큰 쪽 반환
double d = Math.max(9.5, 9.50001);
int i = Math.max(0, -1);
d = 9.50001
i = 0
static double min(double a, double b)
static float min(float a, float b)
static int min(int a, int b)
static long min(long a, long b)

: 주어진 두 값을 비교하여 작은 쪽 반환
double d = Math.min(9.5, 9.50001);
int i = Math.min(0, -1);
d = 9.5
i = -1
static double random()
: 0.0<= 임의의 double 값 < 1.0
해당 범위에 해당되는 double 반환
double d = Math.random();
int i = (int)(Math.randome()*10)+1;
0.0 <= d < 1.0
1 <= i < 11
static double rint(double a)
: 주어진 double값과 가장 가까운 정수값을 double형으로 반환(0.5는 절댓값 반올림)
double d1 = Math.rint(5.5);
double d2 = Math.rint(5.1);
double d3 = Math.rint(-5.5);
double d4 = Math.rint(-5.1);
d1 = 6.0
d2 = 5.0
d3 = -6.0
d4 = -5.0
static long round(double a)
static long round(float a)

: 소수점 첫째자리에서 반올림한 정수값(long) 반환,
(주의)음수의 경우 rint()의 결과가 다름
long l1 = Math.round(5.5);
long l2 = Math.round(5.1);
long l3 = Math.round(-5.5);
long l4 = Math.round(-5.1);

double d1 = 78.8624;
double d2 = Math.round(d1*100)/100.0;
l1 = 6
l2 = 5
l3 = -5
l4 = -5

d1 = 78.8624;
d2 = 78.86



래퍼(wrapper) 클래스 - 서론(JAVA)

  • 객체지향 개념에서는 모든 것이 객체로 다루어져야 하는데, 자바에서는 8개의 기본형을 객체로 다루지 않음

    • 자바가 완전한 객체지향 언어가 아니라는 얘기를 듣는 이유

    • 대신 높은 성능을 얻을 수 있었음

  • 기본형(primitive type) 변수를 객체로 다뤄야 하는 경우도 있음 → 객체로 변환하여 작업을 수행해야 함

    • 매개변수로 객체를 요구할 때

    • 기본형 값이 아닌 객체로 저장해야 할 때

    • 객체 간의 비교가 필요할 때

    • etc…



래퍼(wrapper) 클래스

  • 기본형 변수를 객체로 변환할 때 사용되는 것

    • 이 클래스들을 이용하면 기본형 값을 객체로 다룰 수 있음
  • 8개의 기본형을 대표하는 8개의 래퍼클래스가 있음

  • 생성자는 매개변수로 문자열이나 각 자료형의 값들을 인자로 받음

    • (주의) 생성자의 매개변수로 문자열을 제공할 때, 각 자료형에 알맞은 문자열을 사용해야 함

    • 예) Integer면 “1”은 되지만 “1.0”은 실수타입이라 안 됨

  • 모두 equals()가 오버라이딩 되어있음

    • 주소값이 아닌 객체가 갖고있는 값을 비교

    • 값을 비교할 땐 비교연산자 사용 불가 → compareTo() 사용

  • toString()도 오버라이딩 되어있음

    • 객체가 갖고있는 값을 문자열로 변환
  • 공통 static 상수

    • MAX_VALUE, MIN_VALUE, SIZE, TYPE … etc

    • BYTES(JDK 1.8 ~)

기본형 래퍼클래스 생성자 예시
boolean Boolean Boolean(boolean value)
Boolean(String s)
Boolean b1 = new Boolean(true);
Boolean b2 = new Boolean(“False”);
char Character Character(char value) Character c = new Character(‘a’);
byte Byte Byte(byte value)
Byte(String s)
Byte b1 = new Byte(10);
Byte b2 = new Byte(“10”);
short Short Short(short value)
Short(String s)
Short s1 = new Short(10);
Short s2 = new Short(“10”);
int Integer Integer(int value)
Integer(String s)
Integer i1 = new Integer(100);
Integer i2 = new Integer(“100”);
long Long Long(long value)
Long(String s)
Long l1 = new Long(100);
Long l2 = new Long(“100”);
float Float Float(double value)
Float(float value)
Float(String s)
Float f1 = new Float(1.0);
Float f2 = new Float(1.0f);
Float f3 = new Float(“1.0f”);
double Double Double(double value)
Double(String s)
Double d1 = new Double(1.0);
Double d2 = new Double(“1.0”);



래퍼(wrapper) 클래스 - Number클래스

  • 추상클래스

  • 내부적으로 숫자를 멤버변수로 갖는 래퍼클래스들의 조상

public abstract class Number implements java.io.Serializable {
    public abstract int intValue();
    public abstract long longValue();
    public abstract float floatValue();
    public abstract double doubleValue();
    
    public byte byteValue() {
        return (byte)intValue();
    }
    public short shortValue() {
        return (short)intValue();
    }
}
  • 래퍼클래스의 상속 계층도
- Object - Boolean
         - Character
         - Number - Byte, Short, Integer, Long, Float, Double, BigInteger, BigDecimal



BigInteger, BigDecimal

  • BigInteger - long으로도 다룰 수 없는 큰 범위의 정수를 처리하기 위한 것

  • BigDecimal - double로도 다룰 수 없는 큰 범위의 부동 소수점수를 처리하기 위한 것

  • 연산자의 역할을 대신하는 다양한 메서드 제공

  • 실제 소스 → 객체가 가지고 있는 값을 숫자와 관련된 기본형으로 반환하는 메서드들을 정의



래퍼(wrapper) 클래스 - 문자열을 숫자로 변환하기

  • 첫 번째 방법. int i1 = new Integer(“100”).intValue(); // floatValue(), longValue(), …

    • 오토박싱. 언박싱 도입되어 이렇게 사용 가능하지만 성능은 좀 더 느림
  • 두 번째 방법. int i2 = Integer.parseInt(“100”); // 주로 많이 씀

  • 세 번째 방법. Integer i3 = Integer.valueOf(“100”);

문자열 → 기본형 (parse~) 문자열 → 래퍼클래스 (valueOf)
byte b = Byte.parseByte(“7”);
short s = Short.parseShort(“7”);
int i = Integer.parseInt(“7”);
long l = Long.parseLong(“7”);
float f = Float.parseFloat(“7.7”);
double d = Double.parseDouble(“7.7”);

int i = Integer.parseInt(String s, int radix); // 진법 변환
// 생략시 10진법
// ‘A~F’문자가 16진법이 아닐 때 쓰이면 에러
(NumberFormatException)
Byte b = Byte.valueOf(“7”);
Short s = Short.valueOf(“7”);
Integer i = Integer.valueOf(“7”);
Long l = Long.valueOf(“7”);
Float f = Float.valueOf(“7.7”);
Double d = Double.valueOf(“7.7”);

Integer i = Integer.valueOf(String s, int radix); // 진법 변환
// 생략시 10진법
// ‘A~F’문자가 16진법이 아닐 때 쓰이면 에러
(NumberFormatException)



래퍼(wrapper) 클래스 - 오토박싱(autoboxing) & 언박싱(unboxing)

  • (JDK 1.5 이후) 기본형과 참조형 간의 연산이 가능

    • (JDK 1.5 이전) 기본형과 참조형 간의 연산 불가능 → 래퍼 클래스로 기본형을 객체로 만들어서 연산
  • 자바 언어의 규칙이 바뀐 것은 아님

  • 컴파일러가 자동으로 변환하는 코드를 넣어줌

    • 기본형 ↔ 기본형 Wrapper Class 연산시

    • 형변환이 필요할 때

    • 내부적으로 객체 배열을 가지고 있는 Vector 클래스나 ArrayList 클래스에 기본형 값을 저장해야 할 때
      예시

ArrayList<Integer> list = new ArrayList<Integer>();
list.add(10);             // 오토박싱 10 → new Integer(10)
int value = list.get(0); // 언박싱 new Integer(10) → 10
  • 오토박싱(autoboxing)

    • 기본형 값을 래퍼클래스의 객체로 자동 변환해주는 것
  • 언박싱(unboxing)

    • 래퍼클래스의 객체를 기본형 값으로 자동변환 해주는 것
컴파일 전 코드 컴파일 후 코드
int i = 5;
Integer iObj = new Integer(7);
int sum = i + iObj;

Integer intg = (Integer)i;
Object obj = (Object)i;
Long lng = 100L;
int i = 5;
Integer iObj = new Integer(7);
int sum = i + iObj.intValue();

Integer intg = Integer.valueOf(i);
Object obj = (Object)Integer.valueOf(i);
Long lng = new Long(100L);