Sparta/What I Learned

22.12.6

코딩하는 또롱이 2022. 12. 7. 01:41

어제 못 다한 Map 정리를 끝내고 자바 완강!

 

컬렉션 프레임워크
Stack, Queue, ArrayDeque
▶️ Stack
- 마지막에 저장한 데이터를 가장 먼저 꺼내는 자료구조 (LIFO)

이런 식으로 처음에 들어간 데이터들 위로 나중에 들어간 데이터들이 쌓이면서 나중 데이터들 먼저 빠져나오는 것이 스택이다❗

 

▶️ 예제

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(9);
        stack.push(5);
        stack.push(7);

        System.out.println(stack);
        System.out.println(stack.peek());
        System.out.println("peek() size : " + stack.size());
        System.out.println(stack.pop());
        System.out.println("pop() size : " + stack.size());

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

peek()은 stack의 제일 마지막 데이터를 확인하고 삭제 없이 값만 가져온다.

pop()은 맨 마지막 데이터를 return 하면서 삭제 한다.

empty()는 stack이 비어있으면 true, 데이터가 한 개라도 있으면 false를 반환한다.

 

 

▶️ Queue
- 처음에 저장한 데이터를 가장 먼저 꺼낸다.(FIFO)

▶️ 예제

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);
        System.out.println(queue.poll());
        System.out.println(queue);
        System.out.println(queue.peek());
        System.out.println(queue);
    }
}

 

Queue에서 poll() 함수 제일 먼저 반환되는 데이터를 보여주고 삭제시킨다.

Queue에서의 peek() 함수는 제일 먼저 반환되는 데이터를 보여주고 값은 그대로 유지한다.

stack과 마찬가지로 clear(), isEmpty(), size() 사용 간응. (empty() 불가능)

 

▶️ ArrayDeque
- 기본 Stack, Queue의 기능을 모두 포함하면서도 성능이 더 좋아 실무에서 많이 사용

▶️ 예제

import java.util.ArrayDeque;

public class Main {
    public static void main(String[] args) {
        ArrayDeque<Integer> arrayDeque = new ArrayDeque<>();
        arrayDeque.addFirst(1);
        arrayDeque.addFirst(2);
        arrayDeque.addFirst(3);
        arrayDeque.addFirst(4);
        System.out.println(arrayDeque);

        arrayDeque.addLast(0);
        arrayDeque.addLast(9);
        System.out.println(arrayDeque);

        arrayDeque.offerFirst(10);
        System.out.println(arrayDeque);

        arrayDeque.offerLast(-1);
        System.out.println(arrayDeque);

        arrayDeque.push(22);
        System.out.println(arrayDeque);
        System.out.println(arrayDeque.pop());
        System.out.println(arrayDeque);

        System.out.println(arrayDeque.peek());
        System.out.println(arrayDeque);

        System.out.println(arrayDeque.poll());
        System.out.println(arrayDeque);

        System.out.println(arrayDeque.size());
        arrayDeque.clear();
        System.out.println(arrayDeque);
        System.out.println(arrayDeque.isEmpty());
    }
}

 

offerFirst() arrayDeque의 크기에 문제가 생길 때 false 값 리턴.

arrayDeque에서 peek(), poll(), pop() 함수를 쓰면 Front쪽 data를 반환한다.

  Stack Queue ArrayDeque
peek() 데이터 보여주고 삭제 데이터 보여주고 유지 데이터 보여주고 유지
pop() 데이터 보여주고 유지   데이터 보여주고 삭제
poll()   데이터 보여주고 삭제 데이터 보여주고 삭제

 

 

 

제네릭스
다양한 타입의 객체들을 다루는 메소드나 컬렉션 클래스에 컴파일 시의 타입 체크를 해주는 기능을 의미

 

👉 제네릭스를 왜 사용해야할까?

- 객체의 타입을 컴파일 시에 체크하기 때문에 안정성이 높아진다.

- 의도하지 않은 타입의 객체가 저장되는 것을 막고 잘못된 형변환을 막을 수 있기 때문이다.

- 윈도우는 Ctrl+클릭 / 맥은 Commend+클릭을 이용해 명세 확인이 가능하다.

 

👉 제네릭스의 형식

public class 클래스명<T> {...}
public interface 인터페이스명<T> {...}

 

👉 자주 사용되는 타입인자 약어

  • <T> == Type
  • <E> == Element
  • <K> == Key
  • <V> == Value
  • <N> == Number
  • <R> == Result (Return)

타입이 달라서 컴파일 에러났다.

▶️ 예제

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

public class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList();
        list.add("string");
        Collection<String> collection = list; // List의 상위가 Collection

        List<Exception> exceptionList = new ArrayList<>();
        Collection<Exception> exceptionCollection = exceptionList;

        List<IllegalArgumentException> exceptions = new ArrayList<>();
        exceptionCollection.addAll(exceptions);
    }
}

exceptions가 exceptionList의 자손 클래스라서 컴파일 에러 없이 ? extend E라는 명에 의해 addAll()을 쓸 수 있다.

 

 

 

 

람다(익명 함수)

▶️ 장점

식별자 없이 실행 가능한 함수 (함수의 이름을 따로 정의하지 않아도 곧바로 함수처럼 사용할 수 있는 것)

문법이 간결하여 보다 편리한 방식

 

▶️ 단점

람다를 사용하여서 만든 익명 함수는 재사용이 불가능하다.

→ 람다만을 사용할 경우 비슷한 메소드를 중복되게 생성할 가능성이 있으므로 지저분해질 수 있다.

 

▶️ 형식

[기존의 메소드 형식]

반환타입 메소드이름(매개변수 선언) {
               수행 코드 블록
}

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

 

▶️ 예제

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Korea");
        list.add("Usa");
        list.add("Uk");

        Stream<String> stream = list.stream();
        stream.map(str -> str.toUpperCase()).forEach(it -> System.out.println(it));
    }
}

▶️ 예제

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Korea");
        list.add("Usa");
        list.add("Uk");

        Stream<String> stream = list.stream();
        stream.map(str -> {
            System.out.println(str);
            return str.toUpperCase();
        }).forEach(it -> System.out.println(it));
    }
}

중괄호를 쓸 경우엔 함수처럼 return 값을 주어야 한다.

▶️ 예제

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Korea");
        list.add("Usa");
        list.add("Uk");

        Stream<String> stream = list.stream();
        stream.map(str -> {
            System.out.println(str);
            return str.toUpperCase();
        }).forEach(System.out::println);
    }
}

메서드가 하나일 경우 forEach 문이 이렇게 간결하게 표시 가능❗❗

 

 

 

스트림
데이터의 흐름

 

▶️ 스트림?

- 컬렉션의 저장 요소를 하나씩 참조해서 람다식으로 처리할 수 있도록 해주는 반복자이다.

- 스트림을 활용해서 필터링,데이터 변경, 다른 타입이나 자료구조로 변환 등을 할 수 있다.

 

▶️특징

- 데이터 소스를 변경하지 않는다.

- 작업을 내부적으로 반복 처리한다.

- 컬렉션의 요소를 모두 읽고 나면 닫혀서 재사용이 불가능하다. 필요할 경우 재생성을 해야만한다.

 

▶️ 구조

 

스트림 생성

  • 스트림을 이용하기 위해 먼저 스트림을 생성해야한다.
  • Stream<T> Collection.stream() 을 이용하여 해당하는 컬렉션을 기반으로하는 스트림을 생성할 수 있다. 

중간 연산

  • 중간 단계로써 데이터의 형변환 혹은 필터링, 정렬 등 스트림에 대한 가공을 해야 한다.
  • map(변환) / sorted(정렬) / skip(스트림 자르기) / limit(스트림 자르기) 등이 있다.

최종 연산

  • 스트림의 요소를 소모해서 결과를 반환하는 단계이다, 최종 연산 이후에는 스트림이 닫히게 되고 더 이상 사용할 수 없다.
  • 최종 연산의 결과값은 단일 값일 수도 있고, 배열 혹은 컬렉션일 수도 있다.
  • collect()를 이용해서 다른 콜렉션으로 바꾸는 것, reduce를 이용해서 incremental calculation하는 것도 가장 많이 쓰이는 패턴 중 하나이다.

▶️ 예제 (위의 스트림 예제 그대로)

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Korea");
        list.add("Usa");
        list.add("Uk");

        Stream<String> stream = list.stream();
        stream.map(str -> {
            System.out.println(str);
            return str.toUpperCase();
        }).forEach(System.out::println);

        System.out.println(list);
    }
}

처음 add 된 그대로 list는 아무런 변화 없이 그대로 출력 됨을 알 수있다. (데이터 소스 변경 X)

Stream 내부에서만 작업이 진행된다.(내부적으로 반복 처리)

forEach는 return type이 void라 뒤에 함수가 올 수 없다. 즉 Stream이 닫히게 된다.(닫혀서 재사용이 불가능)

 

 

 

 

▶️ 예제

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

        System.out.println(result);

        System.out.println("list -> transformation -> set");
        Set<String> set = list.stream()
                .filter(it -> "서울".equals(it))
                .collect(Collectors.toSet());

        System.out.println(set);

    }
}

👉 System.out.println("list -> transformation -> set");

 list의 자료구조를 set으로 변경하겠다는 의미

 

👉Set<String> set = list.stream()
        .filter(it -> "서울".equals(it))
        .collect(Collectors.toSet());

"서울"이랑 일치하면 set으로 변경

 

set은 중복을 허용하지 않으므로 [서울]이 출력된다.

Set<String> set = list.stream()
        .filter("서울"::equals)
        .collect(Collectors.toSet());

이렇게 메서드 참조형으로 바꿀 수 있다.

 

 

▶️ 예제

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);
        //array가 stream으로 변경

        stringStream.forEach(System.out::println);
    }
}

 

▶️ 예제(Map)

import org.apache.commons.lang3.tuple.Pair;

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

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("사과", 5000, 0.25f),
                new Sale("체리", 8000, 0.03f),
                new Sale("멜론", 9000, 0.1f)
        );

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

 

▶️ 예제

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));
        // 첫 시작을 0으로 배열을 전부 더하겠다는 의미
        // 55
    }
}

 

🚨 스트림 퀴즈

'이'씨 성을 가진 사람들의 수를 세볼려고 합니다. 스트림을 활용해서 코드를 만들어보세요!

이름 : ["김정우", "김호정", "이하늘", "이정희", "박정우", "박지현", "정우석", "이지수"]

힌트! 다음 Javadoc (자바의 클래스 명세)를 확인하시고 참고해보세요.

 

String (Java Platform SE 8 )

Compares two strings lexicographically. The comparison is based on the Unicode value of each character in the strings. The character sequence represented by this String object is compared lexicographically to the character sequence represented by the argum

docs.oracle.com

 

Stream (Java Platform SE 8 )

A sequence of elements supporting sequential and parallel aggregate operations. The following example illustrates an aggregate operation using Stream and IntStream: int sum = widgets.stream() .filter(w -> w.getColor() == RED) .mapToInt(w -> w.getWeight())

docs.oracle.com

더보기
import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("김정우", "김호정", "이하늘", "이정희", "박정우", "박지현", "정우석", "이지수");
        System.out.println("이씨 성을 가진 사람 수 : "+
                names.stream()
                        .filter(name -> name.startsWith("이"))
                        .count()
                +"명");

    }
}

 

 

 

 

네트워킹 - OpenAPI

http는 보안 x, https는 보안 o

URL의 형식 :  '프로토콜://호스트명:포트번호/경로명/파일명?쿼리스트링#참조' 

 

http는 통신에 대한 약속

api는 데이터에 대한 약속

 

<api 예제 사이트>

 

Reqres - A hosted REST-API ready to respond to your AJAX requests

Native JavaScript If you've already got your own application entities, ie. "products", you can send them in the endpoint URL, like so: var xhr = new XMLHttpRequest(); xhr.open("GET", "https://reqres.in/api/products/3", true); xhr.onload = function(){ conso

reqres.in

[RetrofitService]

import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;

public interface RetrofitService {
    @GET("/api/users/")
    Call<Object> getUsers(@Query("page") int page);


}

 

[RetrofitClient]

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitClient {

    private static final String BASE_URL = "https://reqres.in";

    public static RetrofitService getApi(){
        return getInstance().create(RetrofitService.class);
    }

    private static Retrofit getInstance(){
        Gson gson  = new GsonBuilder().setLenient().create();
        return new Retrofit.Builder().baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();
    }
}

 

[Main]

import retrofit2.Call;

import java.io.IOException;

public class Main {
    public static void main(String[] args) {
        Call<Object> result = RetrofitClient.getApi().getUsers(3);

        try{
            System.out.println(result.execute().body());
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }
}

솔직히 아직 뭔말인지 모르겠는데 내가 파이참에서 했던 거랑 비슷한 결이겠지 싶은,,,,?

'Sparta > What I Learned' 카테고리의 다른 글

22.12.8  (0) 2022.12.08
22.12.7  (0) 2022.12.07
22.12.5  (1) 2022.12.05
22.12.4  (0) 2022.12.05
22.12.2  (0) 2022.12.03