즐겁게!! 자신있게!! 살아보세!!

재밌는 인생을 위하여! 영촤!

Language_Study/JAVA

[JAVA, App] 13.Framework

Godwony 2020. 12. 25. 11:17
반응형

List

  • 데이터를 순서대로 저장하는 자료구조
  • 자료구조에서는 배열을 Dense List 라고 하기도 합니다.

1.ArrayList(Vector 는 ArrayList의 Legacy 버전)

  • 데이터를 물리적으로 연속해서 저장하는 List
  • 크기 변경이 가능
  • 제너릭이 구현(인스턴스를 만들 때 데이터 1개의 자료형을 확정을 해야 합니다.)
  • 인스턴스를 만들 때 자료형을 확정하지 않으면 경고가 발생하고 데이터를 가져올 때 Object 타입으로 리턴되서 사용을 하고자 하면 강제 형 변환을 해야 합니다.
  • Linked List 에 비해서 메모리 낭비가 적고 접근 속도가 빠릅니다.
  • Linked List 에 비해서 데이터를 중간에 삽입하거나 삭제하는 경우 속도가 느립니다.
    • Linked List는 논리적으로 연속해서 데이터를 저장
  • 주요 메소드로는 boolean add(E e), E get(int index), int size(), E remove(int index), void sort(Comparator<E>) 등이 있습니다.

2.LinkedList

  • 데이터를 논리적으로(다음 데이터의 참조를 기억) 연속해서 저장하는 List
  • 사용하는 모든 메소드가 ArrayList 와 같은데 동작 방식이 다름

3.ArrayList 와 LinkedList의 작업 속도 측정

    public static void main(String[] args) {
        //10 과 30을 갖는 ArrayList 생성
        ArrayList<Integer> al = new ArrayList<>();

        //데이터 삽입
        al.add(10);
        al.add(30);
        //현재 시간 저장
        long start = System.currentTimeMillis();

        //20이라는 데이터를 10만번 2번째 칸에 삽입
        for(int i=0; i<100000; i=i+1) {
            al.add(1, 20);
        }

        //현재 시간 저장
        long end = System.currentTimeMillis();
        System.out.println("al:" + (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=i+1) {
            li.add(1, 20);
        }

        //현재 시간 저장
        end = System.currentTimeMillis();
        System.out.println("li:" + (end-start));

        //현재 시간 저장
        start = System.currentTimeMillis();

        //모든 데이터 읽어서 출력
        for(int i=0; i<li.size(); i=i+1) {
            System.out.println(li.get(i));
        }

        //현재 시간 저장
        end = System.currentTimeMillis();
        System.out.println("li:" + (end-start));

    }

4.Vector

  • ArrayList 가 만들어지기 전에 ArrayList와 동일한 용도로 사용하던 자료구조인데 데이터를 수정하거나 삭제할 때 다른 스레드가 사용 중인지 확인하고 작업을 수행하던 클래스
  • java에서 Vector 클래스는 최근에는 거의 사용을 하지 않기 때문에 중요하지 않을 수 있는데 c++ 하던 분들이 ArrayList 라고 하지 않고 Vector라고 합니다.

5.Stack

  • LIFO(Last In First Out)
  • 마지막에 삽입된 데이터가 가장 먼저 출력되는 자료구조 클래스
  • 데이터를 삽입하는 동작을 push 라고 하고 마지막 데이터를 꺼내는 동작을 pop 이라고 합니다.
  • 실제 사용된 곳은 메소드를 호출할 때 메소드가 저장하는 자신의 데이터 영역을 Stack으로 만들고 스마트 폰 등에서 화면 저장도 Stack을 사용합니다.
  • 삽입은 E push(E e), 삭제는 E pop(), 삭제하지 않고 마지막 데이터를 가져오는 E peek()
  • 제너릭이 적용되어 있어서 인스턴스를 만들 때 저장할 요소의 자료형을 설정해야 합니다.
    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를 이용합니다.
    public static void main(String[] args) {
        //우선 순위 큐: 데이터를 크기 순서대로 접근할 수 있도록 만든 큐
        //내부적으로 데이터가 정렬된 것이 아니고 정렬된 순서대로 접근할 수 있는 이진 트리를 생성
        PriorityQueue<String> pq = 
                new PriorityQueue<>();
        pq.add("서울");
        pq.add("런던");
        pq.add("크라이스처치");
        pq.add("블라디보스톡");
        pq.add("불산");
        //빠른 열거를 이용해서 데이터를 1개씩 꺼내와서 출력
        //트리의 순회를 이용하지 않기 때문에 데이터가 정렬된 순서가 아닐 수 있음
        for(String city : pq) {
            System.out.print(city + "\t");
        }
        System.out.print("\n");
        //지우면서 가져올 때는 데이터의 개수나 인덱스가 변할 수 있으므로 주의 
        int len = pq.size();
        //데이터를 poll을 이용해서 1개씩 가져와서 출력
        //트리의 순회를 이용하기 때문에 데이터가 정렬된 순서대로 출력
        for(int i=0; i<len; i=i+1) {
            System.out.print(pq.poll() + "\t");
        }
    }

7.Deque

  • 양쪽에서 삽입과 삭제가 가능한 자료구조
  • 자바에서는 인터페이스 형태로 제공
  • ArrayDeque 라는 클래스가 Deque 인터페이스를 implements
  • Deque를 구현한 경우는 ScrollView 계열이 전부 Deque를 이용합니다.
  • 삽입하거나 꺼내는 메소드 이름들에 First 와 Last 가 붙습니다.
ArrayDeque <String> deque = new ArrayDeque<>();
//데이터를 앞에서 저장
deque.addFirst("한국");
//데이터를 뒤에 저장
deque.addLast("미국");
deque.addLast("중국");
deque.addFirst("뉴질랜드");
  • 저장 순서는 뉴질랜드 -> 한국 -> 미국 -> 중국
String nation = deque.pollFirst(); //뉴질랜드
nation = deque.pollLast(); //중국

8.사용자 정의 클래스의 List 정렬

  • 사용자 정의 클래스의 List 가 테이블 구조
    public static void main(String[] args) {
        //매개변수가 없는 생성자를 이용한 인스턴스 생성 및 필드 값 설정
        Player player1 = new Player();
        player1.setNum(1);
        player1.setName("백인천");
        player1.setHitrate(0.412);

        //매개변수가 있는 생성자를 이용한 인스턴스 생성 및 필드 값 설정
        Player player2 = new Player(2, "이종범", 0.393);
        Player player3 = new Player(3, "장효조", 0.387);
        Player player4 = new Player(4, "테임즈", 0.381);
        Player player5 = new Player(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 클래스의 인스턴스 비교 인스턴스 : 타율의 오름차순
        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 static void main(String[] args) {
        //Set 인스턴스 생성 - HashSet, LinkedHashSet, TreeSet 으로 변경하면서 확인
        Set<Integer> set = new TreeSet<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);
        }
    }

4.1-45 사이의 숫자를 6개 입력받아서 오름차순 정렬해서 출력

  • 데이터 6개는 하나의 이름으로 저장
  • 동일한 데이터는 입력받지 않아야 합니다.
  • 데이터는 오름차순 정렬
  • 데이터 6개를 하나의 이름으로 저장할 수 있는 자료구조: 배열, ArrayList, LinkedList, Stack, PriorityQueue, ArrayDeque, HashSet, LinkedHashSet, TreeSet

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, 실제데이터의 자료형>();

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 static void main(String[] args) {
        //Map 인스턴스 생성
        HashMap<String, Object> map = 
            new HashMap<String, Object>();
        //데이터 저장
        map.put("baseball", "야구");
        map.put("soccer", "축구");
        map.put("volleyball", "배구");

        //데이터 가져오기 - 출력만 할 때는 강제 형 변환이 필요없지만 다른 용도로 사용할 때는 강제 형 변환을 해서 가져옵니다.
        String obj = (String)map.get("soccer");
        System.out.println(obj.toUpperCase());
        //없는 key의 값 가져오기 - 언어마다 다르므로 확인
        Object value = map.get("basketball");
        System.out.println(value);

        //동일한 key에 데이터를 삽입하면 업데이트
        map.put("soccer", "발로 하는 축구");
        obj = (String)map.get("soccer");
        System.out.println(obj.toUpperCase());

        //Map의 모든 데이터를 출력 - key의 이름을 사용하지 않음
        System.out.println("=============================");
        //모든 key의 값을 가져오기
        Set<String> keys = map.keySet();
        //Set을 순회
        for(String key : keys) {
            System.out.println(key + ":" + map.get(key));
        }        
    }

5.Class 와 Map을 이용한 저장의 차이

    public static void main(String[] args) {
        //번호, 이름, 타율을 저장하는 Player 클래스의 인스턴스를 만들어서 데이터를 저장
        Player player = new Player(1, "이종범", 0.393);

        //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);

        //DTO 클래스의 인스턴스는 각각의 데이터를 하나씩 출력해야 한다면 메소드를 일일이 호출: 반복문 사용 불가
        System.out.println(player.getNum());
        System.out.println(player.getName());
        System.out.println(player.getHitrate());

        //Map의 인스턴스는 keySet()을 이용해서 반복문으로 출력 가능
        //모든 Map은 아래 구문으로 전체 데이터를 출력할 수 있습니다.
        Set<String> keys = map.keySet();
        for(String key:keys) {
            System.out.println(key + ":" + map.get(key));
        }
    }

6.List의 List(Matrix - numpy) 와 Map의 List(DataFrame - pandas)

    public static void main(String[] args) {
        //각 팀별 선수명단
        ArrayList<String> kia = new ArrayList<String>();
        kia.add("최형우");
        kia.add("김주찬");
        kia.add("김선빈");

        ArrayList<String> dusan = new ArrayList<String>();
        dusan.add("권혁");
        dusan.add("정수빈");
        dusan.add("최주환");

        ArrayList<String> hanhwa = new ArrayList<String>();
        hanhwa.add("김태균");
        hanhwa.add("이성열");

        //팀별 명단을 다시 List로 만들기
        ArrayList<ArrayList<String>> players = 
                new ArrayList<ArrayList<String>>();
        players.add(kia);
        players.add(dusan);
        //팀이 추가되는 경우 팀 이름을 출력하기 위해서 출력하는 로직을 수정
        players.add(hanhwa);

        //데이터 출력하기
        //전체 리스트를 하나 하나의 리스트로 imsi에 대입

        for(int i=0; i<players.size(); i=i+1) {
            if(i == 0) {
                System.out.print("기아:");
            }else {
                System.out.print("두산:");
            }

            ArrayList<String> imsi = players.get(i);
            //imsi 의 데이터를 하나씩 temp에 대입
            for(String temp : imsi) {
                System.out.print(temp + "\t");
            }
            System.out.print("\n");
        }

        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.print("\n");
        }
    }

7.데이터 저장

1) 하나의 행은 Map 이나 DTO 클래스를 이용

  • Map이나 DTO 클래스는 서로 다른 자료형의 데이터를 묶어서 저장이 가능합니다.
  • List 나 배열은 동일한 종류의 데이터를 묶어줍니다.
  • List 나 배열로는 특성이 다른 데이터를 묶을 수 없습니다.

2) 하나의 열을 만들 때 List 나 배열을 사용

  • 열 방향의 데이터는 일반적으로 동일한 자료형으로 구성되기 때문입니다.

MVC(Model - View - Controller) 패턴

  • 애플리케이션을 구현할 때 역할 별로 분리해서 구현하도록 하는 패턴
  • 애플리케이션을 역할 별로 잘 구별해서 분리하지 않으면 어느 하나의 변경이 다른 하나의 변경에 영향을 미치게 됩니다.
    • 유지보수가 어려워집니다.
  • Model에 변화가 생기더라도 View를 변경하지 않아도 되도록 구현하라는 패턴
반응형

'Language_Study > JAVA' 카테고리의 다른 글

[JAVA, App] 15.MutualExclusion  (0) 2020.12.27
[JAVA, App] 14.기본API클래스  (0) 2020.12.27
[JAVA, App] 12.Interface  (0) 2020.12.25
[JAVA, App] 11.Package  (0) 2020.12.25
[JAVA, App] 10.예외처리  (0) 2020.12.25