👩🏻‍💻 𝐋𝐚𝐧𝐠𝐮𝐚𝐠𝐞/⠀⠀⠀⠀ Jᴀᴠᴀ

2023/10/31 🤔 Collections Framework & ArrayList

유리쯔의일상 2023. 11. 1. 00:50
반응형

 

👇 공부한 자료들의 실제 소스파일들을 기록해논 공간입니다 👇

 

 

 

Collections Framework

 

자바 컬렉션 프레임워크(Java Collections Framework)는 자바에서 데이터를 저장, 관리, 처리하기 위한 

데이터 구조 및 알고리즘을 제공하는 라이브러리이다.

표준화된 방법으로 데이터를 다루고 다양한 데이터 구조를 제공하여

개발자가 데이터 처리를 보다 효율적으로 수행할 수 있도록 도와준다

기존 배웠던 배열의 단점을 고민해 보자

배열의 단점
- 길이의 고정성
1. 자료의 저장 유동성이 없다
2. 메모리 낭비
3. 중간의 삽입시 인덱스 조정하는 코딩이 필요함
4. 잦은 예외 ; outoFBoundIndex ..  
5. 요소 접근 시 인덱스로 접근해야된다
6. 연속적으로 값을 저장한다.

 

배열을 좀 더 편하게 사용하자는 취지로 컬렉션 프레임 워크가 나오기 시작했다
자료구조 형식(특정한 구조를 정의한 것)의 자료형 = 컬렉션 프레임워크 
1. 길이가 유동적 : List (종류 : ArrayList, Vector, LinkedList)
2. 값에 의해서 저장 : Map (종류 : hashMap , TreeMap)

자주 쓰는 프레임 워크

1. ArrayList : 가장 자주 쓴다. 연속적으로 값을 할당한다 , 동기화 비보장
2. Vector : 연속적으로 값을 할당한다 , 동기화 보장 
3. LinkedList : 비연속적으로 값을 할당한다.

 

좀 더 상세하게 정리해 보자. 

 

종류 
1. 인터페이스 (Interfaces)
컬렉션 프레임워크의 핵심은 다양한 인터페이스로 정의된다

     - Collection: 모든 컬렉션 인터페이스의 상위 인터페이스로, 기본적인 메서드를 정의한다.
     - List : 순서가 있는 리스트를 나타내는 인터페이스로, 중복 요소를 허용한다.

        종류 : ArrayList, LinkedList, Vector
     - Set : 순서가 없는 집합을 나타내는 인터페이스로, 중복 요소를 허용하지 않습니다.

        종류 : HashSet, TreeSet
     - Map : 키-값(key-value) 쌍을 저장하는 맵을 나타내는 인터페이스로, 각 키는 유일해야 한다, 값은 중복 가능하다

        종류 : HashMap, TreeMap

2. 구현 클래스 (Implementations)
   - 각 인터페이스에 대한 구현 클래스가 제공된다.

      이러한 구현 클래스는 실제 데이터 구조를 나타내며 다양한 요구 사항에 따라 선택할 수 있다.

       예를 들어, ArrayList, LinkedList, HashSet, HashMap 등이 구현 클래스이다.

3. 제네릭스 (Generics)
   - 컬렉션 프레임워크는 제네릭스를 활용하여 타입 안전성을 제공한다

이로써 컬렉션에 저장되는 요소의 데이터 타입을 컴파일 시에 확인할 수 있다

4. 반복자 (Iterators)
   - 반복자는 컬렉션 내의 요소를 순회하고 접근하기 위한 인터페이스를 제공한다

Iterator 인터페이스와 foreach 루프를 활용하여 컬렉션 요소를 반복할 수 있다.

5. 알고리즘 (Algorithms)
   - 컬렉션 프레임워크는 검색, 정렬, 필터링 및 변환과 같은 다양한 데이터 처리 알고리즘을 제공하는데.

Collections 클래스는 컬렉션을 정렬하는 메서드를 제공한다

6. 동기화 (Synchronization)
   - 일부 구현 클래스는 멀티스레드 환경에서 안전하게 사용할 수 있도록 동기화된 버전도 제공한다.

이러한 클래스는 스레드 간의 안전한 동시 액세스를 보장하기도 하다.

동기화 보장 : Vector 

 


자바 컬렉션 프레임워크를 사용하면 다양한 데이터 구조를 효율적으로 활용하여 프로그램을 개발할 수 있으며, 

데이터 저장 및 처리에 필요한 다양한 도구와 메서드를 제공한다

이를 통해 코드를 더 간결하고 가독성 높게 작성할 수 있으며, 데이터 구조를 선택할 때 성능과 요구 사항을 고려할 수 있다.

 

 

 

 

 

ArrayList

가변 크기 배열이라고도 한다.

내부적으로 배열을 사용하여 요소를 저장한다.

그러나 크기가 가변적이므로 배열의 크기를 동적으로 조절할 수 있다

요소를 추가할 때 배열이 꽉 차면 더 큰 배열로 복사하고 이전 배열을 버리는 방식으로 크기를 조절한다

이것은 요소 추가 및 제거를 편리하게 할 수 있게 해 준다

제네릭 클래스로 정의되어 있어, 요소의 데이터 타입을 지정할 수 있다.

예를 들어, ArrayList <String>은 문자열을 저장하는 데 사용되며, ArrayList<Integer>은 정수를 저장하는데 사용된다.

이는 컴파일 시 타입 안전성을 제공하므로 데이터 타입에 대한 오류를 사전에 방지해 준다
요소를 추가할 때 add() 메서드를 사용하고 요소를 제거할 때 remove() 메서드를 사용한다.

또한, clear() 메서드를 사용하여 모든 요소를 제거할 수 있다.
요소에 접근할 때 인덱스를 사용한다.

인덱스는 0부터 시작하여 요소의 위치를 지정하고, 이로써 특정 위치의 요소에 빠르게 접근할 수 있다.

요소를 순회하기 위해 for-each 루프 또는 반복자(Iterator)를 사용할 수 있다

Iterator를 사용하면 요소를 안전하게 순회하고 수정할 수 있다.
ArrayList는 객체 참조를 저장합니다.

따라서 어떤 객체 타입이라도 저장할 수 있으며, 다양한 데이터 유형을 처리할 수 있다.

예를 들어, 문자열, 정수, 사용자 정의 객체 등을 저장할 수 있다

ArrayList는 스레드로부터 안전하지 않다.

멀티스레드 환경에서 안전하게 사용하려면 Collections.synchronizedList()를 사용하여 동기화된 버전을 생성할 수 있다.
성능 고려 시 ArrayList는 요소에 빠르게 접근할 수 있으며, 요소를 순회하거나 검색하는 데 효율적이다.

그러나 중간에 요소를 삽입 또는 제거하는 경우, 다른 요소를 밀거나 당기는 작업이 필요하므로 성능에 영향을 미칠 수 있다.

만약 중간 삽입/제거가 빈번한 작업이라면 LinkedList를 고려하는 게 좋을 수 있다.

중요 포인트

크기의 가변성과 배열과 유사한 동작을 제공하여 데이터의 저장과 관리를 간편하게 할 수 있으며,

제네릭 타입을 사용하여 타입 안전성을 보장한다.

 

 

 

제공 메서드

 





 

 

오늘의 과제

오늘 배운 ArrayList를 사용한 회원 관리 프로그램 만들기

 

package main;
import member.MemberADM;

public class Main {
    public static void main(String[] args) {
        // todo  : ArrayList 를 이용한 회원 관리 프로그램 만들기
        // 1. 고객등록 , 2. 삭제 , 3. 수정 , 4. 전체보기
        new MemberADM();
    }
}
package member;

// 멤버 인스턴스를 만들기 위한 정의
public class MemberDefine {
    private String id = null;
    private String pass = null;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public void setPass(String pass) {
        this.pass = pass;
    }

    public MemberDefine(){}

    public void prt(){
        System.out.println(" ID : " + id);
        System.out.println("PASS: " + pass);
    }
}
package member;

public class Functions {
    // 비밀번호 유효성 검사
    public boolean isPass(String pass){
        // 비밀번호는 5자리 이상 특수문자 "!@#$%^&*"  1개 이상 포함되어야한다
        String spe = "!@#$%^&*";
        int cnt = 0;
        for (int i = 0; i < pass.length(); i++) {
            for (int j = 0; j < spe.length(); j++) {
                if ( pass.charAt(i) == spe.charAt(j)) cnt++;
            }
        }
        if ( cnt >= 1 && pass.length() > 4) return true;
        return false;
    }

    // id 유효성검사
    // id 생성시 규칙은 5자리이상, 한글 불가 영어 대소문자 포함 가능 , 특수문자 1개 이상
    public boolean isId(String id) {
        String tmpId = id.toUpperCase();
        String spe = "!@#$%^&*";
        int cnt = 0;
        for (int i = 0; i < tmpId.length(); i++) {
            if ( tmpId.charAt(i) >= 65 || tmpId.charAt(i) <= 90 ) {
                for (int j = 0; j < spe.length(); j++) {
                    if ( id.charAt(i) == spe.charAt(j)) cnt++;
                }
            }
        }
        if ( cnt >= 1 && id.length() > 4) return true;
        return false;
    }
}
package member;

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

public class MemberADM {
    private Scanner in = new Scanner(System.in);
    private ArrayList<MemberDefine> memberList = new ArrayList<>();
    private Functions fn = new Functions();

    public MemberADM() {
        boolean flag = true;
        while (flag) {
            info();
            int userNum = in.nextInt();
            in.nextLine();
            switch (userNum) {
                case 1: // 고객 등록
                    add();
                    break;
                case 2: // 고객 수정
                    mod();
                    break;
                case 3: // 고객 삭제
                    del();
                    break;
                case 4: // 전체 보기
                    totalView();
                    break;
                case 5:
                    System.out.println("프로그램 종료");
                    flag = false;
                    break;
                default:
                    System.out.println("사용 불가한 메뉴번호 입니다 다시 입력하세요");
            }
        }
    }

    // 회원 등록
    private void add() {
        System.out.println("회원 등록 입니다.");
        MemberDefine m = new MemberDefine();
        while(true) {
            System.out.println("아이디 규칙\n5글자 이상 , 한글 불가 , 영 대소문자 가능 , 숫자 불가 , 특수문자 [ ! @ # $ % ^ & * ] 1개 이상 포함 필수");
            String id = title("아이디");
            if (searchId(id) >= 0) {
                System.out.println("이미 등록된 아이디 입니다.");
            } else if (searchId(id) < 0 && !(fn.isId(id))) {
                System.out.println("아이디 생성규칙을 다시 확인하세요");
            } else {
                m.setId(id);
                System.out.println("비밀번호 규칙\n5글자 이상 , 특수문자 [ ! @ # $ % ^ & * ] 1개 이상 포함 필수");
                String pass = title("패스워드");
                if (fn.isPass(pass)) {
                    m.setPass(pass);
                    System.out.println(id + " 회원 가입 완료.");
                    memberList.add(m);
                    break;
                } else System.out.println("패스워드 생성규칙을 다시 확인하세요");
            }
        }
    }

    // 회원 수정
    private void mod() {
        System.out.println("회원 수정 입니다.");
        String id = title("조회 할 아이디");
        int memberIdx = searchId(id);
        if (memberIdx >= 0) {
            MemberDefine m = memberList.get(memberIdx);
            m.setPass(title("비밀번호"));
        } else System.out.println("입력된 아이디는 찾을 수 없습니다.");
    }


    // 회원 삭제
    private void del() {
        System.out.println("회원 삭제 입니다.");
        String id = title("아이디");
        int delIdxNum = searchId(id);
        if (delIdxNum >= 0) {
            System.out.println(id + " 삭제 완료");
            memberList.remove(delIdxNum);
        } else System.out.println("입력한 아이디는 찾을 수 없습니다");
    }


    // 회원 전체보기
    private void totalView() {
        for (MemberDefine m : memberList) {
            m.prt();
        }
    }

    // 기능 메서드 : 입력 후 리턴
    private String title(String text) {
        System.out.print(text + " 를 입력하세요 >> ");
        String title = in.nextLine();
        return title;
    }


    // 기능 메서드 : 특정 Id를 찾아 해당 인덱스 번호를 리턴
    private int searchId(String id) {
        for (int i = 0; i < memberList.size(); i++) {
            if (memberList.get(i).getId().equals(id)) return i;
        }
        return -1;
    }

    private void info() {
        System.out.println("회원관리 메인메뉴");
        System.out.println("1. 회원등록");
        System.out.println("2. 회원수정");
        System.out.println("3. 회원삭제");
        System.out.println("4. 회원전체보기");
        System.out.println("5. 종료");
        System.out.print(" 메뉴 번호 입력  >> ");
    }
}

 

 

 

 

 

반응형