레이블이 [004. JAVA]인 게시물을 표시합니다. 모든 게시물 표시
레이블이 [004. JAVA]인 게시물을 표시합니다. 모든 게시물 표시

2017년 5월 25일 목요일

[JAVA] String의 equals 메서드에 대한 한가지 Tip

Java에서, String의 equals 메서드에 대한 한가지 Tip



Java를 하는 사람은 다들 알 듯이 String형의 값의 비교는 동등 비교(==)를 사용하면 안되고 equals 메서드를 사용해야합니다.

이때 한가지 주의해야할 Tip이 있습니다.

우선 소스를 보겠습니다.

1 : final String FINAL_STRING = "hello world";
2 : String str = null;
3 :   
4 : if(FINAL_STRING.equals(str)) {
5 :  System.out.println("문자열 값이 같습니다.");
6 : }else{
7 :  System.out.println("문자열 값이 다릅니다.");
8 : }
9 :  
10: if(str.equals(FINAL_STRING)) {
11:  System.out.println("문자열 값이 같습니다.");
12: }else{
13:  System.out.println("문자열 값이 다릅니다.");
14: }

우선 2개의 String형 변수가 있습니다. 하나는 FINAL_STRING 이라는 문자상수고 하나는 str라는 변수입니다.

위 코드를 실행하면 4번 라인의 조건문은 정상적으로 수행되고 10번라인의 조건문은 에러가 발생합니다.
문자열 값이 다릅니다.Exception in thread "main" 
java.lang.NullPointerException
 at helloworld.HelloWorld.main(HelloWorld.java:10)

보시다시피 equals 메서드의 인자에는 null 값이 들어가도 되지만 equals 메서드를 호출하는 변수는 null이면 예외가 발생합니다.

이를 실제로 적용하시는 경우는 이런 경우가 있습니다.
사용자로부터 값을 입력받거나 하는 등 값이 변하는 String형 변수가 있고, 그 변수의 값을 프로그램이 고정으로 사용하는 문자열과 값 비교를 한다면, 꼭 고정된 문자열에서 equals 메서드를 호출하고 동적으로 변할 수 있는 변수를 인자로 넣어줘야 예외가 발생하지 않습니다.

동적으로 변하는 String형 변수에 절대적으로 null이 들어오지 않는다라는 확신이 있다면 아무렇게나 해도 되겠지만 혹시나 만에하나라도 null이 생길수 있는 경우를 대비해서 절대적으로 null이 될 수 없는 문자 상수나 프로그램 내에서 고정적으로 문자열을 할당한 변수를 equals 앞에 써주는게 좋습니다.

결론,
{절대null이 되지 않는 String}.equals(null이 될수도 있는 String)

2016년 3월 29일 화요일

[JAVA] Java에서 CoAP Client 구현하기.(Californium 라이브러리 이용)


[JAVA] Java에서 CoAP Client 구현하기.(Californium 라이브러리 이용)




Java에서 CoAP을 구현하기 위해서 라이브러리를 가져와야하는데 가장 널리 이용되는 것이 Californium 라이브러리인 것 같다.

다양한 CoAP 라이브러리들을 아래 링크에서 확인 할 수 있다.
http://coap.technology/impls.html
Constrained devices, Server-side, Browser-based 등의 분류별로 라이브러리가 소개된다.


Californium은 Server-side에서 Java로 구현된 라이브러리라고는 하지만 Client도 구현되어 있다.
Californium은 Github에서 소스를 공개하고 있다.
https://github.com/eclipse/californium

최신 버전 확인은 MVN Repository 사이트가 어떤 라이브러리든 좋은거 같다.
http://mvnrepository.com/artifact/org.eclipse.californium/californium-core


Java에서 Californium 라이브러리 사용하는 방법

[1] 우선 Java에서 Californium을 이용하기 위해서는 Maven에서 dependency를 설정해줘야 한다.
(Maven 설치 및 Eclipse 연동은 다른 좋은 글들이 많으니 구글에서 찾아보자. 간편하게는 STS(Spring Tool Suite)을 사용해도 된다.)

아래의 설정을 프로젝트의 pom.xml에 추가 한다.( 점은 삭제한다. 다른 내용이 있을 수 있다는 표시인 것이므로... )

 <dependencies>
    ...
    <dependency>
            <groupId>org.eclipse.californium</groupId>
            <artifactId>californium-core</artifactId>
            <version>1.0.3</version>
    </dependency>
    ...
  </dependencies>
  ...
  <repositories>
    ...
    <repository>
      <id>repo.eclipse.org</id>
      <name>Californium Repository</name>
      <url>https://repo.eclipse.org/content/repositories/californium/</url>
    </repository>
    ...
  </repositories>


[2] 이제, Californium 라이브러리를 사용할 수 있다. 아래는 CoAP 서버로 부터 시간정보를 반환 받는 Client 예제이다.

import org.eclipse.californium.core.CoapClient;

public class App 
{
    public static void main( String[] args )
    {
        System.out.println( "Hello! This is CoAP Sample Application." );

        CoapClient client = new CoapClient("coap://californium.eclipse.org:5683/obs");

        if(!client.ping()){
            System.out.println("Server is down. Terminate program.");
            return;
        }

        System.out.println("Request Get mothod of CoAP.");
        String content1 = client.get().getResponseText();
        System.out.println("Response : " + content1);
    }
}



2016년 3월 21일 월요일

[JAVA] Java에서 Json객체 사용하기(Gson 사용)


[JAVA] Java에서 Json객체 사용하기(Gson 사용)




Java에서 Json 객체를 사용하기 위한 방법은 4가지가 있다고 한다.
(출처 : http://blog.takipi.com/the-ultimate-json-library-json-simple-vs-gson-vs-jackson-vs-json/)

저번에 올린 Json Parsing 포스트에서는 Json-simple을 사용한 경우였다.
(저번 포스트 : http://walkinpcm.blogspot.kr/2016/03/java-json-json-parsing.html)

이번에는 또 다른 Java의 Json 라이브러리인 Gson을 사용하는 방법을 정리해본다.
Gson은 구글에서 만든 라이브러리이다.
(참고. Gson docs : http://google.github.io/gson/apidocs/)

본 방법은 이클립스에서 Gson 라이브러리를 추가하여 Java에서 Json 객체를 사용하는 것이다.

(1) 아래 사진 처럼 링크를 따라가서 Gson라이브러리를 다운받는다.
(다운로드 링크 : https://github.com/google/gson)





(2) 이클립스에서, Gson 라이브러리를 추가할 프로젝트에서 우클릭!
    맨 아래 'Properties'를 클릭한다.



































(3) 왼쪽 항목에서 'Java Build Path'를 선택하고 오른쪽 'Libraries' 탭에서 'Add External JARs'를 클릭한다. 여기서 아까 다운받은 Gson 라이브러리 파일을 선택해준다.




(4) 새로 추가된 것을 확인하고 아래 'Apply'와 'OK'를 차례대로 클릭한다.






이 과정을 마치면 프로젝트에 Gson 라이브러리가 추가된다.
예제코드는 저번에 포스팅한 Json-simple을 이용한 Json Parsing 글을 보면 있는데
(저번 포스트 : http://walkinpcm.blogspot.kr/2016/03/java-json-json-parsing.html)
Json-simple과 Gson의 차이점은 simple에서는 'JSON'으로 대문자로 쓰고 Gson에서는 'Json'으로 앞글자만 대문자로 쓴다.
(ex. Json-simple > JSONParser jparser = new JSONParser();)
(ex. Gson > JsonParser jparser = new JsonParser();)

2016년 3월 18일 금요일

[JAVA] Open 날씨 API

[JAVA] Open 날씨 API

(참고 site : http://yooic.tistory.com/43 , 감사합니다.)
날씨 정보를 획득할 수 있는 OpenAPI가 있다.
http://openweathermap.org/
프로그램에서 날씨 정보를 쉽게 얻을 수 있다.
하지만 완전 무료는 아니다.
분당 60건의 조회는 무료로 사용할 수 있는데, 그 이상의 조회를 가능하게 하려면 돈을 지불해야 한다.
금액은 아래에서 확인가능하다.
http://openweathermap.org/price
아! 비쌀수록 더 많은 API를 제공한다.

도시 이름, zip code, GPS로 지역을 선택해서 해당 지역의 날씨 정보를 획득 할 수 있는데,
나는 GPS정보를 이용했다.

예제로 서울시청(위도 37.566386, 경도 126.977948)을 이용해보겠다.
날씨정보를 가져오는 방법은 RESTapi를 call하는 것 같다.

예제코드
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;

public class WeatherByGPSApplication {
    public static void main(String[] args) {
        try{
            //서울시청의 위도와 경도
            String lon = "126.977948";  //경도
            String lat = "37.566386";   //위도

            //OpenAPI call하는 URL
            String urlstr = "http://api.openweathermap.org/data/2.5/weather?"
                        + "lat="+lat+"&lon="+lon
                        +"&appid=본인의키를넣으세요";
            URL url = new URL(urlstr);
            BufferedReader bf;
            String line;
            String result="";

            //날씨 정보를 받아온다.
            bf = new BufferedReader(new InputStreamReader(url.openStream()));

            //버퍼에 있는 정보를 문자열로 변환.
            while((line=bf.readLine())!=null){
                result=result.concat(line);
                //System.out.println(line);
            }

            //문자열을 JSON으로 파싱
            JSONParser jsonParser = new JSONParser();
            JSONObject jsonObj = (JSONObject) jsonParser.parse(result);

            //지역 출력
            System.out.println("지역 : " + jsonObj.get("name"));

            //날씨 출력
            JSONArray weatherArray = (JSONArray) jsonObj.get("weather");
            JSONObject obj = (JSONObject) weatherArray.get(0);
            System.out.println("날씨 : "+obj.get("main"));

            //온도 출력(절대온도라서 변환 필요)
            JSONObject mainArray = (JSONObject) jsonObj.get("main");
            double ktemp = Double.parseDouble(mainArray.get("temp").toString());
            double temp = ktemp-273.15;
            System.out.printf("온도 : %.2f\n",temp);

            bf.close();
        }catch(Exception e){
            System.out.println(e.getMessage());
        }
    }
}

실행결과
지역 : Seoul
날씨 : Clear
온도 : 17.57

[JAVA] json형식의 문자열을 json객체로 parsing하기

[JAVA] json형식의 문자열을 json객체로 parsing하기




웹 등에서 문자열을 리턴 받는데 이게 JSON 형식이면 프로그램에서 훨씬 처리하기 좋다.
문자열을 그대로 이용하면 split으로 문자열을 쪼개는 과정이 필요한데 반해, JSON형식이면 사용성이 좋아진다.

java에서 json을 다루는 라이브러리가 몇몇 있는데 이 글에서는 json-simple 라이브러리를 사용해보려 한다.
(gson 라이브러리도 있는데 이는 https://walkinpcm.blogspot.kr/2016/03/java-java-json-gson.html 에서 정리하였다.)

java에서 json-simple을 사용하기 위해서는 먼저, json-simple 라이브러리를 다운받아서 build path에 추가시켜 줘야한다.

아래 링크에서 json-simple 라이브러리를 다운 받는다.
https://code.google.com/archive/p/json-simple/downloads
맨 위의 최신버전을 받으면 될 듯하다.

다음으로 다운받은 라이브러리를 이클립스에서 생성한 프로젝트의 build path에 추가시켜 준다.
순서는 다음과 같다.
프로젝트 이름에서 우클릭->Properties->왼쪽에서 'Java Build Path'클릭
-> 오른쪽 상단 탭에서 'Libraries' 클릭 -> 'Add External JARs...'클릭
-> 다운받은 json 라이브러리 선택 -> 하단 'Apply'클릭 -> 'OK' 클릭

이제 json 라이브러리를 이용한 코드를 작성하면 된다.
예제는 아래와 같다.
json형식의 문자열을 json객체로 파싱하고 json클래스의 메서드들을 이용해서 정보를 출력한다.

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

public class JsonParserApplication {
    public static void main(String[] args) {
        //JSON으로 Parsing할 문자열 데이터
        String jsonStr = "{\"members\":["
                + "{\"name\":\"홍길동\","
                + "\"email\":\"gildong@hong.com\","
                + "\"age\":\"25\""
                + "},"
                + "{\"name\":\"홍길서\","
                + "\"email\":\"gilseo@hong.com\","
                + "\"age\":\"23\""
                + "}]}";

        try {
            JSONParser jsonParser = new JSONParser();
            JSONObject jsonObj = (JSONObject) jsonParser.parse(jsonStr);
            JSONArray memberArray = (JSONArray) jsonObj.get("members");

            System.out.println("=====Members=====");
            for(int i=0 ; i<memberArray.size() ; i++){
                JSONObject tempObj = (JSONObject) memberArray.get(i);
                System.out.println(""+(i+1)+"번째 멤버의 이름 : "+tempObj.get("name"));
                System.out.println(""+(i+1)+"번째 멤버의 이메일 : "+tempObj.get("email"));
                System.out.println(""+(i+1)+"번째 멤버의 나이 : "+tempObj.get("age"));
                System.out.println("----------------------------");
            }

        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

코드를 실행하면 아래와 같은 결과가 출력된다.
=====Members=====
1번째 멤버의 이름 : 홍길동
1번째 멤버의 이메일 : gildong@hong.com
1번째 멤버의 나이 : 25
----------------------------
2번째 멤버의 이름 : 홍길서
2번째 멤버의 이메일 : gilseo@hong.com
2번째 멤버의 나이 : 23
----------------------------

2016년 3월 17일 목요일

[JAVA] 자바에서 웹크롤러(Web Crawler) 구현하기

[JAVA] 자바에서 웹크롤러(Web Crawler) 구현하기



가끔 특정 웹페이지의 특정 문자열을 프로그램으로 가져오고 싶을 때가 있다.
이럴때 간단하게 할 수 있는 방법이 웹크롤러를 구현해서 해당 웹페이지의 소스코드를 가져오는 것이다.

가져온 소스코드에서 split함수로 필요한 문자열을 추출해 내면 된다.

아래 예제는 예제사이트인 example.com의 소스코드를 추출해서 출력하는 프로그램이다.

import java.net.*;
import java.io.*;

public class WebCrawler {

    public static void main(String[] args) {
        try{
          //example.com은 연습으로 사용하기 위한 페이지이다. 간단한 페이지로 소스코드의 양도 적다.
            String urlstr = "http://www.example.com";
            //URL 문자열을 처리하기 위해 URL클래스를 이용한다.
            URL url = new URL(urlstr);

            //소스코드를 가져오기 위한 스트림을 선언한다.
            BufferedReader bf;
            String line;

      //URL클래스의 openStream()함수로 지정한 웹주소의 소스코드를 받아올 수 있다.
            bf = new BufferedReader(new InputStreamReader(url.openStream()));

            while((line=bf.readLine())!=null){
                System.out.println(line);
            }

            //스트림을 닫아준다.
            bf.close();
        }catch(Exception e){
            System.out.println(e.getMessage());
        }
    }
}

2016년 2월 11일 목요일

[JAVA 교육] 객체 직렬화(Object Serialization)

[JAVA 교육] 객체 직렬화(object serialization)


(*본 게시물은 본인이 교육을 통해서 배우는 내용을 정리하는 글입니다. 부족한 부분이 많으니 참고해주시기 바랍니다. 혹시 정확한 의미를 알고 싶으시거나, 틀린 내용에 대해 조언해주시고 싶은 분들께서는 댓글을 남겨주시면 최대한 빠르게 답변하겠습니다. 감사합니다.)

1. Object Serialization

1. 개념
  1. App data Object 멤버변수를 이용해서 관리하고 저장하거나 전송하는 .
    1. 저장하고 싶을 객체 자체를 그대로 저장한다.
    2. 객체가 아닌 단순 text 저장할 때의 단점
      1. 구분자를 넣어야 한다.
      2. 파싱 해야한다.(파싱 : 구분자를 기준으로 문자열을 쪼개고 위치의 문자가 어떤 의미인지 파악하는 과정)
    3. 객체를 저장
      1. 단점 : 다시 읽을 어떤 객체인지 확인하기 위해서   클래스가 필요하다.
      2. 장점 : 개발자가 저장을 위해 일이 적다.
2. 종류
  1. 자바의 직렬화 : Sun(, Oracle)에서 만든
    1. 자바의 직렬화를 위해 사용되는 클래스
      1. ObjectInputStream
      2. ObjectOutputStream
  2. ProtoBuf(Protocol Buffers)
    1. 구글에서 만든
    2. 서로 다른 언어간 데이터 전송을 위한 프로토콜
    3. 이기종 플랫폼 간에 구조화 데이터를 쉽게 주고 받을 있도록 하는
  3. AVRO
    1. Apache 재단에서 만든
    2. 주로 빅데이터를 직렬화하는 용도
3. 자바에서의 구현
  1. implements Serialization : Serialization 인터페이스를 구현한다.
    1. Serialization 인터페이스는 marker 인터페이스이다.
  2. 직렬화 클래스
    1. ObjectInputStream
      1. readObject() : 읽어 들일 반드시 형변환을 해줘야한다.(Object 형으로 return되기 때문이다.)
    2. ObjectOutputStream
      1. writeObject()
  3. serialVersionUID 입력해 주어야 한다.
    1. 클래스의 구조가 변경되더라도 serialVersionUID 같으면 동일 클래스임을 보장한다.
  4. transient라는 속성이 있다.
    1. 변수에 선언하는 제한자이다.
    2. transient 선언된 변수는 직렬화에서 제외된다.(직렬화 없거나 하고 싶지 않은 변수에 선언한다.)
    3. transient 반드시 붙여야 하는 경우가 있다.
      1. 예로, thread 직렬화 되지 못하도록 짜여져 있다.
      2. thread 사용되는 변수는 직렬화 제외해야 한다.

2016년 2월 6일 토요일

[JAVA 교육] I/O 입출력

[JAVA 교육] I/O 입출력


(*본 게시물은 본인이 교육을 통해서 배우는 내용을 정리하는 글입니다. 부족한 부분이 많으니 참고해주시기 바랍니다. 혹시 정확한 의미를 알고 싶으시거나, 틀린 내용에 대해 조언해주시고 싶은 분들께서는 댓글을 남겨주시면 최대한 빠르게 답변하겠습니다. 감사합니다.)


1. I/O(입출력)
        a. 단위
                i. byte
                        1) InputStream
                        2) OuputStream
                ii. char
                        1) Reader
                        2) Writer
        b. 노드
                i. 노트 스트림 클래스
                ii. File
                        1) FileInputStream
                        2) FileOutputStream
                        3) FileWrite
                        4) FileReader
                iii. Socket
                iv. Pipe
                v. Memory 메모리
        c. 필터
                i. 필터 스트림
                ii. 내가 원하는 (data type)객체 단위로 입출력
                        1) DataInputStream
                        2) DataOutputStream
                iii. Buffering
                        1) BufferedInputStream
                        2) BufferedOutputStream
                iv. Object 직렬화
                        1) 직렬화를 위해서는 직렬화 할 객체의 클래스가 반드시 Serializable을 implements해야한다.
                        2) ObjectInputStream
                        3) ObjectOutputStream
        d. 직렬화 클래스
                i. implements Serializeable
                        1) 메서드를 가지고 있지 않은 Marker Interface이다.
                ii. serialVersionUID - 변수이다.
                        1) static final
                        2) 클래스 구조변경이 이전 클래스와 같은 클래스임을 확인하기 위함.

2016년 2월 4일 목요일

[JAVA 교육] Thread 쓰레드 / Generic 제네릭 / Collection framework

[JAVA 교육] Thread 쓰레드 / Generic 제네릭 / Collection framework

(*본 게시물은 본인이 교육을 통해서 배우는 내용을 정리하는 글입니다. 부족한 부분이 많으니 참고해주시기 바랍니다. 혹시 정확한 의미를 알고 싶으시거나, 틀린 내용에 대해 조언해주시고 싶은 분들께서는 댓글을 남겨주시면 최대한 빠르게 답변하겠습니다. 감사합니다.)

  1. Thread 쓰레드
    1. 프로세스와 쓰레드 비교
      1. 프로세스
        1. 프로그램
        2. 보통 한 프로그램이 한 프로세스
        3. but, 한 프로그램이 여러 프로세스를 실행할 수도 있다.(ex. 크롬에서 각 탭이 각 프로세스)
      2. 쓰레드
        1. 최소실행단위
        2. 멀티쓰레드 가능(한 프로세스 안에서 여러 쓰레드가 실행)
        3. 프로세스 안의 실행 단위
    2. main 쓰레드
      1. main() 메서드를 실행
      2. 다른 thread를 생성하고 실행한다.
    3. 생성/실행
      1. 코드
        1. Runnable 인터페이스를 구현하는 방법.
          • class MyRunner implements Runnable {
                public void run(){ }
            }
        2. Thread 클래스를 상속받아서 구현하는 방법.
          • class MyThread extends Thread {
                public void run() {  }
            }
        3. Runnable 익명 객체(익명 클래스)를 이용하여 구현할 수도 있다.
        4. 만일, 구현해야할 함수가 1개라면 별도의 클래스를 만들지 않고 람다식으로 코드를 작성해도 된다.
          람다식은 별도의 클래스를 만들지 않고 아래와 같이 작성한다.
          • Thread thread = new Thread( () -> {
                //쓰레드가 실행할 코드..
            } );
        5. run()
          1. run()함수에 쓰레드가 실행할 코드를 작성한다.
      2. 쓰레드 생성
        • ex1. Thread t1 = new Thread(runnable 객체);
        • ex2. Thread t2 = new MyThread();
        • 쓰레드를 구현할때는 Thread클래스를 상속받는거 보다 Runnable 인터페이스를 구현하는 것이 권장된다. 왜냐하면 Thread를 상속 받으면 다른 클래스를 상속 받을 수 없기 때문이다.
      3. 쓰레드 실행
        • ex. t1.start();
    4. 자바에서는 쓰레드 스케줄링 기법으로 우선순위(Priority)방식과 순환 할당(Round-Robin)방식을 사용한다.
      1. 우선순위가 높은 쓰레드를 먼저 수행하되, 우선순위가 동일하다면 순환 할당 방식으로 쓰레드를 실행한다.
      2. 순환 할당 방식은 시분할 방식이다. 각 쓰레드가 정해진 시간 만큼 수행되고 다시 대기 상태가 된다.
    5. 흐름도
      1. 기본 흐름도
        Runnable(대기)상태와 Running(실행)상태가 반복된다.
      2. Running상태에서 sleep()명령이 오면 TIME_WAITING상태에 들어갔다가 sleep 시간이 끝나면 Runnable 상태가 되었다가 순서가 오면 Running상태가 된다.

        • 여기서 동기화 문제가 발생한다. 쓰레드 1번이 공유객체 값을 100으로 설정하고 sleep 된 동안아 쓰레드 2번이 공유객체 값을 50으로 설정하면 쓰레드 1번은 sleep에서 돌아왔을때 공유객체의 값이 바뀌어 있다. 이를 동기화 문제라 한다.
        • 이를 해결하기 위해서 synchronized를 이용한다. 쓰레드가 synchronized된 공유객체를 참조하려하면 Lock pool에서 BLOCKED상태로 빠진다. Lock pool에서 lock flag를 획득하면 공유객체를 참조 할 수 있고 참조가 끝나면 lock flag를 반환한다.
        • 쓰레드가 공유객체의 lock flag를 획득한 상태에서 sleep명령을 받으면 lock flag를 그대로 가진 상태에서 TIME_WAITING 상태가 된다. 그래서 sleep 동안에 다른 쓰레드가 공유객체를 참조할 수 없다.
        • 실행중인 상태에서 wait() 함수가 수행되면 Wait pool에서 WAITING상태로 들어간다. 대기하다가 notify()함수가 수행되면 BLOCKED상태가 된 후 대기 상태가 된다.
    6. 쓰레드풀(or Bean Pool)
      1. 갑작스런 병렬 작업의 폭증으로 인한 쓰레드의 폭증을 막기 위해 사용한다.
      2. 쓰레드를 제한된 갯수로 정해 놓고 작업 큐에 들어오는 작업들을 하나씩 쓰레드가 맡아 처리한다.
      3. 작업 처리가 끝난 쓰레드는 다시 작업 큐에 돌아온다.
    7. Thread 클래스의 메서드
      1. yield()
        1. 실행 중에 우선순위가 동일한 다른 쓰레드에게 실행을 양보하고 실행 대기 상태가 된다.
        2. 다른 쓰레드가 종료될 때까지 기다린다는 보장은 없다.
      2. join()
        1. 다른 쓰레드의 종료를 기다린다.
        2. join()을 호출한 쓰레드의 종료가 될 때까지 대기한다.
        3. ex. ThreadA에서 ThreadB.join() 을 실행하면 ThreadA는 ThreadB가 종료 될 때까지 대기한다.
      3. wait()
        1. 동기화 메소드 또는 블록에서만 호출 가능한 Object의 메서드이다.(Thread의 메서드가 아니다.)
        2. wait()함수가 포함된 함수를 호출한 쓰레드를 일시정지 상태로 만든다.
        3. notify(), notifyAll() 함수에 의해 실행 대기 상태로 갈 수 있다.
      4. stop()
        1. 쓰레드를 즉시 종료시킨다.(run()메서드가 정상적으로 끝나지 않는다.)
        2. 위험한 종료 방법이다.
      5. interrupt()
        1. 쓰레드를 종료시킨다.
        2. 안전하게 run()메서드를 정상적으로 종료한다.)
  2. Generic 제네릭
    1. 자바5부터 새로 추가되었다.
    2. Collection에서 널리 사용된다.
    3. 제네릭이 제공해주는 기능(이점)
      1. Type safety
        1. 컴파일 시에 강한 타입 체크를 할 수 있다.
        2. 객체를 리턴받을 때 형변환 하지 않아도 된다.
    4. 제네릭 타입
      1. 타입을 파라미터로 가지는 클래스와 인터페이스
      2. 선언 시 클래스 또는 인터페이스 이름 뒤에 "<>"를 붙인다.
      3. "<>" 사이에는 타입 파라미터 위치
      4. 제네릭 타입은 두개 이상의 타입 파라미터 사용 가능하다.
        1. ex. class<K, V, ... >, interface<K, V, ... >
    5. 제네릭 메서드
      1. 리턴 타입 앞에 "<>"기호를 추가하고 타입 파라미터를 기술한다.
    6. 와일드카드 타입
    7. 제네릭 타입의 상속과 구현
      1. 제네릭 타입을 부모 클래스로 사용할 경우 타입 파라미터는 자식 클래스에도 기술해야한다.
      2. 자식 클래스에는 추가적인 타칩 파라미터를 가질 수 있다.
      3. 인터페이스의 경우도 동일하다.
  3. Collection framework
    1. Collection
      1. 특징 : 순서가 없다, 중복을 허용한다.
      2. Set
        1. 순서가 없고, 중복도 허용하지 않는다.
        2. 순서가 없어서 index를 사용하는 get, set을 지원하지 않는다.
        3. Set 인터페이스를 구현한 클래스
          1. HashSet
          2. TreeSet
            1. Comparable한 TreeSet은 값을 넣을 때 자동으로 정렬한다.
      3. List
        1. 순서가 있고, 중복을 허용한다.
        2. List 인터페이스를 구현한 클래스
          1. ArrayList
          2. LinkedList
          3. Vector - Thread safe
            1. synchronized 되어 있다는 것. 그래서 싱글쓰레드에서는 성능이 떨어지니까 사용 안한다.
    2. Map
      1. Key와 Value의 쌍으로 구성된다.
      2. Map 인터페이스를 구현한 클래스
        1. HashMap
        2. Hashtable
        3. TreeMap
        4. Properties
      3. Key는 unique해야한다. = 중복이 되면 안된다.
    3. 데이터 정렬
      1. Comparable
        1. CompareTo() 스스로 다른 객체와 비교가 가능
          1. 디폴트 비교 규칙을 정할 때 사용한다.
      2. Comparator
        1. Compare() 두 객체를 비교
          1. 부가적인 비교 규칙을 정할 때 사용한다.
        2. CompareTo() 이외의 다른 비교 규칙을 만들고 싶을때, Comparator 인터페이스를 구현한 별도의 비교기 클래스를 만들어서 정렬할 수 있다.
          1. ex. Set<NameCard> cardList2 = new TreeSet<>(new NameCardComparator());
          2. NameCardComparator라는 비교기 클래스를 별도로 만들어서 저렇게 인자로 넣어준다.