728x90
반응형

**Event처리

=>Event는 외부에서 발생하는 사건

=>자바의 awtswing의 이벤트 처리는 Listener인터페이스나 Adapter클래스가 처리합니다.

1.이벤트 처리 방법

=>처리하고자 하는 이번트의 Listener인터페이스를 Implements하거나 Adapter클래스를 상속받은 클래스의 인스턴스를 생성

=>컴포넌트.add이벤트리스너(앞에서 생성한 인스턴스);

 

=>이러한 방식의 처리를 Delegate(위임)를 이용한 처리 방식

이벤트가 발생한 객체가 이벤트를 처리하는 것이 아니고 이벤트가 발생한 객체가 다른 객체에게 이벤트 처리를 위임하는 방식

컴포넌트는 출력에만 집중하고 다른 작업은 별도의 객체가 처리하는 것이 유지보수에 유리

 

=>이벤트 처리하는 메소드를 확인

이 메소드의 매개변수를 이용하면 이벤트가 발생한 객체에 대한 정보를 가져올 수 있습니다.

자바에서는 getSource()를 호출하면 이벤트가 발생한 객체에 대한 참조를 리턴받을 수 있습니다.

가지고 있는 메소드들이 이벤트별로 다른데 이 메소드들이 이벤트에서 사용할 정보를 리턴해줍니다.

키보드 이벤트가 어떤 이벤트 인지

 

2.이벤트 처리 실습

=>버튼을 누르거나 메뉴를 누르는 경우 또는 TextField에서 Return키를 누르는 경우를 처리할 때는 ActionListener를 이용해서 처리

=>버튼과 텍스트 필드를 만들고 버튼을 누르면 텍스트 필드에 입력된 내용을 콘솔에 출력

 

1) Anonymous클래스를 이용하는 방법

디자인 처리랑 이벤트 처리가 같이 되여있다.

책은 같이 사용하는 것으로 되여있다.

책과 실제로 일하는 것은 다르다.

실제 연습할 때는 분할 해서 해야 한다.

=>실습

public class MyWindow extends Frame {

       private Button btn;

       private TextField tf;

      

       public MyWindow() {

               //여러개의 컴포넌트를 묶어줄 container생성

               //안드로이드에서는 layout이다.

               Panel p  = new Panel();

              

               //컴포넌트들을 생성

               btn = new Button("click");

               tf = new TextField(30);

              

               //버튼의 이벤트 처리를 위한 ActionListener인터페이스의 anonymous clss생성

               //자바에서는 listener 대부분 인터페이스이다.

               ActionListener listener = new ActionListener() {

                      //버튼을 누르거나 텍스트 필드에서 Return누르거나 메뉴를 누르면 호출되는 메소드

                      @Override

                      public void actionPerformed(ActionEvent e) {

                             //입력한 내용 가져옥

                             String msg = tf.getText();

                             //출력

                             System.out.println(msg);

                      }

               };

               //btn에서 Action이벤트가 발생하면 listener 대신 처리하도록 위임(Delegation)

               //btn.addActionListener(listener);

              

               //컴포넌트들을 컨테이너에 배치

               p.add(tf);

               p.add(btn);

              

               //컨테이너를 윈도우에 배치

               add(p);

              

               //Frame 기본 설정

               setTitle("이벤트 처리");

               setLocation(100, 100);

               setSize(300, 400);

               setVisible(true);

       }

 

}

 

 

2) .별도의 이벤트 처리 클래스를 생성해서 이벤트를 처리

이벤트 처리하는 것은 handler가 있다.

나중에 연결만해주면 된다.

하지만 생성자를 생성하는 것을 알아야 한다.

작업을 나누어서 하는 것이 편하다ㅏ.

ActionListener인터페이스를 impelements한 클래스를 생성 - EventHandler

public class EventHandler implements ActionListener {

       private TextField tf;

      

       //생성자 -TextField 1개를 주입받는 생성자

       public EventHandler(TextField tf) {

               this.tf = tf;

       }

 

       @Override

       public void actionPerformed(ActionEvent e) {

               String msg = tf.getText();//오류가 난다. TextFiled 업다.

               System.out.println(msg);

       }

 

}

 

=>MyWindow클래스의 생성자에서 이벤트 연결

               //이벤트 처리를 위한 인스턴스를 생성

               //다른데에서 사용하고 싶을 생성자를 해서 넣어주면 사용 가능하다.

               EventHandler handler = new EventHandler(tf);

               btn.addActionListener(handler);

 

 

 

3.인터페이스를 이용하는 방법

1)인터페이스를 구현한 클래스를 만들고 인스턴스를 만드는 방법

=>유지보수를 위해서는 이 방식을 권장

=>생성자나 Setter메소드를 이용해서 데이터를 넘겨야 하는 어려움이 있음

 

2)인터페이스를 가지고 Anonymous Class를 만드는 방법

=>일반적인 자바(안드로이드)책에서 많이 사용하는 방법

=>이 방법은 컴포넌트가 구현된 클래스에 만들기 때문에 클래스의 변수 사용이 자유로워서 많이 이용

 

3)특수한 인터페이스의 경우는 람다를 이요하는 방법

=>Android Studio는 이 방식으로 최적화

 

4.Event Routing

=>여러 개의 이벤트를 하나의 인스턴스가 처리하도록 하는 방법

=>1개의 이벤트를 1개의 인스턴스가 처리하도록 하면 여러 개의 이벤트를 처리 할때 인스턴스의 개수가 늘어나고 제어하기가 어려워집니다.

=>이 때는 이벤트 처리 메소드에서 이벤트가 발생한 인스턴스를 구분해서 분기를 해야 합니다.

awtswing에서는 이벤트 처리 메소드의 매개변수가 getSource()를 호출하면 이벤트가 발생한 객체의 참조를 리턴하기 때문에 이를 이용해서 구분할 수 있고 ActionEvent의 경우는 getActionCommand()를 호출하면 문자열을 리턴해주는데 이 문자열이 버튼의 텍스트입니다.

getSource()를 사용하는 경우는 배열이나 List인 경우

배열이나 List는 반복문을 사용할 수 있다.

 

Button [] btn = new Button[3];

for(int i = 0; i<3, i++){

System.out.println("버튼" +"i")

}

버튼을 3개 만들 때

Button btn1, btn2, btn3;

btn1 = new Button("버튼1");

btn2 = new Button("버튼2");

btn3 = new Button("버튼3");

 

배열이나 리스트 이용하면 비교하기도 편하고

관리하기도 편하다.

=>이전 Frame에 버튼을 2개 추가해서 이벤트 라우팅 구현-MyWindow클래스에서 작업

1)인스턴스 변수로 버튼을 2개 추가

       private Button btn1, btn2;

       private Button[] buttons = new Button[2];

 

2)생성자 메소드에서 버튼 2개를 만들어서 윈도우에 추가

       //버튼을 생성해서 패널에 추가

               btn1= new Button("button1");

               p.add(btn1);

              

               btn2= new Button("button2");

               p.add(btn2);

              

               //버튼의 이벤트 처리 -라우팅을 이용하지 않는 경우

               // 경우 많으면 힘들다.

               /*ActionListener event1 = new ActionListener() {

                      //버튼을 누르거나 텍스트 필드에서 Return누르거나 메뉴를 누르면 호출되는 메소드

                      @Override

                      public void actionPerformed(ActionEvent arg0) {

                             System.out.println("버튼1 클릭했습니다.");

                      }

               };

               btn1.addActionListener(event1);

              

               ActionListener event2 = new ActionListener() {

                      //버튼을 누르거나 텍스트 필드에서 Return누르거나 메뉴를 누르면 호출되는 메소드

                      @Override

                      public void actionPerformed(ActionEvent arg0) {

                             System.out.println("버튼2 클릭했습니다.");

                      }

               };

               btn2.addActionListener(event2);*/

              

               //이벤트 라우팅을 이용하는 방법

               ActionListener eventRouting = new ActionListener() {

                      //버튼을 누르거나 텍스트 필드에서 Return누르거나 메뉴를 누르면 호출되는 메소드

                      @Override

                      public void actionPerformed(ActionEvent arg0) {

                             //arg0.getActionCommand() 경웬느 text 사용해야 한다.

                             /*switch(arg0.getActionCommand()) {

                             case "button1":

                                    System.out.println("버특1클릭");

                                    break;

                             case "button2":

                                    System.out.println("버특2클릭");

                                    break;

                             }*/

                             System.out.println(arg0.getActionCommand() +" 예약");

                      }

               };

               btn1.addActionListener(eventRouting);

               btn2.addActionListener(eventRouting);

 

=>P 만들고 후에 코드를 추가해야 합니다.

패널을 만들고 해야 한다.

 

5.ItemEvent

=>체크박스 라디오 버튼 이나 콤보박스(Choice) 선택을 변경하는 경우에 발생하는 이벤트

=>ItemListener인터페이스 처리

=>이벤트 처리 메소드의 매개변수가 getItem() 호출하면 어떤 Item 이벤트가 발생했는지 있고 getStateChange()메소드를 호출하면 어떤 상태로 변경되었는지 확인이 가능

 

6.TextListener

=>TextField TextArea에서 텍스트의 변경이 발생했을 때를 처리하는 리스너

=>TextValueChanged(TextEvent e)메소드를 이용해서 처리

=>텍스트가 변경될 상태 변화에 따라 메시지를 출력하거나 유효성을 검사하는 용도로 사용

 

영문대소문자 그리고 숫자 특수문자가 1 이상이면 강함이라고 출력

그렇지 않은 경우에는 약함이라고 출력

특수문자는 영문 대소문자가 아니고 숫자도 아니면 특수문자로 판단

 

               //텍스트 필드나 텍스트 에어리어의 문자열이 변경될 처리를 위한 인스턴스

               TextListener t1 = new TextListener() {

                     

                      @Override

                      public void textValueChanged(TextEvent e) {

                             //텍스트 필드에 입력된 문자열을 가져오기

                             String msg = tf.getText();

                             //대소문자 숫자 ,특수문자 개수를 저장할 변수를 생성

                             int dae = 0;

                             int so = 0;

                             int su = 0;

                             int etc =0;

                            

                             //문자열을 문자단위로 접근

                             for(int i = 0;i < msg.length(); i++) {

                                    //앞에서 부터 한글자씩 가져오기

                                    char ch = msg.charAt(i);

                                    //System.out.println(ch);

                                    if(ch >= 'A' && ch <= 'Z') {

                                            dae += 1;

                                    }else if(ch >= 'a' && ch <= 'z') {

                                            so += 1;

                                    }else if(ch>= '0'  && ch <= '9'){

                                            su += 1;

                                    }else {

                                            etc += 1;

                                    }

                             }

                            

                             /*if(dae >0 && so > 0 && su >0 && etc>0) {

                                    System.out.println("강함");

                             }*/

                            

                             if(dae * so * su  * etc != 0) {

                                    System.out.println("강함");

                             }else {

                                    System.out.println("약함");

                             }

                      }

               };

               tf.addTextListener(t1);

 

**keyListener

=>키보드 이벤트를 처리하기 위한 리스너

1)처리를 위한 메소드

void keyPressed(keyEvent e);키보드를 누를

 

void keyReleased(keyEvent e);키보드에서 손을

 

void keyTypers(keyEvent e);키보드를 누르고 누른 키가 문자 키일 호출되는 메소드

keyPressed 키보드 위치만을 감지를 해서 대소문자 구분을 하지 못했고   keyTypers 대소문자 구분을 했습니다.

 

2)keyEvent클래스

=>모든 key값이 상수로 정의되어 있습니다.

=>getKeyChar() 이용해서 누른 문자를 가져올 있고  getKeyCode() 이용해서 누른 키보드의 숫자 값을 가져올 있습니다.

 

 

c, java, c# ..

옵션을 만들때 int enum 이용

int enum =>정수

python 문자열로 만든다.함수를 찾아도 어려운 이유가 여기 있다. 옵션들이 문자로 되여있다.

문자열 dictionary

color = ""

 

성별

python => String str = "";

 

c,java int gender  ->0 남자

                    ->1 여자

숫자 경우 2여도 되고 3 되고

java, c 상수 만들 경우 대문자로 쓴다.

int MAN = 0; //남자

int MAN = 1;

 

=> 바꿀 경우

final int WOMAN = 0;

       int MAN =1;

 

옵션 -> 택일 : 일련번호사용 (성별 ) - 영문자( A: 65, B : 66, C:67  ..)

     -> 다중선택(취미등 ) : 2 지수승 사용

취미 현재 2개이다

독서

컴퓨터

ð  4가지 경우가 있다.

1.  하나도 선택 안한

2.  독서

3.  컴퓨터

4.  독서 + 컴퓨터

독서 , 컴퓨터 , 복싱 = > 8

독서 ,컴퓨터 , 복싱 , 1 = > 16

여러개 옵션을 사용한 것은 이렇게 사용하면 안된다. 그래서 비트로 한다.

 

복싱

컴퓨터

독서

 

0

0

0

 

1

1

1

 

독서    1

컴퓨터  2

복싱    4

독서 + 복싱 : 5

하나의 BIT 하나이다.

옵션이 많으면 감당할 없다. 4, 5, 6, 7.....

그래서 1인지 확인 해야 한다. 1인지 확인 하는 방법은 &1 이다.나머지는 0이니깐

 

& 0 & 1 =>0

  1 & 1 =>1

 

키보드 문자키는 같이 못눌린다.

 

CTRL: 128

ALT : 512

512 640이나 물어보는 것은 낭비이다.

그래서 & 512한다.

0 & 512 => 0

0 아닌것 하고 하면 512

CTRL 경우에는 & 128

 

두가지

판단 ALT, SHIFT, ALT, MOUSE 감지

 

특정 os 타겟팅  ->여기는 숫자로 쓰준다. 확정되여있다.

swift(Object -c)       ios

andriod  ->안드로이드

vc ++ vc## -> windows 윈도우용

 

shift : 4

 

java->플랫폼의 독립적 운영체제마다 달라서 확정 주지 않다. 운영체제 특징도 많이 알아야 한다. 운영체제마다 값이 다르기 때문이다.

자바는 shift 4

thread 운영체제제에서  thread우선순위가 다르다.

window 10 이고 7이다.

 

 

자바나 ,python 윈도우형이 별로 없는 이유가 vc++, vc##편하기 때문이다.

 

ctrl+->   -> 가속도 10으로

ctrl+s ->자동 발사 s-> 싸는

 

 

 

3) 방향키를 이용해서 레이블을 움직이고 control + x 누르면 프로그램 종료하는 윈도우

KeyWindow

//키보드 이벤트 처리를 위한 인스턴스를 생성

               KeyListener listener  = new KeyListener() {

                      //키보드를 눌렀을 호출되는 메소드

                      @Override

                      public void keyPressed(KeyEvent arg0) {

                             //조합키 확인: shift -1, control -2 , alt -8

                             int modifiers = arg0.getModifiers();

                             //System.out.println(modifier);

                             //contlol+ X이면 종료

                             if((modifiers &2 ) != 0) {

                                    //별도로 누른 키가 X인지 확인 -대소문자 구분해서 하고자 하는 경우는 getKeyChar()

                                    int key = arg0.getKeyCode();

                                    if(key == KeyEvent.VK_X) {

                                            System.exit(0);

                                    }

                             }

                            

                             //System.out.println("아무 키나 누르면 호출됩니다.");

                             //대다수의 프로그램 언어가 유사하게 만들어졌다.

                            

                             //KeyChar 대소문자 구분 a->a A->A

                             //System.out.println(arg0.getKeyChar());

                             //keyCode 대소문자 구분 안함: a->64 A->65 방향키

                             //System.out.println(arg0.getKeyCode());

                            

                             //현재 레이블의 위치 가져오기

                             int x = lbl.getLocation().x;

                             int y = lbl.getLocation().y;

                            

                             //누른 키보드 가져오기

                             int code = arg0.getKeyCode();

                             switch(code){

                             case KeyEvent.VK_UP:

                                    y = y -5;

                                    break;

                             case KeyEvent.VK_DOWN:

                                    y = y + 5;

                                    break;

                             case KeyEvent.VK_LEFT:

                                    x = x -5;

                                    break;

                             case KeyEvent.VK_RIGHT:

                                    x = x + 5;

                                    break;

                             }

                             lbl.setLocation(x, y);

                      }

                      //키보드에서 손을 호출되는 메소드

                      @Override

                      public void keyReleased(KeyEvent arg0) {

                             //System.out.println("키보드에서 손을 때면 무조건 호출");

                      }

                      //문자키를 눌렀을 호출되는 메소드

                      @Override

                      public void keyTyped(KeyEvent arg0) {

                             //System.out.println("문자 키를 눌렀을 호출");

                      }

               };

               //윈도우에 키보드 이벤트 리스터를 연결

               this.addKeyListener(listener);

 

 

8.MouseListener

=>마우스 이벤트를 처리해주는 리스터

=>클릭 , 영역에 마우스가 들어온 경우 , 영역에서 벗어나는 경우 ,마우스는 누를 , 마우스에서 손을 땔때 처리를 위한 메소드가 존재

=>MouseEvent에서는 마우스의 좌표를 리턴해주는 메소드와 클릭 횟수 등을 리턴해주는 메소드가 존재

 

 

9.MouseMotionListener

=>마우스를 드레그 때를 처리해주는 리스너

=>버튼을 누르고 움직일 때는 위한  Dragged메소드와 마우스를 움직이면 무조건 호출되는 Moved 메소드가 존재

 

 

10.WindowListener

=>윈도우 이벤트를 처리해주는 리스너

=>윈도우 관련된 7개의 이벤트 처리 메소드가 존재

=>윈도우의 종료 버튼을 누를 처리를 위한 메소드는 windowClosing

이전 윈도우의 생성자에 종료 버튼을 누를 프로그램이 종료되도록 이벤트 처리 코드를 추가

WindowListener windowListener = new WindowListener() {

                      //7개가 만들어진다.

                      @Override

                      public void windowActivated(WindowEvent e) {

                             // TODO Auto-generated method stub

                            

                      }

                     

                      @Override

                      public void windowClosed(WindowEvent e) {

                             // TODO Auto-generated method stub

                            

                      }

                     

                      @Override

                      public void windowDeactivated(WindowEvent e) {

                            

                      }

                     

                      //종료 버튼을 누를 호출되는 메소드

                      @Override

                      public void windowClosing(WindowEvent e) {

                             //프로그램 종료

                             System.exit(0);

                      }

                     

                      @Override

                      public void windowDeiconified(WindowEvent e) {

                            

                      }

                     

                      @Override

                      public void windowIconified(WindowEvent e) {

                            

                      }

                     

                      @Override

                      public void windowOpened(WindowEvent e) {

                            

                      }

               };

               //윈도우 이벤트 연결

               this.addWindowListener(windowListener);

사용하지도 않는 메소드를 overriding해놓았다.

 

 

11.이벤트 처리를 Listener인터페이스를 이용해서 처리하도록 하면 실제 사용하는 메소드는 1 밖에 없는 인터페이스의 메소드는 전부 추상 메소드라서 반드시 재정의 해야 합니다.

java awt에서는 메소드가 2 이상인 Listener들을 Adapter클래스에 비여있는 내용으로 구현해서 필요한 메소드만 재정의 있도록 Adapter class 제공합니다.

Adapter class 전부 추상 클래스라서 직접 인스턴스를 생성하지 못합니다.

 

앞의 윈도우 이벤트 처리 구문을 수정

               //Listener 인터패이스라서 모든 메소드를 구현해야 하지만

               //Adapter 추상클래스라서 추상메소드 필요한 메소드만 구현하면 됩니다.

               WindowAdapter windowListener= new WindowAdapter() {

                      //종료 버튼을 누를 호출되는 메소드

                      @Override

                      public void windowClosing(WindowEvent e) {

                             //프로그램 종료

                             System.exit(0);

                      }

               };

               //윈도우 이벤트 연결

               this.addWindowListener(windowListener);

 

 

**Swing

=>jvm 자원을 이용해서 GUI(Graphic User Interface)프로그래밍

=>플랫폼에 독립적인 프로그래밍

=>AWT보다 속도도 빠르고 효율적

 

**Container

1.JFrame

=>윈도우 클래스

=>종료 기능을 부여할 때는 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) 호출

=>pack이라는 메소드를 제공해서 윈도우 전체 크기를 하위 COmponent들을 배치한 크기로 설정

=>setIconImage(Image image) 이용해서 아이콘 설정 가능

 

2.전체 화면 크기 구하기

Tookit toolkit = Tookit.getDefaultToolkit();

Dimension size = toolkit.getScreenSize();

 

3.JPanel

=>패널 클래스

=>생성자에 Panel(boolean isDoubleBuffered):더블 버퍼링 여부를 설정

더블 버퍼링: 출력할 내용을 메모리에 저장해두고 출력하는 방식

            메모리 사용량은 늘어나지만 다음에 다시 출력할 출력 속도를 빠르게 해줍니다.

4.JScrollPane

=>스크롤 기능을 가진 클래스

=>부모 화면보다 컴포넌트를 배치할 사용

=>생성자를 호출해서 인스턴스를 만들 하위 컴포넌트를 대입

 

 

**Swing 일반 컴포넌트

1.경계선 설정 기능(Border)

=>setBorder메소드에 AbstractBorder클래스의 하위 클래스 인스턴스를 대입하면 경계선이 만들어집니다.

=>AbstractBorder클래스의 하위 클래스 :BevelBorder, CompoundBorder, EmptyBorder, EctchedBorder, TitleBorder

 

2.Component 마우스를 올리면 보여지는 tooltip 설정 기능

=>setTooltipText메소드에 문자열을 대입하면 툴팁이 만들어집니다.풍선 도움말

 

 

3.JLabel

=>문자열 출력을 위한 컴포넌트

=>생성자에서 Icon 대입하면 이미지 출력 가능

맞춤 설정도 가능합니다.

 

 

 

 

4.버튼

=>AbstractButton(추상클래스) 클래스로 부터 상속받은 클래스를 이용

=>JButton,JTOGGLEButton,JRadioButton 으로 구분

=>현재 윈도우에 버튼을 추가해서 버튼을 누를 마다 애니메이션을 시작하고 중지하는 기능을 구현

=>스레드를 만들어야 하는 순간

중간중간 다른 작업을 수행할 있도록 만들어야

실행 중간에 멈출수 있도록 해야

네트워크에서 다운로드나 업로드를 받을 (오랜 시간이 걸리는 작업)

상바대는 작업이라면 버튼 하나면 된다. 시작 중지

public class MyFrame extends JFrame {

       JLabel lbl;

       ImageIcon icon;

       JButton btn;

       //여기에서 만든 변수는 자동 초기하된다.

       //애니메이션을 수행할 스레드 변수

       Thread th;//자바는 네트워크 작업할 스레드 필수 하니깐

       public MyFrame() {

               JPanel p = new JPanel();

               //JLabel lbl = new JLabel("문자열");

               //이미지를 가지고 아이콘을 생성

               //이미지 파일 크기 그래도 성성됩니다.

               icon = new ImageIcon("C:\\project\\JAVA_PROJECT\\java\\src\\java\\img\\heli1.png");

               lbl = new JLabel(icon);

               p.add(lbl);

              

               //버튼을 만들어서 패널에 추가

               btn =   new JButton("시작");

               p.add(btn);

              

               //버튼을 누를 이밴트 처리를 위한 인스턴스를 생성

               //위임해도 실행하는데는 아무런 영향이 없다.

               ActionListener listener = new ActionListener() {

                      @Override

                      public void actionPerformed(ActionEvent e) {

                             switch(e.getActionCommand()) {

                             case "시작":

                                    btn.setText("중지");

                                    //스레드를 생성해서 시작

                                    th = new Thread() {

                                            String[] images = {"heli1.png" ,"heli2.png","heli3.png"};//images[i%images.length]

                                            public void run() {

                                                   try {

                                                          int i = 0;

                                                          while(true) {

                                                                 //0.1초마다 대기

                                                                 Thread.sleep(100);

                                                                 //아이콘 생성

                                                                 icon = new ImageIcon("C:\\project\\JAVA_PROJECT\\java\\src\\java\\img\\"+(i%10)+".png");

                                                                 lbl.setIcon(icon);

                                                                 i += 1;

                                                          }

                                                   }catch (InterruptedException e) {

                                                          return ;

                                                   }

                                            }

                                    };

                                    th.start();

                                   

                                    break;

                             case "중지":

                                    btn.setText("시작");

                                    //스레드를 중지

                                    th.interrupt();

                                    break;

                             }

                      }

               };

               btn.addActionListener(listener);

               add(p);

              

               //Frame 기본 설정

               setTitle("이미지 레이블");

               setLocation(100, 100);

               setSize(1000, 1000);

               setVisible(true);

               //종료 기능 부여

               setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

              

               //이미지 교체 애니메이션

               //현재는 코드가 진행이 안된다.

               /*String[] images = {"heli1.png" ,"heli2.png","heli3.png"};*/

               /*int i = 0;

               while(true) {

                      try {

                             Thread.sleep(50);

                             //icon = new ImageIcon("C:\\project\\JAVA_PROJECT\\java\\src\\java\\img\\"+(i%10)+".png");

                             icon = new ImageIcon("C:\\project\\JAVA_PROJECT\\java\\src\\java\\img\\heli"+(i%3)+".png");

                             lbl.setIcon(icon);

                             i = i+ 1;

                      } catch (InterruptedException e) {

                             // TODO Auto-generated catch block

                             e.printStackTrace();

                      }

               }*/

               //시작하고 중지 스레드 interrupte걸어서

              

               /*for(int i = 0 ; i< 10; i++) {

                      try {

                             Thread.sleep(1000);

                             System.out.println(i);

                             //lbl.setText("레이블:"+i);

                            

                             icon = new ImageIcon("C:\\project\\JAVA_PROJECT\\java\\src\\java\\img\\"+i+".png");

                             //끝부분만 바꾸면 바꿀 있다.

                             lbl.setIcon(icon);

                            

                      } catch (InterruptedException e) {

                      }

               }*/

       }

}

 

 

5.JTextField

=> 줄의 문자열을 입력받기 위한 컴포넌트

=>현재 커서의 위치를 getCaretPosition으로 가져오고 setCaretPosition(int position)으로 설정

마우스 포인터를 cursor하는 경우도 있지만 caret이라고 하는 경우도 있습니다.

cursort 데이터를 단위로 하나씩 접근하는 포인터의 의미로도 사용

 

6.JPasswordField

=>비밀번호를 입력받기 위한 컴포넌트

=>보여지는 문자를 echoChar라고 합니다.

=>입력한 내용을 가져올 때는 getText deprecated 되서 getPassword 사용하는 것을 권장

 

 

7.JTextArea

=>여러 입력을 위한 컴포넌트

=> 바꿈 모드 설정을 위한 setLineWrap(boolean warp). setWrapStyle(boolean word):단어 단위 바꿈

 

8.JComboBox

=>콤보박스

=>여러 개의 항목 중에서 화면에 하나만 출력하고 하나만 선택할 있도록 해주는 컴포넌트

 

9. JList

=>리스트 또는 리스트 박스

=>여러 개의 항목 여러 개를 화면에 출력할 있고 여러 개를 선택하도록 있도록 해주는 컴포넌트

=>ComboBox JList 용도가  Radio CheckBox 같은데 항목이 많을 Radio CheckBox 영역을 너무 많이 차지 하기 때문에 이런 경우에는 comboBox List 사용

항목의 개수 때문에

 

 

10.JTable

=>테이블 모양으로 데이터를 출력하는 컴포넌트

1)생성자

JTable():비여있는 상태로 생성

JTable(int rows, int cols);행과 수를 지정해서 생성

JTable(TableModel model): 데이터 모델을 이용해서 생성 -MVC구현을 위해서 존재

 

2)데이터 출력

setValueAt(Object value, int row, int col):row col 해당하는 셀에 value toString 결과를 출력

 

setModel(TableModel model);테이블 모델을 만들어서 출력

 

3) DefaultTableModel

DefaultTableModel()

DefaultTableModel(int 행개수, int 열개수)

DefaultTableModel(Object [][]data, Object[] columnName):첫번째 매개변수는 셀에 출력할 데이터의 이차원배열이고 뒤의 데이터는 컬럼이름 배열

 

4)테이블 모델을 이용해서 데이터를 설정한 경우의 데이터 편집

addRow(Object[] data)

insertRow(int row,Object[] data)

moveRow(int start, int end, int to);start부터 end까지의 행을 to 위치로 이동

 

updateUI();다시 출력

 

5)테이블 모델을 이용하기를 권장하는 이유

=>JTable 출력하는 모양에만 관여를 하고 실제 데이터의 삽입과 삭제는 TableModel 관여

 

**Pane

=>특정 목적에만 이용하도록 만든 컴포넌트

1.JScrollPane

=>스크롤을 만들어주는 컴포넌트

 

2.JEditorPane

=>텍스트를 출력하기 이한 컴포넌트

=>TextArea 다른 점은 URL 연결해서 HTML 출력할 있고 RTF포맷도 출력이 가능

 

3.JTabbedPane

=>탭을 만들기 위한 컴포넌트

 

4)javax.swing.JOptionPane

=>메시지나 줄의 입력을 받기 위한 대화상자

1)MessageDialog

=>단순 메시지 출력을 위한 대화상자

=>JOptionPane.showMessageDialog() 이용해서 생성

 

2)ConfirmDialog

=>버튼을 2 이상 배치해서 생성한 버튼에 따라 다른 작업을 하고자 사용

=> JOptionPane.showConfirmDialog() 이용해서 생성

누른 버튼의 인덱스를 리턴합니다.

 

3)InputDialog

=>하나의 텍스트필드를 배치해서 줄의 텍스틀 입력받을 있는 대화상자

=> JOptionPane.showInputDialog() 이용해서 생성

확인 버튼을 누르면 입력한 내용이 String으로 리턴되고 취소버튼을 누르면 null 리턴됩니다.

입력한 내용이 없는데 확인을 누르면 null 아니고 "" 리턴됩니다.

 

 


showMessageDialog
(Component parentComponent, Object message, String title, int messageType, Icon icon)

Brings up a dialog displaying a message, specifying all parameters.

 

               //showMessageDialog(Component parentComponent, Object message, String title, int messageType, Icon icon)

               //단순한 메시지 출력 - 리턴값이 없습니다.

               //JOptionPane.showMessageDialog(this, "메시지","제목",JOptionPane.ERROR_MESSAGE);

               //ERROR_MESSAGE red

              

               //2 이상의 버튼을 배치해서 confirm 받는 메소드

               /*

               int result = JOptionPane.showConfirmDialog(this, "정말로 삭제","삭제",JOptionPane.YES_NO_CANCEL_OPTION);

               if(result == JOptionPane.YES_OPTION) {

                      JOptionPane.showMessageDialog(this, "yes","제목",JOptionPane.ERROR_MESSAGE);

               }else if(result == JOptionPane.NO_OPTION) {

                      JOptionPane.showMessageDialog(this, "no","제목",JOptionPane.ERROR_MESSAGE);

               }else {

                      JOptionPane.showMessageDialog(this, "cancel","제목",JOptionPane.ERROR_MESSAGE);

               }*/

              

               //한줄의 텍스트를 입력받는 대화상자를 출력

               //입력한 내용이 없는 상태에서 확인을 누르면 ""

               //

               String name = JOptionPane.showInputDialog(this,"이름을 입력하세요","");

               System.out.println(name);

 

**메뉴

=>JMenuBar, JMenu, JMenuItem(JMenuItem, JCheckBoxMenuItem, JRadioButtonMenuItem)

=>메뉴에 setMnemonic(int 단축키) 설정하면 alt 조합해서 단축키로 사용 가능

응용프로그램을 만들 alt 포함해서 단축키를 만드는 것은 권장하지 않습니다.

미국에서 메뉴에 대한 단축키를 alt 사용한다.

ctrl 단독으로 많이사용한다.

 

**Stream

1.  입출력 Stream

2.  1.8에서 등장한 Map Reduce 프로그래밍일 위한 스트림 ->우리가 하는

 

 

 

반응형

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

java-15  (1) 2020.10.05
java-14  (0) 2020.10.04
java-12  (0) 2020.10.02
java-11  (0) 2020.10.01
java-10  (0) 2020.09.30
728x90
반응형

상호배제 : 스레드가 수정하고 있는 공유자원은 다른 스레드가 수정할 수 없다.

변수에 volatile :long,double 같은 64bit 자료형

예약으로 되여있지만 거의 사용하지 않는다.

synchronized: 이 메소드가 끝났을 때 까지 나머지는 대기 해야 한다.

synchronized(객체명): 이 블록내에서 이 객체는 동기화가 된다.

이 객체는 다른 것들이 사용할 수 없다.

volatile :특수 변수의읽고 쓰기 작업에 대해 원자성을 보장해주는 예약어

윈도우 64BIT는 문제가 없는데

a영역을 하는 중 thread 가 들어오면 문제가 생긴다.

vabtile a

a작업 다 끝나야 b 쪽에서 다 하고 끝난다.

 

메소드의 결과형 앞에 SYNCHRONIZED를 추가

이것이 문제가 된다.

 

int x = 0;

 

threa 형식으로 할때

a();수행하다가 sleep를 하면 b를 진행()

a()에서 1를 만들었는데 2가 된다.

 

 

synchronized a 순서데로 한다. 다른 스레드가 끼여들지 못하게끔

비동기는 왔다 갔다 할 수 있다. asynchronized

 

threadshare로 해서 만들었다.

 

스레드는 우선순위를 정할 수 없다.

 

**Mutual Exclusion

=>하나의 스레드가 수정 중인 공유자원을 사용이 끝나기 전에 다른 스레드가 수정하면 안된다.

 

1.volatile

=>변수앞에 붙이는 예약어로 변수가 연산에 사용될 때 원자성을 보장

원자성 :작업이 완전히 끝나기 전에는 다른 작업이 끼어들 수 없다.

=>32bit시스템에서 64bit자료형인 long, double을 멀티 스레드 환경에서 사용하다 보면 작업이 완료되기 전에 다른 스레드에서 사용해서 잘못된 결과를 사용할 수 있습니다.

이 경우에 volatile을 보여주면 위와 같은 상황이 발생ㅇ하지 않습니다.

 

2. synchronize메소드

=>메소드 결과형 앞에 synchronized를 붙이면 메소드를 동기화해서 실행

=>이 메소드가 완료되기 전에는 다른 스레드가 수행될 수 없도록 합니다.

 

파일 입출력은 cpu가 필요없다.direct memory access (DMA) 데이터 옮길 때는 CPU가 필요하다.

CPU가 읽고 다 읽으면 INTERRUPT준다.

다운로드 받는 동안 다른 것 가능하다.

 

GUI에서는 오래 시간 하면 뒤에로 간다.

계산하고 , 화면 출력하는 것은 오래 걸려서 뒤에서 뺀다.

 

3. synchronized블럭

synchronized (인스턴스 ) {

           코드 작성

}

=>블럭 내에서 인스턴스를 사용하는 부분만 동기화가 됩니다.

한번에 이루어져야 하는 부분만 동기화 할 수 있습니다.

 

//Runnable:스레드로 동작할 있도록 해주는 인터페이스

public class ThreadImpl implements Runnable {

 

       //인덱스 변수와 합께를 저장할 변수

       private int idx;

       private int result;

      

       //result 리턴하는 메소드

       public int getResult() {

               return result;

       }

      

       //idx 값을 1 증가하면서 result 추가하는 메소드

       //10000 수행하는 메소드

       //메소드 앞에 SYNCHRONIZED 붙으면 멀티 스레드 환경이더라도 메소드의 수행이 종됴될 까지

       //다른 작업은 수행할 없습니다.

       //방법 1 -스레드 끝나고 하면 의미가 없다.

       /*private synchronized void sum() {

               for (int i = 0; i < 10000; i++) {

                      idx += 1;

                      try {

                             Thread.sleep(1);

                      }catch(Exception e) {}

                      result += idx;

               }

       }*/

      

       //방법 2 - 일부분으로 해서 사용한다.

       private void sum() {

               for (int i = 0; i < 10000; i++) {

                      // 블록 안에서this(자기 자신) 메소드를 사용하는 부분을 동기화

                      synchronized(this) {//동기화 블록을 추천한다.

                             idx += 1;

                             try {

                                    Thread.sleep(1);

                             }catch(Exception e) {}

                             result += idx;

                      }

               }

       }

       //스레드로 동작할 내용을 작성하는 메소드

       @Override

       public void run() {

               sum();

       }

 

}

 

 

public class MutexMain {

       public static void main(String[] args) {

               //Runnable인터페이스를 implements 클래스에 인스턴스 생성

               ThreadImpl threadImpl = new ThreadImpl();

              

               //Thread클래스의 생성자에 대입해서 thread인트턴스 생성

               Thread th1 = new Thread(threadImpl);

               Thread th2 = new Thread(threadImpl);

               //스레드는 비동기 이다.

               th1.start();

               th2.start();

               //스레드가 하나일 경우 문제가 없지만 두개 경우 문제가 생긴다.

              

               //System.out.println(threadImpl.getResult()); //0이다.

               //동기화는 순서이다.

               //네이버 비동기로 한다.

              

               try{

                      //스레드의 수행이 끝나면 결과를 출력

                      Thread.sleep(40000);

                      System.out.println(threadImpl.getResult()); //

               }catch(Exception e) {

               }

              

       }

}

 

**생산자와 소비자 문제

=>공유 자원을 생성하는 스레드와 사용하는 스레드가 동시에 동작 중일 때 소비자 스레드는 생산자 스레드가 공유 자원을 생성을 해주었을 때 동작을 해야 합니다.

공유자원을 생성하지 않은 상태에서 소비자 스레드가 동작하게 되면 예외가 발생합니다.

 

1.wait 메소드

=>스레드의 작업을 대기 시키는 메소드

wait() :notity()가 호출 될 때 까지 대기 -싸인을 주는 것

wait(long msec): 매개변수로 대입된 시간만큼 대기

 

2.notify메소드

=>대기 중인 스레드에게 신호를 보내서 작업을 수행하도록 해주는 메소드

notify():wait중인 스레드 중 1개 에게만 신호를 보내는 메소드

notifyAll():wait중인 모든 스레드에게 신호를 보내는 메소드

 

3.주의할 점

=>wait notify메소드는 Object클래스의 메소드

=>waitnotifysynchronized메소드에서만 동작

메소드가 synchronized메소드가 아니면 예외가 발생합니다.

 

4.실습

1) 공유 자원 클래스

=>List를 인스턴스 변수로 받고 List에서 데이터 1개를 꺼내서 출력하는 메소드 와 List 데이터 1개를 저장하는 메소드를 소유

//공유 자원을 소유할 클래스

public class Product {

       //공유자원 변수

       private List<Character> list;

      

       //생성자 -list 초기화

       public Product() {

               list = new ArrayList<Character> ();

       }

      

       //데이터 1개를 받아서 저장하는 메소드

       public void put(Character ch) {

               list.add(ch);

               System.out.println(ch+" 입고 되었습니다");

               try {

                      Thread.sleep(1000);

               } catch (InterruptedException e) {}

               System.out.println("입고 현재 수량:" +list.size());

       }

      

       //데이터 1개를 꺼내서 출력하는 메소드

       public void get() {

               //첫번째 데이터를 삭제하고 리턴

               Character ch = list.remove(0);

               System.out.println(ch+" 출고 되었습니다");

               try {

                      Thread.sleep(1000);

               } catch (InterruptedException e) {}

               System.out.println("출고 현재 수량:" +list.size());

       }

}

 

 

2)생산자 스레드

=>앞에서 만든 Product 생성자의 매개변수로 받아서 스레드를 26 데이터를 삽입

a-z

=>Thread클래스로 부터 상속받는 Producer클래스

public class Producer extends Thread {

       private Product product;

      

       //외부에서 인스턴스 주입받아서 객체를 생성하는 생성자

       public Producer(Product product){

               this.product = product;

       }

 

 

       //스레드로 동작하는 메소드

       public void run() {

               for (char i = 'A';i <= 'Z'; i++) {//i = i+1인터로 가능성이 있다.

                      product.put(i);

               }

       }

 

}

 

3)소비자 스레드

=>Product를 외부에서 받아서 스레도로 26get동작

=>Thread클래스로부터 상속 받는 Customer

public class Customer extends Thread {

       //공유 자원 변수

       private Product product;

      

       //외부에서 주입 받는 생성자

       public Customer(Product product) {

               this.product = product;

       }

      

       public void run() {

               for(int i = 0; i < 26; i++) {

                      product.get();

               }

       }

}

 

4)main메소드를 소유한 Main클래스

예외 처리해도 좋지만

100 개 수집시 구글이 크롤링 한다.

순차적으로 사용하면 예외처리 하지 않고 예외처리 해주면 중간에 멈춰도 작업 할 수 있다. 동시에 하면 시간이 빠르다.

daemon은 같이 죽는다. 같이 죽을려면 daemon하면 된다.

출고가 오류난다. 출고는 입고한 다음 해야 한다.

public class Main {

 

       public static void main(String[] args) {

               //공유 자원 생성

               Product product = new Product();

              

               //Thread 클래스를 상속받은 클래스의 인스턴스를 만들고 스래데로 동작

               Customer customer = new Customer(product);//꺼내는

               Producer producer = new Producer(product);//저장하는

              

               //thread 직접 start  가능하다.

               //runable thread한다음 start해야 한다.

               customer.start();

               producer.start();

              

       }

 

}

 

 

 

5).이 상태에서 실행하면 customer스레드가 예외를 발생시킵니다.

product에 데이터가 없는데 읽을려고 해서 예외 발생

특정 조건을 만족하지 않으면 wait를 호출해서  대기모드로 만들고 조건이 만족되면 norify를 호출해서 wait중인 스레드를 깨워주면 됩니다.

synchronized에서만 가능하다.

 

6)Product클래스의 메소드를 수정

notify wait하면서 기다리고 계속 깨워줘야 한다.

       //데이터 1개를 받아서 저장하는 메소드

       public synchronized void put(Character ch) {

               if(list.size() >2) { //2개이상 생산하지 않는다.

                      //2 만들고 대기한다.

                      try {

                             wait();

                      } catch (InterruptedException e) {

                             e.printStackTrace();

                      }

               }

               list.add(ch);

              

               //데이터 추가후  신호룰 보내준다.

               notify();

              

               System.out.println(ch+" 입고 되었습니다");

               try {

                      Thread.sleep(1000);

               } catch (InterruptedException e) {}

               System.out.println("입고 현재 수량:" +list.size());

       }

      

       //데이터 1개를 꺼내서 출력하는 메소드

       //synchronized 붙지 않으면 jvm 모니터링을 하지 않기 때문에 신호를 보낼 없습니다.

       public synchronized void get() {

               //list 데이터가 없으면 대기

               if(list.size() == 0) {

                      try {

                             wait();

                      } catch (InterruptedException e) {

                             e.printStackTrace();

                      }

               }

               //첫번째 데이터를 삭제하고 리턴

               Character ch = list.remove(0);

               notify();//잠자고 있으면 깨워라

               System.out.println(ch+" 출고 되었습니다");

               try {

                      Thread.sleep(1000);

               } catch (InterruptedException e) {}

               System.out.println("출고 현재 수량:" +list.size());

       }

 

캐릭터를 만들어서 모든 캐릭터 정보를 했으면 아무런 문제도 없다.

 

 

공경력 = 무기 + _ + 공성원

공성원이 0으로 된다.

공경력 계산을 할 때는 wait()하다가 공성정보 읽고 (notify)로 해서

방어력

 

multi -thread동시에 읽을 경우 문제가 생긴다. 그래서 공성정보 먼저 읽으면 무제 없다.

m 두번 눌리면 새 창을 만들다가 창으로 바꿘다.

m은 두번 눌려서 되는 원인이 공성정보가 후에 조회 되였다.

그래서 어떤 것 되고 해야 한다.

 

 

로그인시

id

pw

 

기타정보 를 따로 읽어도 되는데 로그인 정보를 읽으려면 위에것 먼저 조회하고 해야 한다.

 

 

처음에는 작업2를 하면 안된다. wait하고 작업1에서 notify만 하면 된다.

업무에 대한 이해를 알아야 한다.

 

DeadLock: 결코 발생할 수 없는 사건을 무한정 기다리는 것

select - shared lock

insert,update, delece - executed lock

 

toad등에서 insert, update, delete lock을 한다.

eclipse에서 insert할 경우 안된다. 기다려야 한다.

commit/rollback할 때 까지 기다린다.

기다리고만 한다.

select 는 된다.

 

awt, swing으로 하면 안드로이드 하면 된다.

 

**Semaphore

=>공유자원을 동시에 사용할 수 있는 스레드의 개수를 설정할 수 있는 클래스

=>이 클래스를 이용하면 동시에 수행되는 스레드의 개수를 지정 가능

1.생성자

Semaphore(int permit): 동시에 수행될 스레드 개수

2.메소드

acquire():공유자원에 lock을 설정하는 메소드, 이 메소드가 호출되면 공유자원 개수가 1개 줄어듭니다.

release()"공유자원에 lock을 해제하는 메소드, 이 메소드가 호출되면 공유자원 개수가 1개 늘어납니다.

 

3.작업 방법

=>Semaphore클래스의 인스턴스를 스레드 외부에서 생성

=>Semaphore인스턴스를 스레드에게 전달해서 공유자원을 사용하는 부분에서 이용

 

4.실습

1) 세마포어가 적용된 스레드 클래스

 

public class ThreadEx extends Thread {

       public void run() {

               System.out.println("몬스터 생성");

               try {

                      Thread.sleep(3000);

               } catch (InterruptedException e) {

                      e.printStackTrace();

               }

               System.out.println("몬스터 소멸");

       }

}

 

public class SemaphoreMain {

       public static void main(String[] args) {

               //만드는 만큼 몬스타가 생긴다.

               for (int i = 0; i < 20; i++) {

                      ThreadEx th = new ThreadEx();//20개가 동시에 진행된다.

                      th.start();

               }

              

              

       }

}

 

 public class ThreadEx extends Thread {

       //세마포어 변수

       private Semaphore sem ;

      

       //외부에서 Semaphore 주입받습니다.

       public ThreadEx(Semaphore sem) {

               this.sem = sem;

       }

      

       public void run() {

               try {

                      //lock 취득 - 사용 개수가 1 줄어듬

                      sem.acquire();//3,2,1,0

                      //몬스터를 몇개 만들고 없에버린다.

               } catch (InterruptedException e1) {

                      // TODO Auto-generated catch block

                      e1.printStackTrace();

               }

               System.out.println("몬스터 생성");

               try {

                      Thread.sleep(3000);

               } catch (InterruptedException e) {

                      e.printStackTrace();

               }

               System.out.println("몬스터 소멸");

               //몬스타를 죽고 난다음 release하라고 해야 한다.

               sem.release();//하나씩 늘어난다.

       }

}

 

2)main메소드

public class SemaphoreMain {

       public static void main(String[] args) {

               //동시에 실행시키고 싶은 개수 만큼

               //동시에 3 까지 실행되는 세마포어 생성

               Semaphore sem = new Semaphore(3);

               //만드는 만큼 몬스타가 생긴다.

               for (int i = 0; i < 20; i++) {

                      ThreadEx th = new ThreadEx(sem);//20개가 동시에 진행된다.

                      th.start();

               }

       }

}

 

스레드는 동시에 진행하는 것이아니다.

 

 

**병렬처리

=>동시에 2개 이상의 작업을 수행하는 것

=>자바에서는 fork&join프레임워크(1.7)와 스트림 API(1.8)에서 제공

1부터 100까지의 합계를 구하는 경우 프로세스가 2개 이상이라면 1-50까지를 하나의 프로세스가 계산하고 다른 프로세서가 51- 100까지의 합을 계산해서 더하면 훨씬 효율적으로 작업을 할 수 있게 됩니다.

=>리턴 값 여부에 따라 달라질 수 있는데 작성 방법

작업을 수행하고 RETURN여부에 따라서 상속받는 것이 다른다. RecursiviAction(리턴 값이 없는 경우)이나 RecursiveTask(리턴 값이 있는 경우) 클래스를 상속받는 클래스를 생성하고 compute메소드를 재정의해서 작업을 어떻게 분할해서 수행할지 작성하고 결과를 리턴하면 됩니다.

RecurisiveTask는 리턴할 데이터 타입으로 제너릭을 적용해야 하고 compute의 리턴 타입도 일치해야 합니다.

 

//1-60 60 걸려야 한다.보통은

작업을 나누어서 해야 하기 때문에 정도 까지는 걸린다.

 

//1부터 60까지의 합계를 분할새어 수행하는 클래스

public class ParallelProcessing extends RecursiveTask<Integer>{

       //합계를 시작할 결과 끝나는 값을 저장할 인스턴스변수

       public int start;//생성자 안만들고 public으로 하기

       public int end;

      

       //생성자를 이용해서 start end 주입받기

       public ParallelProcessing(int start,int end) {

               this.start = start;

               this.end  = end;

       }

      

       //start부터 end까지의 합계를 구해서 리턴하는 메소드

       private int sum() {

               System.out.println("start:" + start +" end:"+end);

               int r =0;

               for(int i = start; i <= end; i++) {

                      r += i;

                      try {

                             Thread.sleep(1000);

                      } catch (InterruptedException e) {}

               }

               return r;

       }

 

       @Override

       protected Integer compute() {

               if(end - start < 10) {

                      return sum();

               }

              

               int half =  (end + start)/2;

              

               //1부터 15, 16 - 30

               //10보다 작을 까지 쪼개서 한꺼번에 실행시킨다.

               //자기가 자기를 계속 호출한다.ParallelProcessing

               ParallelProcessing p1 = new ParallelProcessing(start,half);

               ParallelProcessing p2 = new ParallelProcessing(half+1,end);

               /*p1.start = 1;

               p1.end = 30;

              

               p2.start = 31;

               p2.end = 60;*/

              

               //첫번째 적업 실행

               p1.fork();

               //첫번째 작업 결과에 두번째 작업 결과를 더해서 리턴

               return p2.compute() + p1.join();

       }

 

}

 

public class Main {

       public static void main(String[] args) {

               ParallelProcessing p = new ParallelProcessing(1, 60);

               //위의 작업을 나누어서 있는 pool 생성

               ForkJoinPool pool = new ForkJoinPool();

               //pool 작업을 대입해서 실행

       System.out.println(pool.invoke(p));//java.lang.StackOverflowError 스택이 터져버렸다.

       }

}

 

 

 

 

**java GUI

1.awt

=>운영체제의 자원을 이용해서 GUI프로그래밍

=>운영체제 별로 다르게 출력될 수 있습니다.

=>운영체제에 종속적이라고 느리고 무겁습니다.

 

2.swing

=>jvm자원을 이용해서 GUI프로그래밍

=>운영체제에 독립적이고 속도가 AWT보다는 빠릅니다.

=>SWING의 대부분의 클래스는 AWT로 부터 상속받았습니다.

 

3.javaFX

=>가볍고 풍부한 UI제공

=>레이아웃 , 스타일 ,애플리케이션 로직의 분리:MVC구현

=>HTML이나 CSS도 사용이 가능

=>swing으로 만들어져 있는 많안 애플리케이션들이 javaFX로 변환되고 있는 중

 

4.awt swing의 이벤트 처리 방식이 안드로이드 이벤트 처리 방식

awtswing은 이벤트 처리 클래스가 별도의 클래스로 존재하는데 안드로이드에서는 뷰의 내부 클래스로 존재

 

 

**AWT

=>운영체제에 종속적인 GUI프로그래밍

=>최근에는 거의 사용 안함

 

 

1.GUI화면 구성 요소

1)COMPONENT

=>화면에 보여지는 개체들의 최상위 클래스

 

2)cONTAINER

=>COMPOENT로 부터 상속을 받아서 다른 컴포넌트들을 묶어서 출력하기 위한 컴포넌트

=>단독으로 출력가능한 객체 :Frame, Dialog

=>단독으로는 출력이 안되는 객체: Panel, Window

=>브라우저를 이용해서 출력하는 객체 :Applet -사용을 금기시 함

html5에서는 별도의 플러그 없이 앱 애플리케이션을 구현하자는 주의여서 active -X, apple, flash등의 사용을 배제

 

 

2.Component의 주요 메소드

Color getBackground(), void setBackground(Color color)->배경색 관련 메소드

Cursor getCursor(),void setCursor(Cursor cursor)->마우스 커서 관련 메소드

Font getFont(), void setFont(Font font) ->포트

Color getForeground(), void setForeground(Color color) -> 글자 색

Point getLocation(), void setLocation(Point)->좌표

Dimension getSize(), void setSize(Dimension dimension)->크기

=>크기와 좌표는 분할해서 2개로 설정해도 된다.

Rectangle getBounds(), void setBounds(Rectangle rectangle) ->좌표와 크기

=>숫자 4개로 설정이 가능

위치의 기본값은 0 ,0 크기의 기본값도 0,0

안드로이도 크기 안주면 보이지 않는다.

 

void setEnabled(boolean isEnabled): 할성화 여부 설정

void setVisible(boolean isVisible): 화면 출력 여부 ->맨처음에 전체 윈도우를 불러야만 사용가능

 

3.Frame

=>애플리케이션의 가장 기본이 되는 윈도우

=>기본적으로 화면에 출력되지 않도록 설정되어 있기 때문에 setVisible을 호출해서 화면에 보여지도록 설정해야 합니ㅏㄷ.

=>setTitle을 이용하면 제목을 설정할 수 있습니다.

=>종료버튼이 제공이 되지만 기능은 없습니다.

나중에 이번트 처치를 해야만 창을 종료할 수 있습니다.

 

4.COmponent를 다른 component에 추가할 때는 add(Component component) 를 호출하면 추가됩니다.

 

 

5.윈도우 생성

=>제공되는 클래스를 사용할 때 제공되는 클래스의 인스턴스를 바로 만들어서 사용하는 경우인데 기능이 충분해서 인스턴스 생성만으로 옵션들을 설정해서 사용합니다.

=>상속받아서 사용하는 경우는 기능이 부족해서 기능을 추가해서 (Overriding)사용하기 위해서 입니다.

초기화 작업을 하거나 메소드 overriding을 해서 사용

상속시 생성자도 안하고 overriding하지 않으면 이다. 그냥 메소드 추가하는 방법은 없다고 보셔도 됩니다.

 

1)Frame인스턴스를 만들어서 출력

public class FrameMain1 {

       public static void main(String[] args) {

               //이렇게 하게 되면 너무 지전분하다.

               //윈도우 생성

               Frame f = new Frame();

               //좌표를 설정

               f.setLocation(100, 100);

               //윈도우 크기 설정 - 기본 크기가 0,0이므로 크기 설정하지 않으면 출력 안됨

               f.setSize(300, 500);

               f.setTitle("처음 만들어보는 윈도우");

               //f.setBackground(Color.GREEN);

               f.setBackground(new Color(128,0, 255));

               //윈도우를 화면에 출력 - 기본적으로 보이지 않도록 설정되어 있어서 메소드를 호출해야 보여짐

               f.setVisible(true);

       }

}

 

 

2)Frame으로 부터 상속받는 클래스를 만들고 클래스의 인스턴스를 만들어서 출력

=> 이 방법이 권장

=> 생성자를 만들어서 필요한 옵션을 설정

public class MyFrame extends Frame{

       //생성자

       public MyFrame() {

               setTitle("프레임 상속");

               setLocation(20,20);

               setSize(400,400);

               setVisible(true);

       }

}

 

public class FrameMain2 {

       public static void main(String[] args) {

               new MyFrame();

       }

}

 

6.Pannel

=>단독으로 출력될 없는 컨테이너로 여러 컴포넌트들을 묶어서 출력하기 위한 객체

1)생성자

Panel();

Panel(LayoutManager layoutManager):배치 방법을 설정해서 생성

 

2)주요메소드

add(Component component):패널위에 컴포넌트를 추가

 

7.Dialog(대화상자)

1)ModalModeless

Modal: 대화상자가 화면에 출력되어 있으면 다른 곳으로 제어권을 뺏기지 않는 대화상자, 열기와 저자 대화상자

파일에서 열기 누르면 다른데 누를수 가 없다.

적용, 저장이 있다.

 

Modeless:화면에 출력된 상태에서 다른 곳으로 제어권을 옮길 수 있는 대화상자,  찾기와 바꾸기

옵션을 대화상자에서 변경하고 바로 적용하고자 할 때 사용

modeless는 지역변수로 만들면 나중에 대화상자를 닫지 못하는 경우가 발생할 수 있습니다.

항상 메소드 바같쪽에 나둬야 한다.

 

2)생성자

Dialog(Frame이나 Dialog owner):대화상자가 닫히고 난 후 포커스를 받을 윈도우를 설정해서 생성

대화상자 기반의 프로그램은 계산기 =>dialog(null)

Dialog(Frame이나 Dialog owner,String title)

Dialog(Frame이나 Dialog owner,boolean modal) //truemodal

Dialog(Frame이나 Dialog owner,String title,boolean modal)

순서를 잘 확인해야 한다.

 

modalless상태

       //생성자

       public MyFrame() {

               setTitle("프레임 상속");

               setLocation(20,20);

               setSize(400,400);

              

               //대화상자를 만들어서 출력

               //대화상자가 모달로 출력이 되면 출력이후 문장은 대기 상태

               Dialog dialog = new Dialog(this,"대화상자");

               //Dialog dialog = new Dialog(this,"대화상자",true);//대화상자 밖에 안만들어진다. modal 절대로 다른데로 옮긴다.

               dialog.setLocation(10 ,10);

               dialog.setSize(100,100);//modaless 만들어져 있다.

              

               //setVisible(true);//먼저 윈도우 보여주기

               dialog.setVisible(true);

              

               setVisible(true);

       }

 

 

       public MyFrame() {

               setTitle("프레임 상속");

               setLocation(20,20);

               setSize(400,400);

              

               //대화상자를 만들어서 출력

               //대화상자가 모달로 출력이 되면 출력이후 문장은 대기 상태

               //Dialog dialog = new Dialog(this,"대화상자");

               Dialog dialog = new Dialog(this,"대화상자",true);//대화상자 밖에 안만들어진다. modal 절대로 다른데로 옮긴다.

               dialog.setLocation(10 ,10);

               dialog.setSize(100,100);//modaless 만들어져 있다.

              

               //setVisible(true);//먼저 윈도우 보여주기

               dialog.setVisible(true);

              

               setVisible(true);

       }

       public MyFrame() {

               setTitle("프레임 상속");

               setLocation(20,20);

               setSize(400,400);

              

               //대화상자를 만들어서 출력

               //대화상자가 모달로 출력이 되면 출력이후 문장은 대기 상태

               //Dialog dialog = new Dialog(this,"대화상자");

               Dialog dialog = new Dialog(this,"대화상자",true);//대화상자 밖에 안만들어진다. modal 절대로 다른데로 옮긴다.

               dialog.setLocation(10 ,10);

               dialog.setSize(100,100);//modaless 만들어져 있다.

              

               setVisible(true);//먼저 윈도우 보여주기

               dialog.setVisible(true);

              

               //setVisible(true);

       }

8.Button

1) 생성자

Button();

Button(String ,title)

 

2)메소드

String getLable();

void setLable(String lable);

setBackground()......

 

9.Checkbox도 버튼으로 본다.

1)생성자

Checkbox();

Checkbox(String ,title)

Checkbox(String ,title , boolean state)

Checkbox(String ,title ,CheckboxGruop group, boolean state)

=>CheckboxGroup 인스턴스를 생서애서 대입하면 라디오 버튼

 

public class ButtonWindow extends Frame {

      

       private Button btn;//이러야 메소드에서 버튼을 여러개 사용 가능핟.

       //성별을 체크하는 라디오 버튼

       private Checkbox man, woman;

      

       public ButtonWindow() {

               setTitle("button window");

               setLocation(100,100);

               setSize(300,300);

              

               Panel  p = new Panel();

              

               btn = new Button("button");

               //버튼을 패널에 추가

               p.add(btn);

              

               man = new Checkbox("man");

               woman = new Checkbox("woman");

               p.add(man);

               p.add(woman);

              

               //패널을 윈도우에 추가

               add(p);

              

               setVisible(true);

       }

}

 

 

 

public class ButtonWindow extends Frame {

      

       private Button btn;//이러야 메소드에서 버튼을 여러개 사용 가능핟.

       //성별을 체크하는 라디오 버튼

       private Checkbox man, woman;

      

       public ButtonWindow() {

               setTitle("button window");

               setLocation(100,100);

               setSize(300,300);

              

               Panel  p = new Panel();

              

               btn = new Button("button");

               //버튼을 패널에 추가

               p.add(btn);

                            

               CheckboxGroup group = new CheckboxGroup();

               man = new Checkbox("man", group,true);

               woman = new Checkbox("woman", group,false);

               p.add(man);

               p.add(woman);

              

               //패널을 윈도우에 추가

               add(p);

              

               setVisible(true);

       }

}

 

 

 

public class ButtonWindow extends Frame {

      

       private Button btn;//이러야 메소드에서 버튼을 여러개 사용 가능핟.

       //성별을 체크하는 라디오 버튼

       private Checkbox man, woman;

      

       public ButtonWindow() {

               setTitle("button window");

               setLocation(100,100);

               setSize(300,300);

              

               Panel  p = new Panel();

              

               btn = new Button("button");

               //버튼을 패널에 추가

               //btn.setLabel("button1");

               p.add(btn);

              

               //man = new Checkbox("man");

               //woman = new Checkbox("woman");

              

               CheckboxGroup group = new CheckboxGroup();

               man = new Checkbox("man",group, true);

               woman = new Checkbox("woman",group, false);

               p.add(man);

               p.add(woman);

              

               //패널을 윈도우에 추가

               add(p);

              

               setVisible(true);

              

               //5초후에 버튼의 레이블 변경

               /*try {

                      Thread.sleep(5000);

                      btn.setLabel("update");

               }catch(Exception e) {}*/

              

               /*for(int i = 0 ; i < 20 ;  i++) {

               try {

                      Thread.sleep(1000);

                      btn.setLabel("button "+ i);

               } catch (InterruptedException e) {}

              

               }*/

              

               //색상 바꾸기

               Color [] colors = {Color.RED , Color.BLUE, Color.GREEN};

               int i =0;

               while(true) {

                      try {

                             Thread.sleep(1000);

                             btn.setBackground(colors[i%colors.length]);

                             i++;

                      } catch (InterruptedException e) {}

                     

               }

       }

}

          

public class FrameMain2 {

       public static void main(String[] args) {

               //new MyFrame();

               new ButtonWindow();

               //한글이 안되면 바꿔야 ms949

       }

}

 

 

10.choice

=> 여러 개의 항목을 출력하고 그 중에 하나를 선택할 수 있도록 해주는 컴포넌트

1)생성자

Choice()

 

2)메소드

void add(String item)

String getItem(int index)

int getSelectedIndex():선택된 인덱스를 리턴

String getSelectedItem():선택된 문자열을 리턴

void remove(int index또는 String item)

 

 

11.Label

=>텍스트 출력 컴포넌트

1) 생성자

Label ()

Label(String text) 문자열 출력

Lable(String text, int alignment):맞춤을 지정해서 출력

alignment는 정수지만 옵션이기 때문에 직접 숫자를 설정하지 않고 클래스의 상수 이용

 

2)메소드

String getText()

void setText(String text)

void setAlignment(int alignment)

 

 

 

12.List

=>여러개의 항목을 출력하고 선택할 수 있도록 해주는 컴포넌트

=>Multiple Mode설정을 이용해서 여러 개 선택이 가능

1)생성자

List()

List(int rows):보여 줄 행의 개수

List(int rows, boolean multipleMode): 행의 개수를 설정하고 다중 선택 모드를 설정

 

2)choice의 메소드에 추가

int [] getSelectedIndexes():여러 개 선택한 경우 선택된 인덱스를 배열로 리턴

String[] getSelectedItems()

 

13.TextField

=>한 줄의 문자열을 입력받는 컴포넌트

1)생성자

TextField()

TextField(int columns):크기(글자 개수) 설정

TextField(String text):초기 문자열

TextField(String text,int columns):초기 문자열

 

2)메소드

void setEchoChar(char ch):화면에 보여질 문자 (동그라미나 별등을 보여준다.)

 

 

14.TextArea()

=>여러 줄 입력받는 컴포넌트

=>TextArea(String text, int rows, int columns, int scrollbars);

 

15.Scrollplane

=>GUI프로그래밍에서는 자신의 부모보다 더 큰 콘텐츠는 화면에 출력할 수 없습니다.

부모보다 큰 경우에는 Scroll이 가능한 컴포넌트에 배치를 해서 스크롤 바를 이용해서 보여주도록 해야 합니다.

=>생성자

ScrollPane(int 스크롤바정책): 항상 보여줄 것인지 아니면 필요할 때만 보여줄 것인지 등

 

16.메뉴

=>MenuBar, Menu,MenuItem(CheckboxMenuItem)

=>MenuBar인스턴스를 만들고 Frameadd

=>Menu를 만들고 Menu MenuBaradd,Menu를 만들 때는 문자열과 함께 생성

=>MenuItem이나 Menu를 만들어서 Menu에 부착

순세대로 add하면 menu에 만들어진다.

               MenuBar menuBar = new MenuBar();

               Menu menu = new Menu("file");

               //메뮤 아이템 생성

               MenuItem item = new MenuItem("open");

              

               menu.add(item);

               //메뉴 바에 메뉴 부착

               menuBar.add(menu);

               //프레임에 메뉴바 부착

               setMenuBar(menuBar);

 

 

 

17.Common Dialog

=>자주 사용하는 기능의 대화상자를 미리 만들어서 제공

=>awt에서는 FileDialog를 제공

많이 사용하는 것은 만들 필요 없다.

 

1)FileDialog의 생성자 - modal

FileDialog(Frame owner, Sring title, int mode): mode는 열기 대화상자인지 저장 대화상자로 만들것인지 결정 -FileDialog.LOAD, FileDialog.SAVE

save저장 load 열기 - 어떤 파일을 선택했는지 알아야 한다. 그래서 getFile()

 

2) FileDialog의 메소드

String getFile();//선택한 파일명 리턴

String getDirectory();//선택한 디렉토리명 리턴

 

String setFile(String file);//파일을 선택

String setDirectory(String directory);//디렉토리를 선택

 

               //파일 대화상자 밖에 안준다.

               FileDialog open = new FileDialog(this,"open",FileDialog.LOAD);

               //기본 디렉토리 설정

               open.setDirectory("c:\\");

               open.setVisible(true);//현재 디렉터리

               //선택한 파일 경로 출력하기

              System.out.println(open.getDirectory()+open.getFile());

               try {

                      BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(open.getDirectory()+open.getFile())));

                      String line = br.readLine();

                      System.out.println(line);

               } catch (Exception e1) {

               }

 

 

18.Layout

=>컨테이너에 컴포넌트를 배치하는 방법

=>Panel은 생성할 때 설정이 가능하고 Frame panel모두 setLayout메소드를 이용해서 변경도 가능

1)FlowLayout

=>Panel의 기본 배치 방법으로 가로 방향으로 컴포넌트를 배치하고 더 이상 공간이 없으면 아래쪽으로 배치

=>new FlowLayout()으로 생생

 

2)BorderLayout

=>Frame의 기본 배치 방법으로 동서남북 그리고 중앙에 하나의 컴포넌트만 배치하는 방법

add를 다른 옵션없이 사용하면 중앙에 1개만 배치됩니다.

=>각 방향에 배치를 할 때는 add(String 방향, Component component)로 배치

=>방향은 대소문자 구분을 함 (East, West, North,South, Center)

=>동서남북에 배치가 안되면 그 영역은 전부 Center의 영역

=>하나의 영역에 하나의 컴포넌트만 배치가 가능한데 컴포넌트를 Panel로 만들어서 배치하면 여러 개도 배치 가능

 

제목 : 제목입력란 (TextField)

내용 : 내용입력란 (TextArea)

 

public MainWindow() {

              

               //여러개의 컴포넌트들을 올려 놓을 있는 패널을 생성

               Panel northPanel = new Panel();

               //레이블과 텍스트 필드를 만들어서 패널에 배치

               //패털은 flowLayout이라서 순선대로 배치

               Label lblTitle = new Label("title");

               TextField txtTitle = new TextField(30);

               //화면에 보여지는 문자 설정

               txtTitle.setEchoChar('*');//작은 따옴표이다

               northPanel.add(lblTitle);

               northPanel.add(txtTitle);

              

               //프레임은 BorderLayout이라서 방향과 함께 배치

               //패널을 블록에 배치

               add("North" ,northPanel);

              

               Panel centerPanel = new Panel();

               Label lblContent = new Label("content");

               TextArea taContent = new TextArea(20,30);

               centerPanel.add(lblContent);

               centerPanel.add(taContent);

               add("Center",centerPanel);

              

               Panel southPanel = new Panel();

               //패널의 레이아웃을 변경

               //셀의 개수가 부족하면 행이나 열의 개수를 늘려서 배치

               southPanel.setLayout(new GridLayout(2,2));

               for(int i = 0; i < 9 ; i ++) {//4->9 할때 알아서 배치한다.

                      Button button = new Button("button"+i);

                      southPanel.add(button);

               }

               add("South" , southPanel);

              

               setTitle("게시물 입력");

               setLocation(100, 100);

               setSize(300, 400);

              

               //크기 변경을 못하게 설정

               setResizable(false);

               setVisible(true);

       }

 

 

3)GridLayout

=>격자()모양의 레이아웃

=>하나의 셀에 하나의 컴포넌트를 배치

=>add를 호출하면 순서래도 배치

=>셀이 부족하면 자동으로 늘어남

=>new GridLaout(int 행의 수 ,int 열의 수)로 만들어서 setLayout메소드에 대입

 

 

4)CardLayout

=>화면에 하나씩 겹쳐서 배치

 

5)null

=>지금까지의 레이아웃은 크기 조절이나 위치 조정을 못합니다.

=>레이아웃에  null을 설정하면 컴포턴트들의 위치나 크기를 조절할 수 있습니다.

=>위치나 크기를 조정 할 때 해상도나 전체 화면 크기를 고려해서 절대값보다는 상대적인 값으로 설정하는 것을 권장합니다.

=>화면에 배치되는 모든 컴포넌트들의 좌표와 크기를 설정해야 합니다.

 

반응형

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

java-14  (0) 2020.10.04
java-13  (0) 2020.10.03
java-11  (0) 2020.10.01
java-10  (0) 2020.09.30
java-9  (0) 2020.09.29
728x90
반응형

**Properties

=>key Value를 쌍으로 저장하는 자료구조

=>Map은 모든 자료형을 사용할 수 있지만 PropertieskeyValue 모두 String만 가능

=>자료형이 결정되어 있어서 앞에 나온 자료구조 들과 다르게 Generics을 이용하지 않습니다.

=>환결설정을 xml이나 텍스트 파일에 작성해두고 그 내용을 읽어서 프로그램에 적용하고자 하는 용도로 많이 사용

=>Spring같은 프레임워크에서는 메시지 출력 등에 이용됩니다.

 

1.주요 메소드

String setProperty(String key, String value) : 프로퍼티 저장

String getProperty(String key) :key에 해당하는 프로퍼티를 가져옵니다.

 

파일에 저장

void store(OuputStream stream, String comment) :comment와 함께 stream(파일이나 네트워크)에 내용을 저장

파일 같은 것을 저장할  수 있ㄷ.

 

void storeToXML(OuputStream stream, String comment) :comment와 함께 stream xml 형식으로 저장

 

2. XML(eXtensible Markup Language):태그 형식으로 표현하는데 해석을 브라우저가 하지 않고 개발자나 설정된 스키마가 해석하는 형식의 문석

이전에 web에서 데이터를 전송하기 위한 표준으로 사용되었고 설정 파일에 많이 이용되었습니다.

HTML(View)은 비구조적이고 느슨한 문법을 적용하지만 XML(Data)은 구조적이고 엄걱한 문법을 제공

XML은 데이터의 역할이고

ajaxxml의 약자이다.

html은 실시간 신문 기자

rss ->

xmljson형태로 데이터가 되여있다.

xml로 하면 여기저기 schema로 한다.

 

@ java에서는 어노테이션

python에서는 decorator

java , python설정이 같으면 나머지 코드는 부착한다.

python 에서는 static을 몰라서 @static으로 하거나 class를 할경우에도 @class 라고 한다.

어떤 설정을 해야 하는데 만들기 힘들어서 xml로 해서 코드가 바꾼다.

설정파일 이 들어가는데 => xml아님 json(decorator)이다.

https://developers.kakao.com/features/platform

 

요청을 할때 json하면 json하고 xml하면 xml이다.

 

실시간 제공은 거의 xml이다. http://data.go.kr/

 

3.현재 작업디텍토리 사용

./ :현재 작업 디렉토리, 생략하고  파일 경로만 적으면 현재 작업디렉토리에서 작업을 합니다.

명령어를 입력할 때는 Mac에서는 ./를 생략하면 명령어가 없다고 나옵니다.

 

 

4.실습 -프로퍼티를 만들고 저장하기 : 현재 프로젝트 디렉토리에 파일 생성 여부 확인

public class PropertiesMain {

 

           public static void main(String[] args) {

                       //프로퍼티를 저장할 수 있는 인스턴스를 생성하고 데이터를 저장

                       Properties props = new Properties();

                      

                       //프로퍼티 저장

                       props.setProperty("name", "배르캄프");

                       props.setProperty("nation", "holland");

                      

                       //프로퍼티나 맵(dictionary, hashtable라고도 합니다.)

                       //프로퍼티나 맵에 없는 key의 값을 주었을 때 동작 방식을 꼭 확인해야 한다.

                       String name = props.getProperty("name");

                       String age = props.getProperty("age");

                      

                       System.out.println(name);

                       System.out.println(age);

                       //자바는 없으면 null로 뜬다.

                      

                       //props를 현재 디렉토리에 temp.xml파일로 내보내기

                       try {

                                  props.storeToXML(new FileOutputStream("temp.xml"), "주석");

                       }catch(Exception e) {

                                  System.out.println("예외 발생:" +e.getMessage());

                       }

           }

 

}

 

 

 

props.storeToXML(new FileOutputStream("./temp.xml"), "주석");

cmd창에서 mac , unix일 경우  ./ 있어야 검색 가능할 수 도있다.

 

 

** Collections 클래스

=>자바의 자료구조들을 동기화 된 자료구조와 변경 불가능한 자료구조로 변환해주는 클래스로 모든 메소드가 static으로 만들어져 있어서 인스턴스를 생성할 필요 없고 모든 메소드가 매개변수를 대입된 데이터를 변경하지 않고 리턴을 합니다.

=>synchronized가 붙으면 동기화 된 자료구조를 만들어주는 메소드

동기화 :읽기를 하는데는 아무런 제한이 없지만 수정이나 삽입 및 삭제등의 작업을 할 때는 다른 스레드가 사용중이면 작업이 종료될 때 까지 기다렸다가 수행

 

//동기화가 적용되지 않은 List

List<String> list = new ArrayList<String>();

 

List<String> syncList = Collections.synchronizedCollection(list);

//syncList는 동기화가 적용된 list

 

=>unmodifiable이 붙으면 변경이 불가능한 자료구조를 생성

final List<String> list = new ArrayList<String>();=>이것도 변경 불가 ???

//final이 붙은 경우는 list를 수정하지 못하는 것이지 list안의 데이터를 수정 못하는 것이 아닙니다.

list = new ArrayList<String>(); //이 구문은 에러 list자체를 변경할려고 해서 에러

list.add("Hello World");//이구문은 에러가 아님 , list내부를 수정하는 것은 가능

final은 전체를 바꾸는 것이 안되는 것이지 부분적인것 바꿀 수 없는 것은 아니다.

 

List<String> imList = Collections.unmodifiableCollection(list);

//imList는 내부 데이터를 수정하지 못합니다.

 

=>checked를 추가하면 1가지 데이터 타입만 사용이 가능

이 부분은 제너릭을 적용하면 동일한 효과를 만들 수 있음

제너릭을 적용하지 않고 만들어진 자료구조라면 이 메소드를 이용해서 제너릭을 적용하는 효과를 만들 수 있습니다.

제너릭은 인스턴스를 만들 때 자료형을 결정하는 것으로 자료구조 클래스에서 주로 이용

List<String> list = new ArrayList<String>();//list에는 String 만 저장 가능

 

List list1 = new ArrayList();//list1에는 모든 자료형의 데이터를 저장할 수 있습니다.

자동으로 ObjecctList가 됩니다.

이런 경우 String만 저장하도록 변경하고자 하는 경우에 checked를 사용

 

List list2 =  Collections.checkedCollection(list1, String.class);

list2String만 저장 가능

기존데이터를 유지하면서 하는 것이다.

 

**java.util.Random ->숫자

=>랜덤한 값을 생성해주기 위한 클래스

=>랜덤한 값을 seed(난수표)에서 데이터를 순서대로 하나씩 가져오는 개념

seed가 고정이 되면 랜덤 값은 일정한 패턴으로 리턴됩니다.

random_state ->seed설정하는 것

 

1.생성자

Random():현재 시간을 기준으로 seed를 설정, 생성될 때 마다 seed가 변경될 가능성이 높음

Random(long seed) :seed를 매개변수로 설정

 

2.메소드

float nextFloat(): 실수형 난수 생성해서 리턴

int nextInt(): 정수형 난수 생성해서 리턴

int nextInt(int n ):          %n한 결과의 난수를 생성

로또 번호라면  45+1

void setSeed(long seed) :seed를 변경

 

3.java.util.UUID클래스->문자도 가능

=>이 클래스의STATIC 메소드인 randomUUID()를 호출하면 랜덤한 문자열을 생성

결과를 toString()으로 확인하면 랜덤한 문자열을 확인할 수 있습니다.

phone

itunes 일련번호 클릭하면 랜덤한 아이디

iphone에서 SEID

SEED가 고정되면 숫자가 순서대로 나온다.

 

random_state = 1; //seed설정하는 것이다. 데이터  뽑을 때 똑 같다.

잘못 되면 overfit같은 경우가 있을 수 있어서 데이터를 바꿔가면서 해야 한다.

random_ =>seed설정이다.

 

randomseed가 있으면 순서대로 준다.

 

 

 

  

 

random끝까지 하다가 오래하면 터지는 것은 seed를 그대로 나둬야 하는데 확률을 reset되서 확률이 낮아진다.

이벤트 random을 할 경우 첫날 좋은 것 나오면

균등하게 하는지 아니면 뒤쪽에서 하는지 확률을 조작한다.

게임 등에서는 완전한 random을 사용하지 않는다.

seed를 설정해서 어느 정도에 터지 게끔 한다.

여러가지 적용해서 해야 한다.

 

고스톱은 점수를 계산해야 하는데

포커는 규칙을 찾으면 된다.

규칙을 먼저 출력하고 룰에서 우선순위 비교해서 한다.

 

4.랜덤 실습 1

public class RandomMain {

 

       public static void main(String[] args) {

               //seed 설정 없이 랜덤 인스턴스 생성 -seed 현재시간을 설정

               Random r1 = new Random();

               //seed 1번으로 설정

               Random r2 = new Random(1);

              

               //실행할 마다 다르게 나옴

               int result1 = r1.nextInt();

               //실행할 마다 동일하게 나옴

               int result2 = r2.nextInt();

              

               System.out.println("result1 : "+result1);

               System.out.println("result2 : "+result2);

              

               //빨강 ,파랑 ,녹색을 랜덤하게 출력

               //랜덤하게 출력되는 것에 제한을 가하기 위한 배열을 생성

               String [] colors = {"빨강","파랑","녹색"};

               //배열에서 배열만의 인덱스가 랜덤하게 나오도록 r1.nextInt(colors.length)

               //배열의 인덱스에 허용

               String color = colors[r1.nextInt(colors.length)];

               System.out.println("color: " +color);

              

               //빨강을 많이 나오게 하는 방법 1:

               String [] colors1 = {"빨강","파랑","녹색","빨강"};

               for(int i = 0 ; i < 10 ; i++) {

                      String color1 = colors1[r1.nextInt(colors1.length)];

                      System.out.println("color1: " +color1);

               }

              

               //방법 2

               String [] colors2 = {"빨강","파랑","녹색"};

               ///4 나머지 : 0 , 1,2,3 % 3 : 0 , 1 ,2,0

               String color2 = colors2[r1.nextInt(4) % 3]; //1 많이 나오게끔 한다.

              

               //복원추출은 같은 나올 있다.

              

               //비복원 추출 - 배열 사용하면 안된다  중간에 데이터를 지울 없다.

               //비복원 추출 - 훈련데이터 테스트데이트 샘플링, 로또 , 고스톰, 포커

               List<String> list = new ArrayList<String>();

               //1-45까지 저장

               for(int i = 1; i <= 45; i++) {

                      list.add(i + "");

               }

               //20개의 숫자를 비복원 추출

               //똑같은 다시 나오면 안되면 추가하고 제거한다. 나온 것을 꺼집어 내고 해야 한다.

               for(int i = 0; i < 20 ; i ++) {

                      //list사이즈 내에서 데이터를 추출

                      String x = list.get(r1.nextInt(list.size()));// 0 -44까지

                      // 데이터를 제거

                      list.remove(x);

                      //정수를 주면 정수번째로 나와서 오류난다. 그래서 string으로 해야한다.

                      System.out.print( x+ "\t");

               }

               System.out.println();

              

               //랜덤한 문자열 만들기 -이미지 파일 등을 업로드 봤을 파일이름 그리고 유저를 구분하기 위한 이름등을 만들 이용

               String name = UUID.randomUUID().toString();

               System.out.println(name);

       }

      

}

 

5. 랜덤 실습 2

public class Chery {

 

       public static void main(String[] args) {

               String [] image = {"!" , "@" ,"#" ,"$","%" ,"^"};

              

               //Raddom 객체 생성

               Random r = new Random();

               List<String> list = new ArrayList<String>();

               for(int i = 0; i < 3 ; i++) {

                      String temp =image[r.nextInt(image.length)];

                      System.out.print(temp + "\t");

                      list.add(temp);

               }

               System.out.println();

              

               if(list.get(0) == list.get(1) && list.get(0) == list.get(1)) {

                      System.out.println("3개가 모두 일치");

               }else if(list.get(0) == list.get(1) ) {

                      System.out.println("앞의 2개가 잋리");

               }else {

                      System.out.println("");

               }

              

       }

 

}

 

 

**날짜 관련 클래스

1.java.util.Date 클래스

=>날짜와 시간을 저장하기 위한 클래스

1)생성자

Date(): 현재 날짜 및 시간을 가지고 생성

Date(long timeMillist) : 1970년부터 11일 자정 이후부터 지나온 시간을 밀리초 단위로 입력해서 생성

Date(int year, int month, int day) : 년월일을 입력해서 생성 ,년도는 1900년 이후에 지나온 시간,월은 0부터 시작하기 때문에 하나 적게 설정, day는 일반적인 형태로 설정

2020s117 :new Date(120, 0 , 17)

 

Date(int year, int month, int day, int hour, int minute, int second) : 년월일 시분초를 입력해서 생성

 

2)주요 메소드

String toString():년월일 시분초를 문자열로 리턴

int get?() :?에 해당하는 값을 정수로 리턴, deprecated

 

3)Java에서 데이터베이스 연동하는 프레임워크들이 데이터베이스의 DateTime과 매핑할 때

java.util.Date, java.util.Date, java.sql.Time등을 지원

최근에는 java.util.Date보다는 java.sql.Timestamp사용을 권장

 

2.java.util.Calendar

=>날짜와 시간을 저장하는 추상 클래스

1)인스턴스 생성

static Calendar getInstance()를 이용하면 현재 날짜 및 시간을 갖는 인스턴스를 생성해서 리턴

Calendar 클래스를 상속받은 클래스 anonymous로 만들어서 인스턴스를 생성

 

2)주요 메소드

long getTimeInMillis(): 197011일 자정이후에 지나온 시간을 밀리초 단위로 리턴

int get(Calendarfiled summary) :field summary에 해당하는 값을 리턴

void set(Calendarfield summary, int value ): field summary에 해당하는 값을 value로 설정

 

3)Calendar를 상속 받은  GregorianCalendar클래스도 있음

 

4)상위 클래스나 인터페이스를 만드는 목적 중의 하나가 동일한 작업을 수행하는 클래스들의 메소드 이름을 확정하기 위해서 만듭니다.

List인터페이스 , Set인터페이스, Map인터페이스,Calendar인터페이스가 대표적입니다.

 

Calender cal = new GregorianCalendar();//이 방식을 권장

GregorianCalendar cal = new GregorianCalendar();

 

3.  Anonymous Class - 익명 클래스

=>클래스나 인터페이스를 상속받아서 인스턴스를 만들 때 상속받는 클래스를 만들지 않고 인스턴스를 바로 생성하는 문법

=>어떤 클래스나 인터페이스를 상속받아서 사용하는 것이 1번 뿐이라면 상속받는 클래스를 만드는 것은 자원의 낭비

클래스나 인터페이스는 한 번 만들어지면 메모리에서 소멸되지 않습니다.

클래스 만들지말고 인스턴스 만들어서 사용하라

=>List의 데이터를 정렬할 때 sort 메소드에 매개변수로  Comparator<E>인터페이스를 대입해야 합니다.

인터페이스이므로 인스턴스 생성을 못하기 때문에 sort멘소드에 대입을 할려면 상속을 받는 클래스를 만들고 인스턴스를 만들어서 대입해야 합니다.

 

Interface Comparator<T>

상속 받은 걸 만들어 줘야 하고

Comparator implements한 클래스를 만든다.

 

앞에 5개 일경우

1 ~ 5

0 ~ 4

 

public class StringComp implements Comparator<String> {

 

       @Override

       public int compare(String o1, String o2) {

               return o1.compareTo(o2);

       }

 

}

 

public class ListSortMain {

       public static void main(String[] args) {

               //문자열 List 생성하고 데이터를 저장

               ArrayList<String> list = new ArrayList<String>();

               list.add("야구");

               list.add("농구");

               list.add("축구");

               list.add("농구");

              

              

               //Comparator인터페이스를 implements 클래스의 인스턴스를 만들어서 정렬

               StringComp comp = new StringComp();

               //데이터 정렬 -Comparator 매개변수로 요구

               list.sort(comp);

              

              

               //Comparator Anonymous Class만들기

               //Comparator c = new Comparator();//오류다  인터페이스 이기 때문이다.

               //클래스 없이 Comparator 인터페이스를 구현한 클래스의 인스턴스를 바로 만들기

               // 문법의 확장인 람다가 자바의 함수형 프로그래밍을 지원

               Comparator<String> c = new Comparator<String>() {

 

                      @Override

                      public int compare(String o1, String o2) {

                             //desc

                             return o2.compareTo(o1);

                      }

                     

               };

              

               list.sort(c);

              

               //데이터 출력

               for(String temp :list) {

                      System.out.print(temp+"\t");

               }

       }

}

4.실습

public class DateMain {

 

       public static void main(String[] args) {

               //java.util.data 년도는 1900 이후 지나온 년도 ,월은 0부터 시작 ,일은 1부터 시작

               //2020 1 17일을 만들고자 하는 경우

               Date date = new Date(2020, 1, 17); //3929 2 17일이 됩니다.

               System.out.println(date);//Tue Feb 17 00:00:00 KST 3920

              

               date = new Date(120, 0 , 17);

               System.out.println(date); //Fri Jan 17 00:00:00 KST 2020

              

               //Calendar클래스의 인스턴스를 생성

               //Calendar 클래스는 추상 클래스 - 추상 클래스는 인스턴스를 생성할 없습니다.

               //이렇게 작성을 하면 calender클래스의 인스턴스를 만드는 것이 아니고

               //calendar클래스를 상속받은 Anonymous Class 생성해서 인스턴슬르 만든 리턴

               //자바에서 인터페이스나 추상클래스를 리턴타입으로 하는 모든 메소드는 원리가 적용됩니다.

               Calendar cal= Calendar.getInstance();

               //toString 너무 많은 양의 데이터를 리턴하도록 만들어져서 보기 어려움

               //System.out.println(cal);

       //java.util.GregorianCalendar[time=1579231502749,areFieldsSet=true,

       //areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Seoul",

       //offset=32400000,dstSavings=0,useDaylight=false,transitions=22,lastRule=null],

       //firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2020,MONTH=0,WEEK_OF_YEAR=3,

       //WEEK_OF_MONTH=3,DAY_OF_MONTH=17,DAY_OF_YEAR=17,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=3,

       //AM_PM=1,HOUR=0,HOUR_OF_DAY=12,MINUTE=25,SECOND=2,MILLISECOND=749,

               //ZONE_OFFSET=32400000,DST_OFFSET=0]

              

               //필요한 데이터만 추출 - 월은 0부터 시작하기 때문에 출력할 때는 +1

               System.out.println(cal.get(Calendar.MONTH)+1);

              

               //1 부터 12 까지의 수를 배열에 저장

               //int [] months = {31, 29 , 31, 30 , 31, 30 ,31, 31, 30, 31, 30, 31};

               //2월의 날수

               //months[1];

              

               //프로그램의 편리성을 위해서 첫번째 위치에 의미없는 값을 삽입해서

               //인덱스와 데이터의 위치를 맞추는 경우가 있습니다.

               //프로그래밍 에서 메모리 절약을 위해서 0부터 하지만

               //개발 할때는 index맞추는 것이 좋다.

               int [] months = {0,31, 29 , 31, 30 , 31, 30 ,31, 31, 30, 31, 30, 31};

               //2월의 날수

               //months[2];//인덱스 맞추게 한다.

              

       }

 

}

 

5.SimpleDateFormat

=>Format으로 끝나는 클래스는 java.text패킺ㅣ에 존재하고 서식에 맞춘 문자열을 만들어주는 클래스

=>DecimalFormat(숫자를 문자열) ,choiceFormat(실수 구간을 문자열로 - 숫자 데이터를 범주형으로 만들기) ,MessageFormat(폼에 데이터를 삽입)등이 있습니다.

{1} 1번 데이터가 삽입된다.

 

범주형은 선택할 있는 것을 제한둔다. 조건문으로 해도된다.

0 ~ 59 f

60 ~ 69 d

점수 구간에 들어가면 범주형 if로도 가능하다.

데이터를 분석하는것

Strin gender ; =>enum

gender

값을 제한 하는 것을 범주혹은 Category라고 한다. 특정한 값만 쓸수 있게끔

분석 ->chart textMining

1 2를 차트 할때 남여로 바꾸는 것으로 해야 한다. 범주형

 

MessageFormat

워드 엑셀 매핑 시키는 것 라벨 기능 데이터를 입력해서 차곡차곡 쌓아 주는 것

 

회귀는 음수가 없다 . 빨간색으로 하던지 괄호 하던지 한다.

엑셀 에 서식

 

**java.util.Scanner클래스

=>입력 스트림으로부터 데이터를 읽어내기 위한 클래스

1.생성자

Scanner(InputStream is): is로 부터 데이터를 읽어내기 위한 Scanner객체를 생성

=>키보드 스트림 : System.in

InputStream -입력받을 수 있는 객체

 

2.주요 메소드

int nextInt():Enter나 공백 앞까지 읽어서 정수로 변환한 후 리턴

               Enter나 공백 앞에 정수로 변환할 수 없는 데이터가 있으면 예외를 발생

 

String next():Enter나 공백 앞까지 읽어서 문자열로 변환한 후 리턴

           공백앞 까지 읽다보니 중간에 공백을 포함한 문자열은 나누어서 읽게 됩니다.

 

String nextLine():Enter까지 읽어서 문자열로 변환한 후 리턴

 

double nextDouble():실수로 변환해서 리턴

 

void close():Scanner 닫기, 이 메소드를 호출하지 않음녀 메모리 정리가 이루어지지 않는다고 (memory leak)경고 발생

 

3.콘솔에서 키보드 입력의 문제점

=>키보드 입력을 하게 되면 입력한 내용 전체를 버퍼에 저장

=>키보드 입력을 읽어가는 메소드들은 버퍼에서 필요한 만큼 가져가서 수행을 합니다.

=>숫자 데이터를 입력받고 바로 이어서 문자열을 입력받는 경우에 문제가 발생할 수 있는데 그 이유가 숫자를 입력하고 Enter를 눌러서 숫자 입력을 종료하게 되는데 숫자 데이터를  가져가는 메소드는 Enter는 버퍼에 남겨두고 가져갑니다.

nextLine메소드는 버퍼에 Enter가 남아있기 때문에 새로운 입력을 받지 않고 Enter를 가지고 가서 자신의 입력을 종료시킵니다.

=>이런 경우에 버퍼을 비울 수 있는 메소드가 있다면 버퍼를 비우고 입력을 받고 버퍼를 비우수 없다면 Enter를 입력받을 수 있는 메소드를 호출해주면 됩니다.

자바에서는 숫자 다음에 문자열을 입력받는 경우 입력받기 전에 Scanner.nextLine()을 호출해서 버퍼의 Enter를 삭제시킵니다.

 

c언어는 버퍼를 비울 수 있기 때문에 버퍼 비우는 함수를 호출한 후 다시 입력받고 파이썬 경우는 문자열을 입력받는 input()만 제공

java에서는 int하고 문자열 시 문제 생긴다.

 

 

**Thread

=>Program:유사한 작업을 위한 file의 집합

=>Process:실행 중인 프로그램

Process는 자신의 작업이 수행 중인 동안 쉬는 시간이 생기더라도 다른 프로세스에게 제어권을 넘기지 않습니다.

일반적인 함수나 메소드를 호출하는 것이 Process입니다.

 

=>Thread :Process의 일부분으로 자원할당과 실행의 단위

독자적으로 실행할 수 없고 Process의 일부분으로만 실행가능

한번 실행하고 종료되면 재시작이 안됩니다.

재시작할려면 Process 새로 만들거나 재시작해야 한다.

자신의 작업이 실행 중인 동안 일정 시간 단위 또는 쉬는 시간이 생기면 다른 스레드에 제어권을 넘길 수 있습니다.

동시에 실행되는 것이 아니고 제어권을 넘겨서 다른 작업도 할 수 있다는 개념입니다.

쉬는 시간동안 다른 것 하니깐 빨라진 것처럼 보인다.

 

=>Task :ProcessThread

 

1.여러개의 Thread를 동시에 실행시켰을 때의 장점

=>일반적으로는 작업의 처리 속도가 빨라집니다.

=>자원을 효율적으로 사용할 수 있습니다.

 

2.여러개의 Thread를 동시에 실행시켰을 때 의 단점

=>여러개의 Thread가 공유자원을 동시에 수정할려고 하는 부분을 제어해야 해서 복잡해 질 수 있음

=>너무 많은 Thread를 생성해서 실행하면 Thread간의 이동하는 시간이 작업시간보다 길어져서 오히려 느려지는 현상이 발생할 수 있습니다.(Thrashing)

 

3 .java.lang.Thread 클래스

=> Thread를 위한 클래스

1) 생성자

Thread(): 스레드의 이름을 jvm이 설정

Thread(String name):스레드 이름을 name 으로 설정해서 생성

Thread(Runnable r): r을 가지고 Thread를 생성

Thread(Runnable r, String name) : r을 가지고 스레드를 생성하고 이름은 name으로 설정

 

2)메소드

=>static void sleep(int msec) throws InterrupedExption

현재 스레드를 msec 만큼 대기시키는 메소드

사용을 할 때 InterruptedExcption을 처리 해 주어야 합니다.

 

=>vid run() ; 스레드로 수행할 내용을 가지는 메소드

실행이 안된다.

 

=>void start(): 스레드를 실행하도록 하는 메소드

 

=> getName(), setName(String name) :스레드 이름 가져오기와 설정

=> getPriority(),SetPriority(int priority) : 스레드의 우선 순위 가져오기와 설정

=>isAlive(): 실행중인 상태인지 확인할 수 있는 메소드 ->boolean

 

4. Runnable인터페이스

=>public void run();스레드로 수행할 내용을 가지는 메소드

 

 

5.스레드를 만들고 실행

1)Thread클래스를 상속하는 방법

=>Thread클래스를 상속받는 클래스를 만들고 스레드로 수행할 내용을 RUN메서드에 작성

=>앞에서 만들어진 클래스의 인스턴스를 만들고 START()를 호출

 

 

2)RUNNABLE 인터페이스를 구현하는 방법

=>Runnable 인터페이스를 implements한 클래스를 만들고 스레드로 수행할 내용을  run메소드에 작성

=>앞에서 만든 클래스의 인스턴스를 생성

=>앞에서 만든 인스턴스를 Thread클래스의 생성자에 대입해서 Thread 클래스의 인스턴스를 만들고 start()호출

runnablerun밖에 없고 thread에 가야 start가 있다.

 

 

3)스레드로 동작해야 하는 필수적인 작업은 네트워크 작업입니다.

안드로이드나 ios는 네트워크 전송에 스레드를 사용하지 않으면 에러

annanmys고려해야 하고 한파일에 클래스를 두개 만들어도 된다.

모든 언어가 보통 2가지 방법이 있다. 클래스로 부터 상속 받아서 하는 방법과 또 한가지 더 있다.

쉬는 동안 다른 thread에 간다.

 

4).스레드 생성 실습

public class ThreadEx extends Thread {

 

       public void run() {

               //1초마다 Hello Thread라는 문자열을 10 출력

               for (int i = 0; i < 10; i++) {

                      System.out.println("Hello Thread");

                      //한개 스레드 1 대기

                      try {

                             Thread.sleep(1000);

                      } catch (InterruptedException e) {

                             System.out.println(e.getMessage());

                      }

               }

       }

}

 

public class Main1 {

 

       public static void main(String[] args) {

               //ThreadEx 인스턴스 2개를 생성

               ThreadEx th1 = new ThreadEx();

               ThreadEx th2 = new ThreadEx();

              

               //일반적인 메소드 호출 :하나의 메소드 수행이 종료되고 다른 메소드가 수행된다.- 20

               //th1.run();

               //th2.run();

              

              

               //스레드 실행 :하나의 스페드가 쉬는 시간이 생기면 다른 스레드의 작업을 처리

               th1.start();

               th2.start();

               //동시에 진행 되는 것이 아니라 시간이 워낙 짧아서 동시에 진행하는 것처럼 보인다.

              

       }

 

}

 

//하나의 파일이 클래스를 2 만든 다면

//PUBLIC class 1개이어야 하고 파일 이름은 public class이름이어야 한다.

 

//Runnable인터페이스를 implements 클래스

class RunnableImple implements Runnable{

       //스레ㅔ드 수행할 내용을 가지고 있는 메소드

       @Override

       public void run() {

               // TODO Auto-generated method stub

              

       }

      

}

 

public class Main2 {

       public static void main(String[] args) {

               RunnableImple r1= new RunnableImple();

              

               //r1 R2 같은 기능

               Runnable r2 = new Runnable() {

 

                      @Override

                      public void run() {

                             // Hello Runnable 1초마다 5 출력

                             try {

                                    for (int i = 0; i < 5; i++) {

                                           Thread.sleep(1000);

                                           System.out.println("Hello Runnable");

                                    }

                             }catch(Exception e) {

                                    System.out.println("스레드 예외:"+ e.getMessage());

                             }

                      }

                     

               };

              

               //Thread 클래스의 인스턴스 생성

               Thread th = new Thread(r2);

               //r2 run 메소드를 스레드로 수행

               th.start();

              

               Thread th1 = new Thread() {

                      public void run() {

                             // Hello Thread 1초마다 5 출력

                             try {

                                    for (int i = 0; i < 5; i++) {

                                           Thread.sleep(1000);

                                           System.out.println("Hello Thread");

                                    }

                             }catch(Exception e) {

                                    System.out.println("스레드 예외:"+ e.getMessage());

                             }

                      }

               };

               //스래드로부터 상속을 받은 경우에는 바로 start()호출

               th1.start();

       }

}

 

6.스레드 상태 및 수명주기

1)new : 스레드가 만들어지고 실행 대기 중기 상태 - Start를 호출하고 실행 대기

2)runnable :실행 중인 상태

3)waiting: 강제로 대기 중인 상태인데 이 떄는 다른 스레드가 notity()notifyAll()을 호출해주면 다시 실행

어떤 신호가 오기를 기다리는 상태

4).timed_waiting:자신의 실행 시간이 오기르 기다리고 있는 상태 ,일정 시간 단위로 작업을 수행하는 time sharing system에서 자신의 차례를 기다리고 있는 상태

5)block: 입출력 요청이 있는 경우 요청을 처리하기 위해서 cpu를 사용할 필요가 없기 때문에 block상태로 작업을 수행하다가 입출력 요청이 끝나면 cpu에 알려서 작업을 계속 수행할 수 있는 상태

6)terminate:thread가 종료된 상태

run메소드의 수행이 종료되었거나 다른 스레드에 의해서 강제로 종료된 경우

 

=>스레드는 한 번 종료되면 다시 실행 시킬 수 없습니다. terminate상태로 가면 끝이다.

 

 

7.Daemon Thread

=>Daemon Thread가 아닌 스레드가 하나도 없으면 자동으로 실행을 중지하는 스레드

=>일반 스레드의 보조적인 역할을 수행하는 스레드

=>일반 스레드는 자신의 run메소드가 종료되거나 다른 스레드에서 강제로 종료시키지 않으면 자신의 작업을 계속 수행합니다.

다른 스레드에서 예외가 발생해도 자신의 작업은 계속 수행합니다.

=>대표적인 데몬 스레드가 main메소드 , 일반 응용 프로그램에서 임시 저장 기능이나 네트워크 프로그램에서 중간 중간 commit하는 작업 등이 있습니다.

main 다른 작업이 아무것도 없으면 알아서 종료된다.

 

=>데몬 스레드를 만드는 방법은 start()를 호출하기 전에 setDaemon(true)를 호출하면 됩니다.

=>데몬을 설정했을 때와 그렇지 않을 때의 수행 내용을 비교해보아야 합니다.

public class Main3 {

       public static void main(String[] args) {

              

               Thread th = new Thread() {

                      public void run() {

                             try {

                                    for(int i = 0; i < 10 ; i++) {

                                           Thread.sleep(1000); //10

                                           System.out.println("데몬 스레드");

                                    }

                             }catch(Exception e) {

                                    System.out.println(e.getMessage());

                             }

                      }

               };

              

               //일반 스레드는 중지하거나 interrupt emd 생기지 않으면 절대 종료하지 않는다.

               //windows죽어도 프로세스 상에는 살아 있는 것이 있다.

               //무한 반복문은 영원히 죽는다.

               //자기 작업이 끝날 까지 죽는다.

               //다른 스레드가 없으면 종료되도록 만들 힜다.

               //th 데몬으로 설정 -다른 작업이 없으면 자동으로 종료

               //프로그램에서는 데몬 스레드가 많이 사용됩니다.

               //sart하기 전에 데몬으로 설정

               th.setDaemon(true);

               th.start();

               //th.setDaemon(true);

              

               //3초동안 실행해다가 죽는다.

               try {

                      Thread.sleep(3000);

               }catch(Exception e) {

                      System.out.println(e.getMessage());

               }

               System.out.println("메인 종료");

       }

}

 

 

8.스레드의 우선순위

Field Summary

=>2개 이상의 스레드가 동작 중인 경우 어떤 스레드가 먼저 수행될 지 또는 자주 수행될지는 알 수 없습니다.

=>이런 특정 스레드를 먼저 또는 자주 수행하도록 할 수 있는 기능이 우선순위 부여입니다.

우선순위를 설정하더라도 반드시 우선순위에 따라 동작하지 않습니다.

확률적으로 우선순위가 높으면 먼저 또는 자주 수행되는 것입니다.

=>우선 순위를 가져오는 메소드가 int getPrority()이고 우선순위를 설정하는 메소드가 void setPrority(int priority)

=>setPrority의 매개변수는 정수를 대입받도록 되어있지만 실제로는 Thread 클래스의 Field SummaryMAX_PRORITY, NORM_PRIORITY ,MIN_PRIORITY를 설정하도록 합니다.

=>위처럼 설정하라고 하는 이유는 2가지 인데 첫번째는 우선순위는 일정한 범위가 있습니다.

아무 정수나 대입하면 안됩니다.

두번째 이유는 스레드의 우선순위 범위는 운영체제마다 다릅니다.

윈도우는 1-10까지 이고 unix에서는 1- 7까지 입니다.

10이라는 숫자를 대입하면 윈도우에서는 있는 범위내의 숫자이기 때문에 아무런 문제가 되지 않지만 unix에서는 없는 숫자가 됩니다.

Thread.MAX_PRORITY로 설정하면 JVM이 알아서 WINDOWS에서 10 UNIX에서는 7로 설정을 합니다.

자바가 모든 운영체제에서 동작하는 애플리케이션을 한 번만 제작해도 되는 이유는 JAVA의 옵션들을 사용한다면 값은 JVM이 운영체제 별로 알아서 할당을 합니다.

JDK(개발도구) 자체는 운영체제 별로 분류가 되어 있지 않지만 실행을 해주는 JVM이 운영체제 별로 별도로 존재해서 JVM이 알아서 옵션 값들을 설정합니다.

=>fIELD Summary는 메소드들에서 사용하기 위한 옵션 값들입니다.

 

 

만개 정도 scrapping할 경우 thread를 이용하면 빨리 할 수 있다.

mmo rpgthread

게임에스 client쪽은 스레드

서버는 프레임을 사용하기 때문에 보통은 대신해준다.

웹프로그램밍에서  was가 알아서 thread만들어준다.

 

 

//class 만드는 경우는 대부분 인스턴스를 2 이상 만드는 경우

class Threadext extends Thread{

       public void run() {

               //스레드 자신의 이름을 10 출력(1초만다 쉬면서)

               for (int i = 0; i < 10; i++) {

                      try {

                             Thread.sleep(1000);

                             System.out.println(getName());

                      } catch (InterruptedException e) {

                             // TODO Auto-generated catch block

                             e.printStackTrace();

                      }

               }

       }

}

 

public class Main4 {

 

       public static void main(String[] args) {

               //정수이다.

               //System.out.println(Thread.MAX_PRIORITY);//10

               Threadext th1= new Threadext();

               Threadext th2= new Threadext();

               Threadext th3= new Threadext();

              

               //순서를 확인할 없다.

               //그래서 스레드 운선 순위 설정

               //확율적으로 th3 먼저 시작할 가능성이 높아집니다.

               //여러번 수행해야 한다 근데 꼭이라고 없다.

               th1.setPriority(Thread.MIN_PRIORITY);

               th2.setPriority(Thread.NORM_PRIORITY);

               th3.setPriority(Thread.MAX_PRIORITY);

              

               th1.start();

               th2.start();

               th3.start();

       }

 

}

 

 

9.thread 강제 종료

=>thread를 강제로 종료할 때는 스레드 인스턴스가 interrupt()라는 메소드를 호출해주면 되는데 스레드클래스의 run메소드에 interruptException이 발생했을 때 run메소드를 종료하도록 코드를 만들어주어야 합니다.

thread를 강제로 종료하고 싶을때

전투를 걸어놓고 중지 못하게 할 경우 특정한 thread는 작업이 끝날 떄 까지 종료안되게 할 때가 있다.

 

=>Threadext클래스에서 catch구문에서 return 을 생략하고 실행해보고 rerurn을 넣고 실행

두번째 스레드의 이름인 thread-1이 계속 출력되기도 하고 3초 후에 출력이 안되기도 합니다.

return 이 있고 없고에 따라서 스레드가 강제로 종료되기도 하고 그렇지 않기도 합니다.

//class 만드는 경우는 대부분 인스턴스를 2 이상 만드는 경우

class Threadext extends Thread{

       public void run() {

               //스레드 자신의 이름을 10 출력(1초만다 쉬면서)

               for (int i = 0; i < 10; i++) {

                      try {

                             Thread.sleep(1000);

                             System.out.println(getName());

                      }

                      //InterruptedException 발생했을 return 하도록 만들어주면 스레드가 강제로

                      //종료 있습니다.

                      catch (InterruptedException e) {

                             // TODO Auto-generated catch block

                             //e.printStackTrace();

                             //중지하게 하려면 interrupt신호를 보낸다.

                             //스마트 전화올 경우

                             return; //interrup할때 1번은 안나온다.

                      }

               }

       }

}

 

public class Main4 {

 

       public static void main(String[] args) {

               //정수이다.

               //System.out.println(Thread.MAX_PRIORITY);//10

               Threadext th1= new Threadext();

               Threadext th2= new Threadext();

               Threadext th3= new Threadext();

              

               //순서를 확인할 없다.

               //그래서 스레드 운선 순위 설정

               //확율적으로 th3 먼저 시작할 가능성이 높아집니다.

               //여러번 수행해야 한다 근데 꼭이라고 없다.

               th1.setPriority(Thread.MIN_PRIORITY);

               th2.setPriority(Thread.NORM_PRIORITY);

               th3.setPriority(Thread.MAX_PRIORITY);

              

               th1.start();

               th2.start();

               th3.start();

              

                //스래드 종료

               try {

                      Thread.sleep(3000);

                      //th2스레드에게 interrupt 발생시킨것이다 하지만 중지가 안된다.

                      th2.interrupt();

               }catch(Exception e) {

                     

               }

       }

 

}

 

10.Thread 실행 제어

void join(int millis, int nanos) :입력한 시간동안만 스레드를 수행

윈도우즈와 같은 클라이언트 운영체제에서는 1/20 이항의 설정은 의미가 없습니다.

원도우즈는 nanos 아무런 의미가 없다. 무의미하다.

클라이언트에서는 1초에 50 정도가 maximum이다.

 

void suspend() :작업을 일시 정지 (wait)

void resume():  일시 정지된 스레드가 작업을 계속

 

void yield():실행 상태를 양보하고 대기 상태로 전환

 

 

 

*종료안되게 할 경우 :

keyboard Interrupt

 

11.ThreadGroup

=>Thread를 묶어서 관리하기 위한 클래스

=> 몇 몇 메소드가 특정 운영체제에서 제대로 동작하지 않아서 비추천

=>List등을 이용해서 그룹화하기를 권장

 

 

Multi Thread 고려사항

=>2개 이상의 스레드가 실행중인 경우를 multi thread

1.long 의 문제

=>32bit 시스템에서 64bit 자료형인 long을 사용하면 부분수정 문제가 발생할 수 있음

 

 

 

실행 하고 정보를 제어블록에 저장한다.

스레드를 바꿀때 현재 상태 저장하고 th2제어블록 읽는다.

스레드 바꿀때 th2제어블록에 저장한다음 th1의 제어블록 을 읽고 실행한다.

 

정보를 저장하고 읽는 것을 context switching

=>스레드의 개수가 너무 많거나 짧은 시간 단위로 작업하면 일하는 시간보다 읽는 시간이 길어지면 over head(conext switch -문맥 교환) 가 많이 발생해서 효율이 떨어진다.

 

정말 특별한 경우가 아니면 공유변수 global variable 만들지 말라 ?

static변수를 만드는 것을 좀 금지 하면 좋다.signle ton

싱글톤 패턴

애플리케이션이 시작될 때 어떤 클래스가 최초 한번만 메모리를 할당하고(Static) 그 메모리에 인스턴스를 만들어 사용하는 디자인패턴.

Critical Section(임계 영역) : 공유자원을 사용하는 코드 영역

3.공유자원 문제

1) 수정중인 공유자원을 다른 스레드가 수정하는 경우

i라는 데이터가 있다.0에서 출발할 것이다.

 

 

thread동시에 돌릴 경우 이상한 값이 나올 수 있다.

이론적으로 는 1부터 200까지 나와야 하는데

total 200가지 합계가 나와야 한다.

약간의 dealy를 발생하면

i = 0  sum = 0 A

더하기 전에 다른 스레드가 사용해버리면 이상한 결과가 나올 수 있다.

 

 

은행에서 잔액이 10000 , 10000을 찾으려고 할 경우 atml기계에서 5000원 찾을 경우 10000을 찾을 수 없다. 다른데서 수정해 버렸기 때문에

읽는데는 문제가 안된다. 수정시 문제가 생긴다.

=>하나의 수정이 종료되고 다른곳에서 사용해야 한다.  동기화(Synchronized)

a가 끝날 때 까지 B가 기다려야 한다.

=>mutual Exclusion(상호 배제 ) ->lock으로 해결

2). 생산자와 소비자 문제

=>작업순서의 문제

공장자동화 로봇으로 만들 경우

진열대를 공유한다.

A   가 진열대에 물건 올리면  B가 처리한다.

진열대 공유

동시에 해도 된다.

 

 

 

 

a가 물건을 생산해주면 b가 처리한다.

A가 물건을 쌓기만하고 B가 처리안할 떄 > 적체

A가 안했는데 B가 하려고 할때 ->문제가 생긴다.

 

=>생산자가 생산하면 소비자는 작업을 수행해야 한다.

구현 방법 : 끝났는지 안 끝났는지 계속 쳐다본다. 이 방법은 별로 안좋아서 signal줬으면

wait(소비자) notify(생산자)

 

카톡 등은 udp이다. 안받을 수 있다.

정확하게 메시지 보내야한다.

 

signal두개 있다. notify(하나만) ,notifyAll (전체 일어나는 것)

 

3) dead lock

=>결코 발생할 수 없는 사건을 무한정 기다리는 것

A

B

 

x1(A소유)

x2(B소유)

A,B

A,B

 

x1 B가 필요하는데 x2가 안줄려고한다.

x2A가 필요하는데 x1가 안줄려고한다.

synchronized를 잘못 줘서 문제가 생긴다.

양쪽 다 synchronize를 주는 것은 문제가 생긴다.

 

1차선인데 양쪽 오는 경우 서로 양보 안하는 것

 

4.Semaphore ->CLASS이름

=>공유자원 여러개

화장실이 3개가 있을 경우  동시에 3명 가능하다.

A가 들어갔다.

B가 들어갔다.

C가 들어갔다.

D가 왔는데 3개 노크해봐야 한다. 다 찼을 경우

 

 

 

 

DA뒤에 서고 Eb뒤에 섰을 경우 B가 먼저 나오면 문제가 생긴다.

 

그래서 밖에 현광판을 새운다.

3 -> 2 -> 1 ->0

0일 경우 빈자리가 없어서 기다린다.

공유자원이 여러개 일때 관리가 편하게 할 때

 

VISUAL c는 이름이 같게 되여있다.

 

 

 

 

 

Properties

반응형

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

java-13  (0) 2020.10.03
java-12  (0) 2020.10.02
java-10  (0) 2020.09.30
java-9  (0) 2020.09.29
java-8  (0) 2020.09.28
728x90
반응형

**인터페이스 사용

1.    인터페이스

=>final 상수와 추상 메소드 만을 가진 개체

=>최근에는 default method(구현된 메소드)를 소유 가능

=>다른 클래스에 implements 해서 사용, 다른 Property클래스인터페이스에 entends 가능

 

2.    사용 목적

=>다형성 구현을 위해서

=>템플릿 메소드 패턴을 구현하기 위해서

인터페이스에 메소드의 모형을 만들고 클래스에서 구현하는 방식

클래스가 인터페이스를 implements했다면 클래스에는 인터페이스의 메소드가 구현되어 있다는 보장을 할 수 있습니다.

추상메소드는 상속받은 곳에서 반드시 재정의 해야 합니다.

overring안하면 안된다.

최소한 메소드는 만들어져 있다 고 보장할 수 있다.

인터페이스를 다른 말로 부를 때 protocol(규칙,규약,약속)이라고도 합니다.

collection 인터페이스

 

**자료구조(Data Structure)

=>0개 이상의 데이터를 저장하는 방법

=>예전에는 각 자료구조의 특징을 숙지하고 직저 구현을 해서 사용했는데 최근에는 프로그래밍언어에서 자료 구조를 미리 구현해놓고 이 자료구조를 가져다 사용하는 경우가 많습니다.

제공되는 자료구조는 프로그래밍언어마다 다르고 부르는 이름도 다릅니다.

r은 다르다.

자료구조 특징만 알면 된다.

python에서는 list특징만 주고 사용법만 아시면 된다.

=>알고리즘을 잘 설계하더라도 자료구조를 선택하면 속도 향상은 한계가 있습니다.

자료구조 알고리즘 자료구조를 먼저 선택하고 알고리즘을 한다.

=>자바의 경우는 자료구조 관련 클래스들이 java.util패키지에서 제공합니다.

java.lang ->java.util

 

**java.util의 자료구조 관련 인테페이스와 클래스

1.Arrays 클래스

=>배열 관련된 작업을 위한 클래스

=>배열의 특징(Array)

배열은 한 번 생성되면 크기 변경이 안됩니다.

배열은 데이터를 연속적으로 빈 공간 없이 배치해야 합니다.

배열은 공간낭비가 없습니다.

 

연속적으로 배치할 수 있는 빈 공간이 없으면 생성이 불가능

데이터를 삽입하거나 삭제하고자 할 때는 복사해서 작업을 수행해야 합니다.

크기 변경이 안되기 때문에 삽입할려면 새로운 공간을 할당받아서 삽입해야 하고 연속적으로 배치되어야ㅑ 하기 때문에 삭제를 할려면 삭제된 이후의 데이터를 앞으로 당겨야 하는 문제가 발생하기 때문입니다.

c언어는 배열을 stack에서 한다.

stack은 기본적으로  1mb크기다.

int ar[1000000] =>stackOverflow

그래서 c언어는 point만들고 참조형으로 한다.

java는 참조형으로 되여있다.heap에 저장한다.

머신런닝은 c 해야 할 가능성이 있다. python의 모든 라이버러리가 cjava 등으로 되여있다. 많은 양의 데이터 가지고 할때 내부적으로는 c로 하고 가져고 온다. 대부분의 알고리즘은 c로 한다.c가 빠르기 때문이다.

 

삽입은 크기를 추가한다는 옮겨야 하기 때문에 복사하고 해야 한다.

삭제를 할 경우 연속적으로 빈 공간 없이 배치해야 하는 것은 삭제하면 빈공간이 생겨서 앞으로 땡겨야 한다. 그래서 앞으로 땡기는데 시간이 걸린다.

삽입 삭제를 거의 안하면 arrays로 만드는 것이다.

수정은 개수의 변화가 아니라 값이 변하는 것이다.

ar[0] = 10;

ar[0] = 20;//으로 변경

 

2.collection 인터페이스

=>데이터의 모임과 인터페이스

=>ListSet인터페이스에게 상속

=>Collection들에 공통으로 구현해야 할 메소드를 선언

stack    -> push

-> pop

ArrayList : add

list 개열은 add로 하면 좋지 않는가 ?

각기 다를 경우 그래서 인터페이스를 만들고 : add라고 하고 implements stack, ArrayList로 해주면 된다.

이름을 통일하게 하기 위해서 정해줄려고 collection인터페이스를 만들었다.

다시 collection을 분할 시켰다. list, set

 

BeanContext, BeanContextServices, BlockingDeque<E>, BlockingQueue<E>, Deque<E>, List<E>, NavigableSet<E>, Queue<E>, Set<E>, SortedSet<E>, TransferQueue<E>

 

public interface Collection<E>

extends Iterable<E>

Iterable=> for써서 하나씩 접근 하는 것이다.

python __iterable__

 

3.List 인터페이스

=>데이터를 물리적 또는 논리적인 순서대로 연속해서 저장하는 자료구조 인터페이스

=>ArrayList, LinkedList, Stack, Queue, Deque등에서 구현하거나 상속

python은 기본적으로 LinkedList  이고 문제 생겨서 후에 queue.를 추가하였다.

 

4.Set 인터페이스

=>데이터를 중복없이 해싱을 이용해서 저장하는 자료구조 인터페이스

=>HashSet, LinkedHashSet , TreeSet 클래스에서 구현

 

5.Map 인터페이스

=>keyValue를 쌍으로 저장하는 자료구조 인터페이스

=>Table 또는 Dictionary라고도 합니다.

=>HashMap, LinkedHashMap, TreeMap 클래스에서 구현

python에서 ordered dict= >treeMap

 

6.Property클래스

=>KEYValue를 쌍으로 저장하는데 자료형이 String만 가능한 클래스

=>설정이나 메시지 저장에 많이 사용되는 클래스

 

 

7.Iterator & Enumeration

=>데이터를 순서대로 하나씩 접근할 수 있도록 해주는 포인터 : Cursor라고도 합니다.

=>자바에서는 Enumeration이 먼저 나왔고 후에 비슷한 기능을 개량한 Iterator가 추가 되었습니다.

=>우리말로 번역할 때는 반복자(c++ enumeration) 또는 열거자(python iterator) 로 변역

=>인터페이스가 구현된 컬렉션의 데이터는 for(임시변수 : 컬렉션){}구문을 이용해서 컬렉션의 모든 데이터를 임시변수에 하나씩 대입해서 {}안에서 사용할 수 있습니다.

=>Iterator의 메소드 :hasNext()(다음데이터 있느냐?) next()(다음 데이터 이동해라)

=>Enumeration의 메소드:hasMoreElements() nextElement()

 

**List

=>데이터를 순서대로 저장하는 자료구조

=>자료구조에서는 배열을 Dense List라고 하기도 합니다.

1.ArrayList(VecorArrayList Legacy버전)

=>데이터를 물리적으로 연속해서 저장하는 List

=>크기 변경이 가능(확장과 축소가 가능)

=>제너릭이 구현(인스턴스를 만들 때 데이터 1개의 자료형을 확정을 해야 합니다.)

=>인스턴스를 만들 때 자료형을 확정하지 않으면 경고가 발생하고 데이터를 가져올 때 Object타입으로 리턴되서 사용을 하고자 하면 강제 형 변환을 해야 합니다.

=> LinkedList 에 비해서 메모리 낭비가 적고 접근 속도가 빠릅니다.

=> LinkedList에 비해서 데이터를 중간에 삽입하거나 삭제하는 경우 속도가 느립니다.

LinkedList는 논리적으로 연속해서 데이터를 저장

=>주요 메소드로느 boolean add(E e), E get(int index), int size(),E remove(int index)(지울때 데이터를 return한다.), void sort(Comparator <E>) (데이터가 많을 때 ) 등이 있습니다.

 

2. LinkedList

=>데이터를 논리적으로 (다음 데이터의 참조를 기억) 연속해서 저장하는 List

=>사용하는 모든 메소드가 ArrayList와 같은데 동작 방식이 다름

 

 

배열  10 , 30 ,20 하나하나 뛰여 쓰는 구조이다. 출발점 밖에 없다.

하나 뛰면 1 두개 뛰면 2

 

 

 

 

ArrayList 아래에 비여있다. 출발점 밖에 없다.

 

40추가시 복사 안하고 아래에 추가한다.

 

 

 

 

 

DoubleLinked List python 음수 양수 가능한 것은 headtail이 있기 때문이다.

0번이 없다. 한칸 가면 10

get할 때 음수를 사용할 수 있는 것

 

 

 

메모리가 심함 : 낭비가 적을 수도 있다.( 연속적인 공간, 확장이 가능하다.)

삽인과 삭제가 용이하다.

point로 한다.

 

메모리 충돌

재시작해서 하면 메모리 문제가 있ㄷ.

빈공간이 40m이지만 30m데이터를 열 경우

배열 과 arryaList. 는 저장이 불가하다. 연속적으로 해야 하기 때문에

그래서 DOuble Linked List 가능하다. 연결이 가능하다

공간1에서 20m할당하고 공간 2에서 10m할당한다.

 

 

ORACLE 9 I ->INTERNET

ORABLE 10 G -> 초과하면 메모리 따로 할당해서 가능하다.

 

 

 

30을 지울 경우

ArrayList 30을 지울 경우 땡겨줘야 한다. 아니면 접근이 불가하다.

마지막 지우는 것은 괜찮은데 중간에것 은 문제가 생긴다.

                                   

 

 

 

 

 

 

 

 

DoubleLinked List 30을 살제 할 경우 포인터를 바꾼다.

데이터 하나하나 접근해서 가져올때 늦다.

일부분만 하면 된다.

 

연결해서 필요한 결과만 가져오면 된다.

 

지금은 디스크가 크기 때문에 arrayList를 많이 사용한다.

데이터를 그냥 쌓고 썼다 삭제 할 필요 없다.

게시판 등 읽기만 가능할 때 ArrayList 를 많이 사용한다.

웹프로그래밍은 대부분 ArrayList 사용한다. 읽기라도 빨리 읽자

Double Linked List 서버 등 추가 삭제 많이 할때

 

python은 기본을 list로 주고 queue를 준다. queue 순서대로 끄낸다. Linked List읽기 속도가 늦다.

읽기 - ArrayList

삽입 삭제 - Linked List

 

ArrayList는 데이터가 많을 수록 늦게 걸린다. 오래 걸린다.

ArrayLIST는 밀어내기 해서 늦게 걸린다.

 

실습은 정수로 했지만 실제 는  row단위로 하면 더 오래 걸릴것이다.

알고리즘을 할 경우 시간 측정하기

정밀도나 재현율 등으로 해서 알고리즘 한다.

 

 

회사 : 마이다스아이티

 

 

3.ArrayListLinkedList 작업 속도 측정

public class ListCompare {

 

       public static void main(String[] args) {

               // 정수 데이터를 저장하는 ArrayList생성

               // 제너릭에서는 기본형은 사용할 없음 - 기본형을 대체하는 Wrapper클래스 사용

               ArrayList<Integer> a1 = new ArrayList<>();// ArrayList<> 1.7부터 가증하다.

               // 데이터 삽입

               a1.add(10);

               a1.add(30);

 

               // 데이터 1 가져오기

               Integer e = a1.get(0);

               System.out.println(e);

 

               // 데이터 1 삭제

               a1.remove(0);

 

               // 데이터 전체 출력

               for (Integer imsi : a1) {

                      System.out.println(imsi);

               }

 

               // 10 30 갖는 ArrayList생성

               a1 = new ArrayList<>();// ArrayList<> 1.7부터 가증하다.

               // 데이터 삽입

               a1.add(10);

               a1.add(30);

 

               // 현재 시간 저장

               long start = System.currentTimeMillis();

               // 20이라는 데이터를 10만번 2번째 칸에 삽입

               for (int i = 0; i < 100000; i++) {

                      a1.add(1, 20);

               }

               // 현재 시간 저장

               long end = System.currentTimeMillis();

               System.out.println("a1:" + (end - start));

 

               // LinkedList 생성

               LinkedList<Integer> li = new LinkedList<>();

               // 데이터 삽입

               li.add(10);

               li.add(30);

 

               // 현재 시간 저장

               start = System.currentTimeMillis();

               // 20이라는 데이터를 10만번 2번째 칸에 삽입

               for (int i = 0; i < 100000; i++) {

                      li.add(1, 20);

               }

               // 현재 시간 저장

               end = System.currentTimeMillis();

               System.out.println("li:" + (end - start));

              

               //데이터 읽기 ================================

               // 현재 시간 저장

               start = System.currentTimeMillis();

               for (int i = 0; i < a1.size(); i++) {

                      //System.out.println(a1.get(i));

                      a1.get(i);

               }

               // 현재 시간 저장

               end = System.currentTimeMillis();

               System.out.println("a1읽기:" + (end - start));

              

              

               // 현재 시간 저장

               start = System.currentTimeMillis();

               for (int i = 0; i < li.size(); i++) {

                      //System.out.println(li.get(i));

                      li.get(i);

               }

               // 현재 시간 저장

               end = System.currentTimeMillis();

               System.out.println("li읽기:" + (end - start));

 

       }

 

}

 

4. Vector

=>ArrayList가 만들어지기 전에 ArrayList와 동일한 용도로 사용하던 자료구조인데 데이터를 수정하거나 삭제 할 떄 다른 스레드가 사용 중인지 확인하고 작업을 수행하던 클래스

=>java에서 Vector클래스는 최근에는 거의 사용을 하지 않기 때문에 중요하지 않을 수 있는데 c++하던 분들이 ArrayList라고 하지 않고 Vector라고 합니다.

vector 데이터의 모임 , scalar등 도 vector이기도 한다.

 

5.Stack

=>LIFO(Last In First Out)

=>마지막에 삽입된 데이터가 가장 먼저 출력되는 자료구조 클래스

=>데이터를 삽입하는 동작을 push라고하고 마지막 데이터를 꺼내는 동작을 pop이라고 합니다.

=>실제 사용된 곳은 메소드를 호출할 때 메소드가 저장하는 자신의 데이터 영역을 stack으로 만들고 스마트폰 등에서 화면 저장도 Stack을 사용합니다.

안드로이드는 startActivity  finish

아이폰은  push pop으로 사용한다.

겹쳐놓고 사용하는 것이 stack이라고 한다.

=> 삽입은 E push(E e), 삭제는 E pop(), 삭제하지 않고 마지막 데이러를 가져오는 E peek()

=> 제너릭이 적용되어 있어서 인스턴스를 만들 때 저장할 요소의 자료형을 설정해야 합니다.

 

네비게이션

최악이는 array

arrayListLinkedList 출발점을 끝까지 가야 한다.

최근에 데이터 사용해야 하는 것은 stack이 좋다.

public class StackTest {

 

       public static void main(String[] args) {

               //문자열 저장하는 스택 생성

               Stack <String> stack = new Stack<>();

               //데이터 저장은  push

               stack.push("안중근");

               stack.push("윤봉길");

               stack.push("김좌진");

              

               //마지막 데이터 제거하면서 가져오기

               String human = stack.pop();

               System.out.println(human);

              

               //마지막 데이터를 제거하지 않고 가져오기

               human = stack.peek();

               System.out.println(human);

               human = stack.peek();

               System.out.println(human);

       }

 

}

=>Stack size 설정한 경우에 Stack 이미 데이터가 전부 저장된 상태에서 데이터를 push하는 경우를 Stack Overflow라고 합니다.

Stack에서 데이터가 없는 상태에서 pop 하는 경우를 Stack Underflow라고 합니다.

 

 

6.Queue

=>FIFO(First In First Out)

=>먼저 삽입된 데이터를 먼저 제거하는 자료구조

=>자바에서는 인터페이스로 제공되고 여러 List클래스에 구현되어 있습니다.

=>PriorityQueue라는 우선순위 큐에도 구현되어 있습니다.

우선순위 큐는 우선순위에 따라 데이터를 정렬하고 있는 큐입니다.

=>데이터를 삽입하는 메소드는 add이고 데이터를 꺼내는 메소드는 peek poll

=>용도는 스케쥴링에 주로 이용

=>입력받은 내용을 순서대로 실행하고자 Queue 이용합니다.

인쇠

데이터를 입력하면 priorityqueue는 순서대로 한다.

데이터 입력할때 이것 사용하면 sort할 필요없다.

정렬 할 필요 없다. PriorityQueue 바꾸지 않고 Set 이용하면 중복도 처리 필요 없다.

 

0

1

가방

2

점퍼

0번과 2번 지운다. 0번과 2번 지우면 에러 난다.

0번 지우면

0

가방

1

점퍼

지울 때 마다 땡겨줘야 한다. 그다음 2로 지워면 오류 난다. 사이즈나 인덱스가 변할 수있다.

그래서 뒤에서 부터 지운다.

 

정렬 -데이터 정렬

정렬 - 트리 형태의 정렬

                                                                     정렬후

 

 

 

데이터 확정되면 quicksort등으로 만들면 되나.

데이터를 추가할 때마다 정렬할 경우 tree를 만든다. 작으면 왼쪽 크면 오른쪽

 

tree 읽는 방법    : InOrder .왼쪽 ->부모 -> 오른쪽

                        FreeOrder -> 부모

                        FirstOder -> 부모 마지막

PriorityQueueInOrder

하나씩 접근할 경우는 예측할 수 없다 . 전체 해야만 정렬이 된다.

 

이진트리 검색 이진트리 정렬

건물의 arrayList로 만들면 삽입과 삭제가 늦어서 버벅거린다.

 

실습

public class QueueTest {

 

       public static void main(String[] args) {

               //운선순위 : 데이터를 크기 순서대로 접근할 있도록 만든

               //내부적으로 데이터가 정렬된 것이 아니고 정렬된 순서대로 접근할 있는 이진 트리를 생성

               //문자열 저장하는 스택 생성

               PriorityQueue <String> pq = new PriorityQueue<>();

               //데이터 저장은  push

               pq.add("서울");

               pq.add("런던");

               pq.add("크라이스 처치");

               pq.add("블라디보스톡");

               pq.add("불산");

              

               //PriorityQueue 크기 순서대로 저장 되였다고 했는데

               //빠른 열거를 이용해서 데이터를 1 꺼내와서 출력

               //sort 되지 않았다.

               //하나씩 꺼내면 트리의 순회를 이용하지 않기 때문에 데이터가 정렬된 순서가 아닐 있음

               for(String city :pq) {

                      System.out.print(city + "\t");

               }

               System.out.print("\n");

              

               //데이터를 poll이용해서 1개씩 가져와서 출력

               //sort 순서데로 나온다.

               //pq.size()쓰면 안된다 . 5 사용해야 한다.

               //poll 제거하면서 가져오기 때문에

               //지우면서 가져올 데이터의 개수나 인덱스가 변할 있으므로 주의

               //트리의 순회를 이용하기 때문에 데이터가 정렬된 순서대로 출력  

               int len = pq.size();

               for (int i = 0; i < len; i++) { //5 고정하거나 데이터 개수를 고정해야 한다.

                      System.out.print(pq.poll() + "\t");

               }

               //     i pq. size()

               //     0 5 pq.poll()삭제씩 한다.

               //     1 4

               //     2 3

               //장바구니 경우 조심해야 한다.

       }

 

}

 

7.Deque

=>양쪽에서 삽입과 삭제가 가능한 자료구조

=>자바에서는 인터페이스 형태로 제공

=>ArrayDeque라는 클래스가 Deque인터페이스를 Implements

=>Deque를 구현한 경우는 ScrollView 계열이 전부 Deque를 이용합니다.

메모리는 위에것을 재사용한다. deque를 재사용하는 것이다. 핸드폰 넘길 때

애플의 api를 한번 확인해보라

애플은 일반 숫자면 shift사용하면 된다.

 

windows안된다.

 0 1 2 3

0 1 2 4 8

 

애플 된다. shift계산

0                   1                     2

0 << 0            1 << 0              1 << 2

 

=>삽입하거나 꺼내는 메소드 이름들에 FirstLast가 붙습니다.

어떤 종류의 데이트를 저장할 지 먼저 생각해야 한다.

ArrayDeque <String> deque = new ArrayDeque <>();

//데이터를 앞에서 저장

deque.addFirst("한국");

//데이터를 뒤에 저장

deque.addLast("미국");

deque.addLast("중국");

deque. addFirst("뉴질랜드");

 

저장 순서는 뉴질랜드 -> 한국->미국 -> 중국

 

String nation = deque.pollFirst();//뉴질랜드

nation = deque.pollLast();//중국

 

 

8. 사용자 정의 클래스의 List 정렬

=>사용자 정의클래스의 LIST가 테이블 구조

몽고 디비의 COLLECTION이라고 보면 된다.

// 선수번호(정수인데 Primary Key) ,선수이름, 타율

//primary key 정수 인것이  좋다. 속도 때문에

public class Player {

       private int num;

       private String name;

       private double hitrate;

      

       //매개변수가 없는 생성자

       public Player() {

               super();

       }

      

       //모든 필드를 매개변수로 받아서 인스턴스 필드에 대입해주는 생성자

       public Player(int num, String name, double hitrate) {

               super();

               this.num = num;

               this.name = name;

               this.hitrate = hitrate;

       }

      

       //인스턴스 필드들을 private 만들어서 인스턴스가 접근을 못합니다.

       //인스턴스가 필드들에 접근할 있도록 해주는 메소드: 접근자 메소드(getters & 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 double getHitrate() {

               return hitrate;

       }

 

       public void setHitrate(double hitrate) {

               this.hitrate = hitrate;

       }

      

       //필드의 값을 빠르게 확인하기 위한 메소드 : 디버깅을 위한 메소드

       @Override

       public String toString() {

               return "Player [num=" + num + ", name=" + name + ", hitrate=" + hitrate + "]";

       }

}

 

 

public class ListMain {

 

       public static void main(String[] args) {

               //매개변수가 없는 생성자를 이용한 인스턴스 생성 필드값 실행

               Player player1 = new Player();

               player1.setNum(1);

               player1.setName("백인천1");

               player1.setHitrate(0.412);

              

               //매개변수가 있는 생성자를 이용한 인스턴스 생성 필드값 설정

               Player player2 = new Player(2,"이종범2",0.393);

               Player player3 = new Player(3,"이종범3",0.381);

               Player player4 = new Player(4,"이종범4",0.387);

               Player player5 = new Player(5,"이종범5",0.376);

              

               //5개의 인스턴스를 소유한 ArrayList 인스턴스 생성

               ArrayList<Player> list = new ArrayList<>();

               list.add(player1);

               list.add(player2);

               list.add(player3);

               list.add(player4);

               list.add(player5);

              

               //Player 클래스의 인스턴스 비교 인스턴스 파율의 오름차순

               //anorymose, new Comparator<Player> 쓰야 한다.

               //이것이 된다면 어떤 종류에서도 가능핟.

               Comparator<Player> comparator = new Comparator<Player>() {

 

                      @Override

                      public int compare(Player arg0, Player arg1) {

                             /*if(arg0.getHitrate() > arg1.getHitrate()) {

                                    return 1;

                             }else if(arg0.getHitrate() == arg1.getHitrate()) {

                                    return 0;

                             }else {

                                    return -1;

                             }*/

                             return arg0.getName().compareTo(arg1.getName()) * -1;

                      }

                     

               };

              

               list.sort(comparator);

               //데이터 출력

               for(Player player: list) {

                      System.out.println(player);

               }

       }

 

}

 

** Set

=>데이터를 해싱을 이용해서 저장위치를 선정하고 중복된 데이터는 저장하지 않는 자료구조

=>데이터의 저장 순서를 모르기 때문에 인덱스의 개념이 없습니다.

=>제너릭이 구현:인스턴스를 만들 요소의 자료형을 결정

1.구현된 클래스

HashSet: 저장 순서를 없는 sET

LinkedHashSet: 저장 순서를 있는 Set으로 전체를 순서래도 접근하면 저장된 순서래도 리턴

TreeSet :Comparator 인터페이스의 compareTo 멤서도를 이용해서 크기 순서대로 리턴하는 sET

 

2.주요 메소드

boolean add(E e): 데이터를 추가하고 성공 여부를 리턴 ,동일한 값의 데이터를 삽입할려고 하면 데이터를 삽입하지 않고 FALSE 리턴

boolean remove(E e): e 해당하는 데이터가 있음녀 삭제하고 결과를 리턴

int size(): 데이터 개수 리턴

데이터 1개를 접근하는 메소드는 없고 FOR(임수 변수 , set) 이용해서 데이터 전체를 접근

데이터 한개를 꺼내는 메소드가 없다.

 

3.Set사용

public class SetUse {//Set 이름 하면 에러가 난다.

 

       public static void main(String[] args) {

               // Set 인스턴스 생성 - HashSet ,LinkedHashSet , TreeSet으로 변경하면서 확인

              

               System.out.println("HashSet");

               Set<Integer> set = new HashSet<Integer>();

               // Set 데이터 추가

               set.add(100);

               set.add(300);

               set.add(200);

               set.add(500);

               set.add(400);

               // 데이터 전부 출력

               for (Integer temp : set) {

                      System.out.println(temp);

               }

              

               System.out.println("LinkedHashSet");

              

               // Set 인스턴스 생서

               Set<Integer> linkedHashSet = new LinkedHashSet<Integer>();

               // Set 데이터 추가

               linkedHashSet.add(100);

               linkedHashSet.add(300);

               linkedHashSet.add(200);

               linkedHashSet.add(500);

               linkedHashSet.add(400);

               // 데이터 전부 출력

               for (Integer temp : linkedHashSet) {

                      System.out.println(temp);

               }

              

               System.out.println("TreeSet");

              

               // Set 인스턴스 생서

               Set<Integer> treeSet = new TreeSet<Integer>();

               // Set 데이터 추가

               treeSet.add(100);

               treeSet.add(300);

               treeSet.add(200);

               treeSet.add(500);

               treeSet.add(400);

               // 데이터 전부 출력

               for (Integer temp : treeSet) {

                      System.out.println(temp);

               }

       }

 

}

 

 

4. 1-45사이의 숫자를 6 입력받아서 오름 차순 정렬해서 출력

=>데이터 6개는 하나의 이름으로 저장

=>동일한 데이터는 입력받지 않아야 합니다.

=>데이터는 오름차순 정렬

=>데이터 6개를 하나의 이름으로 저장할 있는 자료구조 :배열 ,ArrayList, LinkedList, Stack ,ProrityQueue, ArrayQueue, HashSet,LinkedHashSet, TreeSet

 

public class LottoInput {

 

       public static void main(String[] args) {

               //1-45까지의 정수를 저장할 자료구조를 생성

               TreeSet<Integer> lotto = new TreeSet<Integer>();

               //키보드로 부터 입력받기 위한 인스턴스 생성

               Scanner sc = new Scanner(System.in);

               while(lotto.size() < 6) {

                      try {

                             System.out.print("1-45까지의 중복되지 않은 숫자 :");

                             //문자를 입력해서 예외가 발생하면 catch구문이 동작하고 그러면 반복문의 시작 부분으로 돌아가서 수행

                             int su = sc.nextInt();

                            

                             if(su < 1 || su > 45) {

                                    System.out.println("1-45 사이의 숫자만 입력하세요 !!!");

                                    continue;

                             }

                            

                             //입력받은 숫자를 set 추가 : 숫자가 중복되면 false

                             boolean result = lotto.add(su);

                             if(result == false) {

                                    System.out.println("중복된 숫자는 안됩니다.");

                             }

                      }catch(Exception e) {

                             System.out.println("1-45 사이의 숫자만 입력하세요 !!!");

                             sc.nextLine();

                      }

               }

              

               //lotto 데이터 출력

               for(Integer su : lotto) {

                      System.out.print(su + "\t");

               }

               sc.close();

       }

 

}

 

 

 

 

**Map

=>key Value 쌍으로 저장하는 자료구조

=>key 중복될 없지만 Value 중복되거나 null 있습니다.

=>제너릭 미지정 자료형이 2개라서 인스턴스를 생성할 key Value자료형 2개를 설정해야 합니다.

key 특별한 경우가 아니라면 String

=>여러 종류의 데이터를 하나로 묶기 위한 용도로 주로 이용

DTO클래스의 용도와 유사

=>관계형 데이터베이스의 테이블은 DTO클래스의 List이고 No SQL Collection Map List입니다.

=>Map. Key 무한정 추가시킬 있습니다.

DTO클래스는 클래스를 만들 사용한 필드를 제외하고는 확장이 안됩니다.

 

1.Map 구현 클래스

1) HashMap(Hashtable): Key 해싱에 의해서 저장하기 때문에 key 순서를 없습니다.

2) LinkedHashMap : KEY 데이터를 저장한 순서대로 배치

3) TreeMap: key COMPAREtO메소드를 이용해서 비교한 크기 순선대로 배치

 

 

2.인스턴스 생성

HashMap<String ,실제데이터의 자료형> map = new HashMap<String ,실제데이터의 자료형>();

HashMap<String ,실제데이터의 자료형> map = new HashMap<?  ,?>();

 

3.데이터 관련 메소드

void put(key ,value): key 값에 VALUE 저장, 동일한 KEY이름을 입력하면 수정

 

Object get(key) :key 해당하는 리턴, key 없으면 null리턴

       리턴되는 데이터가 Object라서 출력하는 것이 아니고 사용할 거라면 저장할 때의 자료형으로 강제 변환해서 사용

 

Object remove(key) : key 해당하는 데이터 삭제

 

Set<Key 자료형> keySet(); Map 모든 key Set으로 리턴

 

4.Map 기본방법

public class MapUse {

       public static void main(String[] args) {

               // Map 인스턴스 생성

               HashMap<String, Object> map = new HashMap<String, Object>();

               // 데이터 저장

               map.put("baseball", "야구");

               map.put("soccer", "축구");

               map.put("volleyball", "배구");

 

               // 데이터 가져오기

               // Object obj = map.get("soccer");

               /// 출력을 때는 강제 변환이 필요없지만 다른 용도로 사용할 때는 강제 변환을 해서 가져옵니다.

               String obj = (String) map.get("soccer");

               System.out.println(obj.toUpperCase());

 

               // 없는 key 가져오기 -언어마다 다르므로 확인

               Object value = map.get("basketball");

               System.out.println(value);// java- null python 튕긴다.

 

               map.put("soccer", "발로하는 축구");

               obj = (String) map.get("soccer");

               System.out.println(obj.toUpperCase());

 

               // Map 모든 데이터를 출력 -key 이름을 사용하지 않음

              System.out.println("===============================");

               Set<String> keys = map.keySet();

               // Set 순회

               for (String key : keys) {

                      System.out.println(key + " : " + map.get(key));

               }

              

       System.out.println("=============LinkedHashMap==================");

 

               // 순서대로 하고 싶다면 LinkedHashMap으로 바꾸면 된다.

 

               // Map 인스턴스 생성

               LinkedHashMap<String, Object> map1 = new LinkedHashMap<String, Object>();

               // 데이터 저장

               map1.put("baseball", "야구");

               map1.put("soccer", "축구");

               map1.put("volleyball", "배구");

 

               // 데이터 가져오기

               // Object obj = map.get("soccer");

               /// 출력을 때는 강제 변환이 필요없지만 다른 용도로 사용할 때는 강제 변환을 해서 가져옵니다.

               String obj1 = (String) map1.get("soccer");

               System.out.println(obj1.toUpperCase());

 

               // 없는 key 가져오기 -언어마다 다르므로 확인

               Object value1 = map1.get("basketball");

               System.out.println(value1);// java- null python 튕긴다.

 

               map1.put("soccer", "발로하는 축구");

               obj1 = (String) map1.get("soccer");

               System.out.println(obj1.toUpperCase());

 

               // Map 모든 데이터를 출력 -key 이름을 사용하지 않음

              System.out.println("===============================");

               Set<String> keys1 = map1.keySet();

               // Set 순회

               for (String key : keys1) {

                      System.out.println(key + " : " + map1.get(key));

               }

       }

}

 

mac 메뉴 눌리다가 실수 가능성이 없다.

windows 여러가 나온다.

 

5. class Map 이용한 저장의 차이

public class ClassAndMap {

 

       public static void main(String[] args) {

               //번호 ,이름,타율을 저장하는 Player클래스의 인스턴스를 만들어서 데이터를 저장

              Player player = new Player(1, "이종범" , 0.393);

               //Player 코드

              

               //3개를 저장하는 map 인스턴스를 생성해서 데이터를 저장

               HashMap<String,Object> map = new HashMap<String,Object>();

               map.put("num", 2);

               map.put("name", "정호조");

               map.put("hitrate", 0.387);

              

               //서로간의 장단점이 있다.

               //대부분의 IDE에서 일반 인스턴스를 사용할 Code sense 동작

               //하나의 속석을 가져올 때는 클래스가 유용

               //map key 기억해야 합니다.

               String name = player.getName();//오타칠 가능성이 별로 없다.

               name = (String)map.get("name");

              

               //전체를 출력할 떄나 속성을 확장할 떄는 Map 유리

               //Dto클래스의 인스턴스는 속성 확장이 안됩니다.

               //dto클래스의 인스턴스는 속성을 확장할려면 클래스 구조를 변경해야 합니다.

               //테이블 설계하면 아무것도 추가 못한다. ->관계형 데이터베이스

               //map 제한이 없음

               map.put("homerun", 31);//필요하면  얼마든지 확장 있다.

              

               //전체를 출력한다면 map 훨씬 편하다.

               //DTO클래스의 인스턴스는 각각의 데이터를 하나씩 출력해야 한다면 메소드를 일일이 호출 : 반복문 사용 불가

               System.out.println(player.getNum());

               System.out.println(player.getName());

               System.out.println(player.getHitrate());

              

               //mAP 인스턴스는 KEYSET() 이용해서 반복문으로 출력 가능

               Set<String> keys = map.keySet();

               for(String key : keys) {

                      System.out.println(key + " : " + map.get(key));

               }

              

       }

 

}

 

 

6. 이차원 배열과 Map List

List List(Matrix - numpy 머신런닝) Map List(DataFrame - pandas기술통계 )

데이터가 바꿔더라도 연산의 결과등으로 사용 가능하게 해야 한다.

 

자바스크립트

angular react native

 

map 사용하면 mvc 하는데 도움이 된다.

배열에 배열 나올 같으면 고민해야 한다.

머신런닝 이름이 필요없기 때문에 배열의 배열을 사용한다.

2차원 벼열 : 제목이 없는 matrix 계산

74

83

76

32

54

68

64

74

83

 

map List 출력이나 분석

국어

영어

수학

74

83

76

32

54

68

64

74

83

합계를 구할 map list 제목을 빼고 해야 한다. .values()

 

microsoft windows list안에 list

mac map으로 한다음 다시 map list 만든다.

출력은 운영체제가 해버린다.

public class DoubleArray {

       public static void main(String[] args) {

               // 팀별 선수 명단

               ArrayList<String>  kia = new ArrayList<>();

               kia.add("최형우");

               kia.add("김주찬");

               kia.add("김선빈");

              

               ArrayList<String> dusan = new ArrayList<>();

               dusan.add("권혁");

               dusan.add("정수빈");

               dusan.add("최주환");//데이터 추가시 출력하는데 문제가 없다.

              

               //팀이름은 가지고 있지 않다

               //후에 추가한다.

               ArrayList<String> hanhwa = new ArrayList<>();

               hanhwa.add("김태군");

               hanhwa.add("이성열");

              

               //팀별 명단을 다시 List 만들기

               ArrayList<ArrayList<String>> players = new ArrayList<ArrayList<String>>();

               players.add(kia);

               players.add(dusan);

               //팀이 추가되는 경우 이름을 출력하기 위해서 출력하는 로직을 수정

               players.add(hanhwa);

              

               //데이터 출력하기

               //전체 리스트를 하나 하나의 리스트로 imsi 대입

               for(ArrayList<String> imsi: players) {

                      //imsi 데이터를 하나씩 temp 대입

                      for(String temp : imsi) {

                             System.out.print(temp + "\t");

                      }

                      System.out.println();

               }

               //팁이 명확하다.

               System.out.println("=======================");

               for(int i = 0 ; i < players.size(); i++) {

                      //팀이 추가할 경우 문제가 생긴다.

                      if(i == 0) {

                             System.out.println("기아:");

                      }else {

                             System.out.println("두산:");

                      }

                      ArrayList<String> imsi = players.get(i);

                      //imsi 데이터를 하나씩 temp 대입

                      for(String temp : imsi) {

                             System.out.print(temp + "\t");

                      }

                      System.out.println();

               }

              

               System.out.println("=======================");

               //앞에서의 문제는 List List 만들 List 특징을 같이 저장하지 못한다는데 있습니다.

               //팀이름은 문자열이고 팀의 선수 명단은 배열이라서 같이 List 저장을 못합니다.

               // 부분을 Map이나 Class 해결해야 합니다.

              

               //List 팀이륾을 갖는 Map 생성

               Map<String, Object> map1 = new HashMap<String, Object>();

               map1.put("team", "기아");

               map1.put("player", kia);

              

               Map<String, Object> map2 = new HashMap<String, Object>();

               map2.put("team", "두산");

               map2.put("player", dusan);

              

               //후에 추가하기

               Map<String, Object> map3 = new HashMap<String, Object>();

               map3.put("team", "한화");

               map3.put("player", hanhwa);

              

               //MAP lIST 생성

               ArrayList<Map<String, Object>> kbo = new ArrayList<Map<String, Object>>();

               kbo.add(map1);

               kbo.add(map2);

               kbo.add(map3);

              

               for(Map<String,Object> map : kbo) {

                      System.out.print(map.get("team") + ":");

                      ArrayList<String> p = (ArrayList<String>)map.get("player");

                      for(String temp : p) {

                             System.out.print(temp + "\t");

                      }

                      System.out.println();

               }

              

       }

}

 

7.데이터 저장

1)하나의 행은 Map이나 DTO클래스를 이용

=>mAP이나 DTO클래스는 서로 다른 자료형의 데이터를 묶어서 저장이 가능합니다.

=>lIST 배열은 동일한 종류의 데이터를 묶어줍니다.

=>lIST 배열로는 특성이 다른 데이터를 묶을 없습니다.

 

PYTHON에는 ["Hi" ,1 ] : ? =>이렇게 안한다.

list

 

 

 

 

문자와 숫자가 있을 경우 숫자로 바꾼다. 수자인데 문자로 들어오면 오류 나기 때문이다.

 

2)하나의 열을 만들 List 배열을 사용

=> 방향의 데이터는 일반적으로 동일한 자료형으로 구성되기 때문입니다.

 

**MVC(Model -View - Contrlloer)패턴

=>애플리케이션을 구현 역할 별로 분리해서 구현하도록 하는 패턴

=>애플리케이션을 역할 별로 구별해서 분리하지 않으면 어느 하나의 변경이 다른 하나의 변경에 영향을 미치게 됩니다.

유지보수가 어려워집니다

=>Model 변화가 생기더라도 View 변경하지 않아도 되도록 구현하라는 패턴

 

 

***** dto클래스를 만들때와 map일떄를 비교해라

관계형 데이터베이스는 dto클래스의 리스트

nosql MAP 리스트

MAP . 찍으면 안나와서 실수 문제

"NUM" -> "num"

대소문자 실수 많이 한다.

문자열로 경웨에는 주의 해서 봐야 한다.

 

 

 

 

 

반응형

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

java-12  (0) 2020.10.02
java-11  (0) 2020.10.01
java-9  (0) 2020.09.29
java-8  (0) 2020.09.28
java-7  (0) 2020.09.27
728x90
반응형

**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
728x90
반응형

**예외처리

1.예외처리

try{

           예외가 발생할 가능성이 있는 구분

}

catch(예외클래스 변수명){

           예외 클래스에 해당하는 예외가 발생했을 때 처리할 구분

}

catch ...

 

finally{

           예외 발생 여부에 상관없이 수행하는 구무

}

=>try가 나오면 반드시 1개 이상의 cathchfinally가 와야 합니다.

=>catch는 여러 번 나올 수 있는데 위쪽의 catch에 아래쪽 catch보다 상위 클래스 예외를 처리하는 것은 안됩니다.

상위 클래스 타입의 참조형 변수에는 하위 클래스 타입의 인스턴스 참조를 대입할 수 있습니다.

=>try , catch, finally  별도의 블럭이기 때문에 각 블럭에서 만든 변수는 그 블럭에서만 사용가능

 

 

2.최상위 예외

java.lang.Throwable

=> 메소드

String getMessage() : 예외 내용을 문자열로 리턴

void printStackTrace():예외 발생 내역을 역추적해서 출력

 

3.도달할 수 없는 코드에러

       public static void main(String[] args) {

              

               try {

                      int[] ar = {100, 300};

                   System.out.println(ar[2]);//ArrayIndexOutOfBoundsException

               }

               //Exception클래스가 ArrayIndexOutOfBoundsException 상위클래스 예외가 발생하면 Exception 처리

               //아래 catch구분은 도달할 없는 코드가 됩니다.

               catch(Exception e) {

                      System.err.println(e.getMessage());

               }

               catch(ArrayIndexOutOfBoundsException e) {

                      System.out.println("예외가 발생했습니다.");

                      //메세지 내용을 출력한 것이다.

                      System.out.println(e.getMessage());

                      //출력하는 텍스트 색상을 변경하기 위해서 out대신에  err 사용

                      System.err.println(e.getMessage());

               }

       }

 

4, 모든 예외를 하나의 catch에서 처리하고자 할 때는 예외 클래스를 Exception이나 Throwable을 설정하면 됩니다.

Catch는 하나만 만들어서 사용할 수있다.

               try {

                      int[] ar = {100, 300};

                   System.out.println(ar[2]);//ArrayIndexOutOfBoundsException

               }

               catch(ArrayIndexOutOfBoundsException e) {

                      System.out.println("예외가 발생했습니다.");

                      //메세지 내용을 출력한 것이다.

                      System.out.println(e.getMessage());

                      //출력하는 텍스트 색상을 변경하기 위해서 out대신에  err 사용

                      System.err.println(e.getMessage());

               }

               //Exception클래스가 ArrayIndexOutOfBoundsException 상위클래스 예외가 발생하면 Exception 처리

               //아래 catch구분은 도달할 없는 코드가 됩니다.

               catch(Exception e) {

                      System.err.println(e.getMessage());

               }

 

 

5.throws

=>메소드를 만들 매개변수 뒤에 thrwos 기재하고 예외클래스 이름을 작성하면 메소드를 호출한 곳에서 예외를 반드시 처리해야 합니다.

자바는 RuntimeException 외에 예외가 발생할 가능성이 있는 메소드의 경우 예외 처리를 강제하는 경우가 있습니다.

=>main메소드에 Throws예외클래스 이름을 붙이면 예외처리를 하지 않아도 됩니다.

main메소드는 jvm 호출하는 메소드라서 main에서 예외를 다른 곳에서 처리하도록 하면 jvm 예이를 처리하게 됩니다.

권장하지는 않습니다.

 

 

6.예외처리를 반드시 해야 하는 경우

java.lang.Thread클래스의 sleep이라는 메소드는 밀리초 단위를 매개변수로 받아서 매개변수 만큼 스레드를 중지시켜주는 메소드 입니다.

이 메소드를 이용해서 10초동안 1초마다 Hello Exception출력하기

mainjvm이 불러서 jvm이 하는 것이다.

 

예외 처리 목적 : 2가지

예외 내용 기록하기 위해서

예외가  발생해도 계속 처리하는 것이다.

 

이렇게 하면 안 좋다.

 

예외처리 강조

바깥쪽에 있는 것이다.파일헨들링, 네트워크 , Db

파일 헨들링     

네트워크

db

스레드

 

내부  ------------ 외부

       public static void main(String[] args) {

               int i = 0;

               while(i < 10) {

                      System.out.println("Hello Exception");

                      try {

                             //sleep라는 메소드는 InterruptedException 발생할 가능성이 있으므로

                             // 예외에 대한 처리를 해야주어야만 합니다.

                             //java 예외를 강제한다.

                             Thread.sleep(1000);

                      } catch (InterruptedException e) {

                             System.err.println(e.getMessage());

                      }

                      i = i+1;

               }

       }

 

7.예외 강제 발생

=>예외가 발생할 상황이 아닌데 강제로 예외를 발생시킬 수 있는데 이 때는 throw 예외 객체를 주면 된다.

예외 객체를 만들 때는 new 예외클래스이름(메시지) 형태로 작성

 

8.사용자 정의 예외 클래스

=>Exception 클래스러부터 상속받아서 생성

 

9.try - with - resources

=>1.7버전부터 지원

try(인스턴스 생성){

           인스턴스를 생성

}catch(예외 클래스 이름 변수명){

           예외처리 구문

}

=>try()안에서 생성한 자원은 예외 발생 여부에 상관없이 catch구문 뒤에서 자동으로 해제를 합니다.

try()안에서 생성한 자원은 close().를 호출할 필요가 없습니다.

파일핸들링, 네트워크 , db=>는 마지막에 무조건 close(), disconnect해야 한다.ㅏ 반드시 자원 해제를 해야 한다.

 

예전 구문

Socket socket = null;//try , catch, finally는 따른 블록이다.finally에 사용할려고 한다.

try{

           socket = 소켓 생성

           socket 사용;

}catch(예외클래스 변수명){

           예외가 발생했을 때 처리를 구문;

}finally{ 

           sockte.close();

}

 

1.7이후에 가능한 구문

try (Socket socket = 소켓생성) {

           socket = 소켓 생성

           socket 사용;

}catch(예외클래스 변수명){

           예외가 발생했을 때 처리를 구문;

}

이 소켓은 try- catch구문을 나오면 자동으로 자원 해제가 됩니다.

 

=============java의 패키지

**java.lang패키지

=>자바의 기본 패키지

=>이 패키지는 import하지 않아도 패키지 이름을 생략 가능

1.Object클래스

=>자바의 최상위 클래스

=>자바의 모든 클래스는 Object클래스로부터 상속됨

=>이 클래스의 모든 속성이나 메소드는 다른 모든 클래스에서 사용 가능

=>이 클래스는 자바의 모든 클래스의 공통된 내용을 가지기 위해서 만들어진 클래스라서 인스턴스 생성은 하지 않습니다.

 

 

Object clone();복제를 위한 메소드인데 재정의 해서 사용

boolean equals(Object obj): 인스턴스의 내용을 비교하기 위한 메소드로 재정의해서 사용

 == : 참조형의 경우 참조가 같은지 비교

equals: 참조형에서 내부 데이터가 같은지 비교

 

int hashCode(): 인스턴스의 해시코드(참조)를 리턴해주는 메소드

해시코드가 같으면 동일한 메모리 영역을 참조하는 것


wait
notify메소드는 멀티스레드에서 사용하는 메소드

 

String toString():인스턴스를 문자열로 표현하기 이한 메소드

이메소드는 직접 호출해도 되지만 출력하는 메소드에 인스턴스를 대입하면 자동 호출 재정의하지 않으면 클래스 이름과 해시코드를 리턴

python__str__이다.

print() => __str__부르고

system.out.print() => toString()부른 것이다.

 

실습

=>번호와 이름을 갖는 클래스

package java;

 

//여러개의 속성을 표현하기 위한 클래스는 속성의 값을 빠르게 확인하기 위해서 (디버깅)

//toString 오버라이딩 합니다.

public class DTO {

       //속성은 private으로 만들고 접근자 메소드를 public으로 선언해서 사용

       private int num;

       private String name;

      

       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;

       }

      

       //[Source] - toString()

       @Override

       public String toString() {

               return "DTO [num=" + num + ", name=" + name + "]";

       }

}

 

 

public class Main3 {

 

       public static void main(String[] args) {

               //DTO클래스의 인스턴스를 만들고 내용을 채운후 출력

               DTO dto1= new DTO();

               dto1.setNum(1);

               dto1.setName("김정화");

              

               //출력 -인스턴스 이름을 출력하는 메소드에 대입하면 toString() 호출한 결과가 출력

               System.out.println(dto1);

               //toString() 없을 경우 java.DTO@15db9742

               //toString() 있을 경우 DTO [num=1, name=김정화]

       }

 

}

 

 

**기본형과 참조형

=>기본형은 변수 자체가 데이터이고 참조형은 변수가 데이터가 저장된 곳의 참조를 의미

==는 변수를 비교하는 연산자

기본형의 경우는 데이터를 비교하지만 참조형의 경우는 데이터를 비교하는 것이 아니고 데이터의 참조를 비교

 

String str = sr.nextLine();

String msg = "문자열";

 

str에 입력한 내용과 msg에 저장한 내용이 같더라도 == 로 비교하면 false가 나올 수 있습니다.

내용이 같더라도 저장 장소가 다를 수 있다.

참조형 데이터의 경우 내용을 비교할 때  equals메소드를 이요합니다.

Stringequals가 재정의 되어 있어서 equals를 이용하면 내용 비교가 가능

 

               String id = "root";

               Scanner sc =  new Scanner(System.in);

               System.out.print("아이디 : ");

               String input = sc.nextLine();

              

               //참조형이라서 내용이 같더라도 false 나올 있습니다.

               System.out.println(id == input);

               System.out.println(id.equals(input));

              

               sc.close();

 

데이터베이스에서도 같는지 안 같는지 equals로 비교하면 된다.

num이 기본키일 경우 아래의 것으로 비교한다.

if (this.num == other.num) {

                      return true;

               }else {

                      return false;

               }

 

모델링 컬럼에 들어갔는지

       private int num;

       private String name;

똑같으면 안되라는 것을 처리 하기 위해서

       //인스턴스의 내용을 비교하는 메소드

       public boolean equals(DTO other) {

               //내용 비교

               //num name 일치하면 true 그렇지 않으면 false

               if (this.num == other.num && this.name.equals(other.name)) {

                      return true;

               }else {

                      return false;

               }

       }

 

       //인스턴스의 내용을 비교하는 메소드

       public boolean equals(DTO other) {

               //내용 비교

               //num name 일치하면 true 그렇지 않으면 false

               if (this.num == other.num && this.name.equals(other.name)) {

                      return true;

               }else {

                      return false;

               }

       }

 

               //DTO클래스의 인스턴스를 만들고 내용을 채운후 출력

               DTO dto1= new DTO();

               dto1.setNum(1);

               dto1.setName("김정화");

              

               //출력 -인스턴스 이름을 출력하는 메소드에 대입하면 toString() 호출한 결과가 출력

               System.out.println(dto1);

               //toString() 없을 경우 java.DTO@15db9742

               //toString() 있을 경우 DTO [num=1, name=김정화]

              

              

               DTO dto2 = new DTO();

               dto2.setNum(1);

               dto2.setName("김정화");

              

               //new 하면  instance생기고 메모리 할당한다.

               //참조를 비교 - 각각 new 했기 때문에 참조가 다름

               System.out.println(dto1 == dto2);

               //내용을 비교 - equals 재정의해서 내용을 비교

               System.out.println(dto1.equals(dto2));

 

Database

 

응용프로그램

 

 

디자인

 

코딩

 

디자인과 코딩을 연경할려면 DTO dto3 = dto1;원리를 사용한다.

 

디비접속 디비에 바로 반영이 된다. COMMIT,작업 취소 같은 것을 쉽게 못한다.

디비에 접속하면 DB에 연결하는 것이 아니라 COPY본을 준다.

 

 

 

 

 

COMMIT하면 DB COPY에 것을 DB에 반영하는 것이고

ROLLBACK하면 DB COPY 없어진다.

원본을 복재해서 사용한다.

 

원본을 복제 :

자바에서는 CLONE이라고 하고

자바이외에 했던 언어는 deep copy(깊은 복사)

clone는 나랑 똑같은 것을 준다.

public DTO 자바는 이름을 맞추는 것이기 때문에 이름을 맞추는 것이 좋다.

public DTO clone(){

           //새로 만들어줘야 한다.

           DTO ? = new DTO();

           ?.setNum(this.num);

           ?.setName(this.name);

           return ?

}

DTO dto1 = new DTO();

dto1.setNum(1);

dto2.setName("김정화");

 

DTO dto1 = new DTO();

static 에서 DTO클래스 ->static(메소드)

DTO dto3 = dto1;

dto3.setNum(2);

System.out.println(dto1.getNum()); //2가 뜬다. 복사는 메모리 라는 것이다.

 

 

 

set값은 바꾸는 것이고

get은 꺼내는 것이다.

 

변수.get

변수.set

 

실습

=>DTO복재 CLONE

DTO.java

       //인스턴스의 내용을 복사해서 리턴해주는 메소드

       public DTO clone() {

               //새로운 인스턴스를 생성

               DTO other = new DTO();

               //기존 인스턴스의 내용을 복제

               //this 생략해도 되는데 기존 인스턴스의 내용이라는 것을 강조하기 위해서 thisfmf 붙임

               other.setNum(this.num);

               other.setName(this.name);

               return other;

       }

Main3.java

               //참조를 복사 -하나의 변경이 다른 것에도 영향을 주게 됩니다.

               DTO dto3= dto1;

               dto3.setNum(2);

               System.out.println(dto1);

              

               //내용을 복제 - 하나의 변경이 다른 것에 영향을 주지 않음

               DTO dto4 = dto1.clone();

               dto4.setNum(3);

               System.out.println(dto4);

 

결과 =>

 

heap , stackuser mode가 한다.

jvm으로 하기 때문에

운영체제게 kernel mode로 까지 하기 때문이다.

 

 

반응형

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

java-10  (0) 2020.09.30
java-9  (0) 2020.09.29
java-7  (0) 2020.09.27
java-6  (0) 2020.09.26
java-5  (0) 2020.09.24
728x90
반응형

**패키지 이름이나 클래스 이름을 변경하고자 할 때

=>직접 클릭해서 변경하는 것은 권장하지 않습니다.

=>IDE에는 대부분 리팩토링 기능을 제공하는데 리팩토링 기능을 이용해서 변경을 하면 동일한 이름으로 만들어진 모든 것을 전부 변경해줍니다.

 

Eclipse에서는 변경하고자 하는 패키지 이름이나 클래스 이름을 선택하고 마우스 오른쪽 클릭하고

[Refactor] -[Rename]을 선택하고 변경하고자 하는 이름을 입력

 

 

**absstract(추상)

1)추상메소드

=>내용이 없는 메소드

=>다형성 구현을 위해서 하위 클래스에 오버라이딩 구현을 위해서 만든 메소드

=>Startcraft라는 클래스의 attack이라는 메소드는 없어도 실행상에는 아무런 문제가 없었지만 상위 클래스 자료형으로 만들어진 변수에 하위 클래스 자료형의 인스턴스를 대입하는 경우 변수는 상위 클래스 자료형의 요소만 사용이 가능하기 때문에  하위 클래스에 있는 attack을 호출을 못합니다.

attack을 호출할 수 있도록 Starcraft클래스에 attack을 만들어 준 것입닏.

Starcraftattack메소드는 직접 호출하기 위해서 만든 것이 하위 클래스의 메소드를 호출할 수 있도록 하기 위해서 만든 메소드입니다.

이런 메소드는 내용을 가질 필요가 없습니다.

=>매소드의 자료형 앞에 abstract를 추가하면 추상 메소드가 되고 이 메소드는 내용이 없습니다.

public abstract 결과형 메소드이름();

:

 

 

 

 

 

=>추상 메소드는 상속받은 곳에서 반드시 구형을 해야 합니다.

Overriding을 해우저야 합니다.

 

=>자바에서는 추상 메소드는 반드시 추상 클래스나 인터페이스에 존재해야 합니다.

 

 

2)추상 클래스

=>인스턴스를 만들 수 없는 클래스

=>Startcraft라는 클래스는 실제 게임을 위해서 만든클래스가 아니고 다형성 구현을 위해 만든 크래스이기 때문에 직접 사용할 필요가 없는 클래스

이 클래스는 인스턴스를 만들 필요가 없는 클래스 입니다.

이런 클래스는 개발자가 실수로 인스턴스 만드는 것을 방지해주는 것이 좋습니다.

인스턴스를 만들지 못하도록 할 때는 class 라는 예약어 앞에 abstract가 추가해주면 추상 클래스가 됩니다.

=>이 클래스는 상속을 통해서만 사용할 수 있게 됩니다.

 

 

 

 

//abstract를 붙이면 추상클래스가 되면 이 클래스의 생성자를 호출하면 에러

public abstract class Starcraft {

          

           //하위 클래스의 인스턴스가 attack을 호출할 수 있도록 오버라이딩을 위한 메소드

           //abstract가 붙이면 추상 메소드가 됩니다.

           //이 메소드는 내용이 없습니다.

           //이 메소드를 소유한 클래스나 인터페이스를 상속하거나 구현한 클래스 에스는 반드시 이 메소드를

           //재정을 해주어야 합니다.

           public abstract void attack() ;

}

 

 

 

**final

1. 변수 앞에 final을 붙이면 이 변수는 읽기 전용이 됩니다.

=>어떤 작업을 할 때 변수의 내용을 변경하지 않는다면 굳이 일반 변수를 사용하지 말고  final을 사용하는 것이 안정성 측면에서 뛰어남

 

2. 메소드 앞에 final을 붙이면 이 메소드는 오버라이딩 할 수 없습니다.

=>오버라이딩:메소드를 다시 정의 하는 것, 기능확장 또는 기능변경할 수 있다.

=>이 메소드가 시스템을 핸들링하거나 이름이 중요한 메소드 인 경우

 

3. 클래스 앞에 final을 붙이면 이 클래스는 상속할 수 없습니다.

=>상속을 못한다는 것은 기능 확장이나 변경을 못하게 하는 것입니다.

=>시스템 관련된 클래스이거나 다른 클래스들과 연관관계가 높은 클래스라서 상속을 못하게 합니다.

 

예전에는 프로그램개발시

자료형 ,변수 를 배울 때

R의 내용을 잊어버리는게 좋다. r에서 배열은 1차원 배열

 

 

 

 

최근 자료형,변수 이름으로 선언

var ->변수

let ->상수 (read only)

위의 기능을 잘 구분해야 한다.

 

읽기전용 - 동시에 사용해도 문제 없음

수정가능 - 동시에 사용하면 문제 가능성이 있음

 

카카오톡에서는 동시에 로그인은 문제가 아니라 동시에 글 쓰기가 문제이다.

카카오톡 2개 로그인해서 동시에 2개 보낼 경우

동시에 수정하는 것은 문제가 생긴다. 아이디가 같을 경우 같은 화면인데 숫자가 안 같게 나올 수 있다.

그래서 같이 쓸수 없는 것과 같이 쓸 수 있는 것을 구분해서 하는 것이 좋다.

JAVA까지는 FINAL이 붙였는지 안 붙였는지 개발자가 판단해야 한다.

C++은 예약어가 거의 없다. 추상인지 아닌지는 개발자가 알아서 해야 한다.

 

Mfcwindows를 핸들링할 수 있기 때문에 bluescreen이 뜬다.

c#등 하라는 것 추천하는 것은 .net등을 사용해서 windows를 핸들링 못하게 한다.

 

 

 

 

 

 

 

위의 경우 삽입인데 수정으로 하여 직관적이지 않을 경우가 있어서 수정을 못하게 한다.

 

상속을 적절히 잘 만들어야 한다.

java는 점점 더 무거울 수 있는데

java의 장점이 하나있다.

java      A class                      

 

A classx라는 메소드를 사용해도 1.3에 돌아갈 수 있다.

 

 

java      A class                      

             AEx class(A 상속햇)

1.2Aclass1.3에서도 돌아갈 수 있다. 바꾼 것이 없기 때문이다.

 

java      A class                       

 

             AEx class(A 상속햇)

           AExEx class

A class가 문제 가 있을 경우 deprecated 하면된다.

원본 그대로 두고 상속받을 class를 만들고 하면 된다.

 

mfc는 사용하면 큰 문제가 생길 수 있다.

win95   A class

           win95에 있는 A class win98에서 지원이 안된다.

win98를 만들면 A class 를 수정한다.

옛날에 만든 것은 돌아가지 않는다.

windowsupdate가 없다 .포맷하고 한다.

맥은 업데이트가 가능하다. 예전에것 돌아간다. 맥은 포맷을 잘 안한다.

 

dll ->프로그램 공유 다른 프로그램에서 사용할 수도 있어니 삭제 하는 것인가 >=>이것은 종속 관계이다.

 

**Interface

=>추상 메소드와 final상수 그리고 default method 만을 소유한 개체

=>인터페이스에 만들어져 있는 메소드는 거의 추상 메소드이기 때문에 인터페이스를 구현한 클래스에서는 메소드를 반드시 재정의를 해야 합니다.

1.클래스에 인터페이스 구현

class 클래스이름 extends 상위 클래스이름 implements 인터페이스이름 나열{

}

 

2.인터페이스는 여러 개 구현할 수 있습니다.

클래스는 반드시 1개만 상속할 수  있습니다.

인터페이스에 있는 것은 추상메소드입니다.

반드시 재정의를 해줘야 합니다.

인터페이스를 구현하면 인터페이스에 있는 메소드가 반드시 존재한다고 보장할 수 있습니다.

인터페이스 이름 대신에 프로토콜(규칙, 규약, 약속)이라고도 합니다.

인터페이스는 GUI 이벤트 처리에 많이 이용합니다.

 

 

3.인터페이스 생성

interface 인터페이스이름{

           상수 선언

           메소드 선언

}

=>상수는 final을 붙이지 않아도 상수화 됩니다.

int N = 10; =>final int N = 10; 으로 해석

 

=>메소드는 abstract를 붙이지 않아도 추상 메소드가 됩니다.

public void attack(); =>public abstract void attack();

 

=>이름을 만들 때는 able이나 listener라는 단어를 뒤에 붙이는 경우가 많은데 listener는 이벤트 처리를 위한 인터페이스인 경우 붙입니다.

 

4.인터페이스 생성과 사용

1)인터페이스를 생성하고 변수 1개와 메소드 1개를 선언

public interface ISample {

          

           //final 이 없어도 final : 변경 못함

           public String TODAY = "2021-01-10";

          

           //abstract가 없어도 abstract

           //내용을 만들면 안되고 ISample implements 한 곳에서는 반드시 Overriding(재정의)을 해야 합니다.

           public void disp();

 

}

 

2)앞에서 만든 인터페이스를 implements하는 클래스를 생성

=>하나의 인터페이스를 implements하는 클래스의 경우 이름을 인터페이스이름Impl로 많이 정하고

클래스를 상속받는 경우는 클래스이름Ex 로 많이 합니다.

 

//ISample이라는 인터페이스를 구혀한 클래스

public class ISampleImpl implements ISample {

 

           @Override

           public void disp() {

                       //인터페이스에 있는 변수를 가지고 와서 출력

                       System.out.println(TODAY);

                       //수정은 안됨 - 인터페이스의 변수는 무조건 상수

                       TODAY = "2021-01-11";

           }

 

}

//ISample이라는 인터페이스를 구혀한 클래스

public class ISampleImpl implements ISample {

 

           @Override

           public void disp() {

                       //인터페이스에 있는 변수를 가지고 와서 출력

                       System.out.println(TODAY);

                       //수정은 안됨 - 인터페이스의 변수는 무조건 상수

                       //TODAY = "2021-01-11";

           }

 

}

 

3)MAIN메소드를 소유한 실행 클래스를 만들어서 disp()를 호출

public class Main {

 

           public static void main(String[] args) {

                       //ISampleImpl 클래스에 있는 disp라는 메소드를 호출

                       //s자 있는지 먼저 확인한다.

                       ISampleImpl iSampleImpl = new ISampleImpl();

                       iSampleImpl.disp();

                      

           }

 

}

 

5.인터페이스는 생성자가 없기 때문에 인스턴스 생성을 할 수 없습니다.

new 인터페이스이름()을 하는 것은 에러

 

6.인터페이스를 자료형으로 해서 변수는 선언할 수 있습니다.

변수를 만들면 인터페이스를 implements한 클래스의 인스턴스의 참조를 대입할 수 있습니다.

ISampleImpl iSampleImpl = new ISampleImpl();

=>위의 문장을 아래처럼 변경해도 됩니다

ISample iSampleImpl = new ISampleImpl();

 

 

7.default method

=>인터페이스에는 내용이 있는 메소드를 만들 수 없지만 예외적으로 default method는 내용을 가질 수 있습니다.

=>추상 메소드가 아니라서 메소드를 오버라이딩 할 필요가 없습니다.

=>접근 지정자를 defualt로 설정해야만 합니다.

 

           //인터페이스에서 내용을 갖는 메소드를 만들고자 할 때는 접근지정자로  default를 사용해야 합니다.

           default void print() {

                      

           }

 

 

8.인터페이스는 여러개 구현이 가능

 

9.인터페이스끼리 상속 가능

interface 인터페이스이름 extends 다른 인터페이스이름{

}

 

====>7,8,9는 빼셔도 됩니다.

 

10.인터페이스 활용

=>템플릿 메소드 패턴을 구현할 때 많이 사용

=>메소드의 모양은 인터페이스에 만들어 두고 실제 구현은 인터페이스를  implements 한 클래스에 하는 것

=>C언어에서는 메소드의 원현은 header파일에 하고 구현을 c파일에서 하는 것도 템플릿 메소드 패턴이고 하나의 파일에서 메소드의 원형은 상단에 만들고 실제 내용은 하단에 구현하는 형태도 템플릿 메소드 패턴

=>고객과 대화하는 분석가 나 설계를 담당하는 설계자 또는 고객은 메소드의 구현 내용은 의미가 없지만 고객의 요청이 제대로 구현되어 있는지는 중요합니다.

고객이나 분석가 또는 설계를 담당하는 사람과 개발자가 대화할 때는 인터페이스를 이용합니다.

고객의 요청 1개마다 메소드는 1개씩 만 만들어져야 합니다.

 

고객:

HELLO JAVA를 출력할 수 있도록 요청시:

 

 

 

 

 

개발자가 이렇게 하면 안된다.고객은 이런 것 알 필요없다.

 

 

 

이름을 잘 못 만들어도 연결하는 것만 잘 하면 된다.

 

메뉴판에서 사진은 return이다.

 

(int x, String y) 매개변수 의 순서를 고려해야 한다.

select from 2개 이상일 경우에는 sort로 해야 한다. 데이터베이스는 행과 열의 순서가 없다.

그래서 2개가 넘어가면 순서를 생각해야 한다.

그래서2개 가 있으면  (int x, String y)가 아닌

class T{

           int x

           String y;

}

T.x T.y이런식으로 하는게 좋다.

여러개가 있을 경우 순서 등 고려해야 하고 문제가 생길 수 있어니깐 하나로 해야 한다.

 

 

 

 

 

 

 

 

**Inner Class

1.클래스 사이의 관계

1). is a: 상속관계

2). has a:포함관계

=>하나의 클래스가 다른 크래스 안에서 사용되는 경우

 

2.InnerClass(내포 클래스)

=>클래스 안에 존재하는 클래스

=>일반 inner class, static inner class, local inner class , anonymous class 4가지

 

 

3.일반 inner class

=>class안에 만들어지는 클래스

=>내부 클래스를 외부 클래스에서만 사용하기 위해서 생성

=>안드로이드의 이번트 처리 인터페이스 들이 내부 인터페이스 형태로 많이 만들어져 있습니다.

=>클래스 안에 클래스를 만들었기 때문에 소스 파일은 1개이지만 컴파일을 해서 클래스를 만들 때는 내부 클래스도 별도의 클래스로 만들어집니다.

외부클래스이름$내부클래스이름.class 형태로 만들어집니다.

=>외부 클래스는 접근 지정자가 default public만 가능하지만 내부 클래스는 private protected도 가능

 

4.static inner class

=>inner class static멤버가 있으면 에러가 발생합니다.

=>이런 경우에는 inner class를 만들 때 stack을 붙여주면 에러가 없어지게 됩니다.

=>static은 인스턴스를 만들기 전에 생성이 되어야 하는데  inner class는 다른 클래스 내부에 있기 떄문에 코드로만 존재하다가 처음 인스턴스를 만들 때 메모리 할당을 받기 때문에 static 멤버 생성이 안됩니다.

class앞에 static을 붙여서 이 클래스 자체를 메모리에 바로 할당하도록 해주어야 합니다.

 

 

5.local inner class

=>local(지역) :메소드 내부에서 생성

=>메소드 내에서 클래스를 만들어서 메소드 내부에서만 사용할 수 있도록 한 클래스

지역에 무엇인가를 만들면 지역이 실행될 때 만들어지고 지역이 종료가 되면 자동 소멸

 

 

6은 좀 어렵다.

6.Anonymous Class(익명 객체)

=>이름 없는 클래스를 가지고 인스턴스를 만들어서 사용

=>클래스에 이름이 있으면 static(method) 영역에 메모리 할당이 되서 사용이 종료되더라도 프로그램이 종료될때 까지 메모리에 계속 남아있게 됩니다.

=>이름 없는 형태로 만들어서 필요할 때만 메모리 할당을 해서 사용하고 사용이 종료되면 소멸시키기 위해서 사용합니다.

메모리가 부족한 모바일이나 임베디드 프로그래밍에서 많이 사용

안드로이드의 이벤트 처리를 이 방법을 이용해서 많이 구현했고 최근의 andriod studio에서는 이 문법을 사용하면 코드 최적화를 통해서 람다식(자바의 함수형 프로그래밍)으로 변환됩니다.

람다는 프로그래밍 언엄다 의미가 다름(파이썬에서는 한 줄 짜리 이름 없는 함수)

 

 

class A{

           메소드;

}

=>A클래스를 상속받아서 메소드를 재정의 한후 메소드를 호출

 

class B extends A{

           메소드 재정의

}

 

B  ob =  new B();//인스턴스

ob.메소드();

//(new B()).메소드();로 작성해도 됩니다.

 

 

 

=>anonymous클래스를 이용하는 방법

new A(){

            메소드 재정의

}.메소드();

 

=>새로운 클래스를 만들지 않았으므로 static영역에 적재되지 않아서 메모리 효율이 위보다 좋아집니다.

 

7.실습

1)메소드 1개를 갖는 인터페이스를 생성

=>Anonymous인터페이스

 

2) Anonymous 인터페이스를 구현한 클래스를 만들고  disp를 재정의

=>AnonymousImpl

           @Override

           public void disp() {

                       System.out.println("일반적인 방법의 상속과 구현");

 

           }

 

3)main메소드에 위의 메소드를 호출하는 구문을 작성

           public static void main(String[] args) {

                       /*

                       //인스턴스의 참조를 obj에 저장했으므로 인스턴스 재사용 가능

                       Anonymous obj = new AnonymousImpl();

                       obj.disp();

                       */

                      

                       //어차피 한번밖에 안해서도 되기 때문에

                       //인스턴스의 참조를 저장하지 않았으므로 인스턴스 재사용 불가능

                       new AnonymousImpl().disp();

                      

                       //클래스를 만들지 않고  Anonymous인터페이스 사용하기

                       new Anonymous() {

 

                                  @Override

                                  public void disp() {

                                              System.out.println("익명 객체를 이용한 인터페이스 사용");

                                  }

                                 

                       }.disp();

           }

 

*사이트 주소:

API

 

1.7 API: http://docs.oracle.com/javase/7/docs/api/

 

1.8 API: http://docs.oracle.com/javase/8/docs/api/

 

 

 

예제 코드

 

http://www.java2s.com/Code/JavaAPI/CatalogJavaAPI.htm

 

http://www.java2s.com/Tutorial/Java/CatalogJava.htm

 

 

 

 

 

**document구성

=>api 디렉토리 안에 있는 index.html이 도큐먼트 시작

=>왼쪽에 2개의 창이 있고 오른쪽에 1개의 창

왼쪽 위의 창은 패키지를 출력

 

왼쪽 아래 창은 패키지 안에 속한 인터페이스와 클래스로 구성

 

오른쪽 창은 선택한 인터페이스 또는 클래스의 구조와 설명 및 사용 가능한 멤버를 출력

 java를 할수 있는 것이 나온다.

 

1.class

=>abstract class: 인스턴스 생성을 할 수 없다.

new 다음에 사용할 수 없습니다.

상속을 통해서만 사용

 

=>final class:상속할 수 없다.

extends 뒤에 나올 수 없습니다.

 

=>extends 뒤에 나오는 이름은 상위 클래스

 

=>implements 뒤에 나오는 이름은 인터페이스

 

public class Date extends Date=>상속 맏은 것

 

=>Direct Known Subclasses:현재 클래스를 상속받은 클래스들

 

2.class설명 뒤에 나오는 항목 중 Field Summary

=>static final 변수(상수): 이 클래스에 메소드들에서 사용하는 옵션

=>클래스이름.상수이름을 사용하면 됩니다.

 

많이사용하게 되는 언어인데 java.lang.thread

field summary 는 수정하면 안된다.

 

3.classs설명 뒤에 나오는 항목 중 Constructor(생성자)

=>인스턴스를 만들기 위한 특별한 용도의 메소드: new 생성자(매개변수)의 형식으로 호출

=>생성자가 없는 경우

1). interfaceabstract class가 아닌지 확인: interfaceabstractinstance 생성을 못하므로 생성자가 없습니다.

메소드로 직접간다.

2).모든 메소드가 static(클래스 이름으로 호출이 가능해서 인스턴스 만들 필요 없다.)이라서 인스턴스 생성이 필요없기 때문

java.lang.System , java.lang.Math 클래스 등

public final class System

extends Object

#final이여서 상속할 수 없다.

직접 메소드로 간다.

전부 static붙어서 인스턴스 생성할 필요없다.

 

 

3)생성자가 없는데 모든 메소드가 static이 아닌 경우

생성자가 없으면 instance를 만들 수 없는데 메소드가 static이 아니다.

=>디자인 패턴(사용하는 용도에 따라 클래스를 다르게 디자인 하는 것)을 적용해서 인스턴스를 별도의 방법으로 만들도록 한 클래스

디자인 패턴 - 개발 할 때는 중요하게 평가 받는다.

 

 

Singleton이나 아닌가 는 것은 메소드를 쭉 한번 봐야 한다.

=>Singleton Pattern:인스턴스를 1개만 만들게 하는 디자인 패턴

                          클래스 안에서 메소드들을 찾아보면 자기 자신의 자료형을 리턴하는 static메소드가 있어서 이 메소드를 이용해서 인스턴스를 생성

                       java.lang.Runtime클래스가 대표적인데 이 클래스에는

                       static Runtime getRuntime()메소드가 있ㄷ어서 이 메소드를 통해서 인스턴스를 생성합니다ㅏ.

Runtime runtime = Runtime.getRuntime();

 

=>Factory Method Pattern:인스턴스를 다른 클래스의 메소드를 이용해서 생성하는 패턴

                                  자신의 클래스이름 뒤에 FacotyBuilder라는 이름이 추가된 클래스가 있으면 이 클래스는 Factory Builder를 이용해서 인스턴스를 생성

 

생성자가 없으면 잘 보고 확인하고 적절하게 사용해야 한다.

 

 

4.Method Summary

=>호출 가능한 메소드 목록이 출력

=>메소드를 볼 때는 오른쪽의 리턴 타입 부분에서 static이 있는지 없는지 확인

static이 있으면 인스턴스 생성없이 클래스이름으로 바로 호출이 가능하고 static이 없는 메소드는 인스턴스를 생성해서 인스턴스.메소드이름 의 형태로 호출

 

=>메소드의 매개변수를 확인 :메소드를 호출할 때 넘겨주어야 하는 데이터

 

=>메소드의 리턴 타입을 확인 :결과를 저장해서 다시 사용할 수 있는지 확인

void이면 결고를 다른 곳에 재사용 할 수 없기 때문에 호출하는 것으로 끝

그 이외의 자료형으로 나와있으면 그 데이터를 변수에 저장해서 다른 곳에 이용할 수 있습니다.

 

 

=>메소드를 클릭해서 메소드의 상세내용보기를 한 후 예외처리를 해야하는지 확인해봐야 하는데 이클립스에서는 예외 처리를 해야 하는 메소드를 호출할 때 예외처리를 하지 않으면 에러가 발생 에러가 발생하면 예외처리 구문으로 묶어도 됩니다.

 

5.Method Summary 출력 가장 하단에 박스에 있는 메소드 이름 들

=>상속받은 그대로 사용하는 메소드들의 이름입니다.

=>이 메소드들의 자세한 설명은 상위 클래스에서 확이해야 합니다.

boolean => true , false주면 된다.

voidreturn이 없다.

 

python에서

start = 0 시작

__add__ =>+를 연산자 오버로딩해야 한다.

 

valuereturn

값이 없거나 None이면 void라는 것이다.

문자 와 숫자는 오류난다.

 

https://matplotlib.org/

https://seaborn.pydata.org/

https://scikit-learn.org/

 

 

6.java.lang.System.클래스에 있는 exit라는 메소드를 이용하면 프로그램을 종료할 수 있습니다.

System.exit(0);

 

7.java.lang.Math클래스에 있는 round라는 메소드를 이용하면 반올림을 할 수 있습니다.

long l = Math.round(5.4)

 

 

8.java.lang.String클래스에 있는 chatAt이라는 메소드를 이용하면 문자열에서 특정 위치에 있는 문자를 추출할 수 있습니다.

이 메소드를 이용해서 "Hello Java"의 세번째 글자를 출력

 

String str = new String("Hello Java");

char ch = str.charAt(2); =>l

 

**예외처리

1.에러

1)물리적 오류(컴파일 오류):문법적으로 맞지 않는 문장을 만들어서 컴파일이나 실행이 되지 않는 현상

=>이클립스에서는 빨간색 에러를 표시해줍니다.

=>반드시 수정을 해서 실행을 시켜야 합니다.

 

 

2)논리적 오류:문법적으로는 잘못 된 것이 없어서 실행이 되는데 실행 결과가 이상하게 나오는 현상

=>에러가 아니기 때문에 코드 상에는 찾기가 어렵고 메모리 값을 확인하기 위한 디버깅을 수행해서 오류를 수정

 

 

3)예외(Exception):문법적으로는 오류가 없어서 실행은 되지만 실행 중 특수한 상황이 발생하면 에러가 발생하는 현상

=>예외처리를 이용해서 잘못된 부분이 있으면 수저을 하고 그렇지 않으면 예외를 기록해서 프로그램을 종료하게 하거나 정상적으로 동장하도록 해주어야 합니다.

 

4)단언(Assertion):물리적 오류도 아니고 예외도 아닌데 개발자가 특수한 조건을 설정해서 조건에 맞지 않는 경우 강제로 예외를 발생시켜 프로그램을 중단시키는 것

=>운영체제 버전이 맞지 않으면 실행을 못하게 하거나 특정 포트가 사용 중이면 실행을 못하게 하는 것

정상적인 상황인데 실행을 못하게 한다. 예를 들면 신한은행에서 iphone탈옥하는 것 사용 못하게한다.

 

 

2.Eclipse에서 디버그 모드로 실행

=>디버그 모드: 메모리에 저장된 값을 확인하기 위해서 실행하는 모드

break point 사용 가능

=>break point 프로그램이 실행하다가 중단할 수 있는 중단점

부분적으로 실행 가능 하는 것이 break point

break point를 만들 때는 라인 번호 옆에 있는 거터를 선택하고 마우스 오른쪽을 클릭해서 Tooggle Break point메뉴를 클릭하면 됩니다.

=>run메뉴의 debug를 실행하면 디버그 모드로 실행됩니다.

 

=>결과가 이상하게 나오거나 실행중 오류가 발생해서 중단되면 중단점을 만들어서 디버그 모드로 실행해서 확인

위처럼 하기 싫으면 코드 중간 중간에 System.out.print를 이용해서 로그를 출력해서 확인하는 방법도 있다.

로그를 출력하는 것은 에러를 수정하고 나면 필요 없는 문장이 되는데 삭제를 하지 않으면 시스템 자원을 소모하게 됩니다.

클라이언트 프로그램은 부담을 적게 줄수 있지만 서버 프로그램은 불필요한 로그를 찍는 것이 시스템 자원을 많이 소모할 수 있습니다.

 

3.예외처리의 목적

1)예외가 발생하더라도 프로그램을 중단하지 않고 계속 실행하기 위해서

2)예외의 내용을 기록해서 예외를 수정하거나 학습용으로 사용하기 위해서

public class Main1 {

           public static void main(String[] args) {

                       int [] ar = {100,200};

                       System.out.println("예외처리의 목적");

                       try {

                                  System.out.println(ar[2]);

                       }catch(Exception e){

                                  System.err.println(e.getMessage());

                       }

                       System.out.println("예외처리의 목적중 하나는 예외가 발생하더라도 계속 작업을 수행하기 위해서입니다.");

                      

           }

}

=>예외가 발생했지만 맨 아래에 출력 구문을 수행

예외처리를 하게되면 예외가 발생하더라도 이후 구문을 전부 수행합니다.

 

 

 

 

 

 

 

 

4.자바의 에러처리

=>자바는 모든 예외를 객체로 처리

=>자바에서 예외 처리의 최상위 인터페이스는 java.lang.Throwable

다시 Error( .심각한 예외)Exception(덜 심각한 예외)으로 처리

=>Exception은 다시 RuntimeException과 일반적인 Exception으로 분류

RuntimeException은 실행 중 jvm에 의해서 발생하는 예외로 개발자가 처리 하지 않아도 되는 예외이고 일반적인  Exception은 컴파일러가 컴파일할 때 확인하는 Exception으로 개발자가 반드시 처리를 해주어야 합니다.

대다수의 언어는 모든 예외를 개발자가 처리해도 되고 처리하지 않아도 문법적으로 오류가 없는데 자바는 일반적인  Exception의 겨우는 반드시 예외처리를 해야 합니다.

 

 

5.자주 발생하는 예외

1)NullPointerException:null인 참조형 변수가 자신의 멤버를 호출하는 경웨 발생하는 예외

a.b이 경우 발생하면 anull이어서 발생

for(임시변수 in 컬렉션) 이 경우에는 컬렉션이 null이어서 발생

a[b] 이 경우 발생하면 anull이어서 발생

 

2)NuberFormatException:숫자가 아니어서 발생하는 예외

=>GU프로그램이나 웹 프로그램에서는 숫자를 직접 입력받을 수 없습니다.

문자열을 입력받은 후 숫자로 변환을 해서 사용합니다.

숫자로 변환할려고 할 때 숫자로 변경할 수 없는 데이터라서 발생하는 예외

 

3)ClassCastException: 강제 형변환이 안되는 데이터를 강제로 형변환 할려고 해서 발생하는 예외

 

4)ArrayIndexOutOfBoundsException:배열이나 List에서 사용할 수 없는 인덱스를 사용한 경우

 

5)Ai=rithmeticException:산술 연산 예외

 

6.예외처리 방법

try{

           예외가 발생할 가능성이 있는 코드

}catch(예외처리 클래스이름 변수명){

           예외처리클래스이름에 해당하는 예외가 발생했을 때 처리할 구문

}catch 클래스이름이 다르면 여러 개 반복 사용가능

finally{

           예외 발생 여부에 상관없이 무조건 수행할 구문

}

=>try.가 나오면 catch1개 이상나오거나 finally가 반드시 나와야 합니다.

=>finally에는 대부분 외부 자원(파일 , 네트워크 , 데이터베이스 등)을 사용했을 때 정리하는 코드가 작성이 됩니다.

프로그램에서 file close()안하고 사용중 일경우 다른 데는 읽기 전용으로 뜬다.

 

 

 

 

 

 

빠른 것과 늦은 것 이 했을 경우 빠른 것이 뻥난다.

토큰은 로그아웃하고 하는게 좋다.

토큰을 반납작업을 해야 한다. finally에 해야 한다.

finally 안테 만들지 않고  catch다음에 적어도 수행되던데 왜 finally?

finally에 작성한 문장은 catch구문을 수행한 다음에 실행된다는 보장을 할 수 있지만 finally가 아닌 영역에 적은 것은 catch구문 수행 후에 된다는 보장을 할 수 없습니다.

 

 

순서가  random하게 출력한다.

 

 

그래서 아래처럼 수정한다.

                       int [] ar = {100,200};

                       System.out.println("예외처리의 목적");

                       try {

                                  System.out.println(ar[2]);

                       }catch(Exception e){//예외 발생

                                  System.err.println(e.getMessage()+"발생");

                       }finally {

                                  System.out.println("예외처리의 목적중 하나는 예외가 발생하더라도 계속 작업을 수행하기 위해서입니다.");

                       }

 

python에서는

try:

except IndexError as e:

 

except ? as e:

 

finally:

 

 

line : 5

****0

***1*2

**3***4

*5*****6

789012345

for(int i = 0; i< line ; i++){

           공백 : 4 3 2 1 0    

           j = 0 ; j < 4-i ; j++   => 4 + (-1)*i

 

           if(i == 0){//첫번째 줄

                       System.out.println(su % 10);

                       su = su+1;

           }

           else if(i == line -1){//마지막줄

                       //2*line -1

                       j = 0  j< 2*line -1

                       su1씩 증가하면서 출력

           }

           else{//중간이것

                       System.out.println(su % 10);

                       su = su +1;

                      

                       2 * i -1 개 공백 출력                 

 

                       System.out.println(su % 10);

                       su = su +1;

           }

}

%10하면 절대로 9나눌 수 없다.

 

 

***

***

***

 

*

**

***

 

***

**

*

 

*

**

*

 

 

quick sort

5          3          8          9          6          2          7

 

 

pivot

j

 

pivot을 기준으로 왼쪽에는 pivot 보다 작은 값 오른쪽에는 pivot보다 큰 값

 

left :

right:6

 

pivot = left

j = pivot

pivot 위치의 데이터와 오른쪽에 있는 모든 데이터를 비교한다. 비교해서 pivot위치의 데이터보다 작은 데이터를 만나면 j1증가시켜서 j번째 데이터와 교체를 한다.

반복문 한바퀴를 돌린다.

반복문이 끝나면 pivot 위치의 데이터와 j번째 데이터를 교체한다.

pivotj 로 교체

 

       i = 1

5          3          8          9          6          2          7

 

 

pivot

j

 

5하고 3비교해서 j -> j+1 i3이다.

i 2  8하고 비교 .

i 3  9하고 비교

i 4  j증가 해서 2가 되고  2하고 8교체했다.

i 5  7하고 비교

pivot j 2이고 5하고 2바꾼다.

왼쪽에는 5보다 작고 큰 것은 오른쪽에 있다.

 

==============>

left 부터 pivot -1자리 까지

pivot +1  -> right까지

이 두개 영역으로 분할해서 다시 수행

=>여기서 재귀가 만들어진다.

 

쪼개서 계속 한다. 1개가 될때 까지 계속한다.

 

 

반응형

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

java-9  (0) 2020.09.29
java-8  (0) 2020.09.28
java-6  (0) 2020.09.26
java-5  (0) 2020.09.24
java-4  (0) 2020.09.22
728x90
반응형

pythondir해서 바로 할 수 가 없다.

그래서 document 를 계속 켜야 한다.

java는 유지보수는 편하지만 왔다갔다 하면 좀 번거롭다.

test는 로직이 문제 있는지 확인하는 것이다.

최근에는 TDD사용해서

녹색은 public이다.

빨간색은 private

s붙으면 static

s안 붙으면 class가 못 쓴다.

녹색 못 써서 인스턴스 만들어야 한다.

인스턴스 만든 후 생성자 불러야 한다. new해서

매개변수 있는 것인지 없는 것인지

생성자 괄호안에 아무것도 없으면 매개변수가 없어서 매개변수 없이 호출 가능

 

**만들어진 클래스 이용

1.내가 원하는 기능을 가진 클래스를 찾기

python에서 회귀 분석시 누가 해주는 것을 찾아야 한다. 없으면 새로 만들어야 한다.

 

2.내가 원하는 기능을 수행해주는 메소드를 찾기

=>static인지 아닌지 확인 :static 이라면 instance를 생성할 필요가 없음

static이 아니라면 instance를 생성해야 하므로 항상 생성자를 다시 확인

javastatic이면 s가 보인다.

pythonstatic이면 self가 없다.

 

=>메소드의 매개변수를 확인

매개변수는 메소드에게 일을 시킬 때 메소드가 사용할 데이터입니다.

필요한 데이터를 제공하지 않으면 메소드는 일을 하지 않거나 에러를 발생

 

java에서 합계 구할 경우

매개변수는 list tuple set  => 가 가능하다.

sum을 구할 때 여러개 주기는 번거러워서 그래서 대표하는 것을 쓴다.

반복자 iterable

int ... =>int몇재줘도 괜찮아요

double  실수

string 문자

 

=>return type을 확인

작업을 수행하고 어떤 결과를 돌려주는지 확인

void는 안주는 것이다.다른것은 나한테 주는 것이다.

 

자료형을 먼저 배우는 이유가  매개변수와 , return 등을 배워야 한다.

매개변수를 만들 줄 알아야 메소드를 사용할 수 있기 때문이다.

tupledict를 잘 봐야 한다.

list tuple 수정할 수 있는지 않는지

분석의 결과는 tuple로 주는게 낳다.

list는 번호

dict는 이름으로 =>java에서는 map이다.

cconstructor

 

 

cpu빨라서 느린 것과 싱크 맞추기 업렵다.

 

키보드 입력

파일 출력(쓰기)

네트워크 출력(쓰기)

싱크를 맞추기 위해서는 모아서 해야 하기 때문에 버퍼를 만들었다.

 

프린터도 같은 기능이다. 버퍼크기

버퍼(임시기억 장치)

속도빠른 것과 늦은 것이 일 할때 임시기억 장치에 모아놓고 flush되면 작업한다.

버퍼 내용을 비워서 CPU가는 것 flush라고 한다.

nextInt (정수 부분만 읽기)

nextLine(enter까지 읽는 것)

 

nextInt  버퍼에서 정수부분만 cpu에 읽는 것

정수 입력 받다. nextInt()

문자열 입력 nextLine()

키보드 입력

=>123 enter

=>안녕 enter

 

123      nextInt()

enter   nextLine()

안녕     nextLine()

 

 

nextLine() enter만날때 까지 한다.그래서 안녕이 아닌 enter만 가져갈 경우가 높다.

nextLine() -> 안녕 가져온다.

이것 해결 방법

1). nextLine()한번 더 써주면 된다.(java)

2). nextInt()입력 끝나고 비우고 다시수행 버퍼 비울수 있는 언어는 c언어 밖에 없다.

운영체제가 c90%이기때문에 cfflush()를 입력하면 된다. 이러면 정수 ,enter눌리는 것을 해결할 수 있다.enter밖에 입력안되는 경우를 해결가능하다.

javajvm바꿔서 전달하기 때문에 java는 운영체제 명령어를 호출 할 수 없다.

 

 

채팅할 경우

버퍼에 내용을 써 놓다가 한번에 보이는 것이 낫다.

write, print기는은 보내는 명령이 아니고 버퍼에 기록하는 명령어이다.

chatting->print는 출력이 아니고 버퍼에 기록한다.

버퍼에 내용 쓰주세요 -> flusn() ->다른 분 한테 보여주게 하는 것

채팅 잘되는 것은 프로그램 종료하면 버퍼의 내용에 쓰준다. 프로그램 종료됨녀서 버퍼의 내용을 비워준다.

: 이사짐

B에서 WRITE,PRINT하는 것은 이사가 아니여서 FLUSH를 해줘야 A까지 가서 끝난다.

상대방에 기록이 안되고 메세지가 안넘어가면 FLUSH하면 된다.FLUSH안해줘서 그렇기 때문이다.

 

=

 

 

 

cpu ram사이에 메인보드로 연결한다.

메인보드로 연결하는 것은 연결하는 것이만 속도차이가 있어서 이 문제를 해결한다.

 

 

 

GOOGLE ANALYTICS

이상탐지

거래패턴

데이터를 가지고 있어야 하고 패턴을 가져고 있어야 한다.

 

 

 

 

nextInt()

nextLine()

이렇게 될경우만

sc.nextLine()

만해주면 된다.

 

 

프로그램 끝다 크면 내용이 없어진다. 변수처리 이기 때문이다.

데이터가 없을경우

 

 

현재 게시글이 없습니다.

 

 

 

 

**package &import

1.package

=>관련있는 클래스의 모임

=>파일 시스템에서는 하나의 디렉토리

=>package가 배포 단위

=>클래스는 실행은 가능하지만 배포를 할 수 없습니ㅏㄷ.

=>자바에서는 클래스들을 다른 프로젝트에서 사용하도록 배포하고자 할 떄는 클래스들을 패키지로 묶어서 jar로 압축해서 전달하면 됩니다.

기본적으로 패키지 단위로 가능하다.

 

 

2.자바의 클래스 로드

=>자바는 실행되는 프로그램에 존재하는 모든 클래스들을 jvm(java virtual machine)에 로드하고 실행

=>자바에서는 존재하는 모든 클래스를 별도의 작업없이 바로 사용이 가능

=>사용을 할 때는 클래스의 전체 경로를 입력해야 합니다.

패키지이름.클래스의 형태로 사용해야 합니다.

 

 

3.import

=>import는 가져오는 개념이 아니고 줄여쓰기 위한 개념입니다.

=>클래스를 만들기 전 상단 부분에 import를 해주면 패키지이름을 생략하고 클래스를 사용할 수 있습니다.

1)패키지이름.*

=>패키지에 존재하는 모든 클래스들을 패키지 이름을 생략하고 사용가능

 

2)패키지이름.클래스이름

=>클래스이름에 해당하는 클래스만 패키지 이름을 생략하고 사용가능

 

3)ex

Scanner의 원래 이름은 java.util.Scanner

java.util.Scanner sc = new java.util.Scanner(System.in);

 

=>위처럼 작성하면 너무 길어서 import하고 사용

import java.util.Scanner;

Scanner sc = new Scanner(System.in);

 

=>Eclipse에서는 클래스 이름만 사용한 경우 클래스 이름에 커서를 갖다대면 import해주겠다는 매시지가 보여고 이름 클릭하면 자동으로 import구문이 입력됩니다.

 

주의 할 점이 2가지가 있다.

import java.util.Scanner;

import는 가져오는 개념이 아니다.

 

4)import할 때 주의 할 점

=>클래스를 찾을 때 자바는 현재 프로젝트에서 찾고 없으면 다른 패키지에서 찾습니다.

제공되는 클래스와 동일한 이름의 클래스를 만들면 제공되는 클래스를 사용할 때는 패키지이름을 전부 입력해서 사용해야 합니다.

제공되는 클래스와 동일한 이름의 클래스를 만들지 않는 것이 좋습니다.

 

=>서로 다른 패키지에 동일한 이름의 클래스가 존재한는 경우가 있는데 프로젝트 내에서 2개의 클래스를 모두 사용할 때는 하나는 패키지이름을 전부 입력하는 것이 좋습니다.

java.util.Datejava.sql.Date의 경우 모두 사용하는 경우에 하나는 전체 경로를 입력하는 것이 좋습니다.

 

5)java application을 개발 할 때 import하지 않아도 java.lang패키지는 이미 import가 되어 있어서 클래스 이름만 사용하면 됩니다.

 

c#은 자바가 바로 된다. unity c #

.net

c# ->visual c#(microsoft windows에 돌아가게끔)

c++visual c++

병원 c#, visual c# ->window 테블릿

 

 

c ,python, javascript

python는 파일 단위로 실행

python 모듈

pytho는 다양한 방식으로 import가 가능하다.

a.py --------->파일 단위로 동작한다.

b.py파일을 사용하려면 import b이다.

그러면 b.py를 메모리에 올라간다.

그럼 c.pyb.py import하지 않아도 사용가능하다.

하지만 a.py가 실행해야 한다.

a.py 실행하지 않으면 c.py가 사용불가하다.

pythonimport하면 메도리에  존재된다.

cjavascriptimport include

소스를 포함하는 개념 내 파일에 저장한다.

a.c  #inlcude b.c 하면 b.c에 있는 코드가 a.c에 복사된다.

a.c에서 b.c사용가능하다.

여러번하면 안된다. 에러난다. 이름이 똑 같은것 생기기 깨문이다. 중복명명은 안된다.

c.c에서는 사용불가 하다. 메모리가 아니라 코드이기 때문에

python에서는 여러번 import가능하다.

 

java

jvm

 

 

 

 

 

 

 

클래스를 만들면 jvm에 들어간다. 만들어지면 아무것이나 쓸수 있다. 메모리 적재하고 include필요없다.

그냥 쓰려면 이름이 길다.java.util.Scanner

import java.util.* 이렇게 하면 사용하기 편하다.

자바에서는 import안해도 되는데 패키지이름을 다 적어야 한다.

c, python 는 필요할 때 메모리에 적재한ㄷ.(느리다.)

java는 다 올리고 해서 서버에 좋다. (빨리한다.)

      요청할때 빨리 처리한다 . 그래서 은행 등에서 많이사용한다.

프로그램언어는 상호 보완적인 것이다.

필요할때 메모리에 적재하면  ->client

javascript 믄법 안엔느 다른 서버용으로 만든다.

은행은 java , c#올려놓고 해야 한다.

visual c# -> java c#보다 기능이 안될 수도 있다.

c#   java -> scala, kotlin , .....

 

 

상속(Inheritance):

class Tank{

           //필요한 속성이나 메소드를 만들었다.

           private int offence;

           private int deffence;

           ..........

           public void siz(){

                      

           }

}

 

class Marin{

           private int power;

           private int health;//체력

           ..........

public void shot(){
}

}

 

이 두가지는 공통된 속성이 있다.

방어력 관련 수정하고 싶을 때 이름이 다르고 하면 하나하나씩 수정해야 한다.

유사한 기능은 이름을 같게 한다. 맘데로 만들지 말고

healthdeffence로 바꾸고 등 해야 하기 때문에

똑 같은 것을 상속이 가능하면

class Unit{

           protected int power;

           protected int health;

}

 

class Tank extends Unit{

           public void siz(){

                      

           }

}

class Marin extends Unit {

public void shot(){
}

}

Unit에서 바꾸면된다.

Unit상위 클래스

Tank, Marin은 하위 class이다.

절대로 부모와 자식을 하면 안된다.왜냐하면 Tank, Marin을 먼저 만들고 Unit을 만든다.

하위클래스가 상위클래스의 모든 것을 물려받는다.

프로그램에서는 :

 

 

 

 

 

 

 

 

 

상위 클래스 파악해서 제공하는 것이  Framework(필요한것 만 먼저 제공하는 것이다.)

microsoft V ->Framework이다

c# 프로그램언어

visual c# window개발할 때 편하게 할려고 하는 것이다.-> framework

java spring

engine 자주 사용하는 것 미리 만들어서 제공

 

나한테 상위 클래스를 몇개 준것이다.

 

 

 

 

 

 

 

 

 

 

 

프레임워크로 하면 가져와서 쉽게 쉽게 사용할 수 있다.

자바를 못해도 자바웹프로그래밍을 할 수 있다.

웹프로그래밍은 한번 가공한 것이다.

자바언어 ->쓰기 편리하게 가공한 것이 프래임웨크나 라이브러리 이다.

 

 

상속(Inheritance)과 구현(Implement)은 구분해야 한다.

클래스는 상속 (편하게 하기 위해서 )

인터페이스는 구현 - 프로토콜

interface는 메뉴판이라고 생각하면 된다.

모형만 보고 있는 지 없는지 판단하는 것이 interface라고 한다.

 

 

공격성공률(); head파일

 

공격성공률() {내용}.c =>구현 만들어주는 과정이 구현이다. interface

자바는 다중상속을 지원하지 않는다.

 

 

**상속(Inheritance)

1.개념

=>하위 클래스가 상위 클래스의 모든 것을 물려받는 것

=>물려받는 클래스를 하위(Sub) 클래스라고 하는데 다른 용어로는 Derived(파생 클래스)클래스라고도 하고 물려주는 클래스를 상위(Super)클래스라고 하는데 다른 용어로는 Based(기반 클래스) 클래스라고도 합니다.

 

=>자주 사용하는 상위 클래스들을 파악해서 프로그램을 만들기 쉽게 제공해주는 것을 프레임워크 또는 젠인이라고 부릅니다.

 

원도우 용 프로그램 개발 프레임워크로 가장 유명한 것인 VC#,VC++(MFC)

Java개발 프레임워크로 유명한 것은 Spring

 

2.상속을 이용했을 때의 장점

=>코드를 간결하게 만들수 있기 때문에 유지보수가 편리해집니다.(upgare편리하다.)

 

=>재사용이 증가

 

3.단점

=>상위 클래스의 내용을 변경하면 하위 클래스도 영향을 받게됩니다.

하위 클래스는 상위 클래스에 종속됩니다.

 

 

4.상속을 관계로 표현할 떄는 is a관계라고 합니다.

 

5.java는 단일 상속만 지원합니다.

java의 모든 클래스는 하나의 클래스로부터만 상속을 받을 수 있습니다.

 

6.java의 모든 클래스는 java.lang.Object라는 클래스로부터 상속을 받습니다.

 

7.java에서 상속 방법

class 클래스이름 extends 상위클래스이름{

 

}

 

8.접근지정자와 상속

private: 상속은 되지만 하위 클래스에서 접근할 수 없음(사용 불가)

default(package):동일한 패키지내에서는 하위 클래스에서 상위 클래스의 멤버를 사용할 수 있고 서로 다른 패키지에서는 사용이 불가능

protected:하위 클래스에서 사용가능

public: 하위 클래스에서 사용 가능하고 인스턴스도 사용 가능

 

 

 

9.상속과 접근 지정자

1)상위 클래스로 사용할 Based클래스

 

public class Based {

          

          

           private int num;

                       String title;//접근 지정자를 설정하니 않는 것을 default 또는 package

           protected String content;

           public int readCnt;

          

}

 

2).Based 클래스로 부터 상속받은 Derived 클래스

//Based 클래스를 상속받은 Derived클래스

public class Derived extends Based {

 

}

           public void disp() {

                       //num = 10;//num private 멤버라서 보이지 않는다고 에러메시지

                       //protected로 변경할 것인지 물어봅니다.

                      

                       title = "";

                       content ="내용";

                       readCnt = 0;

                      

           }

num은 빨간색이다. private

readCnt 는 녹색이다. public

 

=>상속을 받을 때는 클래스를 만들 때 super class에 입력해도 되고 클래스를 만든 후 직접 extends상위 클래스 이름을 입력해도 됩니다.

 

 

10.super

1)인스턴스 메소드에서의 super

=>인스턴스 메소드 안에서 어떤 이름을 사용하면 메소드 안에서 먼저 찾고 없으면 메소드 외부에서 찾으면 그래도 없으면 상위 클래스에서 이름을 찾습니다.

상위 클래스에도 없으면 undefined 되었다고 에러메시지 출력

 

=>메소드 안에서 찾지 않고 메소드 외부에서 부터 찾고자 할 때는 this.을 앞에 붙이면 됩니다.

this가 붙으면 메소드 안에서는 찾지 않고 메소드 외부의 클래스에서 먼저 찾고 없으면 상위 클래스에서 찾습니다.

 

=>this.대신에 super.을 붙이면 자신의 클래스에서도 찾지 않고 상위 클래스에서만 찾습니다.

 

=>this를 사용해야만 하는 경우는 메소드 내에 만든 변수와 클래스에 만들어진 변수 이름이 같을 때 클래스에 만들어진 변수를 사용할 때 이용

super는 현재 클래스와 상위 클래스에 동일한 이름의 메소드가 있을 때 상위 클래스의 메소드를 호출하기 위해서 사용합니다.

 

 

실습

=>Based클래스에 print()메소드를 생성

           public void print() {

                       System.out.println("상위 클래스의 print");

           }

 

=> Derived 클래스에 print()메소드를 생성

           public void print() {

                       System.out.println("하위 클래스의 print");

           }

          

           public void method() {

                       print();//앞에 아무것도 붙지 않았기 때문에 자신의 클래스에서부터 찾아 갑니다.

                       //자신의 클래스에 만든 print()

                      System.out.println("=======================");

                      

                       super.print();//상위 클래스에서 print()를 찾습니다.

                       //Based에 만든   print()

           }

 

=>main메소드를 소유한 실행 클래스를 만들어서 Derived 클래스의 method()호출

이것을 호출할려면 메인이나 테스트가 있어야 한다.

public class Main {

 

           public static void main(String[] args) {

                       //Derived 클래스의 method()를 호출

                      

                       //Derived인스턴스를 생성

                       Derived d = new Derived();

                       //메소드 호출 -void

                       //void가 아니면 저장하면 된다.

                       d.method();

 

           }

 

}

상위것 호출하고 싶으면 super. 사용하면 된다.

첫번째 super는 인스턴스 앞에서 쓰는 것이고

 

2)생성자에서의 super()

=>생성자에 첫번째 줄은 작성을 하지 않더라도 무조건 super()입니다.

상위 클래스의 매개변수가 없는 생성자를 호출하는 구문입니다.

 

=>Based클래스를 상속받은 Derived클래스에 생성자를 만들지 않더라도 아래와 같은 생성자가 존재

public Derived(){

           super();//이 구문은 new Based();와 동일한 구문

}

 

=>Based에 생성자를 만들고 super()를 호출하지 않으면 자동으로 super()가 삽입됩니다.

 

=>상속을 받으면 상위 클래스의 모든 멤버를 상속받아서 생성해야 합니다.

상위 클래스의 멤버를 생성할려면 상위 클래스의 생성자를 호출해야 합니다.

코드 상 호출하지 않더라도 무조건 해야 하기 때문에 자바에서는 자동으로 삽입해줍니다.

 

=>상위 클래스에 매개변수가 없는 생성자(default constructor)가 없으면 하위 클래스에 생성자를 만들어서 상위클래스의 생성자를 직접 호출해야 합니다.

생성자 만들지 않으면 상위 클래스를 안 만들었다.

Based가 우리 것 아니면 손을 못데기 때문에 하위 클래스에서 해결해야 한다.

           //상위 클래스에 default constructor가 없는 경우에는 생성자를 만들고  super를 이용해서

           //상위 클래스의 생성자를 호출해야 합니다.

           //중요한 문제이다.

           //프레임워크를 사용하면 상위 클래스를 우리가 수정할 수 없기 때문에

           //하위 클래스에서 해결을 해야 합니다.

           //이런식의 코드가 Andriod Studio 에서 많이 사용됩니다.

           //Andriod Studio(Andriod Native App개발을 위한 JAVA FRAMEWORK)에서 많이 사용됩니다.

           public Derived() {

                       //new Based(10) 과 동일한 코드

                       super(10);

           }

 

 

 

11.polymorphism(다형성)

1)method overriding(메소드 재정의)

=>사위 클래스에 존재하는 메소드를 하위 클래스에서 다시 만드는 것

=>메소드 이름이 같고 매개변수의 개수와 자료형이 같은 메소드를 다시 만드는 것

=>매개변수의 개수나 자료형이 다르면 method overloading(메소드 중복정의)

=>하는 이유는 자신이 만든 클래스의 경우는 다형성 구현을 위해서 이고 프레임워크가 제공하는 클래스가 상위 클래스인 경우는 기능확장을 위해서 입니다.

Based.java

           public void print() {

                       System.out.println("상위 클래스의 print");

           }

 

public class Derived extends Based {

           //상위 클래스에 print()가 존재하는데 하위 클래스에서 다시 만드는 것을 Method Overriding이라고 합니다.

           public void print() {

                       System.out.println("하위 클래스의 print");

           }

}

 

2)프레임워크가 제공하는 클래스를 상속받아서 사용하는 경우

=>프레임워크가 제공하는 클래스는 기본 기능만 제고하기 때문에 기본 기능을 확장하기 위해서 상속을 받아서 사용

=>기본 기능을 확장할 때 메소드 오버라이딩을 사용하는데 이 때 상위 클래스의 메소드를 호출을 해주어야 합니다.

Button클래스를 제공

-Button을 누르면 동작하는 click이라는 메소드를 제공

 

 

Button을 상속받는 ButtonEx라는 클래스를 생성

-버튼을 누르면 동작하는 메소드:click

 

public void method(){

           super.method()

           //추가하고자 하는 기능

}

 

=>상위 클래스의 메소드 호출 시점은 정리를 하는 메소드를 제외하고는 상위 클래스의 메소드를 먼저 호출해야 합니다.

정리하는 메소드는 상위 클래스의 메소드를 나중에 호출합니다.

=>andriod studio같은 경우에는 자신이 제공하는 클래스를 상속받아서 메소드를 호벌이딩 할 때 상위 클래스의 메소드를 호출하지 않으면 에러 발생하고 vc++같은 곳에서는 메소드 오버라이딩 할 떄 상위 클래스 메소드 호출하는 구문이 자동 삽입됩니다.

andoid super.method() 이것 안하면 오류 나고

mfc같은 경우에는 자동으로 만들어진다.

 

항상 하위 클래스는 상위 클래스의 것을 가지고 한다.

 

 

 

 

 

 

 

 

 

상위에 하는 것이다. 상위에 해야 한다. super()

상위를 만들고

소멸, 정리를 할 때는 하위 정리하고 상위 정리한다.

 

3)@override

@이 붙는 것은 자바에서는 annotation이라고 하고 python에서는 decorator라고 합니다.

어노테이션은 자주 사용하는 (반복적으로) 자바 코드를 매번 작성하는 것이 번거롭기 떄문에 이 어노테이션을 추가하면 자바가 컴파일을 할 때 자동으로 코드를 삽입해주는 것입니다.

python에서 static 메소드 작성하고 싶으면 @static메소드

               class 메소드 작성하고 싶으면 @class메소드

 

@Override는 이 메소드가 오버라이딩 된 메소드를 라는 것을 알려주기 위한 어노테이션

이 어노테이션을 붙였는데 이 메소드가 상위 클래스에 없으면 에러가 발생합니다.

 

 

 

 

 

프로그램의 가독성을 높이기 이해서 오버라이딩 한 경우에는 붙여주는 것이 좋습니다.

 

           //상위 클래스에 print()가 존재하는데 하위 클래스에서 다시 만드는 것을 Method Overriding이라고 합니다.

           @Override//이 메소드가 오버라이딩 된 메소드라는 것을 알아볼 수 있습니다.

           public void print() {

                       System.out.println("하위 클래스의 print");

           }

          

           public void method() {

                       print();//앞에 아무것도 붙지 않았기 때문에 자신의 클래스에서부터 찾아 갑니다.

                       //자신의 클래스에 만든 print()

                      System.out.println("=======================");

                      

                       super.print();//상위 클래스에서 print()를 찾습니다.

                       //Based에 만든   print()

           }

 

4)객체 지향 언어에서의 참조형 상이의 대입

=>cjava와 같은 정적 자료형 언어들은 변수를 선언할 때 사용한 자료형의 데이터만 변수에 대입할 수 있습니다.

 

int a =10;

//a에는 정수만 대입이 가능합니다.

 

=>참조형 에서는 한가지 예외가 있습니다.

상위 클래스 타입으로 만들어진 변수에 하위 클래스 타입의 인스턴스 첨조를 대입할 수 있습니다.

 

하위 클래스 타입으로 만들어진 변수에 상위 클래스 타입의 인스턴스 참조는 대입할 수 없는데 강제 형변환을 하면 대입이 되고 문법적인 에러는 없습니다.

원래의 자료형이 하위 클래스 타입이 아니면 실행할 때 예외가 발생합니다.

 

 

Based, Based를 상속받은 Derived가 존재

Based obj = new Based();//클래스 이름과 생성자 이름이 같았다.

//Based로 만든 변수에 Based 인스턴스를 대입 - 에러 없음

Derived ins = new Derived();//에러 없음

 

 

Based o = new Derived();//생성자이름 DerivedBased로 부터 상속을 받았기 때문에 가능

Derived d = new Based();//이 문장은 에러 BasedDerived의 하이 클래스가 아니어서 에러

위의 구조가 성립하기 위해서 강제 형 변환은 가능하다.

 

Derived d = (Derived)(new Based()); //강제 형 변환을 해서 에러는 아님 - 실행시 에러

이것은 new Based()으로 하는 것이다.

소나타를 사고 그래즈로 포장하는 것이다.

Derived d = (Derived)(o); //강제 형 번환을 해서 에러는 아님 - 실행 시 에러 아님

o Based로 만들은 것이고 DerivedBased=> new Derived()

그랜즈를 살려고 했는데 원래 그랜즈 였는데 포장을 소나타로 바꿨다.

 

객체 지향언어는 상속을 많이 사용한다.

 

 

Backgroud Colour

화면에 보여주는 것 같은 모든  GUI프로그램에서

addSubView(Button)

addSubView(Text)

50개 있으면 메소드 50개 만들어야 합니다.

보여주기 기능이기 때문에 아래것으로 바꾸면됩니다.

addSubView(View) ->Button, TextView

보여주기여쏘 특수한 기능이 필요없다.

 

 

c는 클래스의 개념이 없다.

객체 지향은 공통 된것은 상속받아서 사용한다.상속받아서 기능을 추가한다.

대표하는 것은 형변환을 안해도 가질 수 있다.

변수 -> instance

Based ->

derived ->그랜즈

 

 

5)참조형 변수의 멤버 호출

=>참조형 변수는 변수를 선언할 때 사용한 자료형의 멤버만 호출이 가능합니다.

Based o = new Derived();

oBased에 존재 하는 것만 호출할 수 있습니다.

Based에 없고 Derived에 만 존재하는 것은 호출할 수 없습니다.

 

=>예외적으로 overriding된 메소드는 인스턴스 만들 때 사용한 생성자의 것을 호출합니다.

o가 오버라이딩 된 메소드를 호출할 떄는 Based의 것이 호출되는 것이 아니고 Derived의 것이 호출됩니다.

 

Derivedprint()@override이다.@override있어도 없어도 결과는 같다.

 

6)overmorphism(다형성)

=>동일한 메시지에 대하여 다르게 반응하는 성질

=>동일한 코드가 대입된 인스턴스에 따라 다른 메소드를 호출하는 것(마우스의 클릭)

최악의 상황 클래스 이름이 다르는 것 할 수 없지만 공격을 만들기 위해서는 아래 3개 알아야 한다.

1).

 

class Z{

           public void 공격(){

                       System.out.println("저그의 공격");

           }

}

 

 2).

 

class T{

           public void attack(){

                       System.out.println("테란의 공격");

           }

}

 3).

 

class P{

           public void offence(){

                       System.out.println("프로세스의  공격");

           }

}

 

 

메인 공격함수 호출

 

class Main{

           public static void main(String[] args){

                       Z z = new Z();

                       z.공격();

                       T t = new T();

                       t.attack();

                       p p = new P();

                       p.offence();

           }

}

 

 

 

3개를 전부 attack으로 바꾼다.

1).

 

class Z{

           public void attack(){

                       System.out.println("저그의 공격");

           }

}

 

 

2).

 

class T{

           public void attack(){

                       System.out.println("테란의 공격");

           }

}

 

 

3).

 

class P{

           public void attack(){

                       System.out.println("프로세스의  공격");

           }

}

 

 

메인 공격함수 호출 아직은 다행성이 아니다.

 

class Main{

           public static void main(String[] args){

                       Z z = new Z();

                       z.attack ();

                       T t = new T();

                       t.attack ();

                       p p = new P();

                       p.attack ();

           }

}

 

 

하위는 상위에 담을 수 있다.

 

class Star{

}

 

1).

 

class Z extends Star{

           public void attack(){

                       System.out.println("저그의 공격");

           }

}

 

2).

 

class T extends Star {

           public void attack(){

                       System.out.println("테란의 공격");

           }

}

 

 

3).

 

class P extends Star {

           public void attack(){

                       System.out.println("프로세스의  공격");

           }

}

 

 

메인 공격함수

 

class Main{

           public static void main(String[] args){

                       Star s = new Z();

                       s.attack ();->여기가 에러난다.

                       s= new T();

                       s.attack ();->여기가 에러난다.

                       s= new P();

                       s.attack (); ->여기가 에러난다.

           }

}

 

 

3개의 attack()을 호출하기 위해서 s.attack ();

 

class Star{

           public void attack(){

          

           }

}

 

 

아래것으로 하면 각자 자기의 것만 호출한다. override의 기능

 

class Main{

           public static void main(String[] args){

                       Star s = new Z();

                       s.attack (); //Zerg

                       s= new T();

                       s.attack ();//Teran

                       s= new P()

                       s.attack (); //Protoss

           }

}

 

 

모든 단축키는 하나만 눌어면 된다.

Unit u = new Tank();

u.attack() -> Tank attack을 부른다.

 

star, attack()필요는 없지만 깔끔하게 하기 위해서 이다.

블록이 있는데 내용이 필요 없을 때

 

class Star{

           public void attack(){

           //block이 있을 경우 내용을 입력할 수 도 있다

           }`

}

 

 

 

내용이 필요없을 때 abstract로 하면 된다.

 

abstract class Star{

           public abstract void attack();

           // abstract있으면 내용이 필요없다.

}

 

 

class abstract Star =>인스턴스를 못 만든다. new Star()할 필요없다.

상속을 해서 쓰는 것 abstract class

c## virtual 이라고 부른다.

 

예전에는 게임을 c로 했지만 객체 지향이 없어서 요즘에는 사용하지 않는다.

 

12. 다형성 구현 실습

1).다향성과 상관없이 Terran,Zerg, Protoss의 공격 메소드를 생성하고 Mian에서 실행하는 코드를 작성하고 실행

 

=> Terran클래스를 생성하고 attack 메소드를 구현

public class Terran {

           //테란의 공격 메소드

           public void attack() {

                       System.out.println("탱크로 대포를 쏘고 마린으로 총을 쏩니다.");

           }

}

 

=>Protoss클래스 생성하고 attack메소드를 구현

public class Protoss {

           //프로토스 공격 메소드

           public void attack() {

                       System.out.println("칠럿은 찌르고 드래군은 공을 던집니다.");

           }

}

 

=> Zerg 클래스 생성하고 attack메소드를 구현

public class Zerg {

           //저그의 공격 메소드

           public void attack() {

                       System.out.println("저글링은 떼리고 히드라는 침을 뱉습니다.");

           }

}

 

=> Main 메소드를 소유한 실행 크래스를 만들고 3개 클래스의 Attak을 호출하는 코드를 작성

public class Main {

 

           public static void main(String[] args) {

                       Terran t = new Terran();

                       t.attack();

                      

                       Protoss p = new Protoss();

                       p.attack();

                      

                       Zerg z = new Zerg();

                       z.attack();

 

           }

 

}

 

2)위까지 실행하면 3개의 메소드를 호출할 수 있습니다.

지금은 3개 클래스의 인스턴스를 가지고 메소드를 호출하기 위해서 3개의 변수에 각각의 인스턴슬르 대입해서 메소드를 호출햇습니다.

 

메소드를 호출하는 코드가 다릅니다.

인턴페이스에 메소드를 연결할려고 하면 3개의 명령어가 필요합니다.

 

하나의 명령어로 3개 메소드를 모두 호출할 수 있도록 하기 위해서 동일한 코드가 3개의 메소드를 호출할 수 있도록 변경

 

=>Terran, Zerg, Protoss를 클래스의 인스턴스를 모두 저장할 수 있는 변수를 만들기 위해서 3개 클래스에 상속할 상위 클래스를 생성하고 메소드를 오버라이딩 할 수 있도록 attack을 구현

 

public class Starcraft {

                       //하위 클래스의 인스턴스가 attack을 호출할 수 있도록 오버라이딩을 위한 메소드

           public void attack() {

                      

           }

 

}

=>Terran, Zerg, Protoss클래스에 Starcraft클래스를 상속하도록 클래스 선언문 수정

public class Terran extends Starcraft

 

public class Zerg extends Starcraft

 

 

public class Protoss extends Starcraft

 

 

 

=>main 메소드 수정

public class Main {

 

           public static void main(String[] args) {

                       Starcraft s = new Terran();

                       s.attack();

                      

                       s = new Protoss();

                       s.attack();

                      

                       s = new Zerg();

                       s.attack();

 

           }

 

}

 

대입받는 문장은 에러가 안나는데 attack받는 문장은 에러가 난다.

 

andriod 스마트폰 등은 메뉴가 거의 없다.

그래서 스마트폰 은 설명이 먼저 있다.

GUI

DOS는 명령어 하나가 한가지 일 밖에 안한다.

다향성 때문에 여라가지 기능이 있다.그래서 기능이 다를 수 있다.

다향성 설정에서 언어가 바꾼다고 해서 명령은 바꾸지 않는다. 똑같은 인터페이스 일을 한다.

프로그램을 쓰기 쉽게 사용하기 위해서이다.

인터페이스는 표준어 만드는 것이다.

 

 

반응형

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

java-8  (0) 2020.09.28
java-7  (0) 2020.09.27
java-5  (0) 2020.09.24
java-4  (0) 2020.09.22
java-3  (0) 2020.09.20

+ Recent posts