상세 컨텐츠

본문 제목

자바스터디 Day-8

Java

by 일동일동 2022. 10. 28. 09:00

본문

728x90
반응형

1. 제네릭(Generic)
클래스나 메소드에서 사용할 데이터의 타입을 컴파일시에 미리 지정하는 방법

제너릭을 사용하는 이유
- 다양한 타입의 재사용을 높일수 있음
- 클래스에서 사용할 타입의 외부관심도가
- 반복적인 코드, 불필요한 코드를 사용하지 않도록 함
- 강제적인 형변환을 발생시키지 않음


✔ Object 클래스
- 자바의 모든 클래스의 최상위 조상 클래스
- 모든 타입은 Object 클래스 객체화 시킬 수 있음
- 기본 데이터 타입을 객체화 시킨 래퍼타입으로 대입 받을 수 있음

public class Box2<T> {
    private T num1;
    private T num2;
    public T sum(T num1 T num2){
        return num1 + num2;
    }
}
------
Box2<Integer> box = new Box2();
box1.sum(10, 20);
Box2<Double> box2 = new Box2();
box2.sum(10.5, 20.5);
----->

public class Box2<Integer> {
    private Integer num1;
    private Integer num2;
    public Integer sum(Integer num1 Integer num2){
        return num1 + num2;
    }
}

<T>: Type
<E> : Element
<K> : Key
<V> : Value
<N> : Number


2. 컬렉션 프레임워크(Collection Framework)
- 여러가지 데이터를 메모리에 쉽고 효과적으로 처리할 수 있도록 제공하는 클래스들의 집합

자료구조
- 데이터를 효율적으로 관리할 수 있는 데이터 구조를 의미
- 데이터의 특성에 따라 체계적으로 구조화 함

알고리즘
- 어떤 문제를 풀기 위한 절차 및 방법
- 어떤 문제에 대해 입력을 넣으면 원하는 출력을 얻을 수 있도록 만드는 프로그래밍

List 인터페이스
순서가 있는 데이터들의 집합으로 데이터의 중복을 허용
Vector, ArrayList, Queue, Stack, LinkedList

Vector 클래스
- 동적인 길이로 여러 데이터형을 저장하기 위해 사용
- 자바 1.0부터 존재하는 레거시 클래스
- 배열과 동일하게 정수 인덱스를 이용하여 엑세스를 할 수 있음
- 동기화되어 있으며 한번에 하나의 스레드만 벡터의 메소도를 호출할 수 있음

import java.util.Vector;

public class Vector1 {
    public static void main(String[] args) {
        Vector<String> vector = new Vector<>();
        System.out.println("벡터 데이터의 길이: " + vector.size());
        System.out.println("벡터의 크기: " + vector.capacity());
        
        vector.addElement("김사과");
        vector.addElement("오렌지");
        vector.addElement("반하나");
        vector.addElement("이메론");
        vector.addElement("백애리");
        vector.addElement("채리");
        vector.addElement("김사과");
        vector.addElement("반하나");
        vector.addElement("배애리");

        System.out.println("벡터 데이터의 길이: " + vector.size());
        System.out.println("벡터의 크기: " + vector.capacity());

        vector.addElement("배애리");
        vector.addElement("반하나");

        System.out.println("벡터 데이터의 길이: " + vector.size());
        System.out.println("벡터의 크기: " + vector.capacity());

        System.out.println("벡터의 첫번째 요소: " + vector.elementAt(0));

        vector.remove(2);

        System.out.println("벡터 데이터의 길이: " + vector.size());
        System.out.println("벡터의 크기: " + vector.capacity());

        for(int i=0; i<vector.size(); i++){
            System.out.println(vector.get(i) + " ");
        }

        System.out.println();

        vector.removeAllElements();

        System.out.println("벡터 데이터의 길이: " + vector.size());
        System.out.println("벡터의 크기: " + vector.capacity());

    }
}

//벡터 데이터의 길이: 0
//벡터의 크기: 10
//벡터 데이터의 길이: 9
//벡터의 크기: 10
//벡터 데이터의 길이: 11
//벡터의 크기: 20
//벡터의 첫번째 요소: 김사과
//벡터 데이터의 길이: 10
//벡터의 크기: 20
//김사과 
//오렌지 
//이메론 
//백애리 
//채리 
//김사과 
//반하나 
//배애리 
//배애리 
//반하나 
//
//벡터 데이터의 길이: 0
//벡터의 크기: 20


ArrayList 클래스
- 동적인 길이로 여러 데이터형을 저장하기 위해 사용
- 배열과 동일하게 정수 인덱스를 이용하여 엑세스를 할 수 있음
- 비동기식을 사용하며 멀티 스레드를 지원(벡터와 차이점)

import java.util.ArrayList;
import java.util.Iterator;

public class ArrayList1 {
    public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<>();

        arrayList.add(80);
        arrayList.add(95);
        arrayList.add(65);
        arrayList.add(100);
        arrayList.add(90);
        arrayList.add(55);

        System.out.println(arrayList);          //리스트 나열
        System.out.println(arrayList.size());   //사이즈 출력

        for(int i=0; i<arrayList.size();i++){
            System.out.print(arrayList.get(i) + " ");
        }
        System.out.println();

        arrayList.remove(2);            // 리스트 2번째값 삭제
        System.out.println(arrayList);

        arrayList.set(4, 85);               // 리스트 값 변경 ( 자리수, 변경값)
        System.out.println(arrayList);

        Iterator<Integer> iterator = arrayList.iterator();
        while(iterator.hasNext()){
            System.out.print(iterator.next()+ " ");
        }

    }
}
//[80, 95, 65, 100, 90, 55]
//6
//80 95 65 100 90 55 
//[80, 95, 100, 90, 55]
//[80, 95, 100, 90, 85]
//80 95 100 90 85 
//Process finished with exit code 0


🎁 Iterator 인터페이스
컬렉션 프레임워크 인터페이스에서는 Iterator 인터페이스를 구현한 클래스의 인스턴스를 반환하는
iterator() 메소드를 정의하여 각 요소에 접근하도록 설계
- 자바의 컬렉션에 저장되어 있는 요소들을 읽어오는 방법
- 컬렉션으로부터 정보를 얻어내는 방법

Iterator의 장단점
장점: 컬렉션 프레임워크 종류에 관계없이 일관성있게 프로그래밍을 할 수 있음
단점: size 메소드를 얻어와서 반복처리하는 것보다 속도가 좋지 못함

✔ 동기식
프로그램을 차례(순서)대로 처리
✔ 비동기식
여러개의 프로그램을 동시에 처리, 시간이 오래걸리면 다음 문장으로 이동 후 동작하는 방식

Queue 클래스
- FIFO (First in first Out)
- 큐의 한쪽끝을 프론트로 정하여 삭제 연산만 수행함
- 다른 한쪽끝을 리어로 정하여 삽입 연산만 수행함
- 푸시메세지, 운영체젤의 스케줄러

import java.util.LinkedList;
import java.util.Queue;

public class Queue1 {
    public static void main(String[] args) {
        Queue<Integer> queue = new LinkedList<>();
        queue.offer(10);
        queue.offer(50);
        queue.offer(80);
        queue.offer(20);
        queue.offer(70);
        System.out.println(queue);
        System.out.println(queue.peek());       // 첫번째 데이터를 반환
        System.out.println(queue);
        System.out.println(queue.poll());       // 첫번째 데이터를 반환, 삭제
        System.out.println(queue);
        queue.clear();
        System.out.println(queue);
    }
}

//[10, 50, 80, 20, 70]
//        10
//        [10, 50, 80, 20, 70]
//        10
//        [50, 80, 20, 70]
//        []
//
//        Process finished with exit code 0


Stack 클래스
- LIFO(Last Input First Out)
- 한쪽 끝에서만 자료를 넣고 뺄 수 있는 형식의 자료구조
- 브라우저의 뒤로가기 앞으로가기

import java.util.Stack;

public class Stack1 {
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        stack.push(40);
        stack.push(100);
        stack.push(80);
        stack.push(70);
        stack.push(60);
        stack.push(20);
        System.out.println(stack);
        System.out.print(stack.peek());     // 마지막에 들어온 데이터를 리턴
        System.out.println(stack);
        System.out.println(stack.pop());
        System.out.println(stack);
    }
}


//[40, 100, 80, 70, 60, 20]
//20[40, 100, 80, 70, 60, 20]
//20
//[40, 100, 80, 70, 60]


LinkedList 클래스
- 각 노드가 데이터와 포인터를 가지고 한 줄로 연결되어 있는 방식
- ArrayList에 비해 데이터의 추가나 삭제가 빠름
- 인덱스가 없기 때문에 특정 요소에 접근이 느림
- 탐색속도가 떨어짐

import java.util.LinkedList;

public class Linkedlist1 {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("김사과");
        linkedList.add("반하나");
        linkedList.add("오렌지");
        linkedList.add("이메론");
        linkedList.add("채애리");
        System.out.println(linkedList);
        System.out.println(linkedList.peek());  // 첫 데이터를 반환
        System.out.println(linkedList);
        System.out.println(linkedList.poll());  // 첫 데이터를 반환,삭제
        System.out.println(linkedList);
        linkedList.remove("오렌지");
        System.out.println(linkedList);
    }
}

//[김사과, 반하나, 오렌지, 이메론, 채애리]
//김사과
//[김사과, 반하나, 오렌지, 이메론, 채애리]
//김사과
//[반하나, 오렌지, 이메론, 채애리]
//[반하나, 이메론, 채애리]


Set 인터페이스
순서가 없는 데이터 집합으로 데이터의 중복을 허용하지 않음

HashSet 클래스
- 데이터를 중복해서 저장할 수 없음(중복은 자동으로 제거)
- 저장 순서가 유지되지 않음
- 정렬을 하지 않음
- 하나의 null값을 저장할 수 있음

import java.util.HashSet;
import java.util.Iterator;

public class HashSet1 {
    public static void main(String[] args) {
        HashSet<String> hashSet = new HashSet<>();

        hashSet.add("김사과");
        hashSet.add("반하나");
        hashSet.add("오렌지");
        hashSet.add("이메론");
        hashSet.add("채애리");
        System.out.println(hashSet);        // 순서정렬 x
        hashSet.add("김사과");
        hashSet.add("이메론");
        hashSet.add("배애리");
        System.out.println(hashSet);

        for(String s: hashSet){
            System.out.print(s + " ");
        }
        System.out.println();

        Iterator<String> iterator = hashSet.iterator();
        while(iterator.hasNext()){
            System.out.print(iterator.next()+" ");
        }
        System.out.println();
    }
}

//[반하나, 이메론, 김사과, 오렌지, 채애리]
//[반하나, 이메론, 김사과, 오렌지, 채애리, 배애리]
//반하나 이메론 김사과 오렌지 채애리 배애리 
//반하나 이메론 김사과 오렌지 채애리 배애리 



TreeSet 클래스
- 데이터를 중복해서 저장할 수 없음(중복은 자동으로 제거)
- 저장 순서가 유지되지 않음
- 오름차순으로 정렬
- 하나의 null값을 저장할 수 있음
- 이진 탐색 트리 구조로 이루어져 있음

import java.util.TreeSet;

public class TreeSet1 {
    public static void main(String[] args) {
        TreeSet<Integer> treeSet = new TreeSet<>();
        treeSet.add(10);
        treeSet.add(8);
        treeSet.add(20);
        treeSet.add(35);
        treeSet.add(21);
        treeSet.add(4);
        System.out.println(treeSet);
        treeSet.add(35);
        treeSet.add(40);
        System.out.println(treeSet);
        treeSet.remove(20);
        System.out.println(treeSet);

        System.out.println(treeSet.size());
        System.out.println(treeSet.first());
        System.out.println(treeSet.last());
        System.out.println(treeSet.higher(8));
        System.out.println(treeSet.lower(21));

        for(int i: treeSet){
            System.out.print(i + " ");
        }
    }
}

//[4, 8, 10, 20, 21, 35]
//[4, 8, 10, 20, 21, 35, 40]
//[4, 8, 10, 21, 35, 40]
//6
//4
//40
//10
//10
//4 8 10 21 35 40


✔이진 탐색 트리
추가, 삭제에는 시간이 걸리지만 정렬, 검색에 높은 성능을 자랑하는 자료구조

Map 인터페이스
키와 값을 한 쌍으로 이루어지는 데이터의 집합으로 순서가 없고, 키는 중복으로 허용하지 않지만 값은 중복을 허용
HashMap, TreeMap, HashTable

HashMap 클래스
- Map 인터페이스를 구현한 대표적인 클래스
- 키와 값으로 구성된 요소객체를 저장하는 구조를 가지고 있는 자료구조
- 키는 중복될 수 없고, 값은 중복될 수 있음
- 기존의 저장된 키와 동일한 키로 값을 저장하면 기존의 값은 없어지고 새로운 값으로 대체
- 해싱(Hashing)을 사용하기 때문에 많은 양의 데이터를 검색하는데 뛰어난 성능
- 비동기식

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class HashMap1 {
    public static void main(String[] args) {
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("apple", "김사과");
        hashMap.put("orange", "오렌지");
        hashMap.put("banana","반하나");
        hashMap.put("melon", "메엘론");
        hashMap.put("cherry", "채애리");
        hashMap.put("berry", "배애리");       //내부에 키를 이용해서 값을 찾는 용도 ex) hashMap.get("orange") > 오렌지

        System.out.println(hashMap);
        System.out.println(hashMap.get("orange"));

        System.out.println(hashMap.keySet());   // 키 값을 찾아줌

        for(String k: hashMap.keySet()){
            System.out.println("key:"+k+", value:"+hashMap.get(k));
        }

        System.out.println(hashMap.entrySet());

        for(Map.Entry<String, String> entry : hashMap.entrySet()){
            System.out.println("key:"+entry.getKey()+", value:"+entry.getValue());      // key, value 값 한쌍 받기
        }

        System.out.println("======================================");
        Iterator<String> keys = hashMap.keySet().iterator();
        while (keys.hasNext()){
            String key = keys.next();   //~~.next(); 현재값을 반환하고 키를 넘김
            System.out.println("key: "+key+", value:"+hashMap.get(key));
        }

    }
}


//{orange=오렌지, banana=반하나, apple=김사과, cherry=채애리, berry=배애리, melon=메엘론}
//오렌지
//[orange, banana, apple, cherry, berry, melon]
//key:orange, value:오렌지
//key:banana, value:반하나
//key:apple, value:김사과
//key:cherry, value:채애리
//key:berry, value:배애리
//key:melon, value:메엘론
//[orange=오렌지, banana=반하나, apple=김사과, cherry=채애리, berry=배애리, melon=메엘론]
//key:orange, value:오렌지
//key:banana, value:반하나
//key:apple, value:김사과
//key:cherry, value:채애리
//key:berry, value:배애리
//key:melon, value:메엘론
//======================================
//key: orange, value:오렌지
//key: banana, value:반하나
//key: apple, value:김사과
//key: cherry, value:채애리
//key: berry, value:배애리
//key: melon, value:메엘론


TreeMap 클래스
- 이진트리를 기반으로 한 Map 컬렉션
- TreeSet과의 차이점은 TreeSet은 값만 저장하는 구조라면 TreeMap은 키와 값이 저장된 key, value를 저장
- 키는 오름차순으로 정렬됨(숫자:값, 문자열:유니코드)
- HashMap보다 성능이 떨어짐(데이터를 저장할 때, 삭제할 때)
- 검색이 필요한 경우 효율성면이 좋음

HashTable 클래스
- 키와 값을 1:1 형태로 저장
- 키는 값을 식별하기 위한 고유한 키, 값은 키가 가진 값
- 동기화
- HashMap에서는 값을 null이 입력이 가능하지만 HashTable에서는 null입력이 불가능

과제.
학생 관리 프로그램을 만들어보자.

메뉴
1. 학생입력     ----> 학번, 이름, 나이, 연락처
2. 학생리스트   ----> 학번으로 오름차순
3. 학생검색
4. 학생삭제
5. 종료

 

Main Class

import java.util.ArrayList;
import java.util.Scanner;

public class VocaMain {
    public static void main(String[] args) {
        System.out.println("😎 [영어 단어장] 😎");
        System.out.println("print: 지금까지 등록한 영단어가 출력");
        System.out.println("find: 영어 단어를 검색할 수 있음");
        System.out.println("exit: 프로그램을 종료");

        Scanner sc = new Scanner(System.in);

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

        while(true){
            System.out.println("✔ 영어단어 또는 메뉴를 입력하세요");
            String eng = sc.next();
            if(eng.equals("exit")) break;

            switch (eng){
                case "print":
                    for(int i=0; i<list.size(); i++){
                        System.out.println(list.get(i));
//                        System.out.println(list.get(i).getEnglish()+"/"+list.get(i).getKorean());
                    }
                    break;
                case "find":
                    System.out.println("🥰찾는 단어를 입력하세요");
                    String find = sc.next();
                    boolean isFind = false;
                    for(int i=0; i<list.size(); i++){
                        if(list.get(i).getEnglish().equals(find)){      // find -> equals (객체비교, Object 객체이기때문에) // == 는 연산자 비교
                            System.out.println("단어를 찾았습니다! 🥰");
                            System.out.println(list.get(i));
                            isFind = true;
                        }
                    }
                    if(!isFind) System.out.println("찾는 단어가 없습니다! 😗😗");
                    break;


                default:
                    System.out.println("* 뜻을 입력하세요: ");
                    String kor = sc.next();
                    System.out.println("* 레벨을 입력하세요: ");
                    int lev = sc.nextInt();
                    System.out.println("* 날짜를 입력하세요: ");
                    String wdate = sc.next();

                    Word w = new Word(eng, kor, lev, wdate);
                    list.add(w);
//                    System.out.println(list);
            }


        }
        System.out.println("프로그램을 종료합니다");
    }
}


 

public class Word {
    private String english;
    private String korean;
    private int level;
    private String wdate;

    public Word(String english, String korean, int level, String wdate) {
        this.english = english;
        this.korean = korean;
        this.level = level;
        this.wdate = wdate;
    }

    public String getEnglish() {
        return english;
    }

    public void setEnglish(String english) {
        this.english = english;
    }

    public String getKorean() {
        return korean;
    }

    public void setKorean(String korean) {
        this.korean = korean;
    }

    public int getLevel() {
        return level;
    }

    public void setLevel(int level) {
        this.level = level;
    }

    public String getWdate() {
        return wdate;
    }

    public void setWdate(String wdate) {
        this.wdate = wdate;
    }

    @Override
    public String toString() {
        // apple: 사과 (레벨1, 날짜 2022-10-05)
        return english + " : " + korean + " (레벨" + level + ", 날짜 " + wdate + ")";
    }
}

//constructor , getter setter , override > return값
반응형

'Java' 카테고리의 다른 글

자바스터디 Day-10  (0) 2022.10.30
자바스터디 Day-9  (0) 2022.10.29
자바스터디 Day-7  (0) 2022.10.27
자바스터디 Day-6  (0) 2022.10.26
자바스터디 Day-5  (0) 2022.10.25

관련글 더보기