반응형

**java.lang 패키지
1.Object Class: 자바의 최상위 클래스
=>자바의 모든 클래스는 Object 클래스로부터 상속

2.Wrapper Class
=>기본형 데이터를 참조형으로 만들기 위한 클래스
=>Boolean, Byte, Short, Character, Integer, Long, Float, Double 클래스
=>자바의 자료형이 기본형과 참조형으로 나누어져 있어서 하나의 변수에 모든 데이터를 저장할 수 없습니다.
Object 클래스가 최상위 클래스라서
Object 변수명 = 참조형 데이터; //이 문법은 전부 성립
//상위 클래스의 참조형 변수에 하위 클래스 인스턴스를 대입할 수 있다.

=>기본형은 Object 클래스로부터 상속을 받지 않았기 때문에 대입할 수 가 없습니다.
=>이런 문제를 해결하기 위해서 기본형을 참조형으로 표현하기 위해서 만든 클래스가 Wrapper Class 입니다.

1)기본형과 Wrapper 클래스 인스턴스 사이의 변환
int x = 10; //기본형 데이터 생성
Integer i = new Integer(x); //기본형 데이터를 가지고 참조형 데이터를 생성

//참조형 데이터를 기본형으로 변환
x = i.intValue();

=>int 나 Integer 자리만 다른 자료형으로 변환하면 모든 기본형을 변환해서 사용 가능합니다.

2)AutoBoxing 과 AutoUnboxing
=>Wrapper 형 변수에 기본형 데이터를 바로 대입할 수 있습니다.
Integer i = 10; //Integer i = new Integer(i); //AutoBoxing

int x = i; //int x = i.intValue(); //Auto Unboxing

3)Object 사용
=>어떤 메소드의 매개변수 자료형이 Object 라면 어떤 종류의 데이터 든지 대입이 가능합니다.
=>어떤 메소드의 return type이 Object 라면 그 결과는 반드시 원래의 자료형으로 강제 형 변환해서 사용해야 합니다.

4)실습
public static void main(String[] args) {
//기본형 정수 데이터를 참조형 Integer로 생성
Integer i = new Integer(100);
i = 300; //Auto Boxing(기본형 데이터를 참조형으로 자동 변환해주는 문법)

    //기본형을 참조형으로 표현할 수 있기 때문에 Object 클래스의 변수에는 모든 데이터를 대입가능
    Object obj = 300;
    //obj 는 Integer를 저장하기는 했지만 변수의 자료형이 Object라서
    //Object 것만 사용이 가능합니다.
    //원래 자료형에 있던 intValue()를 사용 못함
    //원래 자료형에 있던 것들을 사용할려면 강제로 원래 자료형으로 변환시켜야 합니다.
    System.out.println(((Integer)obj).intValue());

}

2.BigInteger 와 BigDecimal
=>이 클래스들은 java.math 패키지에 있는 클래스입니다.
1)BigInteger
=>Short 와 Integer 로는 아주 큰 정수를 표현할 수 없습니다.
Integer 가 절대값 21억 정도의 숫자까지만 표현
=>Integer의 범위를 넘어서는 정수를 표현하기 위해서 생성
=>내부적으로는 int [] 로 데이터를 저장
=>생성할 때는 new BigInteger(String number)
new BigInteger("1234567890123");
{1234567, 890123} 의 형태로 나누어서 저장
=>저장하고 있는 데이터를 숫자로 변환할 때는 intValue() 와 같은 메소드가 있어서 이 메소드를 이용해서 리턴

2)BigDecimal
=>정밀한 소수나 큰 정수를 사용하기 위한 클래스
=>소수의 표현 범위 문제 때문에 실수를 가지고 연산을 하면 잘못된 결과가 만들어지는 경우가 있습니다.
숫자를 문자열의 형태로 저장하고 있다가 연산을 할 때 숫자로 변경해서 수행하도록 해주는 클래스
=>생성을 할 때는 생성자에 문자열 형식의 숫자를 대입해서 만들고 숫자로 변환할 때는 intValue 와 같은 메소드를 이용
=>산술 연산을 위한 메소드 제공
=>Oracle 을 연동할 때 MyBatis(Java 코드와 SQL을 분리해서 작성할 수 있는 프레임워크) 라는 프레임워크를 사용하면 Number 가 BigDecimal로 Mapping 됩니다.

3)실습
//실수 연산에 문제점 발생
double d1 = 1.60000000000000000000000000000;
double d2 = 0.10000000000000000000000000000;
System.out.println(d1 + d2);

    //실수 연산 문제 해결하기
    BigDecimal b1 = new BigDecimal("1.60000000000000000000000000000");
    BigDecimal b2 = new BigDecimal("0.10000000000000000000000000000");
    System.out.println(b1.add(b2));
    //프로그래밍 언어와 데이터베이스를 연동하는 경우
    //대부분의 경우 데이터베이스가 더 정밀한 숫자를 저장하는 경우가 많습니다.
    //데이터베이스에 실수를 저장했을 때는 float 이나 double로 받는 것 보다는 BigDecimal
    //같은 클래스를 이용해서 저장하고 연산한 후 결과를 float 이나 double로 표현하는 것이 좋습니다.

3.System 클래스
=>모든 메소드가 static 이라서 생성자가 없음(인스턴스를 생성할 필요가 없음)
정확하게는 없는 것이 아니고 생성자가 private 이라서 외부에서 인스턴스 생성이 안됨

1)필드
in: 표준 입력 객체 - 키보드
err: 에러 출력 객체 - 이 객체를 이용해서 출력하면 콘솔에 빨간색으로 출력
out: 표준 출력 객체 - 이 객체를 이용해서 출력하면 콘솔에 검정색으로 출력
=>err 과 out을 같이 사용하면 출력 순서는 변경되기도 합니다.

2)메소드
static long currentTimeMillis(): 1970년 1월 1일 자정이후부터 지나온 시간을 밀리초 단위로 리턴
=>2038년까지만 표현 가능

static void exit(int status): 프로그램 종료(jvm 종료)
=>매개변수로 대입하는 숫자는 운영체제에게 보내는 메시지입니다.
0은 정상 종료라는 의미이고 나머지 숫자는 에러 메시지입니다.
에러 메시지를 전달하면 운영체제가 메시지에 해당하는 작업을 수행하고 종료시킵니다.
=>c 언어에서의 main 의 리턴과 동일한 의미입니다.

static String getProperty(String key): key 에 해당하는 속성 값을 문자열로 리턴
static Map<String, String> getEnv(): 시스템 환경을 문자열로 리턴
static String getEnv(String key): name에 해당하는 시스템 환경을 문자열로 리턴
=>운영체제 버전이나 환경변수 등을 확인

static int identityHashCode(Object obj): 해시코드를 정수로 리턴
=>HashCode: 데이터를 저장하고 데이터를 구분하기 위해서 붙이는 id와 같은 개념
해시코드가 같으면 저장된 데이터가 같다라는 의미입니다.

3)실습
//운영체제 버전과 자바 버전을 확인
System.out.println(System.getProperty("os.name"));
System.out.println(System.getProperty("java.version"));

4.Math
=>모든 멤버가 static 이라서 인스턴스를 생성할 필요가 없음
=>수학과 관련된 메소드를 소유
=>플랫폼(운영체제) 별로 메소드의 수행결과가 달라질 수 있습니다.
=>이에 대한 대안으로 연산속도는 느리지만 모든 플랫폼에서 연산의 결과를 동일하게 만들어주는 StrictMath 클래스를 제공
=>자바스크립트의 Math 클래스가 이 클래스와 동일

5.Runtime
=>프로세스 실행과 관련된 클래스
=>생성자가 없는 클래스인데 메소드들은 static 과 static이 아닌 메소드가 같이 존재
=>이런 클래스는 디자인 패턴을 적용해서 인스턴스 만드는 방법을 별도로 제공
1)인스턴스 생성
static Runtime getRuntime()을 이용

2)주요 메소드
exec(String name): name에 해당하는 명령을 수행
name을 만들 때 공백을 주고 만들면 뒤의 문자열을 파라미터로 해서 앞의 명령을 수행

3)실습
public static void main(String[] args) {
//Runtime 클래스의 인스턴스 2개 생성
Runtime r1 = Runtime.getRuntime();
Runtime r2 = Runtime.getRuntime();

    //해시코드 출력
    //해시코드가 동일하게 출력
    //Runtime은 인스턴스를 1개만 만들 수 있는 클래스
    //생성하는 메소드를 여러 번 호출해도 하나만 가지고 작업 - Singleton 패턴
    System.out.println("r1:" + System.identityHashCode(r1));
    System.out.println("r1:" + System.identityHashCode(r2));

    //메모장 실행
    try {
        r1.exec("notepad.exe "
                + "C:\\Users\\admin\\Desktop\\java\\javaapplication\\java.txt");
    } catch (IOException e) {
        e.printStackTrace();
    }


}

6.String
=>문자열 관련된 클래스
1)인스턴스 생성
=>생성자를 이용해서 인스턴스 생성 가능
String str = new String("Hello Java");

=>문자열 리터럴을 이용해서 생성 가능
String str = "Hello Java";

2)+ 연산자 사용 가능(연산자 오버로딩)
=>기본형 과 + 연산을 하면 기본형을 String으로 변환해서 결합
=>String 과 연산을 하게되면 결합

3)문자열 리터럴은 static(method)영역에 저장되서 한 번 저장하면 그 내용을 변경할 수 없습니다.

4)주요 메소드
int length(): 문자열의 길이를 리턴
char charAt(int idx): idx 번째 문자를 리턴
=>언어에 상관없이 문자열을 이용한 코딩 테스트를 할 때는 자바는 위 2개의 메소드만 사용하라고 제한을 가하는 경우가 있습니다.
c언어는 문자열을 문자 배열로 취급해서 2개를 구하는 것은 가능하지만 나머지는 직접 구현해야 하기 때문입니다.

String trim(): 좌우 공백 제거
String toUpperCase(): 모두 대문자로 변환
String toLowerCase(): 모두 소문자로 변환
=>문자열을 처리하다 보면 앞 뒤의 공백문자나 영문의 대소문자 구별문제가 발생할 수 있습니다.
이런 메소드를 이용해서 적절히 처리

int indexOf(int ch 또는 String str)
int lastIndexOf(int ch 또는 String str)
=>문자나 문자열의 위치를 찾아주는 메소드
문자나 문자열이 없으면 음수를 리턴

boolean equals(String other): 문자열의 내용이 같은지 비교
boolean equalsIgnoreCase(String other): 문자열의 내용이 같은지 비교(대소문자 구분 안함)
int compareTo(String other): 문자열의 코드를 비교해서 결과를 리턴
other가 작으면 1 동일하면 0 크면 -1 을 리턴

String [] split(String regExp): 매개변수로 대입된 정규식을 가지고 문자열을 분할해서 배열로 리턴
String substring(int start, int end): start 위치부터 end 앞 까지 분할해서 리턴
end를 생략하면 끝까지 리턴

String format(String 서식, 데이터 나열): 서식에 데이터를 대입해서 문자열로 만든 후 리턴

5)실습
public static void main(String[] args) {
String requestURI = "/member/login";
//위와 같은 문자열이 있을 때 마지막 / 다음에 문자열을 추출 - login
//위와 같은 형태는 파일 경로에서 파일이름만 추출한다던가 웹 요청 주소에서 공통되지 않은 부분 추출할 때 많이 사용
//split을 이용해서 해결, indexOf 와 substring을 이용하기도 합니다.

    // /로 분할 한 후 가장 마지막 데이터 출력
    String [] sp = requestURI.split("/");
    System.out.println(sp[sp.length-1]);
    //마지막 /의 위치를 찾아서 그 다음부터 끝까지 분할
    int idx = requestURI.lastIndexOf("/");
    System.out.println(requestURI.substring(idx + 1));

    //현재 운영체제가 windows 인 지 확인
    String os = System.getProperty("os.name");
    //os에 windows 라는 문자열이 포함되어 있는지 확인
    idx = os.toLowerCase().indexOf("windows");
    if(idx < 0) {
        System.out.println("윈도우 아님");
    }else {
        System.out.println("현재 운영체제는 윈도우");
    }

}

6)연습문제
=>"eros" 라는 문자열이 있을 때 입력받은 문자열이 anagram 인지 확인
anagram은 문자의 순서만 바꾼 문자열
rose는 eros의 anagram
osrs는 anagram이 아님

=>염기서열
String str = "GCCMGCCGCCGSHDNGCCGKDIJ";
위 문자열에서 GCCG 의 위치를 출력하기
단 한번 찾은 문자열 패턴에서는 다시 찾으면 안됨
4, 15
GCCGCCG 에서 앞에 GCCG를 찾았으면 이 문자열에서는 다시 찾으면 안됨
자바로 해결하는 경우는 length 와 charAt 만 사용하시오.

7)숫자 데이터와 문자 데이터 사이의 변환

  • 숫자 데이터를 문자 데이터로 변환
    숫자데이터 + "": 숫자 데이터와 문자열 데이터 사이에 + 연산을 하게되면 숫자 데이터를 문자열로 변환해서 결합

String.format("숫자서식",숫자데이터) 을 호출하면 숫자 데이터를 숫자서식에 맞춘 문자열로 리턴

String str = String.format("%02d", 8);
str은 "08" 이 됩니다.

=>이 작업이 필요한 경우는 출력을 위해서입니다.
콘솔이나 GUI 환경에서는 숫자 데이터를 직접 출력하지 못합니다.
문자열로 변환해서 출력해야 합니다.

  • 문자 데이터를 숫자 데이터로 변환
    Wrapper 클래스의 메소드를 이용
    정수문자열을 정수로 변환
    int x = Integer.parseInt("123");
    x는 123
    =>키보드나 GUI 입력도구를 이용하면 문자열로 입력받는데 이를 숫자로 변환해서 연산을 하고자 하는 경우에 주로 이용하는데 숫자로 변경하지 못하는 문자열이면 NumberFormatException 이 발생
    예외를 방지하기 위해서는 숫자로 변경가능한지 확인하고 변환해야 합니다.

8)문자열 인코딩

  • Encoding(부호화): 데이터를 메모리에 저장하기 위해서 메모리에 저장되는 코드로 변환하는 것
  • Decoding(해독화): 메모리에 저장된 데이터를 출력하기 위해서 문자로 변환하는 것
    영문과 숫자와 일부 특수문자는 전세계 공통으로 ASCII 코드를 사용하고 인코딩할 때 앞 비트에 0을 추가하는 형태로 만들기 때문에 어떤 종류의 운영체제 또는 프로그램이건 인코딩 방식이 같습니다.

한글처럼 영문과 숫자가 아닌 경우는 별도의 인코딩 방식을 이용해서 저장합니다.
한글 인코딩은 ms949(cp949), euc-kr, utf-8 등이 있습니다.
ms949는 윈도우즈에서 한글을 사용하기 위해서 ms가 만든 인코딩 방식이고 euc-kr은 인터넷에서 한글을 표현하기 위해서 만든 인코딩 방식입니다.
utf-8은 모든 곳에서 공통으로 사용하기 위해 만든 방식으로 한글 한 글자를 3byte 코드로 표현하는 방식인데 현재의 웹 브라우저 들이나 Mac, Linux 등이 지원하는 인코딩 방식입니다.
인코딩 방식을 다르게 해서 읽으면 글자는 깨지거나 읽지를 못합니다.

iso8859-1(iso-latin1):서유럽 문자 인코딩 방식
이 방식에서는 한글을 사용할 수 없습니다.
open source 프로그램 들 중에는 기본 인코딩이 iso-latin1 인 경우가 많습니다.
대표적으로 mysql 같은 경우는 별도의 설정을 하지 않고 설치를 하게되면 옵션 설정을 하지 않으면 한글입력이 안됩니다.

String 클래스에는 이러한 변환을 위해서 메소드를 제공
getBytes(), getBytes(String encoding): 문자열을 byte 배열로 변환해주는 메소드
생성자 중에도 byte 배열을 받아서 만드는 것이 있고 byte 배열과 인코딩 방식을 받아서 만드는 생성자가 존재합니다.

7.StringBuilder
=>변경 가능한 문자열을 저장하기 위한 클래스
=>이 클래스의 Legacy Version으로 StringBuffer 클래스가 있습니다.
=>문자열 리터럴은 static 영역에 저장되기 때문에 변경이 불가능합니다.
다른 문자열을 이어붙이기 위해서 + 연산을 수행하면 현재 내용을 복사해서 다른 영역에서 이어붙인후 다시 리턴하는 구조입니다.

  • 연산을 많이 하면 메모리 낭비가 발생합니다.
    이런 메모리 낭비를 줄이기 위해서 StringBuilder 클래스를 제공

1)생성자
StringBuilder(): 매개변수 없이 생성
StringBuilder(String str): 문자열을 이용해서 생성

2)메소드
void append(String str): 현재 문자열에 str을 이어붙이기
String toString(): 내용을 String으로 변환해서 리턴

3)문자열 이어붙이기를 많이 해야 하는 경우 StringBuilder를 이용하는 것을 고려

4)StringBuffer 는 StringBuilder 보다 먼저 만들어진 클래스인데 이 클래스는 Multi Thread에 safe 한 클래스
=>StringBuffer는 이 클래스의 내용을 수정할 때 다른 스레드가 사용 중인지 확인을 해서 다른 스레드가 사용 중이면 대기하고 있다가 다른 스레드의 끝나면 수정을 합니다.
다른 스레드가 사용 중인지 확인하고 작업을 수행하는 것을 Multi Thread에 safe 하다고 합니다.
항상 사용 전에 확인하는 작업하는 때문에 속도는 느려질 수 밖에 없습니다.
StringBuilder는 확인 작업을 하지 않습니다.
최근에는 Multi Thread 에서의 동기화 문제는 Multi Thread 환경에서만 하는 것을 권장하기 때문에 StringBuilder를 사용해서 프로그래밍을 하고 동기화 문제가 발생하면 다른 방법으로 해결하도록 합니다.

5)실습
public static void main(String[] args) {
String str = "Hello";
//String은 자신의 데이터를 수정할 없기 때문에 메소드를 호출하거나 + 연산을 하면 결과를 리턴합니다.
//원본에는 변화가 생기지 않습니다.
String result = str + "Java";
str.toUpperCase();
System.out.println(str);

    //문자열을 heap에 저장해서 내용을 변경할 수 있는 클래스의 인스턴스 생성
    StringBuilder sb = new StringBuilder("Hello");
    //해시코드 출력
    System.out.println(System.identityHashCode(sb));

    //기존 내용에 Java를 이어붙이기를 합니다.
    sb.append("Java");
    System.out.println(sb);
    //해시코드 출력 : 이전 해시코드와 동일 - 현재 영역에서 작업을 수행
    System.out.println(System.identityHashCode(sb));
}

**Template Programming(일반화 프로그래밍 - Generics)
=>데이터의 자료형을 선언(정적)할 때 결정하는 것이 아니고 실행할 때(동적 - 인스턴스 생성) 결정하는 프로그래밍
=>동일한 알고리즘을 사용하는 작업들을 자료형이 다른 문제 때문에 여러 번 구현해야 하는 번거러움을 없애기 위해서 등장
1.5 버전에서부터 사용할 수 있는데 이전에는 Object 클래스로 해결

예를 들면 퀵 정렬하는 메소드를 만들고자 하는 경우
public void quickSort(int start, int end, int [] ar) //정수 배열을 가지고 하는 경우
public void quickSort(int start, int end, double [] ar) //실수 배열을 가지고 하는 경우
다른 자료형의 데이터도 하는 메소드를 만들고자 한다면 그 자료형의 배열을 매개변수로 받는 메소드를 또 선언해야 합니다.

첫번째 해결책 - Object(최상위 클래스) 클래스 이용
public void quickSort(int start, int end, Object [] ar)
=>Object 클래스는 최상위 클래스라서 어떤 종류의 데이터든지 받을 수는 있지만 실제 사용을 할 때는 원래의 자료형으로 변환해야만 사용이 가능합니다.
이런 식으로 만들면 결과를 사용할 때 항상 원래의 자료형으로 형변환을 해야 합니다.

두번째 해결책 - 미지정 자료형 사용
클래스를 만들 때 미지정 자료형 이름을 만들고 이 미지정 자료형으로 알고리즘을 구현한 후 인스턴스가 만들어 질 때 실제 자료형으로 변경하는 방식을 이용합니다.
이러한 프로그래밍 방식을 템플릿 프로그래밍이라고하고 자바에서는 Generics 라고 부릅니다.

1.java에서의 generics 구현
class 클래스이름 <미지정자료형이름 나열>{
미지정 자료형을 사용;
}

클래스이름<실제자료형>변수명 = new 클래스이름<실제자료형>();
=>1.7 부터는 생성자 뒤에 적는 자료형은 생략이 가능
클래스이름<실제자료형>변수명 = new 클래스이름<>();

2.주의할 점
실제 자료형을 기재할 때 기본형은 안됩니다.
int는 안되기 때문에 int 대신에 Integer를 사용해야 합니다.

Generics 가 적용된 클래스의 인스턴스를 만들 때 실제 자료형을 기재하지 않으면 경고 발생하고 리턴되는 데이터는 Object 자료형이 됩니다.

3.자바의 자료구조 클래스는 대부분 Generics를 적용한 상태로 구현되어 있습니다.

4.실습
1)어떤 자료형의 배열이던지 생성자에게 넘겨주면 disp 라는 메소드를 이용해서 출력하도록 해주는 클래스
=>Generic 이라는 클래스로 생성
//Gerneric을 적용한 클래스
public class Generic {
//E 라는 미지정 자료형 배열
private E [] data;

//생성자
public Generic(E [] data) {
    this.data = data;
}

//메소드
public void disp() {
    for(E temp : data) {
        System.out.print(temp + "\t");
    }
    System.out.println();
}

}

2)main 메소드를 소유한 실행 클래스에서 위의 클래스 사용
public static void main(String[] args) {
//미지정 자료형 1개를 갖는 클래스의 인스턴스 만들기
Integer [] ar = {100, 200, 300};
//클래스를 만들 때 사용한 E 가 Integer로 치환되서 동작
Generic obj1 = new Generic(ar);
//메소드 호출
obj1.disp();

    String [] br = {"김정화", "박은빈"};
    //클래스를 만들 때 사용한 E가 String으로 치환되서 동작
    Generic <String> obj2 = new Generic<String>(br);
    obj2.disp();

}

5.특징
=>static 메소드나 변수에는 Generic을 사용할 수 없음 : 인스턴스 생성할 때 자료형이 결정되기 때문에
=>배열 변수에 자료형을 이용하는 것은 되지만 Generic을 이용해서 배열을 생성하는 것은 안됩니다.
E [] 변수명; //여기까지는 가능
new E[개수]; //이것은 안됩니다.

**Enum(나열형 상수)
=>입력하는 데이터의 값을 제한하고자 할 때 사용하는 일종의 클래스
=>메소드에 대입되는 옵션을 만들 때 주로 이용
메소드에 입력하는 매개변수의 값을 제한하고자 하는 경우에 이전에는 유효성 검사나 final static 상수를 주로 이용
사용자가 실수로 사용 불가능한 값을 입력해도 자료형만 일치하면 에러가 발생하지 않습니다.

=>빨강, 파랑, 녹색 3가지 중에 하나만 입력받는 메소드를 생성
String 으로 설정하면 빨강, 파랑, 녹색 이외의 문자열도 대입이 가능
int로 설정하는 경우 빨강은 0, 파랑은 1, 녹색은 2로 설정할 수 있는데 int는 이 3개의 값 말고도 존재

1.생성
enum 이름{
속성 나열
}

2.인스턴스 생성
이름.속성

3.enum을 이용하는 메소드
public 결과형 메소드이름(이름 변수명){

}
=>이 메소드를 호출할 때는 enum에 만들어진 속성만 대입이 가능

enum Color{
RED, BLUE, GREEN;
}

public void setColor(Color color){

}
=>setColor 메소드를 호출할 때 매개변수는 Color.RED, Color.BLUE, Color.GREEN 3개의 값만 가능
다른 데이터를 대입하면 에러가 발생

**java.util 패키지
1.Arrays 클래스
=>배열 관련된 작업을 위한 클래스
=>모든 멤버가 static 메소드라서 인스턴스 생성은 필요 없음

static void sort(Object [] ar): 배열의 요소를 정렬 해주는 메소드
=>배열의 요소가 Comparable 인터페이스를 implements 한 경우 compareTo 메소드를 이용해서 정렬해주는 메소드

static void sort(Object [] ar, Comparator comp): 배열의 데이터를 Comparator 인터페이스의 compare 메소드를 이용해서 정렬

static int binarySearch(Object [] ar, Object key): ar 배열에서 key의 데이터가 몇번째 있는지 이분 검색해서 결과를 리턴해주는 메소드
제어검색이라서 ar이 정렬이 안된 상태라면 잘못된 결과를 리턴할 수 있습니다.
ar 에 key가 없으면 음수를 리턴

List asList(Object [] ar): ar 배열을 이용해서 List를 만들어서 리턴해주는 메소드

1)실습
public static void main(String[] args) {
//int -> Integer 와 String 은 크기 비교가 가능해서 바로 정렬 가능
//Comparable 인터페이스가 구현되어 있는지 확인

    //정수 배열 생성
    int [] ar = {30, 40, 20, 50, 10};

    //문자열 배열 생성
    String [] br = {"해글러","듀란", "헌즈", "레너드", "박종팔"}; 

    //ar 배열을 정렬
    Arrays.sort(ar);
    for(int temp : ar) {
        System.out.print(temp + "\t");
    }
    System.out.print("\n");

    //br 배열을 정렬
    Arrays.sort(br);
    for(String temp : br) {
        System.out.print(temp + "\t");
    }
    System.out.print("\n");

}

 

2)사용자 정의 클래스의 정렬
=>사용자의 데이터를 저장하기 위한 클래스를 생성 : 관계형 데이터베이스의 테이블
번호, 이름, 점수를 하나로 저장하는 클래스 : User
public class User {
private int num;
private String name;
private int score;

//접근자 메소드: getters and setters
public int getNum() {
    return num;
}
public void setNum(int num) {
    this.num = num;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public int getScore() {
    return score;
}
public void setScore(int score) {
    this.score = score;
}

//저장된 값을 빠르게 확인하기 위한 메소드
@Override
public String toString() {
    return "User [num=" + num + ", name=" + name + ", score=" + score + "]";
}

}

3)main 메소드에서 User 클래스의 배열을 만들어서 정렬하는 코드를 사용
//데이터 정렬
Arrays.sort(users);

//데이터 출력
for(User user : users) {
System.out.println(user);
}

=>문법적으로는 오류가 없지만 실행하면 예외가 발생 - ClassCastException : Comparable로 타입변환이 안됨
=>우리가 만든 User 클래스는 Comparable 인터페이스를 implements 하지 않아서 인스턴스들의 크기 비교가 안됩니다.
=>sort 가 되도록 할려면 User 클래스에 Comparable 인터페이스를 implements 하고 int compareTo 메소드를 재정의 해야 합니다.
this 의 데이터와 매개변수의 데이터를 비교해서 정수를 리턴하는데 양수를 리턴하면 this의 데이터가 작다고 판단하고 0을 리턴하면 this 와 매개변수가 같다고 판단하고 음수를 리턴하면 this의 데이터가 크다고 판단해서 오름차순으로 정렬

4)User 클래스를 수정하고 다시 실행
=>Comparable 인터페이스를 implements

=>compareTo 메소드 재정의
@Override
public int compareTo(User o) {
if(this.num > o.num) {
return 1;
}else if(this.num == o.num) {
return 0;
}else{
return -1;
}
}

5)이렇게 만들면 정적으로 정렬하는 것은 가능한데 동적 정렬이 안됩니다.
코드를 변경하지 않고 정렬방법을 바꾸는 것이 안됩니다.

6)동적으로 정렬 조건을 변경하기 위해서는 sort(Object [] ar, Comparator comp) 메소드를 이용
뒤에 대입되는 comp 인스턴스의 메소드를 이용해서 비교해서 정렬을 합니다.
Comparator 인터페이스를 구현할 때 E는 하나의 요소 자료형이 되고 compare 메소드를 재정의할 때 양수를 리턴하면 앞의 데이터가 크다고 판단하고 0을 리턴하면 2개의 데이터는 같다고 판단하고 음수를 리턴하면 앞의 데이터가 작다고 판단해서 quickSort를 수행합니다.

7)실습
main 메소드에 작성
//User 클래스의 배열 생성
User user1 = new User();
user1.setNum(1);
user1.setName("조 몬타나");
user1.setScore(88);

    User user2 = new User();
    user2.setNum(2);
    user2.setName("마르티나 나브라틸로바");
    user2.setScore(97);

    User user3 = new User();
    user3.setNum(3);
    user3.setName("웨인 그레츠키");
    user3.setScore(87);

    User [] users = {user1, user2, user3};

    //한 줄의 문자열을 입력받기 위한 구문
    Scanner sc = new Scanner(System.in);
    System.out.print("정렬 조건 선택(1.번호 2.이름 3.점수):");
    String menu = sc.nextLine();

    Comparator <User> comp = null;
    switch(menu) {
    case "1":
        comp = new Comparator<User>() {
            @Override
            public int compare(User o1, User o2) {
                if(o1.getNum() > o2.getNum()) {
                    return 1;
                }else if(o1.getNum() == o2.getNum()) {
                    return 0;
                }else {
                    return -1;
                }
            }

        };
        break;
    case "2":
        comp = new Comparator<User>() {
            @Override
            public int compare(User o1, User o2) {
                return o1.getName().compareTo(o2.getName());
            }
        };
        break;
    case "3":
        comp = new Comparator<User>() {
            @Override
            public int compare(User o1, User o2) {
                return o1.getScore() - o2.getScore();
            }
        };
        break;
    default:
        System.out.println("잘못된 메뉴를 선택하셨습니다.");
        //프로그램 종료
        System.exit(0);
    }

    Arrays.sort(users, comp);


    //데이터 출력
    for(User user : users) {
        System.out.println(user);
    }
반응형

'Study > Java' 카테고리의 다른 글

java-11  (0) 2020.10.01
java-10  (0) 2020.09.30
java-8  (0) 2020.09.28
java-7  (0) 2020.09.27
java-6  (0) 2020.09.26

+ Recent posts