2022.10.06 (목요일)

yeonicerely·2022년 10월 6일
0

1. Collection (map, list, set)

  • JDK 1.2부터 컬렉션 프레임 워크가 등장 -> 다양한 종류의 클래스가 추가
  • JDK 1.8부터 람다와 스트림에 의해 표준화가 이루어짐:

  • 컬렉션 프레임 워크에는 크게 3가지의 interface인 map, list, set가 있고, List와 Set의 공통된 부분을 뽑아서 새로운 인터페이스인 Collection을 추가함

A. List

: 순서가 있는 데이터의 집합으로 데이터의 중복을 허용함

예제) 리스트에 학생 이름 추가한 후 출력하기

import java.util.ArrayList;
import java.util.List;

public class ListExcercise {



    private List<String> students; //String을 원소로 가지는 List 선언

    public List<String> getStudents() {
        return this.students;
    } // list가 private 하므로 getter를 통해서 접근 가능

    public ListExcercise(){

        this.students = new ArrayList<>(); // List는 Arraylist임
        this.students.add("김경록");
        this.students.add("김미미");
        this.students.add("김나나");
    }
}
// ListExcercise의 main 클래스

import java.util.List;

public class ListExcerciseMain {

    public static void main(String[] args) {
        ListExcercise listExcercise = new ListExcercise();
        // 인스턴스 생성

        List<String> students = listExcercise.getStudents();
        // getter로 list에 접근
        
        for (String student: students){
            System.out.println(student);
        }
        System.out.println(students.size());
    }
}

B. Set

: 순서를 유지하지 않는(input 순서에 상관없이 원소가 자리함) 데이터의 집합으로 데이터의 중복을 허용하지 않음

1) 오브젝트의 중복은 허용함

  • new를 통해 각각의 인스턴스를 생성했을 때는 각자를 다르게 인식
    -> 주소 값이 달라서 set에서 다른 형태로 인식함
public void testAddObject() {
	Patient patient1 = new Patient("김영환", 33);
	Patient patient2 = new Patient("김영환", 33);
	Set<Patient> setPatient = new HashSet<>();
    setPatient.add(patient1); 
    setPatient.add(patient2);
	System.out.println(setPatient); 
    
    //[domain.Patient@7f31245a, domain.Patient@135fbaa4]

2) HashSet(HashMap) vs TreeSet(TreeMap)

A. 이진 탐색트리 저장(TreeSet)

  • Integer인 경우 부모 노드보다 작은 숫자는 왼쪽, 큰 숫자는 오른쪽으로 배열함

  • 트리의 깊이만큼의 시간이 걸림 -> 트리의 깊이가 얕을 수록 빠른 속도

  • 값이 잘 분산되어있다면 효율적이지만 값이 편향되어 있는 경우(ex. 0,1,2,4,5,6,7,8,9,101,102)는 비효율적임

  • 이를 보완하기 위해 TreeMap에서는 레드 블랙트리 방법이 도입됨

  • 참고: https://code-lab1.tistory.com/62

B. 해싱(Hashing)

  • key 값을 hash function에 넣어서 암호화 -> 암호화된 index의 순서대로 저장함



예제1) 랜덤한 숫자 생성한 후 Set에 넣고 출력하기

// 인터페이스
public interface NumberGenerator11 {
    int generate(int num);
}
// 인터페이스를 상속한 generator class
public class RandomNumberGenerator11 implements NumberGenerator11{

    @Override
    public int generate (int num){
        return (int)(Math.random()*num); // 0이상 num 미만의 정수 생성

    }
}
// Main 클래스
import java.util.HashSet;
import java.util.Set;

public class RandomNumberWithoutDuplicated {
    public static void main(String[] args) {

        RandomNumberGenerator11 randomNumberGenerator11 = new RandomNumberGenerator11();

        // Set에서는 중복제거를 할 수 있음
        Set<Integer> dupliOut = new HashSet<>();

        for (int i=0; i<50 ; i++){
            int r = randomNumberGenerator11.generate(10); // 0~9까지의 정수 생성
            System.out.println(r);
            dupliOut.add(r);
        }

        System.out.println(dupliOut);
        // [1,2,3,4,5,6,7,8,9]
        
    }
}



예제2) 랜덤한 알파벳 대문자 생성한 후 Set에 넣고 출력하기

// generator 클래스
public class RandomLetterGenerator{

    public char generate() {
        return (char)(int)(Math.random()*26+65);
        // 아스키코드 65~90 영어 대문자

    }
}
// main 클래스
import java.util.HashSet;
import java.util.Set;

public class RandomLetterWithoutDuplicated {
    public static void main(String[] args) {

        RandomLetterGenerator randomLetterGenerator = new RandomLetterGenerator();

        Set<Character> alphabetDupliOut = new HashSet<>();

        for (int i=0; i<50 ; i++){
            char alphabet = randomLetterGenerator.generate();
            alphabetDupliOut.add(alphabet);
        }

        System.out.println(alphabetDupliOut);

    }
}


C. Map

: key-value 쌍으로 이루어진 데이터의 집합으로 순서는 유지되지 않음

- key는 중복을 허용하지만 value는 중복을 허용하지 않음 -> python의 dictionary 개념과 유사함

  • 대체로는 TreeMap보다는 HashMap이 빠르지만, Tree가 빠른 경우도 있다. -> 정렬을 해야하는 경우는 TreeMap이 더 유리
    • 데이터를 조회하면서 정렬해야하는 경우는 이미 정렬되어 있는 TreeMap에서 더 빠른 결과를 얻을 수 있다.
    • 데이터를 조회하면서 범위를 지정해야하는 경우는 TreeMap이 더 빠를 수 있다.
    • ...



예제) url에 있는 영어의 개수를 Map에 입력하기 - key에는 문자, value에는 숫자


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

public class MapExcercise2 {
    public static void main(String[] args) {

        String repoAddr = "https://github.com/seanee3670/CodeLion/tree/master/src";
        String repoAddrLower = repoAddr.toLowerCase(); // 소문자 변환

        Map<String, Integer> alphabetCnt = new HashMap<>();

        // 65~90 영어 대문자
        // 97~122 영어 소문자
        // map에 글자 먼저 넣기

        for (int i=0; i<26; i++){
            alphabetCnt.put(Character.toString((char)(i+97)),0);
        }


        // map의 key 값을 이용해서 알파벳 문자인지 확인하기
        for (int i=0; i<repoAddr.length();i++){
            String letter = String.valueOf(repoAddrLower.charAt(i));
            if (alphabetCnt.keySet().contains(letter)){
                alphabetCnt.put(letter,(alphabetCnt.get(letter) +1));
            }
        }

        System.out.println(alphabetCnt.get("b"));
        System.out.println(alphabetCnt.get("c"));
        System.out.println(alphabetCnt.get("r"));

    }
}

2. File 읽기


추가자료 출처
1. 자바의 정석
2. https://coding-factory.tistory.com/557

0개의 댓글