TIL 22.11.16 / 자바_컬렉션

쓰옹·2022년 11월 16일
0

개발자를 향해~~TIL✍

목록 보기
15/87

자바


컬렉션(Collection)

: 자바에서 자료구조를 표현하는 인터페이스
: 모든 자료구조가 구현(implement)하는 인터페이스

자료구조

  1. List : 순서가 있는 데이터 집합. 데이터 중복 허용
    → ArrayList, LinkedList, Stack 등

  2. Set : 순서가 유지되지 않는 데이터 집합. 데이터 중복 허용X
    → HashSet, TreeSet 등

  3. Map : 키(key)와 값(value)의 쌍으로 이루어진 데이터의 집합. 순서 유지 안됨.
    - 키는 중복 허용X, 값은 중복 허용
    - 파이썬의 딕셔너리와 같음
    → HashMap, TreeMap 등

  4. Stack : 마지막에 넣은 데이터를 먼저 꺼내는 자료구조. LIFO(Last In First Out)
    → Stack, ArrayDeque 등

  5. Queue : 먼저 넣은 데이터를 먼저 꺼내는 자료구조. FIFO(First In First Out)
    → Queue, ArrayDeque 등

List

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

public class Main {
    public static void main(String[] args) {
        List<Integer> integerList = new ArrayList<>();
        integerList.add(1);   //넣기
        integerList.add(5);
        integerList.add(4);
        integerList.add(20);
        integerList.add(11);

        System.out.println(integerList);  //[1, 5, 4, 20, 11]

        Collections.sort(integerList);    // 오름차순 정렬
        System.out.println(integerList);  //[1, 4, 5, 11, 20]
        System.out.println(integerList.size());  //크기  5

        integerList.remove(4);   //제거
        System.out.println(integerList);  //[1, 4, 5, 11]

        for(int i = 0; i < integerList.size(); i++){
            System.out.println(integerList.get(i));   //get(인덱스자리)
        }
        for(int current: integerList){     //리스트 원소 하나씩 꺼내서 current에 할당해줌
            System.out.println(current);   // 1
                                                          // 4
                                                         //  5
                                                         // 11
        }
    }
}

Set

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Set<Integer> integerSet = new HashSet<>();  //Set은 인터페이스, HashSet은 클래스
        integerSet.add(1);
        integerSet.add(1);
        integerSet.add(3);
        integerSet.add(2);
        integerSet.add(9);
        integerSet.add(8);
        System.out.println(integerSet); //[1, 2, 3, 8, 9] 내가 넣어준 순서랑 맞지 않음== 순서 없음

        Set<String> stringSet = new HashSet<>();
        stringSet.add("LA");
        stringSet.add("New York");
        stringSet.add("LasVagas");
        stringSet.add("San Francisco");
        stringSet.add("Seoul");
        System.out.println(stringSet);  //[San Francisco, New York, LA, Seoul, LasVagas]

        stringSet.remove("Seoul"); //인덱스가 없으니까 지정을 해줘야 함
        System.out.println(stringSet);  //[San Francisco, New York, LA, LasVagas]

        List<String> target = new ArrayList<>();
        target.add("New York");
        target.add("LasVagas");
        stringSet.removeAll(target);   //removeAll() 컬렉션타입을 넣어줘
        System.out.println(stringSet);  //[San Francisco, LA]

        //.contains() 포함되어있는지 boolean true / false 리턴 함수
        System.out.println(stringSet.contains("LA"));  //true
        System.out.println("Seoul 포함되어있나요? "+ stringSet.contains("Seoul"));  //Seoul 포함되어있나요? false

        System.out.println(stringSet.size());  //2
        stringSet.clear();  //.clear() 다 지우기
        System.out.println(stringSet);     //[]
    }
}

Map

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

public class Main {
    public static void main(String[] args) {
        Map<Integer, String> map = new HashMap<>();
        map.put(1, "apple");
        map.put(2, "berry");
        map.put(3, "cherry");

        System.out.println(map);  //{1=apple, 2=berry, 3=cherry}

        System.out.println("1st in map: " + map.get(0));  //1st in map: null
        //.get()은 맵에서 key를 받아서 value를 리턴한다
        System.out.println(map.get(1));  //apple

        map.remove(2);
        System.out.println(map);  //{1=apple, 3=cherry}
        System.out.println(map.containsKey(2));  //false
        System.out.println(map.containsValue("cherry"));  //true

        map.clear();
        System.out.println(map);   //{}
    }
}

Stack

import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        stack.push(1);
        stack.push(3);
        stack.push(7);
        stack.push(5);
        System.out.println(stack);  //[1, 3, 7, 5] 넣은 순서대로 출력

        System.out.println(stack.peek());             // 5 마지막 넣은 애 확인
        System.out.println("size: " + stack.size());  // size: 4
        System.out.println(stack.pop());              // 5 꺼내면서 리턴
        System.out.println("size: " + stack.size());  // size: 3

        System.out.println(stack.contains(1));  // true
        System.out.println(stack.empty());  //false
        stack.clear();
        System.out.println(stack.isEmpty());  // true
    }
}

Queue

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

public class Main {
    public static void main(String[] args) {
        Queue<Integer> queue = new LinkedList<>(); // 큐는 인터페이스이기 때문에 구현체가 필요함
        queue.add(1);
        queue.add(5);
        queue.add(3);
        System.out.println(queue);         //[1, 5, 3]
        System.out.println(queue.poll());  // 1 빼내면서 리턴
        System.out.println(queue);         //[5, 3]
        System.out.println(queue.peek());  // 5
        System.out.println(queue);         //[5, 3]
    }
}
  • 이 외에도 clear라던지 다 있음

ArrayDeque

  • 실무에서 많이 사용됨
  • 기본 Stack, Queue 기능 모두 포함
  • deque: 양쪽 끝에서 삽입, 삭제 가능
import java.util.ArrayDeque;

public class Main {
    public static void main(String[] args) {
        ArrayDeque<Integer> arrayDeque = new ArrayDeque<>();
        arrayDeque.addFirst(1);        // 큐의 앞자리에다 넣을거다
        arrayDeque.addFirst(2);        // 그냥 add로 하면 뒤로 들어감
        arrayDeque.addFirst(3);
        arrayDeque.addFirst(4);
        System.out.println(arrayDeque);   // [4, 3, 2, 1]

        arrayDeque.addLast(0);
        System.out.println(arrayDeque);   // [4, 3, 2, 1, 0]

        arrayDeque.offerFirst(10);     // 그냥 offer로 하면 뒤롤 들어감
        System.out.println(arrayDeque);   //[10, 4, 3, 2, 1, 0]
        arrayDeque.offerLast(-1);
        System.out.println(arrayDeque);   //[10, 4, 3, 2, 1, 0, -1]
        // 큐의 크기에 문제가 생길 때 .offer은 false / .add는 exception이 발생

        arrayDeque.push(22);  //스택에 있는 기능
        System.out.println(arrayDeque); //[22, 10, 4, 3, 2, 1, 0, -1]
        System.out.println(arrayDeque.pop()); // 22
        System.out.println(arrayDeque);  //[10, 4, 3, 2, 1, 0, -1]

        //.poll  .peek  .size   .clear   .isEmpty 함수 모두 제공
    }
}

제네릭스(Generics)

다양한 타입의 객체들을 다루는 메소드나 컬렉션 클래스에 컴파일 시의 타입 체크를 해주는 기능을 의미
→ 객체의 타입을 컴파일 시에 체크하기 때문에 안정성이 높아진다.
(의도하지 않은 타입의 객체가 저장되는 것을 막고 잘못된 형변환을 막을 수 있다)

  • 제네릭스를 이용해서 짠 코드, 클래스, 메소드는 컨베이어벨트의 느낌.
  • 자바에서 짜는 클래스는 커피, 콜라, 주스의 느낌
  • 동작은 같지만 클래스 타입만 바뀌어야 하는 경우를 쉽게 다룰 수 있음

제네릭스 형식

public class 클래스명<T> {...}    //{} 안에 어떤 형식의 클래스가 오던지 T로 명칭할거임
public interface 인터페이스명<T> {...}
  • 자주 사용되는 타입인자 약어
    • == Type
    • == Element
    • == Key
    • == Value
    • == Number
    • == Result

강의를 한 번 보는걸로는 이해가 잘 안된다.. 다른 자료들도 더 찾아봐야겠다.

람다식(Lambda expression)

: 식별자 없이 실행 가능한 함수

  • 함수의 이름을 따로 정의하지 않고 함수처럼 사용할 수 있음
  • 문법이 간결하여 편리함

무조건 좋다고만 이야기 할 수는 없다 Why?
- 람다를 사용하여서 만든 익명 함수는 재사용이 불가능
- 람다만을 사용할 경우 비슷한 메소드를 중복되게 생성할 가능성이 있으므로 지저분해질 수 있다

  • 형식
    • 기존의 메소드 형식
      반환타입 메소드이름(매개변수 선언) {
      수행 코드 블록
      }
    • 람다식의 형식
      반환타입 메소드이름(매개변수 선언) -> {
      수행 코드 블록
      }

  • 이중콜론(::) 연산자
    : 매개변수를 중복해서 사용하고 싶지 않을 때 사용

스트림

스트림은 곧 '데이터의 흐름'입니다.

  • 컬렉션의 저장 요소를 하나씩 참조해서 람다식으로 처리할 수 있도록 해주는 반복자
  • 스트림을 활용해서 필터링,데이터 변경, 다른 타입이나 자료구조로 변환 등을 할 수 있다
  • 특징

    • 데이터소스를 변경하지 않음
    • 작업을 내부적으로 반복 처리
    • 닫히면 재사용 불가 필요하다면 재생성을 해야함
  • 구조

    1. 스트림 생성
    • Stream<T> Collection.stream() 을 이용하여 해당하는 컬렉션을 기반으로하는 스트림 생성
    1. 중간 연산
    • 데이터의 형변환 혹은 필터링, 정렬 등 스트림 가공
    • map(변환) / sorted(정렬) / skip(스트림 자르기) / limit(스트림 자르기) 등
    1. 최종 연산
    • 스트림의 요소를 소모해서 결과 반환.
    • 최종 연산 이후에는 스트림이 닫히게 되고 더 이상 사용할 수 없음
    • 많이 쓰이는 패턴
      • collect()를 이용해서 다른 콜렉션으로 바꾸기
      • reduce를 이용해서 incremental calculation하기

예제1

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("서울");
        list.add("부산");
        list.add("대구");
        list.add("서울");

        System.out.println(list);  //[서울, 부산, 대구, 서울]

        //다른 리스트로 바꾸기
        List<String> result = list.stream()
                .limit(2)    // 앞에 두개만 남기고 지워
                .collect(Collectors.toList());   //스트림 처리된 걸 하나로 모을건데 Collectors.toList() 이렇게 모을거야
        System.out.println(result);   //[서울, 부산]

        //자료구조 바꾸기
        System.out.println("list -> transformation -> set");
        Set<String> set = list.stream()
                .filter("서울"::equals)   // 받은게 서울이랑 문자가 같은지 보고 같으면 남겨
                .collect(Collectors.toSet()); //이걸 set의 자료구조로 바꿔서 모아줄거야

        System.out.println(set);  //[서울]
    }
}

예제 2

import java.util.Arrays;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        String[] arr = {"SQL", "Java", "Python"};
        Stream<String> stringStream = Arrays.stream(arr);
        stringStream.forEach(System.out::println);  //하나씩 개행해서 출력
        //SQL
        //Java
        //Python
    }
}

예제 3

  • build.gradle의 dependencies 코드 블럭에 libray 추가하고 진행
    • Pair 클래스 쓸 수 있게
import org.apache.commons.lang3.tuple.Pair;

import java.util.Arrays;
import java.util.List;

class Sale {
    String fruitName;
    int price;
    float discount;

    public Sale(String fruitName, int price, float discount) {
        this.fruitName = fruitName;
        this.price = price;
        this.discount = discount;
    }
}

public class Main {
    public static void main(String[] args) {
        List<Sale> sales = Arrays.asList(
                new Sale("Apple", 5000, 0.05f),
                new Sale("Orange", 4000, 0.2f),
                new Sale("Grape", 2000, 0)
        );

        sales.stream()
                .map(sale -> Pair.of(sale.fruitName, sale.price*(1-sale.discount)))
                .forEach(pair -> System.out.println(pair.getLeft() + "실구매가: "+ pair.getRight()+"원 입니다."));

//Apple실구매가: 4750.0원 입니다.
//Orange실구매가: 3200.0원 입니다.
//Grape실구매가: 2000.0원 입니다.
    }
}

예제 4. reduce 이용

import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        System.out.println(list.stream().reduce(0, Integer::sum));
        //identity로 시작해서 list에서 하나씩 꺼내서 reduce.오른쪽 함수를 실행할거야
        // 0 + 1 + 2 + 3 + 4 ...
        // 55
    }
}
Javadoc : 자바의 패키지, 클래스 등 명세를 볼 수있음

에러

java: illegal start of expression
직역하면 '표현의 시작이 옳지 않다' == 문법오류

    • 마지막 항목의 ,가 있어서 에러 발생



마무리

오늘은 알고리즘 타임어택도 있었다.
프로그래머스를 사용해서 4문제를 풀었다.
그래서 오늘 프로그래머스 문제풀기는 패스~!
타임어택으로 푼 문제는 따로 포스팅하기로 하고,

자바 기초 문법 강의를 완강했는데...
초반엔 파이썬하고 비슷한 부분이 있어서 어느 정도 이해는 갔는데
뒤로 갈수록 너무 어려웠다.
하루 빨리 자바 문법 책을 구입해서 좀 더 자세한 내용을 공부해야겠다.

그리고
til로 작성한 내용을 한 곳에 몰아 정리해야겠다.
나중에 관련 내용 찾아보기 좀 힘들듯..ㅎㅎ

할 건 많은데 피곤하고 하루는 짧고..
공부 쉽지 않네!
오히려 좋아🤣🤣

profile
기록하자기록해!

0개의 댓글